Kubernetes 的普及伴隨著安全挑戰,Policy as Code(PaC)應運而生,提供更有效的叢集管理和安全控制。本文將探討如何在 Kubernetes 中實作 PaC,包含資源驗證、變更管理、稽核,並深入解析 jsPolicy 和 Kyverno 等工具的應用。同時,我們也將探討 Kubernetes 原生安全功能,例如 Pod Security Admission(PSA)和 Pod 的 securityContext 設定,並提供結合 PaC 與原生功能的最佳實踐,以開發更安全的 Kubernetes 環境。

透過 Kubernetes 中的 Policy as Code(PaC),我們可以將安全策略編碼化,並自動化執行,有效降低人為錯誤並提升安全管理效率。jsPolicy 和 Kyverno 等工具提供了豐富的功能,例如資源驗證、變更管理和稽核,可以幫助我們更精細地控制叢集資源的存取和操作。此外,Kubernetes 的原生安全功能,如 Pod Security Admission 和 Pod 的 securityContext 設定,也為我們提供了多層次的防護機制。藉由整合 PaC 和原生安全功能,我們可以建立更全面的安全策略,確保 Kubernetes 叢集的安全性和穩定性。

Kubernetes 中的 Policy as Code(PaC)與安全控制實作

隨著 Kubernetes 叢集規模的日益擴大,如何有效管理叢集資源、確保安全性以及遵循最佳實踐變得越來越重要。Policy as Code(PaC)提供了一種有效的方法來實作這些目標。本文將探討 Kubernetes 中的 PaC 實作,特別是在資源驗證、變更管理以及稽核等方面的應用。

資源驗證的重要性

在 Kubernetes 環境中,驗證 API 伺服器的請求是防止不必要變更的重要手段。這不僅能提高叢集的安全性,還能確保最佳實踐的遵循。資源驗證的使用案例包括:

  • 強制執行 Pod 和容器安全組態
  • 限制容器映像檔來源
  • 防止使用 latest 標籤或無版本標籤的容器映像檔
  • 執行多租戶設定(例如:節點親和性、汙點、容忍度等)
  • 驗證容器映像檔簽名
  • 強制執行名稱空間配額和限制範圍
  • 防止在 ClusterIP 服務中使用外部 IP 地址

範例驗證政策

以下是一個使用 jsPolicy 的範例驗證政策,用於禁止在 default 名稱空間中建立或更新資源:

apiVersion: policy.jspolicy.com/v1beta1
kind: JsPolicy
metadata:
  name: "no-default-ns.jimmyray.io"
spec:
  operations: ["CREATE", "UPDATE"]
  resources: ["*"]
  scope: Namespaced
  javascript: |
    if (request.namespace === "default") {
      deny("不允許在 default 名稱空間中建立或更新資源!");
    }

這個政策適用於 CREATEUPDATE 操作,對 default 名稱空間中的任何資源進行驗證。透過使用 AdmissionReview 物件的屬性(如名稱空間和操作),該政策能夠評估傳入的 Kubernetes API 伺服器請求並阻止不符合政策的變更。

API 伺服器請求延遲與 Webhook 順序

在《Site Reliability Engineering》(O’Reilly)一書中,作者提出了監控的「四個黃金訊號」:延遲、流量、錯誤和飽和度。在本文中,我們將探討延遲對 API 伺服器請求的影響。

Kubernetes API 伺服器的延遲直接受到准入控制器和動態准入控制器 Webhook 的影響。為了防止因延遲導致的 API 伺服器問題,應考慮准入控制器和 Webhook 的數量以及它們的超時設定。

Webhook 的執行順序

  • 變更 Webhook:序列呼叫(隨機順序),以避免衝突。
  • 驗證 Webhook:平行呼叫(平行執行)。

變更 Webhook 的個別超時設定可能會增加變更階段的總體超時時間,從而導致 API 伺服器請求延遲增加。

稽核與背景掃描現有資源

雖然動態准入控制器可以組態為「失敗開放」或「失敗關閉」,但為了避免安全控制的漏洞,一些 Kubernetes PaC 解決方案支援稽核或背景掃描功能。這種功能可以對不符合政策的資源進行日誌記錄或報告,從而彌補因 Webhook 服務未能及時回應而導致的漏洞。

使用稽核與背景掃描的好處

  • 增強安全性:對現有資源進行稽核,發現並修復不符合政策的資源。
  • 影響測試:在發布新政策時進行影響測試和分析,而不會對現有叢集資源造成幹擾。

自動化生成資源與政策

為了減少 Kubernetes 和政策管理的負擔,可以使用 PaC 自動化來生成資源和政策。這不僅能提高效率,還能確保一致性和準確性。

隨著 Kubernetes 不斷演進,PaC 的功能和應用場景也將持續擴充套件。未來可能會出現更多創新性的 PaC 解決方案,以滿足日益複雜的叢集管理需求。同時,如何更好地整合 PaC 與現有的 DevOps 和 CI/CD 流程,將成為一個重要的研究方向。

