Chính sách bảo mật Kubernetes với Kyverno: Thực thi Admission Control trong môi trường Production

Security tutorial - IT technology blog
Security tutorial - IT technology blog

Vấn đề: Sự hỗn loạn tiềm ẩn từ lỗi cấu hình sai trong Kubernetes

Với 8 nhóm kỹ sư và 3 cụm production đang vận hành hơn 450 pod, tốc độ triển khai của chúng tôi rất nhanh. Tuy nhiên, các rào chắn bảo mật gần như không tồn tại. Trong một đợt audit định kỳ, chúng tôi phát hiện 14 workload đang chạy dưới quyền root, 2 pod dùng để troubleshooting chạy với toàn quyền truy cập host qua privileged: true, cùng hàng chục deployment bỏ trống hoàn toàn giới hạn CPU và bộ nhớ.

Không thiết lập admission control trong Kubernetes cũng tương tự như việc mở cổng SSH root công khai ra internet. Việc phụ thuộc vào review pull request hay checklist thủ công sẽ thất bại ngay khi các nhóm đẩy lên tới 30 lượt deploy mỗi ngày. Các cấu hình lỗi chắc chắn sẽ bị lọt lưới. Chúng tôi cần những rào chắn tự động ngay tại tầng API server để từ chối các cấu hình rủi ro trước khi chúng kịp chạm tới các worker node.

Ban đầu chúng tôi đã thử nghiệm Open Policy Agent (OPA) Gatekeeper. Dù rất mạnh mẽ, nhưng việc viết và duy trì chính sách bằng ngôn ngữ Rego tạo ra một rào cản học hỏi không cần thiết cho các lập trình viên và kỹ sư nền tảng. Trở ngại đó đã dẫn chúng tôi đến với Kyverno.

Khái niệm cốt lõi: Vì sao Kyverno phù hợp hoàn hảo với quy trình Kubernetes gốc

Kyverno hoạt động như một dynamic admission controller bên trong cụm của bạn. Nó đăng ký với Kubernetes API server thông qua các endpoint ValidatingAdmissionWebhook và MutatingAdmissionWebhook để kiểm tra manifest của tài nguyên trong mỗi yêu cầu tạo mới, cập nhật hoặc xóa.

Khác với các công cụ yêu cầu ngôn ngữ chuyên biệt (DSL), chính sách của Kyverno là các Custom Resource Definition (CRD) chuẩn của Kubernetes. Nếu đội ngũ của bạn đã biết viết Pod spec bằng YAML, họ đã biết cách viết chính sách cho Kyverno.

Bốn chế độ chính sách

  • Validate: Đánh giá các manifest gửi đến dựa trên các quy tắc. Nó sẽ chặn các yêu cầu không tuân thủ ở chế độ Enforce hoặc cho phép tiếp tục đồng thời ghi log cảnh báo ở chế độ Audit.
  • Mutate: Chỉnh sửa tài nguyên linh hoạt ngay lập tức trước khi lưu vào etcd. Các trường hợp sử dụng điển hình bao gồm chèn security context mặc định, gắn nhãn phân bổ chi phí (cost-center) hoặc thêm sidecar container.
  • Generate: Tự động tạo các tài nguyên phụ trợ khi có sự kiện kích hoạt, chẳng hạn như khởi tạo sẵn NetworkPolicy và RoleBinding mặc định mỗi khi có ai đó tạo Namespace.
  • Verify Images: Kiểm tra chữ ký số của container image với khóa Cosign/Sigstore và xác thực thông tin SBOM (Software Bill of Materials) tại thời điểm tiếp nhận.

Thực hành: Triển khai Kyverno và bảo mật cụm Kubernetes

Dưới đây là chi tiết các bước thiết lập và bộ chính sách chúng tôi đã triển khai để loại bỏ hoàn toàn privileged container và bắt buộc chạy dưới quyền non-root trên toàn bộ các cụm.

Bước 1: Cài đặt Kyverno qua Helm

Cài đặt Kyverno vào một namespace riêng bằng Helm chart chính thức. Đối với môi trường production, hãy chạy 3 replica để đảm bảo tính sẵn sàng cao (HA) trong quá trình nâng cấp cụm:

# Thêm và cập nhật Helm repository của Kyverno
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update

# Triển khai Kyverno với các replica chuẩn HA
helm install kyverno kyverno/kyverno \
  --namespace kyverno \
  --create-namespace \
  --set replicaCount=3

