Kyverno 作為 Kubernetes 策略引擎,能有效管理叢集內資源。本文除了探討資源生成與清理策略外,也涵蓋了實際應用場景和程式碼解析,讓讀者能快速上手。資源生成策略允許自動建立 ConfigMap、Secret 等資源,簡化跨名稱空間組態的複雜性。清理策略則能自動移除不需要的資源,例如孤立 Pod 或不符合條件的 Deployment,提升叢集效率和安全性。文章也提供策略例外的設定方式,讓策略管理更具彈性,可排除特定名稱空間或資源,避免誤刪重要資源。

Kyverno 在 Kubernetes 中的資源管理與清理策略

Kyverno 是一個強大的 Kubernetes 策略引擎,用於管理和執行叢集內的各種策略,包括資源生成、驗證和清理。本文將探討 Kyverno 的資源生成策略(Generation Policies)和清理策略(CleanUp Policies),並透過具體示例和程式碼來說明其工作原理和應用場景。

資源生成策略(Generation Policies)

資源生成策略允許 Kyverno 根據預定義的規則自動生成 Kubernetes 資源。這對於需要跨多個名稱空間(Namespace)複製相同組態或資源的場景非常有用。例如,您可以使用生成策略在新建立的名稱空間中自動生成預設的 ConfigMap 或 Secret。

生成策略示例:建立 ConfigMap

以下是一個簡單的生成策略示例,用於在新名稱空間中建立一個包含 ZooKeeper 和 Kafka 地址資訊的 ConfigMap:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: generate-kafka-config
spec:
  rules:
  - name: generate-kafka-configmap
    match:
      any:
      - resources:
          kinds:
          - Namespace
    generate:
      apiVersion: v1
      kind: ConfigMap
      name: kafka-config
      namespace: "{{request.object.metadata.name}}"
      synchronize: true
      data:
        KAFKA_ADDRESS: "192.168.10.13:9092,192.168.10.14:9092,192.168.10.15:9092"
        ZK_ADDRESS: "192.168.10.10:2181,192.168.10.11:2181,192.168.10.12:2181"

程式碼解析

generate:
  apiVersion: v1
  kind: ConfigMap
  name: kafka-config
  namespace: "{{request.object.metadata.name}}"
  synchronize: true
  data:
    KAFKA_ADDRESS: "192.168.10.13:9092,192.168.10.14:9092,192.168.10.15:9092"
    ZK_ADDRESS: "192.168.10.10:2181,192.168.10.11:2181,192.168.10.12:2181"
  • generate 欄位定義了要生成的資源型別和內容。
  • apiVersionkind 指定了要生成的資源型別,在此例中為 v1/ConfigMap
  • namenamespace 定義了生成的 ConfigMap 的名稱和所屬名稱空間,其中 namespace 使用了變數 {{request.object.metadata.name}},表示該 ConfigMap 將被建立在與觸發事件相關的名稱空間中。
  • synchronize 設定為 true,表示 Kyverno 將持續同步該資源,如果資源被手動修改或刪除,Kyverno 將自動還原它。
  • data 欄位包含了要生成的 ConfigMap 的實際資料,包括 Kafka 和 ZooKeeper 的地址。

克隆現有資源

除了生成新的資源外,Kyverno 也支援從現有的資源中克隆資料。以下是一個示例,用於在新名稱空間中克隆來自特定名稱空間(例如 staging)的 Secret 和 ConfigMap:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: clone-resources
spec:
  rules:
  - name: clone-secrets-and-configmaps
    match:
      any:
      - resources:
          kinds:
          - Namespace
    exclude:
      any:
      - resources:
          namespaces:
          - kube-system
          - default
          - kube-public
          - kyverno
    generate:
      namespace: "{{request.object.metadata.name}}"
      synchronize: true
      cloneList:
        namespace: staging
        kinds:
        - v1/Secret
        - v1/ConfigMap
        selector:
          matchLabels:
            allowedToBeCloned: "true"

程式碼解析

cloneList:
  namespace: staging
  kinds:
  - v1/Secret
  - v1/ConfigMap
  selector:
    matchLabels:
      allowedToBeCloned: "true"
  • cloneList 定義了克隆操作的來源和篩選條件。
  • namespace 指定了來源名稱空間為 staging
  • kinds 列出了要克隆的資源型別,包括 v1/Secretv1/ConfigMap
  • selector.matchLabels 用於篩選帶有特定標籤(allowedToBeCloned: "true")的資源進行克隆。