圖表說明

  graph LR
    A[開始] --> B{是否符合政策?}
    B -->|是| C[允許變更]
    B -->|否| D[拒絕變更]
    C --> E[結束]
    D --> E

圖表翻譯: 此圖示呈現了 Kubernetes 中 Policy as Code 的基本工作流程。首先,系統會檢查傳入的變更請求是否符合既定的政策。如果符合,則允許變更;如果不符合,則拒絕變更。最終,無論是允許還是拒絕變更,流程都會結束。

程式碼範例與詳細解析

以下是一個更複雜的 jsPolicy 範例,用於驗證 Pod 的安全組態:

apiVersion: policy.jspolicy.com/v1beta1
kind: JsPolicy
metadata:
  name: "validate-pod-security.jimmyray.io"
spec:
  operations: ["CREATE", "UPDATE"]
  resources: ["Pods"]
  scope: Namespaced
  javascript: |
    if (request.object.spec.containers.some(container => container.securityContext.privileged)) {
      deny("不允許建立特權容器!");
    }
    if (!request.object.spec.containers.every(container => container.resources.requests.cpu && container.resources.requests.memory)) {
      deny("所有容器必須指定 CPU 和記憶體請求!");
    }

詳細解析

  1. 檢查特權容器:該政策檢查 Pod 的 spec.containers 中是否存在任何設定了 securityContext.privilegedtrue 的容器。如果存在,則拒絕該請求。

  2. 檢查資源請求:該政策還檢查每個容器是否都指定了 CPU 和記憶體請求。如果有任何容器未指定,則拒絕該請求。

透過這種方式,該政策能夠有效地強制執行 Pod 安全組態的最佳實踐。

程式碼註解與最佳實踐

  • 詳細註解:在撰寫 jsPolicy 時,應當為程式碼新增詳細的註解,以便其他團隊成員理解政策的邏輯和目的。

  • 遵循最佳實踐:在設計和實施 PaC 解決方案時,應當遵循 Kubernetes 社群的最佳實踐,例如使用名稱空間隔離資源、限制資源配額等。

結語

Kubernetes 中的 Policy as Code 提供了一種強大的工具,用於管理和控制叢集資源,確保安全性和遵循最佳實踐。透過結合資源驗證、變更管理、稽核與背景掃描等功能,可以有效地提高叢集的安全性和穩定性。同時,自動化生成資源與政策可以進一步簡化管理流程,提高效率。未來,隨著 Kubernetes 生態系統的不斷發展,PaC 的應用將會更加廣泛和深入。

Kubernetes中的Policy as Code(PaC)與原生政策功能

使用PaC動態生成資源與政策

Kubernetes的Policy as Code(PaC)解決方案不僅可以用於預防性控制,還能對叢集事件做出反應。某些Kubernetes PaC方案提供了動態生成Kubernetes資源和政策的功能,以回應其他Kubernetes資源的應用。

Kyverno的自動生成(Auto-Gen)功能

Kyverno提供了一個稱為「Auto-Gen」的功能,能夠為對應的控制器資源(如Deployment)自動生成相關的政策,從而減少管理多種資源型別政策的需求。例如,您可以編寫針對Pod的政策,Kyverno會自動為建立Pod的控制器資源生成相應的政策。

Kyverno CLI的應用

Kyverno的Auto-Gen功能同樣適用於Kyverno CLI。在將資源應用到叢集之前,您可以使用CLI將政策應用於YAML檔案,從而在API伺服器請求發出之前進行策略驗證。

生成資源功能

Kyverno的「生成資源」功能使用generate-policy型別來構建對已應用Kubernetes資源的回應政策。舉例來說,在多租戶場景中,當新的Namespace被建立時,可以使用generate policy來準備該Namespace,以確保在佈署應用之前具備必要的網路政策和其他組態。

實際案例:自動生成網路政策

當新的Namespace被建立時,可以使用generate policy自動生成一個拒絕所有流量的網路政策(deny-all network policy),以鎖定該Namespace內所有Pod的輸入和輸出網路流量。隨後,當應用被佈署到該Namespace時,可以應用具有適當輸入和輸出規則的網路政策,以提供應用所需的最低許可權網路存取。

jsPolicy的控制器政策功能

jsPolicy提供了類別似於Kyverno「生成資源」功能的「控制器政策」功能,能夠對叢集事件做出反應。

Kubernetes原生政策功能

Pod安全性

在Kubernetes中,Pod是計算的基本單位,包含一個或多個容器。Pod的安全性主要透過Pod和容器層級的securityContext元素進行組態。Pod層級的securityContext設定較容器層級的設定更為寬泛,並且在設定重疊時會被容器層級的securityContext覆寫。

最佳實踐:容器層級securityContext設定

以下是一個容器層級securityContext的最佳實踐組態範例:

