<style id="sas-global-polish">
html,body{overflow-x:hidden!important;max-width:100%!important}body #masthead.site-header{position:sticky!important;top:0!important;z-index:100!important;background:rgba(255,255,255,.94)!important;border-bottom:1px solid #e6edf6!important;box-shadow:0 10px 30px rgba(15,23,42,.055)!important;backdrop-filter:blur(14px)!important}body #masthead .site-title-centered{max-width:1320px!important;margin:0 auto!important;padding:10px 24px!important;display:flex!important;align-items:center!important;justify-content:space-between!important;gap:28px!important}body #masthead .site-branding{display:flex!important;align-items:center!important;min-width:250px!important;margin:0!important;padding:0!important;text-align:left!important}body #masthead .site-title{margin:0!important;line-height:1!important;display:flex!important;align-items:center!important}body #masthead img.custom-logo{width:190px!important;max-width:190px!important;height:auto!important;display:block!important}body #masthead .site-description,body #masthead .social-links,body #masthead .top-search{display:none!important}body #masthead .main-navbar{flex:1!important;background:transparent!important;border:0!important;box-shadow:none!important;margin:0!important;padding:0!important}body #masthead .main-navbar .container{max-width:none!important;width:100%!important;margin:0!important;padding:0!important;display:flex!important;align-items:center!important;justify-content:flex-end!important}body #site-navigation{display:flex!important;justify-content:flex-end!important;width:auto!important;float:none!important;margin:0!important;padding:0!important}body #site-navigation ul.main-menu{display:flex!important;align-items:center!important;justify-content:flex-end!important;gap:6px!important;margin:0!important;padding:0!important;list-style:none!important;flex-wrap:wrap!important}body #site-navigation ul.main-menu>li{margin:0!important;padding:0!important;float:none!important;display:block!important}body #site-navigation ul.main-menu>li>a{display:flex!important;align-items:center!important;min-height:38px!important;padding:9px 13px!important;border-radius:999px!important;color:#334155!important;font-size:14px!important;font-weight:800!important;line-height:1!important;text-decoration:none!important;background:transparent!important;transition:.18s ease!important}body #site-navigation ul.main-menu>li.current-menu-item>a,body #site-navigation ul.main-menu>li>a:hover{background:#eff6ff!important;color:#1d4ed8!important}body.content-sidebar #primary,body #primary.content-area,body #primary,body .content-area{float:none!important;width:100%!important;max-width:100%!important;display:block!important;padding:0!important;margin:0!important}body #secondary,body aside#secondary,body .sidebar.widget-area,body .widget-area{display:none!important;visibility:hidden!important;width:0!important;max-width:0!important;padding:0!important;margin:0!important}body #content.site-content,body #content .container,body #content .inside,body .site-content,body .container,body .inside,body #main.site-main{width:100%!important;max-width:100%!important;padding-left:0!important;padding-right:0!important;margin-left:0!important;margin-right:0!important}body:not(.page-id-11) .entry-header,body:not(.page-id-11) .entry-content,body:not(.page-id-11) .entry-footer{max-width:980px!important;margin-left:auto!important;margin-right:auto!important;padding-left:22px!important;padding-right:22px!important}body.archive #main,body.blog #main,body.search #main{max-width:1180px!important;margin:0 auto!important;padding:28px 22px!important}@media(max-width:920px){body #masthead .site-title-centered{display:block!important;padding:10px 16px!important}body #masthead .site-branding{justify-content:center!important;margin-bottom:10px!important}body #masthead img.custom-logo{width:170px!important}body #site-navigation,body #site-navigation ul.main-menu{justify-content:center!important}body #site-navigation ul.main-menu>li>a{font-size:13px!important;padding:8px 10px!important}}@media(max-width:560px){body #site-navigation ul.main-menu{gap:4px!important}body #site-navigation ul.main-menu>li>a{font-size:12px!important;padding:7px 9px!important}body #masthead img.custom-logo{width:150px!important}body:not(.page-id-11) .entry-header,body:not(.page-id-11) .entry-content,body:not(.page-id-11) .entry-footer{padding-left:14px!important;padding-right:14px!important}}
</style>
<style>.sas-lesson{max-width:940px;margin:0 auto;padding:38px 18px 78px;font-family:Inter,"Segoe UI",Arial,sans-serif;color:#344054;font-size:17px;line-height:1.86}.sas-lesson h1,.sas-lesson h2,.sas-lesson h3{color:#172033;letter-spacing:-.02em;line-height:1.22}.sas-lesson h1{font-size:clamp(34px,5vw,56px);margin:0 0 18px}.sas-lesson h2{font-size:29px;margin:38px 0 13px}.sas-lesson h3{font-size:22px;margin:26px 0 10px}.sas-lesson .lead{font-size:18px;color:#667085;line-height:1.78}.sas-lesson .box,.sas-lesson .lab,.sas-lesson .warn,.sas-lesson .check,.sas-lesson .note{padding:20px 22px;border:1px solid #e4e7ec;border-radius:18px;background:#f8fafc;margin:23px 0}.sas-lesson .warn{background:#fff7ed;border-color:#fed7aa}.sas-lesson .lab{background:#eff6ff;border-color:#bfdbfe}.sas-lesson .check{background:#ecfdf3;border-color:#bbf7d0}.sas-lesson .note{background:#f5f3ff;border-color:#ddd6fe}.sas-lesson code{background:#eef2ff;padding:2px 6px;border-radius:6px;color:#1e3a8a}.sas-lesson pre{background:#0b1220;color:#dbeafe;padding:18px;border-radius:15px;overflow:auto;font-size:14px;line-height:1.72}.sas-lesson ul,.sas-lesson ol{line-height:1.86}.sas-lesson table{width:100%;border-collapse:collapse;margin:18px 0}.sas-lesson th,.sas-lesson td{border:1px solid #e4e7ec;padding:11px;text-align:left;vertical-align:top}.sas-lesson th{background:#f8fafc;color:#172033}.sas-lesson .next{margin-top:30px;padding:18px;border-radius:16px;background:#eff6ff;border:1px solid #bfdbfe}</style><div class="sas-lesson"><h1>Bài 38: Kubernetes Security: RBAC, Secret và NetworkPolicy</h1><p class="lead">Bài này chi tiết hóa Kubernetes Security theo hướng thực hành chuyên sâu: có lệnh kiểm tra, tình huống production, checklist và bài tập.</p><div class="box"><strong>Sau bài này anh sẽ biết:</strong><ul><li>Kubernetes Security nằm ở đâu trong hạ tầng production.</li><li>Các thành phần và lệnh kiểm tra quan trọng.</li><li>Cách debug khi có lỗi thực tế.</li><li>Checklist an toàn trước khi thao tác.</li></ul></div><h2>1. Bối cảnh thực tế</h2><p>Kubernetes Security là nhóm kiến thức chuyên sâu hơn. Mục tiêu không phải học thuộc lệnh, mà là biết kiểm tra đúng lớp, đọc đúng trạng thái và tránh thao tác gây mất dữ liệu hoặc downtime.</p><h2>2. Khái niệm cần nắm</h2><ul><li><strong>Control plane / data plane:</strong> phần điều khiển và phần chạy tải thật.</li><li><strong>Stateful vs stateless:</strong> ứng dụng có dữ liệu bền vững cần xử lý cẩn thận hơn.</li><li><strong>Health:</strong> trạng thái tổng thể phải nhìn từ nhiều nguồn: service, log, metric, endpoint.</li><li><strong>Blast radius:</strong> phạm vi ảnh hưởng nếu thao tác sai.</li></ul><h2>3. Lab thực hành / lệnh kiểm tra</h2><div class="lab"><strong>Mục tiêu:</strong> dùng lệnh để quan sát trạng thái, không sửa production khi chưa hiểu.</div><pre>kubectl get role,rolebinding -A
kubectl get clusterrolebinding
kubectl auth can-i get pods –as user@example.com -n default
kubectl get secret -A
kubectl get networkpolicy -A
kubectl describe networkpolicy -n app</pre><h2>4. Tình huống thực tế</h2><div class="note"><p>Một user dev có quyền quá rộng. Anh kiểm tra RoleBinding/ClusterRoleBinding, dùng can-i để xác nhận quyền và giảm quyền theo nguyên tắc least privilege.</p></div><h2>5. Quy trình debug an toàn</h2><ol><li>Xác định triệu chứng: lỗi gì, xảy ra từ khi nào, ảnh hưởng ai.</li><li>Kiểm tra trạng thái tổng quan bằng lệnh read-only trước.</li><li>Đọc event/log liên quan.</li><li>Khoanh vùng: network, storage, compute, config hay application.</li><li>Chỉ thay đổi một thứ tại một thời điểm.</li><li>Kiểm tra lại health sau mỗi thay đổi.</li><li>Ghi lại nguyên nhân và bài học.</li></ol><h2>6. Lỗi thường gặp</h2><ul><li>Thấy cảnh báo là chạy lệnh sửa ngay mà không đọc nguyên nhân.</li><li>Không phân biệt lỗi control plane và lỗi workload.</li><li>Xóa resource/volume/secret khi chưa backup.</li><li>Không kiểm tra quyền truy cập và audit log.</li></ul><div class="warn"><strong>Lưu ý production:</strong> Với Kubernetes, storage, cloud và security, lệnh xóa/sửa sai có thể ảnh hưởng nhiều workload. Ưu tiên lệnh xem trạng thái trước.</div><h2>7. Checklist</h2><div class="check"><ul><li>Đã dùng lệnh read-only để kiểm tra.</li><li>Đã xác định resource/service bị ảnh hưởng.</li><li>Đã đọc log/event trước khi sửa.</li><li>Đã có backup/snapshot nếu liên quan dữ liệu.</li><li>Đã có phương án rollback hoặc escalation.</li></ul></div><h2>8. Bài tập</h2><ol><li>Dựng lab hoặc dùng môi trường test.</li><li>Chạy các lệnh kiểm tra trong bài.</li><li>Ghi lại output bình thường.</li><li>Mô phỏng một lỗi nhỏ nếu an toàn.</li><li>Viết runbook 5 bước cho sự cố tương tự.</li></ol><div class="next"><strong>Bài tiếp theo:</strong> GitOps với Argo CD cơ bản</div></div>
Chốt ý nhanh
| Chủ đề | Điểm cần nhớ |
|---|---|
| RBAC | Giới hạn ai được làm gì trong cluster, là nền bảo vệ nền tảng nhất của Kubernetes. |
| Secret | Lưu thông tin nhạy cảm theo cách có tổ chức hơn hard-code trong manifest, nhưng không có nghĩa tự động an toàn tuyệt đối. |
| NetworkPolicy | Giúp kiểm soát pod nào được nói chuyện với pod nào, giảm lan rộng khi một workload bị compromise. |
Phần thực hành mở rộng: security trong Kubernetes là kiểm soát quyền và phạm vi ảnh hưởng
Kubernetes security rất dễ bị học theo kiểu liệt kê tính năng. Nhưng góc nhìn vận hành tốt hơn là: nếu một tài khoản, pod hay namespace gặp sự cố, nó lan được tới đâu? RBAC, Secret và NetworkPolicy đều xoay quanh câu hỏi đó.
Lab 1: Quan sát RBAC hiện có trong cluster
kubectl get roles,rolebindings -A
kubectl get clusterroles,clusterrolebindings
Lab này giúp anh thấy cluster thật ngoài đời thường đã có rất nhiều role mặc định, không nên cấp bừa quyền cluster-admin cho mọi thứ.
Lab 2: Kiểm tra quyền của một service account
kubectl auth can-i get pods --as=system:serviceaccount:default:default
kubectl auth can-i list secrets --as=system:serviceaccount:default:default -A
Đây là cách cực thực tế để kiểm tra phạm vi quyền thay vì đoán.
Lab 3: Tạo Secret và mount vào pod
kubectl create secret generic app-secret --from-literal=DB_PASSWORD=example123
kubectl describe secret app-secret
kubectl get secret app-secret -o yaml
Qua đây anh có thể giải thích luôn vì sao Secret base64 không đồng nghĩa với mã hóa thật nếu không có thêm lớp bảo vệ ở etcd và quyền truy cập.
Lab 4: Viết NetworkPolicy tối thiểu
Mô phỏng một policy chỉ cho pod frontend truy cập backend ở cổng cần thiết. Sau đó kiểm tra ứng dụng nào bị chặn ngoài ý muốn. Bài tập này buộc người học nghĩ về traffic thật, không chỉ copy policy.
Lab 5: Rà soát blast radius của một namespace
- service account nào đang có quyền quá rộng
- secret nào nhiều pod cùng đọc
- namespace có policy mặc định deny hay chưa
Tình huống thực tế
Một pod web bị khai thác RCE nhưng service account của nó lại đọc được secret toàn namespace, đồng thời cluster không có NetworkPolicy nên pod đó nói chuyện được khắp nơi. Lúc này sự cố nhỏ có thể thành sự cố toàn cụm chỉ vì quyền cấp quá rộng.
Lỗi phổ biến
- Cấp cluster-admin cho tool nội bộ chỉ để “cho chạy nhanh”.
- Nhét secret thẳng vào Git hoặc env file công khai.
- Tạo NetworkPolicy nhưng không hiểu default behavior của CNI.
- Không audit định kỳ service account và binding.
Kết bài
Nếu bài này chắc, anh sẽ nhìn Kubernetes security như bài toán giảm blast radius chứ không phải sưu tầm tính năng. Sang bài GitOps với Argo CD, tư duy quyền và kiểm soát thay đổi sẽ còn quan trọng hơn vì manifest bắt đầu đi qua một pipeline tự động hóa rộng hơn.
