Cài đặt và Cấu hình Kyverno như Cluster Gatekeeper
Mục tiêu của chúng ta ở đây là làm cho cluster tự bảo vệ. Pipeline mà chúng ta đã xây dựng rất tốt, nhưng nó không ngăn chặn ai đó có quyền truy cập kubectl deploy thủ công một container không an toàn. Bây giờ chúng ta sẽ cài đặt một gatekeeper–một admission controller–để thực thi các quy tắc của chúng ta trên mọi workload cố gắng chạy trên cluster.
Công cụ của chúng ta cho việc này là Kyverno. Nó mạnh mẽ, native với Kubernetes, và các policy chỉ là YAML đơn giản, làm cho nó hoàn hảo cho dự án của chúng ta.
Cài đặt Kyverno sử dụng Helm
Helm là cách tốt nhất để cài đặt và quản lý các ứng dụng phức tạp như Kyverno trên Kubernetes.
Mở terminal, đảm bảo context
kubectl
của bạn đang trỏ đếnworkshop-cluster
.Thêm Kyverno Helm repository:
helm repo add kyverno https://kyverno.github.io/kyverno/
Cập nhật Helm repository để lấy thông tin chart mới:
helm repo update
Cài đặt Kyverno vào namespace chuyên dụng riêng. Đây là thực tiễn tốt nhất cho các công cụ cluster-wide.
helm install kyverno kyverno/kyverno -n kyverno --create-namespace
Xác minh cài đặt. Có thể mất một phút để tất cả pod Kyverno sẵn sàng.
kubectl get pods -n kyverno
Bạn sẽ thấy một số pod, bao gồm admission controller, background controller và cleanup controller, tất cả ở trạng thái Running.
Tạo Policy Bảo mật Đầu tiên
Bây giờ đến phần mạnh mẽ. Chúng ta sẽ định nghĩa các quy tắc bảo mật như tài nguyên ClusterPolicy
. Đây là các quy tắc cluster-wide.
Trong thư mục k8s của dự án, tạo file mới có tên
policy-disallow-latest-tag.yaml
:# Trong thư mục k8s touch policy-disallow-latest-tag.yaml
Dán policy sau. Đây là thực tiễn tốt nhất cơ bản: nó ngăn chặn deployment mơ hồ và buộc sử dụng tag cụ thể, không thể thay đổi (như Git SHA chúng ta sử dụng trong pipeline).
# k8s/policy-disallow-latest-tag.yaml apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: disallow-latest-tag spec: # Rule này áp dụng cho tất cả Pod, Deployment, StatefulSet, v.v. validationFailureAction: Enforce background: true rules: - name: require-not-latest-tag match: any: - resources: kinds: - Pod validate: message: "Sử dụng image tag 'latest' là rủi ro bảo mật và không được phép. Vui lòng sử dụng image tag cụ thể." pattern: spec: containers: # Pattern này nói "trường image của BẤT KỲ container nào KHÔNG ĐƯỢC kết thúc bằng :latest" - image: "!*:latest"
Thông tin
validationFailureAction: Enforce
là chìa khóa. Nó nói với Kyverno chặn bất kỳ API request nào vi phạm quy tắc này. Thay thế,Audit
, sẽ chỉ log vi phạm. Chúng ta muốn nghiêm ngặt.Tạo file policy thứ hai có tên
policy-require-non-root.yaml
:# Trong thư mục k8s touch policy-require-non-root.yaml
Dán policy này. Nó thực thi rằng container không thể chạy như root user, điều này giảm đáng kể bán kính nổ nếu container bị tấn công. Điều này biến thực tiễn tốt nhất từ
Dockerfile
của chúng ta thành quy tắc cluster-wide không thể thương lượng.# k8s/policy-require-non-root.yaml apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: require-non-root-user spec: validationFailureAction: Enforce background: true rules: - name: check-for-non-root match: any: - resources: kinds: - Pod exclude: any: # Loại trừ Falco và Starboard namespace - resources: namespaces: - falco - falco-system - starboard - starboard-system - starboard-operator # Loại trừ pod với privileged system label - resources: selector: matchLabels: app.kubernetes.io/name: falco # Loại trừ system namespace thường cần root - resources: namespaces: - kube-system - istio-system - monitoring validate: message: "Container không được chạy với quyền root. Đặt spec.securityContext.runAsNonRoot thành true ở cấp độ pod hoặc container." anyPattern: # Pattern 1: Security context cấp độ Pod với runAsNonRoot: true - spec: securityContext: runAsNonRoot: true # Pattern 2: Tất cả container có runAsNonRoot: true trong security context - spec: containers: - securityContext: runAsNonRoot: true
Apply và Test Policy
Apply policy vào cluster sử dụng
kubectl
:kubectl apply -f k8s/policy-disallow-latest-tag.yaml kubectl apply -f k8s/policy-require-non-root.yaml
Test policy “disallow-latest-tag”. Bây giờ, thử tạo pod thủ công sử dụng tag
latest
. Điều này mô phỏng những gì developer có thể làm, bỏ qua CI/CD pipeline của bạn.kubectl run test-pod --image=nginx:latest
Request sẽ bị từ chối! Bạn sẽ nhận được thông báo lỗi trực tiếp từ Kubernetes API server, chứa custom message từ policy của bạn:
Error from server: admission webhook "validate.kyverno.svc-fail" denied the request: resource Pod/default/test-pod was blocked due to the following policies disallow-latest-tag: require-not-latest-tag: 'validation error: Sử dụng image tag ''latest'' là rủi ro bảo mật và không được phép. Vui lòng sử dụng image tag cụ thể. rule require-not-latest-tag failed at path /spec/containers/0/image/'
Test policy “require-non-root”. Bây giờ thử chạy container mặc định, thường chạy với quyền root.
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: test-root-pod namespace: default spec: containers: - name: nginx image: nginx:1.21 # Pod này sẽ bị CHẶN bởi policy vì nó không chỉ định runAsNonRoot EOF
Điều này cũng sẽ bị từ chối với thông báo rõ ràng giải thích rằng container phải được cấu hình để chạy như non-root.
Dọn dẹp test pod thất bại (chúng sẽ không được tạo, nhưng
kubectl run
có thể tạo deployment object):kubectl delete pod test-root-pod-blocked --ignore-not-found
Commit file policy mới vào Git repository của bạn.
git add . git commit -m "feat: Implement Kyverno admission control policies" git push origin main