Giaosucan's blog - Chia sẻ kiến thức theo cách bá đạo

Ticker

20/recent/ticker-posts

Project Zeus 06 - Quản lý resource trên k8s

Tiếp tục phn 5, hệ thống Zeus hiện tại đã hình thành, Jenkins GCP dùng cho CI phụ trách việc build, test, publish artifact lên artifactory. ArgoCD chuyên deploy resources lên K8s.

Developer commit IaC code lên git, tạo PR, argocd pipeline được trigger để provision resources (pod, service, pvc …) lên K8S cluster

Vấn đề đặt ra là, làm sao quản lý được đống resources mà developer tạo ra, làm thế nào đảm bảo được resource này phải theo một quy chuẩn chung (vd các pod phải được gán label, restrict việc access dưới quyền root)

Mặc dù code developer push lên ít nhất có 2 reviewer review, approve merge vào main branch thì argocd mới trigger để thực hiện việc deploy. Tuy nhiên việc review thủ công tốn rất nhiều effort và khó tránh khỏi human mistake.

Giải pháp được đưa ra đó là tạo ra một Gatekeeper engine, mỗi khi resource được tạo ra hay được update, gatekeeper này sẽ audit đảm bảo resource follow một tập hợp rule có sẵn. Nếu không thỏa mãn sẽ restrict việc tạo resource này .Gatekeeper engine cho phép admin phát hiện và reject những resource nào violate rules, đảm bảo security và consistency về resource trong hệ thống.

Engine này gọi là OPA Gatekeeper Policy

![OPA Gatekeeper] Sử dụng openpolicyagent để ngăn chặn việc apply yaml tuỳ tiện và sai lên kubernetes! – NimTechnology]

Cách hoạt động của OPA Gatekeeper như sau

Restrict Namespace and Pod Selectors - OPA Gatekeeper NetworkPolicy  Guardrail (Part 6)

OPA Gatekeeper sử dụng Admission Controller, cài này trên Google giải thích nhưng cũng tương đối khó hiểu. Hiểu kiểu giaosucan’s blog thì như thế này

Giả sử Developer chạy 1 lệnh để tạo deployment như sau

kubectl create deployment nginx --image=nginx

Lệnh này thực chất là call API request tới K8s API server, nếu request đã authorized and authenticated (Developer đã connect thành công vào cluster), Admission Controller sẽ validate request này trước khi deployment resource được tạo dựa vào bộ OPA policies mà administrator tạo sẵn

Quy trình admission controller xử lý API request chạy theo process như ở dưới

17. Admission Control and Authorization - Kubernetes Best Practices [Book]

2 steps cần chú ý là Mutating và Validating, nơi admission review được executed, nếu detect được rule violation, toàn bộ API request sẽ bị reject

Các steps này được thực hiện bởi Open Policy Agent, OPA sẽ decouple phần rule policy khỏi phần resource k8s code để tiện cho việc review, phần tích policy

Open policy agent works

Các policy này được viết dưới dạng YAML hoặc JSON gọi là Constraint Template , OPA sẽ đọc nội dung của Constrain Template để validate các API request đến từ developer.

Ví dụ sau là một Constraint Template, yêu cầu tất cả các pod resource được tạo ra phải có label

https://github.com/open-policy-agent/gatekeeper/blob/master/demo/agilebank/templates/k8srequiredlabels_template.yaml
apiVersion: templates.gatekeeper.sh/v1

kind: ConstraintTemplate

metadata:

    name: k8srequiredlabels

spec:

    crd:

    spec:

	    names:

		    kind: K8sRequiredLabels

Nếu pod tạo mà không có label thì bắn ra message lỗi

violation[{"msg": msg, "details": {"missing_labels": missing}}] {
          provided := {label | input.review.object.metadata.labels[label]}
          required := {label | label := input.parameters.labels[_].key}
          missing := required - provided
          count(missing) > 0
          def_msg := sprintf("you must provide labels: %v", [missing])
          msg := get_message(input.parameters, def_msg)
        }

Policy có rất nhiều K8sPSPCapabilities, K8sPSPAllowPrivilegeEscalationContainer, K8sPSPReadOnlyRootFilesystem. Thực tế khi áp dụng Gatekeeper policy vào hệ thống cũng sinh ra khá nhiều phiền toái cho developer do bị restrict quá nhiều. Do đó phải áp dụng một số ngoại lệ cho một số resources, gọi là exempting namespaces

apiVersion: config.gatekeeper.sh/v1alpha1  
kind: Config  
metadata:  
name: config  
namespace:  "gatekeeper-system"  
spec:  
match:  
- excludedNamespaces:  ["kube-*",  "my-namespace"]  
processes:  ["*"]  
- excludedNamespaces:  ["audit-excluded-ns"]  
processes:  ["audit"]

Ví dụ trên sẽ loại trừ namespace audit-excluded-ns khỏi việc checking rules, cho phép developer có thể tạo resource trong ns này mà không bị audit
Bài toán đặt ra cho infrastructure team là define bao nhiêu rules, rule gì là hợp lý. Nếu áp dụng theo kiểu thà giết lầm hơn bỏ sót apply toàn bộ rule có sẵn của Gatekeeper thì sẽ không ra phiền phức lớn cho developer, nhất là giai đoạn migrate đống Jenkins job từ Jenkins cũ sang hệ thống mới, khi phần lớn request tạo resource của jobs này chắc chắn sẽ bị restrict với OPA policy rules.
Còn nếu exclude và bỏ bớt rule thì tiềm ẩn nguy cơ về bảo mật và khó quản lý được resource, cost
Đón đọc phần sau

Đăng nhận xét

0 Nhận xét