Triển khai OPA Gatekeeper trên Kubernetes Cluster
Chúng ta sẽ cài đặt OPA Gatekeeper để làm Policy Engine, giúp kiểm soát các tài nguyên Kubernetes trước khi chúng được tạo ra. Gatekeeper sẽ hoạt động như một Admission Webhook, chặn các cấu hình không tuân thủ chính sách.
Việc sử dụng OPA Gatekeeper cho phép chúng ta áp dụng các quy tắc (policies) viết bằng Rego để bảo vệ cluster, đặc biệt quan trọng khi tích hợp với Cilium để đảm bảo các Network Policy và L7 Policy luôn an toàn.
Khởi tạo namespace và cài đặt OPA Gatekeeper qua Helm chart chính thức.
helm repo add open-policy-agent https://open-policy-agent.github.io/gatekeeper/charts
helm repo update
helm install gatekeeper open-policy-agent/gatekeeper --namespace gatekeeper-system --create-namespace
Kiểm tra trạng thái các pod trong namespace gatekeeper-system để đảm bảo controller và webhook đã chạy ổn định.
kubectl get pods -n gatekeeper-system
Kết quả mong đợi: Tất cả các pod (gatekeeper-controller-manager, gatekeeper-audit, gatekeeper-webhook) phải ở trạng thái Running.
Viết và áp dụng Constraint để kiểm soát Cilium Network Policy
Bước tiếp theo là định nghĩa các quy tắc bảo mật cụ thể. Chúng ta sẽ tạo một Constraint để ngăn chặn việc tạo CiliumNetworkPolicy cho phép lưu lượng từ tất cả các namespace (0.0.0.0/0) vào pod nhạy cảm.
Constraint là một tài nguyên Kubernetes được định nghĩa bởi Gatekeeper, tham chiếu đến một ConstraintTemplate (mẫu chính sách Rego).
Đầu tiên, tạo file định nghĩa ConstraintTemplate để Gatekeeper hiểu cách ánh xạ quy tắc Rego vào tài nguyên CiliumNetworkPolicy.
Tạo file /etc/policies/cilium-deny-wide-ingress.yaml với nội dung:
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8sciliumwideingress
spec:
crd:
spec:
names:
kind: K8sCiliumWideIngress
validation:
openAPIV3Schema:
properties:
namespaces:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sciliumwideingress
import data.kubernetes.allowed_labels
violation[{
"msg": msg,
"details": {
"allowed": allowed
}
}] {
input.review.object.spec.to == to
to[0].any[0].hostPort == hostPort
hostPort.port == port
hostPort.protocol == protocol
input.review.object.spec.to[0].any[0].fromHost == fromHost
fromHost.cidr == cidr
cidr == "0.0.0.0/0"
msg := sprintf("CiliumNetworkPolicy %v is not allowed to allow wide ingress from 0.0.0.0/0 on port %v protocol %v", [input.review.object.metadata.name, port, protocol])
allowed := false
}
Áp dụng ConstraintTemplate này vào cluster để Gatekeeper nhận diện loại chính sách mới.
kubectl apply -f /etc/policies/cilium-deny-wide-ingress.yaml
Kết quả mong đợi: Tài nguyên ConstraintTemplate được tạo thành công với trạng thái Ready.
Tích hợp Constraint và xử lý ngoại lệ
Bây giờ chúng ta sẽ tạo một thể hiện (instance) của Constraint để kích hoạt chính sách này trên các namespace cụ thể. Đồng thời, chúng ta sẽ thiết lập một Exception để cho phép một số pod đặc biệt (ví dụ: LoadBalancer) vi phạm chính sách này.
Việc xử lý ngoại lệ (Exception) rất quan trọng để không chặn các dịch vụ cần thiết cho hạ tầng hoặc monitoring.
Tạo file /etc/policies/cilium-wide-ingress-constraint.yaml để áp dụng quy tắc.
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sCiliumWideIngress
metadata:
name: deny-wide-cilium-ingress
spec:
match:
kinds:
- apiGroups: ["cilium.io"]
kinds: ["CiliumNetworkPolicy"]
namespaces:
- "default"
- "production"
parameters:
namespaces: ["default", "production"]
Áp dụng constraint vào cluster.
kubectl apply -f /etc/policies/cilium-wide-ingress-constraint.yaml
Kết quả mong đợi: Constraint được tạo và Gatekeeper bắt đầu kiểm tra các yêu cầu tạo CiliumNetworkPolicy mới.
Tiếp theo, tạo file /etc/policies/cilium-exception.yaml để tạo ngoại lệ cho namespace 'monitoring'.
apiVersion: exceptions.gatekeeper.sh/v1beta1
kind: Exception
metadata:
name: monitoring-wide-ingress-exception
spec:
constraintRef:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sCiliumWideIngress
name: deny-wide-cilium-ingress
match:
kinds:
- apiGroups: ["cilium.io"]
kinds: ["CiliumNetworkPolicy"]
namespaces:
- "monitoring"
Áp dụng exception để cho phép monitoring nhận lưu lượng rộng.
kubectl apply -f /etc/policies/cilium-exception.yaml
Kết quả mong đợi: Exception được tạo, các yêu cầu từ namespace 'monitoring' sẽ không bị chặn dù vi phạm quy tắc.
Verify kết quả và kiểm tra Audit Log
Chúng ta cần xác minh rằng chính sách đã hoạt động bằng cách cố gắng tạo một CiliumNetworkPolicy vi phạm và một chính sách tuân thủ.
Thử nghiệm 1: Tạo một policy cho phép 0.0.0.0/0 vào namespace 'production' (dự kiến bị chặn).
Tạo file /etc/policies/test-violation.yaml:
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: test-violation-policy
namespace: production
spec:
endpointSelector:
matchLabels:
app: web
ingress:
- fromHost:
cidr:
ip: "0.0.0.0/0"
prefix: 32
toPorts:
- ports:
- port: "80"
protocol: TCP
Thử áp dụng file này.
kubectl apply -f /etc/policies/test-violation.yaml
Kết quả mong đợi: Lỗi từ Gatekeeper với thông báo "CiliumNetworkPolicy test-violation-policy is not allowed to allow wide ingress..." và tài nguyên không được tạo.
Thử nghiệm 2: Tạo một policy cho phép 0.0.0.0/0 vào namespace 'monitoring' (dự kiến được chấp nhận nhờ Exception).
Thay đổi namespace trong file test-violation.yaml thành 'monitoring' và áp dụng lại.
kubectl apply -f /etc/policies/test-violation.yaml
Kết quả mong đợi: Tài nguyên được tạo thành công (Success) vì Exception đã được áp dụng.
Kiểm tra audit log để xem chi tiết các sự kiện bị chặn hoặc được chấp nhận.
kubectl get constraints.gatekeeper.sh/v1beta1 K8sCiliumWideIngress deny-wide-cilium-ingress -o yaml
Kiểm tra trạng thái vi phạm (violation) trong cluster để xem danh sách các tài nguyên đang không tuân thủ (nếu có).
kubectl get violations
Kết quả mong đợi: Nếu có tài nguyên vi phạm đã tồn tại trước khi áp dụng chính sách, chúng sẽ hiển thị ở đây. Các tài nguyên mới tạo bị chặn sẽ không xuất hiện trong violations vì chúng không được tạo.
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng Secure Service Mesh với eBPF, Cilium và Policy Engine
« Phần 3: Thiết lập chính sách bảo mật mạng (Network Policy) với Cilium
Phần 5: Bảo mật lớp ứng dụng (L7) và quản lý lưu lượng HTTP/gRPC »