返回文章列表

Kubernetes 政策治理工具 Gatekeeper

Gatekeeper 是根據 Open Policy Agent (OPA) 的 Kubernetes 原生政策引擎,提供宣告式方法定義和管理叢集內資源,確保符合安全規範和最佳實務。本文探討 Gatekeeper

Kubernetes DevOps

在 Kubernetes 環境中,Gatekeeper 有效地落實政策與治理,根據 Open Policy Agent (OPA) 提供宣告式管理叢集資源的方法。藉由約束範本定義政策,再利用約束套用至特定資源,並透過資料複製機制將必要資訊同步至 OPA。Gatekeeper 支援 denywarndryrun 等強制執行動作,並提供稽核功能追蹤資源合規性。實務上,建議針對 Pod 層級設定約束,並限定作用範圍,善用 warndryrun 模式驗證政策,避免使用變更政策,並注意敏感資料的安全性。多叢集管理方面,常見挑戰包含資料複製、服務發現、網路路由等,可運用 Consul、Istio 等工具協助解決。Terraform 等自動化工具則有助於簡化多叢集管理的複雜性,確保基礎設施佈署和叢集管理的一致性。

Gatekeeper:Kubernetes 的政策與治理工具

Gatekeeper 是 Kubernetes 環境中的一個重要工具,用於實施和管理叢集內的政策與治理。它根據 Open Policy Agent(OPA)構建,提供了一種宣告式的方法來定義和管理叢集內的資源。

約束範本(Constraint Template)

約束範本是 Gatekeeper 的核心元件之一,用於定義叢集內的政策。它由三個主要部分組成:

  1. Kubernetes 所需的 CRD 後設資料:這部分定義了約束範本的名稱和相關後設資料。名稱應該具有描述性,以便於識別政策的目的。
  2. 輸入引數的架構:這部分定義了輸入引數及其相關型別。在給定的範例中,有一個名為 repos 的引數,它是一個字串陣列。
  3. 政策定義:這部分包含了使用 Rego 語言定義的政策邏輯。當規則匹配時,約束就會被違反。

以下是一個約束範本的範例,用於檢查容器映像是否來自允許的倉函式庫:

violation[{"msg": msg}] {
    container := input.review.object.spec.containers[_]
    satisfied := [good | repo = input.parameters.repos[_] ; good = startswith(container.image, repo)]
    not any(satisfied)
    msg := sprintf("initContainer <%v> has an invalid image repo <%v>, allowed repos are %v", [container.name, container.image, input.parameters.repos])
}

內容解密:

  1. container := input.review.object.spec.containers[_]:從輸入的 Kubernetes 物件中提取容器規格。
  2. satisfied := [good | repo = input.parameters.repos[_] ; good = startswith(container.image, repo)]:檢查容器的映像是否以允許的倉函式庫字首開始。
  3. not any(satisfied):如果沒有任何一個倉函式庫字首匹配,則違反約束。
  4. msg := sprintf(...):生成違反約束的錯誤訊息。

定義約束(Defining Constraints)

要使用約束範本,需要建立一個約束資源。約束資源提供了約束範本所需的引數。

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAllowedRepos
metadata:
  name: prod-repo-is-openpolicyagent
spec:
  enforcementAction: deny
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
        namespaces:
          - "production"
  parameters:
    repos:
      - "openpolicyagent/"

內容解密:

  1. kind: K8sAllowedRepos:指定約束的型別,對應於約束範本的名稱。
  2. match:定義了政策的適用範圍,在此範例中,僅適用於 production 名稱空間中的 Pod。
  3. parameters:提供了約束範本所需的引數,在此範例中,允許的倉函式庫字首是 openpolicyagent/

資料複製(Data Replication)

在某些情況下,需要將叢集中的其他資源快取到 OPA 中,以便進行評估。Gatekeeper 使用 Config 資源來管理需要快取的資料。

apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
  name: config
  namespace: gatekeeper-system
spec:
  sync:
    syncOnly:
      - kind: Service
        version: v1
      - kind: Pod
        version: v1
      - kind: Namespace
        version: v1

內容解密:

  1. syncOnly:指定需要快取的資源型別和版本。

使用者經驗(UX)

Gatekeeper 提供即時的反饋機制,當資源違反定義的政策時,會給予相應的錯誤訊息。

強制執行動作和稽核(Using Enforcement Action and Audit)

Gatekeeper 允許組態不同的強制執行動作,包括 denywarndryrun。此外,還提供了稽核功能,用於檢查叢集中的資源是否符合定義的政策。

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title 強制執行動作和稽核(Using Enforcement Action and Audit)

rectangle "符合政策" as node1
rectangle "違反政策" as node2
rectangle "deny" as node3
rectangle "warn" as node4
rectangle "dryrun" as node5

node1 --> node2
node2 --> node3
node3 --> node4
node4 --> node5

@enduml

圖表翻譯: 此圖示呈現了 Gatekeeper 在資源建立過程中根據政策進行驗證的流程。當資源建立時,Gatekeeper 會檢查其是否符合定義的政策。如果符合,則資源建立成功;如果違反,則根據組態的強制執行動作進行相應處理,包括拒絕建立、給予警告或模擬驗證結果。

使用 Gatekeeper 進行政策與治理的最佳實踐

Gatekeeper 是根據 Open Policy Agent(OPA)構建的 Kubernetes 原生政策引擎,用於實作叢集的政策與治理。在本章中,我們將介紹如何使用 Gatekeeper 來定義、執行和測試叢集內的政策。

瞭解 Gatekeeper 的核心功能

Gatekeeper 提供了一個靈活且可擴充套件的框架,用於定義和執行 Kubernetes 資源的政策。主要功能包括:

  • 政策驗證:Gatekeeper 可以驗證 Kubernetes 資源是否符合定義的政策,並提供錯誤訊息和稽核日誌。
  • 政策執行:Gatekeeper 可以根據定義的政策執行不同的動作,例如拒絕不符合政策的資源建立或更新。
  • 稽核:Gatekeeper 提供了一個稽核機制,可以定期評估叢集內的資源是否符合定義的政策,並提供稽核報告。

使用 Enforcement Action 和 Audit

Gatekeeper 的 enforcementAction 欄位允許您定義政策違規時的行為。有三種可選的動作:

  • deny:拒絕不符合政策的資源建立或更新,並傳回錯誤訊息。
  • warn:允許不符合政策的資源建立或更新,但傳回警告訊息。
  • dryrun:允許不符合政策的資源建立或更新,並記錄稽核日誌。

無論選擇哪種 enforcementAction,Gatekeeper 都會定期評估叢集內的資源是否符合定義的政策,並提供稽核報告。

程式碼範例:檢視 K8sAllowedRepos 的狀態

$ kubectl get k8sallowedrepos
NAME                          ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
prod-repo-is-openpolicyagent   deny                 1

$ kubectl get k8sallowedrepos prod-repo-is-openpolicyagent -o yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAllowedRepos
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: ...
  creationTimestamp: "..."
  generation: 1
  name: prod-repo-is-openpolicyagent
  resourceVersion: "..."
  uid: ...
spec:
  match:
    kinds:
    - apiGroups:
      - ""
      kinds:
      - Pod
    namespaces:
    - production
  parameters:
    repos:
    - openpolicyagent/
status:
  auditTimestamp: "2022-11-27T23:37:42Z"
  totalViolations: 1
  violations:
  - enforcementAction: deny
    group: ""
    kind: Pod
    message: container <nginx> has an invalid image repo <nginx>, allowed repos are ["openpolicyagent/"]
    name: nginx
    namespace: production
    version: v1

內容解密:

此範例展示瞭如何使用 kubectl 命令檢視 K8sAllowedRepos 的狀態。輸出的 YAML 檔案包含了 specstatus 兩個部分。spec 定義了政策的匹配條件和引數,而 status 則包含了稽核時間戳、違規總數和違規詳情。

  • auditTimestamp 表示上一次稽核的時間。
  • totalViolations 表示違規資源的總數。
  • violations 列出了所有違規的資源,包括違規的容器、名稱空間和錯誤訊息。

Mutation(變更)政策

除了驗證政策外,Gatekeeper 也支援變更(Mutation)政策,用於在准入時修改 Kubernetes 資源。然而,變更資源並不是最佳實踐,因為它違反了 Kubernetes 的宣告式原則。

測試政策

Gatekeeper 提供了一個名為 gator 的 CLI 工具,用於在本地測試政策。您可以使用 gator 命令來評估定義的政策是否符合預期。

熟悉 Gatekeeper

Gatekeeper 的 GitHub 倉函式庫中包含了一個示範內容,展示瞭如何使用 Gatekeeper 來實作銀行的合規性要求。建議您透過這個示範來熟悉 Gatekeeper 的操作。

政策與治理的最佳實踐

在實施政策與治理時,以下是一些最佳實踐:

  1. 確定要檢查和執行的 Kubernetes 資源規範欄位:例如,在 Deployment、ReplicaSet 和 Pod 三個層級中,選擇最低的交接點(即 Pod)進行檢查。
  2. 將約束條件(Constraints)限定在需要的資源上:使用 kinds、namespaces 和 label selectors 等條件,將約束條件限定在需要的資源上,以確保一致性和效率。
  3. 在已佈署資源的叢集上使用 warn 和 dryrun:在設定 enforcementAction 為 deny 之前,使用 warn 和 dryrun 以及稽核功能來糾正違規資源。
  4. 避免使用變更(Mutation)政策:考慮使用其他宣告式方法,例如 GitOps。
  5. 避免同步和執行敏感資料:例如 Kubernetes Secrets,因為 OPA 可能會將其快取,並可能導致潛在的安全風險。
  6. 多個約束條件之間的關係:如果有多個約束條件,則任何一個約束條件被拒絕,都將導致整個請求被拒絕。

管理多重叢集的最佳實踐

在現代的雲端架構中,多重Kubernetes叢集的管理已成為企業面臨的重要挑戰。本章將探討多重叢集管理的最佳實踐,分析多叢集架構與聯邦(federation)之間的差異,並介紹管理多個叢集的工具和操作模式。

為何需要多重叢集?

採用Kubernetes時,通常會擁有多個叢集。起初,您可能會為了區分生產環境、測試環境、開發環境而建立多個叢集。Kubernetes提供了名稱空間(namespaces)來實作多租戶功能,將一個叢集劃分為多個邏輯單元。名稱空間允許您定義根據角色的存取控制(RBAC)、配額(quotas)、Pod安全策略(pod security policies)和網路策略(network policies),以實作工作負載的分離。

然而,除了這些功能之外,還有一些其他因素需要考慮,例如:

  • 故障範圍(Blast Radius)
  • 合規性(Compliance)
  • 安全性(Security)
  • 硬性多租戶(Hard Multitenancy)
  • 地區性工作負載(Regional-based Workloads)
  • 特殊工作負載(Specialized Workloads)

故障範圍的考量

在設計架構時,故障範圍是一個重要的考量因素。微服務架構中使用斷路器(circuit breakers)、重試機制(retries)、隔板(bulkheads)和速率限制(rate limiting)來限制系統損壞的範圍。同樣,多個叢集可以幫助防止因軟體問題引起的連鎖故障。

合規性與安全性需求

某些工作負載,如涉及支付卡行業(PCI)或健康保險可攜性和責任法案(HIPAA)的應用,需要特定的安全強化和專用元件。使用獨立的叢集可以簡化這些合規性工作負載的管理。

在大規模的Kubernetes叢集中,安全管理可能變得困難。隨著更多團隊加入,安全需求的多樣性使得單一叢集難以滿足所有需求。多個叢集可以限制因組態錯誤引起的安全風險。

多叢集設計的挑戰

選擇多叢集設計時,您將面臨一些挑戰,包括:

  • 資料複製(Data Replication)
  • 服務發現(Service Discovery)
  • 網路路由(Network Routing)
  • 維運管理(Operational Management)
  • 持續佈署(Continuous Deployment)

這些挑戰可能使您的架構變得過於複雜。然而,透過合理的設計和工具選擇,可以有效地管理多重叢集。

多叢集管理的工具與技術

在後續章節中,我們將探討用於管理多個Kubernetes叢集的工具和技術,包括叢集聯邦、服務網格(Service Mesh)等解決方案,以應對上述挑戰。

叢集聯邦的應用

當您的應用需要跨地區分佈時,多叢集架構將成為必然選擇。叢集聯邦技術可以幫助您管理跨多個叢集的工作負載,實作統一的管理和排程。

特殊工作負載的處理

對於高效能運算(HPC)、機器學習(ML)等特殊工作負載,可能需要特定的硬體支援或效能組態。多叢集架構可以為這些工作負載提供專用的叢集,確保其高效執行。

多叢集管理挑戰與解決方案

在跨地理區域和多叢集佈署工作負載時,資料複製和一致性一直是關鍵挑戰。執行這些服務時,需要決定哪些服務執行在哪裡,並制定複製策略。大多數資料函式庫都具有內建的複製工具,但需要設計應用程式以處理複製策略。對於NoSQL型別的資料函式庫服務,這可能更容易,因為它們可以處理跨多個例項的擴充套件,但仍需要確保應用程式能夠處理跨地理區域的最終一致性或至少跨區域的延遲。一些雲端服務,如Google Cloud Spanner和Microsoft Azure CosmosDB,已建立資料函式庫服務,以幫助處理跨多個地理區域的資料複雜性。

每個Kubernetes叢集都會佈署自己的服務發現登入檔,而登入檔並不同步到多個叢集。這使得應用程式難以輕易地識別和發現彼此。像HashiCorp的Consul這樣的工具可以透明地同步來自多個叢集的服務,甚至是駐留在Kubernetes外部的服務。其他像Istio、Linkerd和Cilium這樣的工具正在建立多叢集架構,以擴充套件叢集之間的服務發現。

網路挑戰

Kubernetes使叢集內的網路變得非常容易,因為它是一個扁平的網路,避免使用網路位址轉換(NAT)。如果需要將流量路由到叢集內外,這就變得更加複雜。進入叢集的流量是以1:1對映的方式實作的,因為它不支援使用Ingress資源的多叢集拓撲。還需要考慮叢集之間的出口流量以及如何路由該流量。當應用程式駐留在單一叢集中時,這很容易,但當引入多叢集時,需要考慮具有應用程式依賴關係的服務的額外跳躍延遲。對於具有緊密耦合依賴關係的應用程式,應考慮在同一個叢集中執行這些服務,以消除延遲和額外的複雜性。

程式碼範例:使用Terraform進行基礎設施佈署

# 定義Google Cloud提供者
provider "google" {
  project = "your-project-id"
  region  = "us-central1"
}

# 建立Kubernetes叢集
resource "google_container_cluster" "primary" {
  name     = "primary-cluster"
  location = "us-central1"

  # 初始節點數量
  initial_node_count = 3

  # 節點組態
  node_config {
    preemptible  = true
    machine_type = "n1-standard-1"

    oauth_scopes = [
      "https://www.googleapis.com/auth/compute",
      "https://www.googleapis.com/auth/devstorage.read_only",
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring",
    ]
  }
}

內容解密:

此Terraform程式碼定義了一個Google Cloud提供者和一個Kubernetes叢集資源。主要功能包括:

  1. 提供者組態:指定使用的雲端提供者(Google Cloud)及其相關設定,如專案ID和區域。
  2. 叢集建立:定義一個名為primary-cluster的Kubernetes叢集,位於us-central1區域。
  3. 節點組態:設定叢集的初始節點數量為3,並定義節點的組態,包括使用搶佔式虛擬機器(preemptible)和機器型別(n1-standard-1)。
  4. OAuth範圍:為節點指定所需的OAuth範圍,以允許必要的API存取許可權。

自動化管理多叢集

管理多叢集的最大開銷之一是營運管理。與其管理一兩個叢集,不如現在管理環境中的許多叢集。管理多叢集最重要的方面之一是確保有良好的自動化實踐,因為這將有助於減少營運負擔。在自動化叢集時,需要考慮基礎設施佈署和管理叢集的附加功能。使用像HashiCorp的Terraform這樣的工具可以幫助佈署和管理整個叢集艦隊的一致狀態。

多叢集管理架構

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title 多叢集管理架構

rectangle "請求" as node1
rectangle "路由" as node2
rectangle "服務發現" as node3
rectangle "同步" as node4

node1 --> node2
node2 --> node3
node3 --> node4

@enduml

圖表翻譯: 此圖表展示了多叢集管理架構,主要元件包括:

  1. 使用者請求:使用者發出請求,透過Ingress Controller進行路由。
  2. Ingress Controller:將請求路由到不同的Kubernetes叢集。
  3. Kubernetes叢集:各個叢集內部使用Consul進行服務發現。
  4. Consul:負責跨叢集的服務同步,實作跨叢集服務發現。

連續交付與多叢集管理

隨著多叢集和連續交付(CD)的出現,需要處理多個Kubernetes API端點,而非單一API端點。這可能會對應用程式的分發造成挑戰。可以輕易地管理多個管道,但假如有上百個不同的管道需要管理,則會使應用程式分發變得非常困難。有鑑於此,需要考慮不同的管理方法。