securityContext:
  allowPrivilegeEscalation: false
  runAsUser: 1000
  readOnlyRootFilesystem: true
  runAsNonRoot: true
  capabilities:
    drop: ["ALL"]
  seccompProfile:
    type: "RuntimeDefault"

這些設定旨在以最低許可權執行容器,防止容器提升許可權並對節點作業系統核心進行未授權的呼叫。

Pod Security Admission(PSA)

由於PodSecurityPolicy(PSP)資源在組態和使用上存在困難,並且在Kubernetes 1.21版本中被棄用,在1.25版本中被移除,Kubernetes引入了Pod Security Admission(PSA)控制器作為替代方案。PSA實作了Kubernetes Pod Security Standards(PSS),定義了三個安全級別:

  • Privileged(不受限制)
  • Baseline(基本安全)
  • Restricted(高安全)

PSA在Kubernetes v1.23版本進入beta階段,並在v1.25版本達到穩定狀態。PSA透過實施PSS,為Pod組態提供了一套標準化的安全控制措施,從而增強了叢集的安全性。

詳細解析Kyverno與jsPolicy的功能特點
Kyverno Auto-Gen的工作原理

Kyverno的Auto-Gen功能根據現有的政策自動為相關資源生成相應的政策。例如,當您定義了一條針對Pod的政策,Kyverno會自動為建立這些Pod的Deployment或其他控制器資源生成相應的政策,從而簡化了多資源型別的政策管理。

Kyverno Auto-Gen範例程式碼
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-labels
spec:
  validationFailureAction: audit
  rules:
  - name: check-for-labels
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "The label 'app' is required"
      pattern:
        metadata:
          labels:
            app: "?*"

此範例中定義了一條名為require-labels的ClusterPolicy,要求所有Pod必須包含app標籤。Kyverno會自動為相關的控制器資源生成相應的政策。

jsPolicy控制器政策的使用場景

jsPolicy的控制器政策功能允許使用者編寫自定義的邏輯,以回應叢集事件並執行相應的操作。這使得jsPolicy非常適合用於需要高度自定義邏輯的安全和策略管理場景。

jsPolicy控制器政策範例程式碼
apiVersion: jspolicy.kyverno.io/v1beta1
kind: JsPolicy
metadata:
  name: deny-privileged-pods
spec:
  rules:
  - name: deny-privileged-pods
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Privileged pods are not allowed"
      validate: `
        if (resource.spec.containers.some(container => container.securityContext && container.securityContext.privileged)) {
          return { valid: false };
        }
        return { valid: true };
      `

此範例展示了一條jsPolicy規則,用於阻止建立具有特權模式的Pod。當檢測到Pod定義中包含特權容器時,該規則將阻止該Pod的建立。

Kubernetes原生安全功能的進化

從PodSecurityPolicy到Pod Security Admission

PodSecurityPolicy(PSP)在早期Kubernetes版本中被用來控制Pod的安全組態,但由於其複雜性和易用性問題,最終被棄用並移除。作為替代方案,Pod Security Admission(PSA)被引入,並在Kubernetes v1.25版本中達到穩定。

PSA的三個安全級別詳解
  1. Privileged(不受限制):此級別提供最小的安全限制,允許Pod以特權模式執行,通常適用於需要高度許可權的工作負載。

  2. Baseline(基本安全):此級別提供了一組基本的安全保證,適用於大多數工作負載。它限制了一些特權操作,但仍然允許大多數應用正常執行。

  3. Restricted(高安全):此級別提供了最嚴格的安全限制,適用於對安全性要求極高的環境。它進一步限制了Pod的能力,例如禁止使用某些特權操作和系統呼叫。

透過選擇適當的安全級別,叢集管理員可以在安全性和靈活性之間取得平衡,從而滿足不同應用和工作負載的需求。

結合PaC與原生功能的最佳實踐

統一安全管理策略

透過結合使用PaC工具(如Kyverno、jsPolicy)和Kubernetes原生的安全功能(如PSA),叢集管理員可以實作統一的安全管理策略。這種結合不僅能夠提供預防性控制,還能實作對叢集事件的動態回應,從而提高叢集的安全性和營運效率。

自動化與自定義並重

在實施安全管理時,應當兼顧自動化和自定義的需求。一方面,利用PaC工具提供的自動生成和驗證功能,可以簡化安全管理的工作量;另一方面,透過自定義邏輯和規則,可以滿足特定場景下的安全需求。

自動化安全管理範例
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: automate-network-policies
spec:
  rules:
  - name: generate-network-policy
    match:
      resources:
        kinds:
        - Namespace
    generate:
      kind: NetworkPolicy
      name: deny-all-traffic
      namespace: "{{request.object.metadata.name}}"
      synchronize: true
      data:
        spec:
          podSelector: {}
          policyTypes:
          - Ingress
          - Egress
          ingress: []
          egress: []

此範例展示了一條Kyverno ClusterPolicy,用於在建立新的Namespace時自動生成一個拒絕所有流量的NetworkPolicy,從而實作自動化的網路安全管理。