Xác nhận các controller pod đang hoạt động ổn định và webhook đã được đăng ký thành công:

kubectl get pods -n kyverno
kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations

Bước 2: Chặn Privileged Container (Quy tắc Validation)

Thiết lập privileged: true sẽ vô hiệu hóa cơ chế cô lập container và trao gần như toàn quyền truy cập vào kernel của máy chủ host. ClusterPolicy dưới đây sẽ chặn privileged container trên phạm vi toàn cụm:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-privileged-containers
  annotations:
    policies.kyverno.io/title: Không cho phép Privileged Containers
    policies.kyverno.io/category: Pod Security Standards
    policies.kyverno.io/severity: high
    policies.kyverno.io/description: >-
      Các privileged container chia sẻ quyền root với hệ điều hành máy chủ host.
      Chính sách này đảm bảo không container nào được phép chạy ở chế độ privileged.
spec:
  validationFailureAction: Enforce
  background: true
  rules:
    - name: validate-privileged
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "Chế độ Privileged bị nghiêm cấm. Vui lòng đặt securityContext.privileged thành false."
        pattern:
          spec:
            containers:
              - =(securityContext):
                  =(privileged): "false"

Áp dụng chính sách vào cụm của bạn:

kubectl apply -f disallow-privileged-containers.yaml

Bước 3: Tự động Mutate tài nguyên để bắt buộc thực thi Non-Root

Thay vì từ chối mọi deployment mà lập trình viên quên khai báo security context, bạn có thể dùng chính sách mutate. Nó sẽ tự động chèn runAsNonRoot: true bất cứ khi nào trường này bị thiếu:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: mutate-non-root-execution
spec:
  rules:
    - name: set-run-as-non-root
      match:
        any:
          - resources:
              kinds:
                - Pod
      mutate:
        patchStrategicMerge:
          spec:
            securityContext:
              runAsNonRoot: true

Bước 4: Kiểm tra việc thực thi chính sách trong thực tế

Kiểm tra hoạt động thực thi bằng cách thử deploy một pod thử nghiệm được cấu hình với đặc quyền host:

apiVersion: v1
kind: Pod
metadata:
  name: rogue-priv-pod
spec:
  containers:
    - name: alpine-test
      image: alpine:latest
      command: ["sleep", "3600"]
      securityContext:
        privileged: true

Gửi manifest lên cụm bằng kubectl:

kubectl apply -f rogue-priv-pod.yaml

API server sẽ lập tức chặn việc tiếp nhận và trả về thông báo lỗi tùy chỉnh của bạn:

Error from server: error when creating "rogue-priv-pod.yaml": admission webhook "validate.kyverno.svc" denied the request:

policy Pod/default/rogue-priv-pod for resource violation:

disallow-privileged-containers:
  validate-privileged: Chế độ Privileged bị nghiêm cấm. Vui lòng đặt securityContext.privileged thành false.

Bước 5: Audit các workload hiện có bằng Policy Report

Bên cạnh việc chặn các lệnh gọi API trực tiếp, Kyverno còn thực hiện quét định kỳ dưới nền đối với các workload đang chạy. Bạn có thể truy vấn mức độ tuân thủ của cụm trực tiếp qua các custom resource PolicyReport:

kubectl get clusterpolicyreports -o wide
kubectl describe policyreport -n default

Báo cáo này làm nổi bật các workload chưa tuân thủ được triển khai trước thời điểm kích hoạt chính sách, giúp các nhóm có thể khắc phục sai lệch từng bước mà không gây gián đoạn dịch vụ đột ngột.

Đánh giá sau 6 tháng vận hành trên môi trường Production

Trong suốt 6 tháng qua, Kyverno đã xử lý hơn 200.000 yêu cầu admission trên các cụm của chúng tôi với độ trễ webhook trung bình dưới 4 mili-giây. Trong giai đoạn đó, công cụ này đã phát hiện và từ chối 47 cấu hình không hợp lệ hoặc chứa quyền privileged trước khi chúng kịp đi vào hoạt động thực tế.

Nhờ các chính sách sử dụng định dạng Kubernetes YAML chuẩn, lập trình viên không cần phải học một ngôn ngữ DSL riêng để hiểu lý do vì sao yêu cầu bị từ chối. Họ đọc thông báo lỗi, cập nhật lại deployment manifest và tiếp tục công việc. Nếu bạn cần một giải pháp quản trị cụm vững chắc mà không tốn nhiều chi phí vận hành, Kyverno chính là câu trả lời hoàn hảo.

Share: