Gatekeeper 作為 Kubernetes 原生策略引擎,透過 Open Policy Agent (OPA) Constraint Framework,提供高度可擴充套件和可客製化的策略管理機制。不同於傳統 OPA 策略,Gatekeeper 採用 ConstraintTemplate 和 Constraint 兩種 Kubernetes 資源定義策略。ConstraintTemplate 作為策略範本,定義 Rego 驗證邏輯和引數 Schema;Constraint 則根據 ConstraintTemplate,設定特定引數和匹配條件,實作對特定資源的驗證。此機制讓策略管理更具彈性,方便重複使用和版本控制。本文將詳細說明如何使用 ConstraintTemplate 和 Constraint,並提供實際 YAML 組態和 kubectl 操作範例,協助工程師有效管理 Kubernetes 叢集資源和安全策略。
隨著 Kubernetes 和雲原生技術的不斷發展,Gatekeeper 和 OPA 的角色將變得越來越重要。未來,我們可以預期看到更多根據 Gatekeeper 的創新安全解決方案和最佳實踐。
Gatekeeper 驗證政策與 OPA CF 的整合應用
Gatekeeper 驗證政策使用 Rego 語言,但其編寫方式與 OPA 有所不同。OPA(傳統)政策是 Rego 檔案,可以匯入其他 Rego 檔案,而 Gatekeeper 政策則由兩個 Kubernetes 資源組成:ConstraintTemplates 和 Constraints。
ConstraintTemplates 與 Constraints 的運作機制
ConstraintTemplates 根據 constrainttemplates.templates.gatekeeper.sh
CRD(自訂資源定義)。建立根據此 CRD 的資源實際上會為每個 ConstraintTemplate 建立額外的 CRD。Rego 在 ConstraintTemplates 中可以匯入 OPA 函式庫,如 future.keywords.in
。然而,若要重複使用使用者提供的函式庫(就像在第 5 章中對 OPA 所做的那樣),則需要在每個 ConstraintTemplate 中的 targets
元素下新增這些函式庫作為額外的目標。
建立 ConstraintTemplate
以下是一個 ConstraintTemplate 的範例 YAML 檔案:
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8sdepregistry
labels:
policy.jimmyray.io/gatekeeper: template
spec:
crd:
spec:
names:
kind: K8sDepRegistry
validation:
openAPIV3Schema:
type: object
properties:
allowedOps:
type: array
items:
type: string
allowedRegistries:
type: array
items:
type: string
errMsg:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sdepregistry
violation[{"msg": msg, "details": {}}] {
input.review.operation = input.parameters.allowedOps[_]
image = input.review.object.spec.template.spec.containers[_].image
not reg_matches_any(image, input.parameters.allowedRegistries)
msg = sprintf("%v: %v image is not sourced from an authorized registry. Resource ID (ns/name/kind): %v/%v/%v",
[input.parameters.errMsg, image,
input.review.object.metadata.namespace,
input.review.object.metadata.name, input.review.kind.kind])
}
reg_matches_any(str, patterns) {
reg_matches(str, patterns[_])
}
reg_matches(str, pattern) {
contains(str, pattern)
}
ConstraintTemplate 解讀
- Kind: 這是一個 ConstraintTemplate。
- 名稱: 由此 ConstraintTemplate 建立的新型別是
K8sDepRegistry
。 - 屬性: 定義將在下游 Constraint 中使用的引數。
- Rego 目標: 包含此政策的 Rego 策略。
建立 Constraint
當建立 Constraint 時,它會被建立為 K8sDepRegistry
資源型別。以下是一個 Constraint 的範例 YAML 檔案:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDepRegistry
metadata:
name: deployment-allowed-registry
labels:
policy.jimmyray.io/gatekeeper: constraint
spec:
enforcementAction: deny
match:
kinds:
- apiGroups: ["*"]
kinds: ["Deployment"]
namespaces:
- "policy-test"
parameters:
allowedOps: ["CREATE", "UPDATE"]
allowedRegistries: ["GOOD_REGISTRY", "VERY_GOOD_REGISTRY"]
errMsg: "INVALID_DEPLOYMENT_REGISTRY"
Constraint 解讀
- ConstraintTemplate 名稱: 用作 Constraint 的種類別。
- 適用範圍: 此 Constraint 僅適用於
Deployment
資源。 - 名稱空間: 此 Constraint 僅適用於
policy-test
名稱空間中的資源。 - 引數: 在 ConstraintTemplate 中定義為屬性的引數允許 Constraint 作者指定 Kubernetes 操作以及允許的登入檔和錯誤訊息。
kubectl 命令操作範例
以下是一些用於操作 ConstraintTemplates 和 Constraints 的 kubectl
命令範例:
# 列出 CRD
$ kubectl get crd -o=custom-columns='NAME:.metadata.name,KIND:.kind'
# 列出 ConstraintTemplate 資源
$ kubectl get constrainttemplate -o=custom-columns='NAME:.metadata.name,KIND:.kind'
# 列出 Constraint 資源
$ kubectl get constraint -o=custom-columns='NAME:.metadata.name,KIND:.kind'
# 列出 K8sDepRegistry 資源
$ kubectl get k8sdepregistry -o=custom-columns='NAME:.metadata.name,KIND:.kind'
程式碼詳細說明
上述 YAML 組態檔案和 kubectl
命令展示瞭如何使用 Gatekeeper 和 OPA CF 在 Kubernetes 環境中實施政策驗證。透過建立 ConstraintTemplates 和 Constraints,管理員可以定義和實施特定的安全和合規政策。
圖表說明
以下是一個簡單的 Mermaid 圖表,用於展示 Gatekeeper 中 ConstraintTemplate 和 Constraint 的關係:
graph LR; A[ConstraintTemplate] -->|建立|> B[CRD]; B -->|定義|> C[Constraint]; C -->|實施|> D[政策驗證];
圖表翻譯: 此圖表展示了 Gatekeeper 中 ConstraintTemplate 如何建立 CRD,並進一步定義和實施 Constraint 以進行政策驗證的流程。
Gatekeeper 約束與約束範本的深入解析
Gatekeeper 是 Kubernetes 中一個強大的策略管理工具,它透過使用約束(Constraint)和約束範本(ConstraintTemplate)來實作對叢集資源的有效控制和驗證。本文將探討 Gatekeeper 的約束與約束範本之間的關係,以及如何利用它們來制定和執行 Kubernetes 中的安全策略。
約束範本(ConstraintTemplate)與約束(Constraint)的關係
在 Gatekeeper 中,約束範本定義了策略的結構和行為,而約束則是這些範本的例項化。約束範本包含了 Rego 策略語言編寫的驗證邏輯,以及引數的 schema 定義。約束則根據範本定義,設定具體的引數和匹配條件,從而實作對特定資源的驗證。
這種設計類別似於 Java 中的類別和物件的關係。約束範本相當於類別,定義了約束的通用行為和結構;而約束則是根據這個類別建立的物件,每個約束都可以有不同的引數和匹配條件。
約束範本的結構
一個典型的約束範本包括以下幾個部分:
- CRD(Custom Resource Definition)定義:定義了約束的自定義資源型別。
- Rego 策略:使用 Rego 策略語言定義了驗證邏輯。
- 引數 Schema:定義了約束引數的結構。
以下是一個簡單的 deny-all 約束範本示例:
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8sdenyall
spec:
crd:
spec:
names:
kind: K8sDenyAll
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sdenyall
violation[{"msg": msg}] {
msg := sprintf("INPUT: %v", [input])
}
內容解密:
apiVersion
和kind
指定了該資源的 API 版本和型別。metadata.name
定義了約束範本的名稱。spec.crd.spec.names.kind
定義了約束的自定義資源型別名稱。spec.targets
列出了目標驗證框架,這裡是 Kubernetes 的准入控制。rego
部分定義了使用 Rego 策略語言編寫的驗證邏輯。
約束的建立與使用
約束是根據約束範本建立的例項,它指定了具體的匹配條件和引數。以下是一個 deny-all-pods 約束的示例,該約束根據前述的 k8sDenyAll 約束範本:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDenyAll
metadata:
name: deny-all-pods
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaces:
- "policy-test"
內容解密:
apiVersion
和kind
指定了該約束所根據的約束範本。metadata.name
定義了約束的名稱。spec.match
定義了該約束匹配的資源型別和名稱空間。
執行動作(Enforcement Actions)
Gatekeeper 允許為約束組態不同的執行動作,包括 deny
、warn
和 dryrun
。
deny
:預設動作,違反約束會導致請求被拒絕。warn
:違反約束會產生警告,但請求仍會被接受。dryrun
:違反約束會被記錄到 Gatekeeper 的日誌中,但請求仍會被接受。
透過合理組態執行動作,可以實作從嚴格強制執行到僅記錄警告的不同策略執行力度。
隨著 Kubernetes 和雲原生技術的不斷發展,Gatekeeper 這樣的策略管理工具將變得越來越重要。它不僅能夠幫助組織更好地管理和控制 Kubernetes 叢集中的資源,還能夠透過靈活的策略組態來滿足不斷變化的業務需求和安全要求。
未來,我們可以預見 Gatekeeper 將進一步增強其功能,例如支援更多的策略語言、提供更豐富的日誌和監控功能,以及更好地與其他雲原生工具整合等。這將使 Gatekeeper 成為 Kubernetes 環境中不可或缺的一部分,為組織提供強大的策略管理和執行能力。
Gatekeeper 約束與約束範本關係圖
graph LR; A[ConstraintTemplate] -->|定義|> B[Constraint]; B -->|例項化|> C[具體策略]; C -->|應用於|> D[Kubernetes資源]; D -->|驗證|> E[合規性檢查];
圖表翻譯:
此圖示展示了 Gatekeeper 中約束範本與約束之間的關係。約束範本定義了策略的通用結構和行為,而約束則是這些範本的例項,應用於具體的 Kubernetes 資源上進行合規性檢查。