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

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

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

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

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

資源

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

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

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

管道

本教學課程使用的 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

您可以使用 Pricing Calculator 根據預測用量估算費用。

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

事前準備

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

    前往「Manage resources」(管理資源)

  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. 前往 Google Cloud 控制台的「Manage resources」(管理資源) 頁面。

    前往「Manage resources」(管理資源)

  2. 在專案清單中選取要刪除的專案,然後點選「Delete」(刪除)
  3. 在對話方塊中輸入專案 ID,然後按一下 [Shut down] (關閉) 以刪除專案。