Bảo mật môi trường Kubernetes là một nhiệm vụ quan trọng đối với bất kỳ tổ chức nào đang triển khai ứng dụng container hóa. Tính chất động và phân tán của Kubernetes tạo ra những thách thức bảo mật đặc thù, đòi hỏi một chiến lược phòng thủ nhiều lớp (defense-in-depth) toàn diện. Hướng dẫn này cung cấp các bước hành động cụ thể và ví dụ mã cho nhà phát triển và kỹ sư vận hành nhằm tăng cường bảo mật cho cụm Kubernetes — từ lúc xây dựng image đến khi chạy thực tế.
1. Bảo mật khi xây dựng Image và quét lỗ hổng
Hành trình bảo vệ cụm Kubernetes bắt đầu từ việc xây dựng các container image an toàn. Image có lỗ hổng là điểm vào chính của tin tặc. Mirantis từng cảnh báo rằng việc triển khai container image có lỗ hổng đã biết có thể làm tổn hại đến ứng dụng và hạ tầng. SentinelOne cũng nhấn mạnh rằng việc sử dụng image lỗi thời hoặc chứa lỗ hổng có thể gây ra rủi ro bảo mật nghiêm trọng.
Các Best practice khi xây dựng Image an toàn:
- Sử dụng Base Image tối giản: Chọn các base image nhẹ như
scratch
hoặcAlpine
. Những image này chỉ chứa các thành phần tối thiểu, giúp giảm bề mặt tấn công. - Dùng Multi-Stage Builds: Tận dụng Docker build nhiều giai đoạn để tách biệt phần phụ thuộc khi build và khi chạy. Cách này đảm bảo chỉ những thành phần cần thiết mới được đưa vào image cuối cùng.
- Chạy dưới người dùng không phải root: Cấu hình container chạy với user không phải root để giảm thiểu rủi ro khi bị khai thác.
- Loại bỏ công cụ không cần thiết: Gỡ bỏ các package, thư viện, và công cụ không sử dụng ra khỏi image production.
Tích hợp quét lỗ hổng vào quy trình CI/CD
Việc quét lỗ hổng nên là một phần không thể thiếu trong pipeline CI/CD. Các công cụ như Trivy, Clair có thể tự động quét image để tìm các lỗ hổng đã biết trước khi triển khai vào cụm. Ngoài ra, Snyk cũng cung cấp các công cụ như Snyk Container và Snyk Open Source để phát hiện và khắc phục lỗ hổng trong image và workload Kubernetes trong giai đoạn build.
Ví dụ mã: Dockerfile Multi-Stage an toàn và quét Image
Dưới đây là một ví dụ Dockerfile cho ứng dụng Go, sử dụng build nhiều giai đoạn với base image Alpine, và chạy bằng user không phải root:
# Stage 1: Build
FROM golang:1.20-alpine AS builder
WORKDIR /app
COPY . .
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp . # Stage 2: Run
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/myapp .
EXPOSE 8080
USER nobody # Run as non-root user
CMD ["./myapp"]
Sau khi build image:
docker build -t my-secure-app:latest .
Bạn có thể sử dụng Trivy để quét image:
trivy image my-secure-app:latest
Lệnh trên sẽ trả về báo cáo chi tiết các lỗ hổng được phát hiện trong image.
2. Kiểm soát quyền truy cập với RBAC
RBAC (Role-Based Access Control) là lớp bảo mật cốt lõi trong Kubernetes để kiểm soát ai có thể làm gì trong cụm. Cấu hình RBAC không đúng có thể dẫn đến rò rỉ quyền truy cập hoặc leo thang đặc quyền.
Best pratice Với RBAC:
- Nguyên tắc phân quyền tối thiểu (Principle of Least Privilege): Chỉ cấp đúng quyền tối thiểu cần thiết cho user, service account hoặc nhóm.
- Tách biệt role đọc và ghi: Không nên gộp quyền
get
,list
vớicreate
,delete
trong cùng một role. - Không sử dụng quyền
cluster-admin
mặc định: Hạn chế việc gán quyền này trừ khi thực sự cần. - Định kỳ kiểm tra vai trò và quyền: Loại bỏ các quyền không còn cần thiết.
Ví dụ: Role và RoleBinding
# Role chỉ cho phép đọc Pod trong namespace "dev"
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata: namespace: dev name: pod-reader
rules:
- apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"] # Gán Role này cho một service account
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata: name: read-pods namespace: dev
subjects:
- kind: ServiceAccount name: dev-sa namespace: dev
roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io
3. Chính sách mạng (Network Policies)
Mặc định, trong Kubernetes, tất cả các Pod có thể giao tiếp với nhau — điều này gây rủi ro bảo mật nghiêm trọng.
Cách khắc phục:
Sử dụng NetworkPolicy để kiểm soát luồng mạng giữa các Pod hoặc namespace.
Ví dụ: NetworkPolicy chặn mọi thứ, chỉ cho phép traffic từ một namespace nhất định
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: name: allow-from-monitoring namespace: dev
spec: podSelector: {} ingress: - from: - namespaceSelector: matchLabels: name: monitoring
Lưu ý:
- Đảm bảo CNI (Container Network Interface) bạn sử dụng hỗ trợ NetworkPolicy (như Calico, Cilium,...).
- Chính sách nên được xây dựng theo nguyên tắc “mặc định từ chối - allow-by-rule”.
4. Chính sách bảo mật Pod (Pod Security Standards)
Từ Kubernetes 1.25, PodSecurity admission được dùng để áp dụng các chính sách bảo mật ở cấp namespace, thay thế cho PodSecurityPolicy (PSP).
Ba cấp độ chính:
privileged
: Cho phép tất cả — KHÔNG nên dùng trong productionbaseline
: Cho phép các thao tác cơ bản, ngăn hành vi nguy hiểmrestricted
: Giới hạn tối đa — phù hợp nhất cho môi trường production
Ví dụ: Gán cấu hình Pod Security Admission ở cấp namespace
apiVersion: v1
kind: Namespace
metadata: name: secure-namespace labels: pod-security.kubernetes.io/enforce: "restricted" pod-security.kubernetes.io/audit: "baseline" pod-security.kubernetes.io/warn: "baseline"
5. Giám sát, ghi Log và Audit
Audit Logging:
- Bật audit logs để giám sát hoạt động người dùng và service account trong cụm.
- Có thể cấu hình audit-policy.yaml để lọc và lưu trữ các hành vi quan trọng.
Giám sát thời gian thực:
- Dùng Falco, Sysdig hoặc OpenTelemetry để phát hiện hành vi bất thường.
- Tích hợp alert với Prometheus + Grafana hoặc ELK stack.
6. Cấu hình Runtime an toàn
Khi Pod đang chạy, cần đảm bảo chúng không vượt quá quyền hoặc gây rủi ro hệ thống:
- Không mount Docker socket (
/var/run/docker.sock
) - Dùng
readOnlyRootFilesystem: true
trong cấu hình Pod - Gán resource limit để tránh chiếm dụng quá mức
- Chạy container với
runAsNonRoot: true
,allowPrivilegeEscalation: false
Ví dụ:
securityContext: runAsNonRoot: true readOnlyRootFilesystem: true allowPrivilegeEscalation: false
Kết luận
Bảo mật Kubernetes không phải là công việc “thiết lập một lần là xong” — đó là một quy trình liên tục từ build image đến giám sát runtime. Việc áp dụng các chiến lược như:
- Xây dựng image an toàn
- Quét lỗ hổng định kỳ
- RBAC tối thiểu
- Chính sách mạng hạn chế
- Ghi log và audit đầy đủ
… sẽ giúp bạn bảo vệ cụm Kubernetes hiệu quả hơn trước các mối đe dọa ngày càng tinh vi.
Cảm ơn các bạn đã theo dõi!