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 中的類別和物件的關係。約束範本相當於類別,定義了約束的通用行為和結構;而約束則是根據這個類別建立的物件,每個約束都可以有不同的引數和匹配條件。

約束範本的結構

一個典型的約束範本包括以下幾個部分:

  1. CRD(Custom Resource Definition)定義:定義了約束的自定義資源型別。
  2. Rego 策略:使用 Rego 策略語言定義了驗證邏輯。
  3. 引數 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])
      }

內容解密:

  • apiVersionkind 指定了該資源的 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"

內容解密:

  • apiVersionkind 指定了該約束所根據的約束範本。
  • metadata.name 定義了約束的名稱。
  • spec.match 定義了該約束匹配的資源型別和名稱空間。

執行動作(Enforcement Actions)

Gatekeeper 允許為約束組態不同的執行動作,包括 denywarndryrun

  • 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 資源上進行合規性檢查。