依據持續整合管道中的公司政策檢查應用程式

如果貴機構使用 Policy Controller 管理 Google Kubernetes Engine (GKE) Enterprise 版叢集的政策,您可以在應用程式的持續整合 (CI) 管道中驗證部署設定。本教學課程會示範如何達成這個結果。如果您是為應用程式建構 CI 管道的開發人員,或是為多個應用程式團隊建構 CI 管道範本的平台工程師,驗證應用程式會很有幫助。

如果您是 IT 管理員和作業人員,希望確保雲端平台中執行的所有資源都符合機構的法規遵循規定,並提供及維護自動化功能來稽核或強制執行規定,以及管理基礎技術架構的生命週期,歡迎參閱這個頁面。如要進一步瞭解我們在Google Cloud 內容中提及的常見角色和範例工作,請參閱「常見的 GKE Enterprise 使用者角色和工作」。

政策是機構安全性和合規性的重要一環。貴機構可透過 Policy Controller,集中管理所有叢集的政策,並以宣告方式設定政策。開發人員可以善用這些政策的集中式和宣告式特性。您可以在開發工作流程中盡早使用這些特徵,根據這些政策驗證應用程式。在 CI 管道中瞭解政策違規情形,而非在部署期間,主要有兩大優點:可將安全性左移,並縮短意見回饋迴圈,減少修正違規情形所需的時間和成本。

本教學課程使用 Cloud Build 做為 CI 工具,並提供包含政策的 GitHub 範例存放區,以供示範。

資源

本教學課程會使用幾項 Kubernetes 工具。本節說明這些工具的用途、彼此之間的互動方式,以及是否能以其他工具取代。

本教學課程使用的工具包括:

  • Policy Controller: 以開放原始碼專案 Open Policy Agent - Gatekeeper 為基礎。 Policy Controller 會針對 Kubernetes 叢集中建立的物件強制執行政策 (例如禁止使用特定選項,或強制使用特定標籤)。這些政策稱為「限制」。限制條件定義為 Kubernetes 自訂資源。Policy Controller 是 Google Kubernetes Engine (GKE) Enterprise 版的一部分,但您可以改用 Open Policy Agent - Gatekeeper 實作。

  • GitHub: 在本教學課程中,我們使用 GitHub 代管 Git 存放區:一個用於範例應用程式,另一個則包含 Policy Controller 的限制。為求簡單,這兩個存放區是單一 Git 存放區中的兩個不同資料夾。但實際上,這兩個會是不同的存放區。您可以使用任何 Git 解決方案。

  • Cloud Build: Cloud Build 是 Google Cloud的 CI 解決方案。在本教學課程中,我們會使用這項工具執行驗證測試。雖然實作細節可能因 CI 系統而異,但本教學課程中說明的概念適用於任何以容器為基礎的 CI 系統。

  • Kustomize: Kustomize 是 Kubernetes 設定的自訂工具。這項功能會採用「基本」設定,並套用自訂項目。您可透過此工具,以 DRY (Don't Repeat Yourself) 方法處理 Kubernetes 設定。使用 Kustomize 時,您可以將所有環境通用的元素保留在基本設定中,並為每個環境建立自訂項目。在本教學課程中,我們會將 Kustomize 設定保留在應用程式存放區中,並在 CI 管道中「建構」設定 (例如套用自訂項目)。您可以使用本教學課程中說明的概念,搭配任何可產生 Kubernetes 設定的工具,將設定套用至叢集 (例如 helm template 指令)。

  • Kpt: Kpt 是用來建構 Kubernetes 設定工作流程的工具。Kpt 可讓您擷取、顯示、自訂、更新、驗證及套用 Kubernetes 設定。由於 Config Sync 支援 Git 和 YAML 檔案,因此與 Kubernetes 生態系統中現有的大多數工具相容。在本教學課程中,我們會在 CI 管道中使用 kpt,從 anthos-config-management-samples 存放區擷取限制,並根據這些限制驗證 Kubernetes 設定。

pipeline

本教學課程使用的 CI 管道如下圖所示:

Policy Controller 的 CI 管道

管道會在 Cloud Build 中執行,而指令則會在包含範例應用程式存放區副本的目錄中執行。管道會先使用 Kustomize 產生最終的 Kubernetes 設定,接著,它會使用 kpt 從 anthos-config-management-samples 存放區擷取要驗證的限制。最後,它會使用 kpt 根據這些限制條件驗證 Kubernetes 設定。為完成最後一個步驟,我們會使用名為 gatekeeper 的特定設定函式執行這項驗證。在本教學課程中,您會手動觸發 CI 管道,但實際上,您會將其設定為在 git push 至 Git 存放區後執行。

目標

  • 使用 Cloud Build 執行範例應用程式的 CI 管道。
  • 請注意,管道會因違反政策而失敗。
  • 修改範例應用程式存放區,確保符合政策規定。
  • 再次成功執行 CI 管道。

費用

本教學課程使用下列 Google Cloud的計費元件:

  • Cloud Build
  • Google Kubernetes Engine (GKE) Enterprise 版

如要根據預測用量估算費用,請使用 Pricing Calculator

完成本教學課程後,您可以刪除已建立的資源以避免繼續計費。詳情請參閱「清除所用資源」一節。

事前準備

  1. 選取或建立 Google Cloud 專案。在 Google Cloud 控制台中,前往「管理資源」頁面:

    前往「管理資源」

  2. 啟用專案的計費功能。

  3. 如要執行本教學課程中列出的指令,請開啟 Cloud Shell:

    前往 Cloud Shell

  4. 在 Cloud Shell 中執行 gcloud config get-value project

    如果指令沒有傳回您選取的專案 ID,請將 Cloud Shell 設定為使用您的專案:

    gcloud config set project PROJECT_ID
    

    PROJECT_ID 替換為您的專案 ID。

  5. 在 Cloud Shell 中,啟用必要的 Cloud Build API:

    gcloud services enable cloudbuild.googleapis.com
    

驗證範例應用程式設定

在本節中,您將使用 Cloud Build,為我們提供的範例應用程式存放區執行 CI 管道。這個管道會根據 anthos-config-management-samples 存放區中的限制,驗證該範例應用程式存放區中的 Kubernetes 設定。

如要驗證應用程式設定,請按照下列步驟操作:

  1. 在 Cloud Shell 中,複製範例應用程式存放區:

    git clone https://github.com/GoogleCloudPlatform/anthos-config-management-samples.git
    
  2. 使用 Cloud Build 執行 CI 管道。建構作業的記錄會直接顯示在 Cloud Shell 中。

    cd anthos-config-management-samples/ci-app/app-repo
    gcloud builds submit .
    

    您執行的管道定義於下列檔案。

    steps:
    - id: 'Prepare config'
      # This step builds the final manifests for the app
      # using kustomize and the configuration files
      # available in the repository.
      name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
      entrypoint: '/bin/sh'
      args: ['-c', 'mkdir hydrated-manifests && kubectl kustomize config/prod > hydrated-manifests/prod.yaml']
    - id: 'Download policies'
      # This step fetches the policies from the Anthos Config Management repository
      # and consolidates every resource in a single file.
      name: 'gcr.io/kpt-dev/kpt'
      entrypoint: '/bin/sh'
      args: ['-c', 'kpt pkg get https://github.com/GoogleCloudPlatform/anthos-config-management-samples.git/ci-app/acm-repo/cluster@main constraints
                      && kpt fn source constraints/ hydrated-manifests/ > hydrated-manifests/kpt-manifests.yaml']
    - id: 'Validate against policies'
      # This step validates that all resources comply with all policies.
      name: 'gcr.io/kpt-fn/gatekeeper:v0.2'
      args: ['--input', 'hydrated-manifests/kpt-manifests.yaml']

    在 Policy Controller 中,限制是限制範本的例項。限制範本包含用於實作限制的實際 Rego 程式碼。gcr.io/kpt-fn/gatekeeper 函式需要限制範本和限制定義才能運作。範例政策存放區同時包含這兩者,但實際上可以儲存在不同位置。視需要使用 kpt pkg get 指令,下載限制範本和限制。

    本教學課程會使用 Cloud Build 搭配 gcr.io/kpt-fn/gatekeeper 驗證資源,但您也可以使用其他兩種替代方案:

    kpt fn eval hydrated-manifests/kpt-manifests.yaml --image gcr.io/kpt-fn/gatekeeper:v0.2
    
    gator test -f hydrated-manifests/kpt-manifests.yaml
    
  3. 幾分鐘後,您會發現管道失敗,並顯示下列錯誤:

    [...]
    Step #2 - "Validate against policies": [error] apps/v1/Deployment/nginx-deployment : Deployment objects should have an 'owner' label indicating who created them.
    Step #2 - "Validate against policies": violatedConstraint: deployment-must-have-owner
    Finished Step #2 - "Validate against policies"
    2022/05/11 18:55:18 Step Step #2 - "Validate against policies" finished
    2022/05/11 18:55:19 status changed to "ERROR"
    ERROR
    ERROR: build step 2 "gcr.io/kpt-fn/gatekeeper:v0.2" failed: exit status 1
    2022/05/11 18:55:20 Build finished with ERROR status
    

    以下檔案定義了設定違反的限制。這是名為 K8sRequiredLabels 的 Kubernetes 自訂資源。

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sRequiredLabels
    metadata:
      name: deployment-must-have-owner
    spec:
      match:
        kinds:
          - apiGroups: ["apps"]
            kinds: ["Deployment"]
      parameters:
        labels:
          - key: "owner"
        message: "Deployment objects should have an 'owner' label indicating who created them."

    如要查看與這項限制相應的限制範本,請前往 GitHub 上的requiredlabels.yaml

  4. 自行建構完整的 Kubernetes 設定,並觀察到確實缺少 owner 標籤。如要建構設定:

    kubectl kustomize config/prod
    

修正應用程式,使其符合公司政策

在本節中,您將使用 Kustomize 修正政策違規問題:

  1. 在 Cloud Shell 中,將 commonLabels 區段新增至基本 Kustomization 檔案:

    cat <<EOF >> config/base/kustomization.yaml
    commonLabels:
      owner: myself
    EOF
    
  2. 建構完整的 Kubernetes 設定,並觀察 owner 標籤是否已存在:

    kubectl kustomize config/prod
    
  3. 使用 Cloud Build 重新執行 CI 管道:

    gcloud builds submit .
    

    管道現在會成功執行,並輸出下列內容:

    [...]
    Step #2 - "Validate against policies": [RUNNING] "gcr.io/kpt-fn/gatekeeper:v0"
    Step #2 - "Validate against policies": [PASS] "gcr.io/kpt-fn/gatekeeper:v0"
    [...]
    

清除所用資源

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

後續步驟