清理策略(CleanUp Policies)

Kyverno 的清理策略允許使用者定義定時任務,以清理叢集中不再需要或不符合特定條件的資源。這對於維護叢集整潔和自動化資源管理非常有幫助。

清理策略示例:刪除副本數小於 2 的 Deployment

以下是一個清理策略示例,用於刪除標有 canremove=true 且副本數小於 2 的 Deployment 資源:

apiVersion: kyverno.io/v2beta1
kind: ClusterCleanupPolicy
metadata:
  name: clean-deploys
spec:
  match:
    any:
    - resources:
        kinds:
        - Deployment
        selector:
          matchLabels:
            canremove: "true"
        conditions:
          any:
          - key: "{{ target.spec.replicas }}"
            operator: LessThan
            value: 2
  schedule: "*/5 * * * *"

程式碼解析

match:
  any:
  - resources:
      kinds:
      - Deployment
      selector:
        matchLabels:
          canremove: "true"
      conditions:
        any:
        - key: "{{ target.spec.replicas }}"
          operator: LessThan
          value: 2
schedule: "*/5 * * * *"
  • match 定義了清理策略的匹配條件,包括資源型別、標籤選擇器和自定義條件。
  • kinds 指定了要清理的資源型別為 Deployment。
  • selector.matchLabels 用於選擇帶有特定標籤(canremove=true)的 Deployment。
  • conditions 定義了額外的篩選條件,在此例中使用 JMESPath 表示式檢查 Deployment 的副本數是否小於 2。
  • schedule 定義了清理任務的執行頻率,在此例中為每 5 分鐘執行一次。

Kyverno 清理策略與政策例外深入解析

在前面的章節中,我們探討了 Kyverno 在 Kubernetes 中的應用,特別是在資源管理與策略執行的角色。現在,我們將深入瞭解 Kyverno 的清理策略(CleanUp Policies)以及如何建立策略例外(Policy Exceptions),進一步提升叢集的管理效率與安全性。

清理策略的實際應用

Kyverno 的清理策略允許使用者自動化地移除不再需要的資源,從而保持叢集的整潔並減少潛在的安全風險。這些策略可以針對特定的資源型別進行組態,例如刪除未被其他工作負載所管理的孤立 Pod。

刪除特定 Deployment 資源

以下是一個清理策略的範例,用於刪除名為 admission-test/test 的 Deployment 資源:

apiVersion: kyverno.io/v2alpha1
type: Normal
reason: PolicyApplied
message: "successfully cleaned up the target resource Deployment/admission-test/test"

為了使此策略生效,我們需要建立一個具有適當許可權的 ClusterRole,並利用 ClusterRole 聚合機制將許可權授予 Kyverno 的清理控制器:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kyverno-cleanup-deploys
  labels:
    app.kubernetes.io/component: cleanup-controller
    app.kubernetes.io/instance: kyverno
    app.kubernetes.io/name: kyverno-cleanup-controller
rules:
- verbs:
  - get
  - watch
  - list
  - delete
  apiGroups:
  - "apps"
  resources:
  - deployments

清理孤立 Pod

孤立 Pod 是指未被其他工作負載管理的 Pod,這些 Pod 有時會被遺忘在叢集中,導致資源浪費。以下是一個清理孤立 Pod 的策略範例:

spec:
  match:
    any:
    - resources:
        kinds:
        - Pod
        conditions:
          all:
          - key: "{{ target.metadata.ownerReferences[] || `[]` }}"
            operator: Equals
            value: []
  schedule: "*/5 * * * *"

同樣地,我們需要為清理控制器建立適當的 ClusterRole:

rules:
- verbs:
  - get
  - watch
  - list
  - delete
  apiGroups:
  - ""
  resources:
  - pods

內容解密:

此段落程式碼的作用是定義一個清理策略,用於刪除孤立的 Pod 資源。

  • match 欄位用於指定需要清理的資源型別,此處為 Pod。
  • conditions 欄位檢查 Pod 是否具有 ownerReferences,若為空,則表示該 Pod 為孤立 Pod,應被清理。
  • schedule 欄位設定策略的執行頻率,此處設定為每 5 分鐘執行一次。

策略例外機制

Kyverno 允許使用者在策略中定義例外規則,以排除特定資源或名稱空間的處理。這種機制使得策略的應用更加靈活和精細化。

靜態例外規則

以下是一個範例,展示瞭如何使用 exclude 欄位來排除特定名稱空間的資源:

spec:
  rules:
  - name: match-pods-except-admin
    match:
      any:
      - resources:
          kinds:
          - Pod
    exclude:
      any:
      - resources:
          namespaces:
          - policy-excluded-namespace

動態例外規則

Kyverno 也支援動態例外規則,透過 ConfigMap 來維護需要排除的名稱空間列表:

spec:
  validationFailureAction: Audit
  background: true
  rules:
  - name: exclude-namespaces-dynamically
    context:
    - name: namespacefilters
      configMap:
        name: namespace-filters
        namespace: default
    match:
      any:
      - resources:
          kinds:
          - Pod
    preconditions:
      all:
      - key: "{{request.object.metadata.namespace}}"
        operator: AnyNotIn
        value: "{{namespacefilters.data.exclude}}"
    validate:
      message: >
        Creating Pods in the {{request.namespace}} Namespace,
        which is not in the excluded list of Namespaces
        {{ namespacefilters.data.exclude }},
        is forbidden unless it carries the label `foo`.
      pattern:
        metadata:
          labels:
            foo: "*"

內容解密:

此段落程式碼的作用是定義一個動態例外規則,用於根據 ConfigMap 中的組態排除特定名稱空間的 Pod。

  • context 欄位用於參照 ConfigMap namespace-filters,並從中取得排除的名稱空間列表。
  • preconditions 欄位檢查請求中的名稱空間是否不在排除列表中,若不在,則進行進一步的驗證。
  • validate 欄位定義了驗證規則,要求 Pod 必須攜帶特定的標籤 foo,否則將被禁止建立。

策略例外的啟用與應用

Kyverno 從 1.9.0 版本開始引入了策略例外的 alpha 功能,允許使用者建立例外資源以排除特定資源的處理。要啟用此功能,需要在安裝 Kyverno 時設定相應的引數:

$ helm install kyverno kyverno/kyverno -n kyverno --create-namespace \
--values values.yaml \
--set "extraArgs={-v=4,--dumpPayload=true,--enablePolicyException=true}"

啟用後,可以建立策略例外資源,例如:

# Image registry validation policy specification
spec:
  validationFailureAction: Enforce
  background: true
  rules:
  - name: detect-deprecated-registry
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: >
        The \"k8s.gcr.io\" image registry is deprecated.
        \"registry.k8s.io\" should now be used.
      foreach:
        # 省略具體驗證邏輯

內容解密:

此段落程式碼的作用是定義一個映象倉函式庫驗證策略,用於檢查 Pod 是否使用了已棄用的 k8s.gcr.io 映象倉函式庫。

  • validationFailureAction 設定為 Enforce,表示當驗證失敗時,將強制阻止資源的建立。
  • validate 欄位中的 message 用於提供錯誤訊息,指引使用者使用新的 registry.k8s.io 映象倉函式庫。

Kyverno 策略管理流程圖示

  graph LR;
    E[E]
    A[開始] --> B[定義清理策略];
    B --> C[建立 ClusterRole];
    C --> D[應用清理策略];
    D --> E{檢查資源是否符合清理條件};
    E -->|是| F[清理資源];
    E -->|否| G[結束];
    F --> H[記錄清理結果];
    G --> I[結束];

圖表翻譯:
此圖示展示了 Kyverno 清理策略的管理流程。首先定義清理策略,接著建立必要的 ClusterRole,然後應用清理策略並檢查資源是否符合清理條件。若符合,則進行清理並記錄結果;若不符合,則結束流程。

隨著 Kubernetes 生態的不斷發展,Kyverno 的策略管理功能將進一步增強,以滿足更複雜的叢集管理需求。未來,我們可以期待 Kyverno 在以下幾個方面取得進展:

  1. 更強大的策略自定義能力:允許使用者根據具體需求自定義更複雜的策略規則。
  2. 更高效的策略執行引擎:最佳化策略執行的效能,減少對叢集資源的佔用。
  3. 更完善的策略例外機制:提供更靈活的例外規則組態,以滿足不同場景下的需求。

透過不斷地改進和最佳化,Kyverno 將成為 Kubernetes 環境中不可或缺的策略管理工具,為叢集的安全性和穩定性提供強有力的保障。