使用 Config Sync 安全發布

本文件說明叢集運算子和平台管理員如何使用 Config Sync,安全地在多個環境中推出異動內容。這種做法有助於避免錯誤同時影響所有環境。

Config Sync 可讓您使用儲存在 Git 存放區中的檔案,管理單一叢集、多租戶叢集和多叢集 Kubernetes 設定。

設定可代表多種項目,包括:

如果您要部署在 Google Kubernetes Engine (GKE) Enterprise 版上建構平台時所需的設定、政策和工作負載,例如安全防護代理程式、監控代理程式和憑證管理員,Config Sync 就非常適合。

雖然您可以使用 Config Sync 部署面向使用者的應用程式,但我們不建議將這些應用程式的發布生命週期,連結至先前提及的管理工作負載發布生命週期。建議您改用專門的應用程式部署工具,例如持續部署工具,讓應用程式團隊負責自己的發布時間表。

Config Sync 是一項功能強大的產品,可管理許多元素,因此您需要防護措施,避免發生重大影響的錯誤。本文將說明幾種建立防護措施的方法。第一節介紹階段性推出,第二節則著重於測試和驗證。第三節說明如何監控部署作業。

使用 Config Sync 實作分階段推出功能

在多叢集環境中 (GKE Enterprise 使用者常見的情況),我們不建議同時在所有叢集中套用設定變更。分階段推出更新,每次更新一個叢集,可大幅降低任何錯誤的潛在影響,因此更安全。

您可以使用 Config Sync,透過下列幾種方式導入階段性推出:

  • 使用 Git 提交或標記,手動將變更套用至叢集。
  • 使用 Git 分支,在合併變更時自動套用變更。您可以為不同叢集群組使用不同分支。
  • 使用 ClusterSelectorNamespaceSelector 物件,選擇性地將變更套用至叢集或命名空間的子群組。

所有階段性推出方法都有優缺點。下表顯示可同時使用的方法:

相容性 Git 修訂版本或標記 Git 分支 叢集選取器 命名空間選取器
Git 修訂版本或標記 不相容 相容 相容
Git 分支 不相容 相容 相容
叢集選取器 相容 相容 相容
命名空間選取器 相容 相容 相容

下列決策樹可協助您決定何時使用其中一種階段性推出方法。

推出方法的決策樹。

使用 Git 修訂版本或標記

相較於其他階段性推出方法,使用 Git 提交或標記可提供最多控制權,也是最安全的方法。您可以在控制台中使用「Config Sync」頁面 Google Cloud ,同時更新多個叢集。如要逐一對叢集套用變更,並精確控制變更時間,請使用這個方法。

使用這種方法時,您會將每個叢集「釘選」至存放區的特定版本 (提交或標記)。這個方法與使用 Git 提交做為容器映像檔標記類似。如要實作這個方法,請在 RootSyncRepoSync 自訂資源spec.git.revision 欄位中指定提交、標記或雜湊。

如果您使用 Kustomize 等工具管理 RootSyncRepoSync 自訂資源,可以減少推出作業所需的人工工作量。使用這類工具時,您只需在一處變更 revision 參數,然後依您選擇的順序和步調,選擇性地將新的 RootSyncRepoSync 自訂資源套用至叢集。

此外,您可以使用 Google Cloud 控制台,同時更新屬於同一機群的多個叢集的 revision 參數。不過,如果您有自動化系統可更新設定,我們不建議使用 Google Cloud 控制台變更設定。

舉例來說,下列 RootSync 定義會將 Config Sync 設定為使用 1.2.3 標記:

apiVersion: configsync.gke.io/v1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-sync-system
spec:
  sourceType: git
  sourceFormat: unstructured
  git:
    repo: git@example.com:gke/config-sync.git
    revision: 1.2.3
    auth: ssh

如果您將這項設定套用至叢集,Config Sync 會使用 example.com:gke/config-sync.git 存放區的 1.2.3 標記。

如要更新叢集,請將 spec.git.revision 欄位變更為叢集的新值。您可以藉此定義要更新的叢集和更新時間。如要復原變更,請將 spec.git.revision 欄位改回先前的值。

下圖說明此方法的推出程序。首先,將變更提交至 Config Sync 存放區,然後更新所有叢集上的 RootSync 定義:

Git 修訂版本和標記的推出程序。

建議您採取以下行動:

  • 請使用 Git 修訂 ID,而非標記。由於 Git 函式的運作方式,您可以保證這些物件永遠不會變更。舉例來說,git push --force 無法變更 Config Sync 使用的提交內容。這種做法有助於稽核,並追蹤記錄中使用的提交內容。此外,與標記不同的是,您不需要額外步驟即可提交 ID。
  • 如果您偏好使用 Git 標記而非 Git 修訂 ID,可以透過支援保護機制的 Git 解決方案保護標記。
  • 如要同時更新多個叢集,請前往 Google Cloud 控制台。如要一次更新多個叢集,這些叢集必須屬於同一個機群 (且位於同一個專案)。

使用 Git 分支版本

如要讓系統在 Git 存放區中合併變更後,立即將變更套用至叢集,請將 Config Sync 設為使用 Git 分支,而非修訂版本或標記。這個方法是在 Git 存放區中建立多個長期分支,並在不同叢集中設定 Config Sync,從不同分支讀取設定。

舉例來說,簡單的模式有兩個分支:

  • 非正式環境叢集的 staging 分支版本。
  • 實際工作環境叢集的 main 分支版本。

如果是非正式版叢集,請建立 RootSyncRepoSync 物件,並將 spec.git.branch 欄位設為 staging。如果是正式版叢集,請建立 RootSyncRepoSync 物件,並將 spec.git.branch 參數設為 main

舉例來說,下列 RootSync 定義會將 Config Sync 設定為使用 main 分支:

apiVersion: configsync.gke.io/v1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-sync-system
spec:
  git:
    repo: git@example.com:gke/config-sync.git
    branch: main
    auth: ssh

下圖說明此方法的推出程序:

Git 分支版本的推出程序。

您可以根據特定需求調整這個模式,使用兩個以上的分支,或使用對應至環境以外項目的分支。如要還原變更,請使用 git revert 指令在同一分支上建立新提交,還原先前提交的變更。

建議您採取以下行動:

  • 處理多個叢集時,請至少使用兩個 Git 分支,協助區分實際工作環境和非實際工作環境叢集。
  • 大多數 Git 解決方案都提供受保護的分支功能,可防止刪除或未經審查的分支變更。詳情請參閱 GitHubGitLabBitbucket 的說明文件。

使用 ClusterSelector 和 NamespaceSelector 物件

Git 分支是逐步在多個叢集推出變更的好方法,這些叢集最終都會採用相同的政策。不過,如要僅將變更推出至部分叢集或命名空間,請使用 ClusterSelectorNamespaceSelector 物件。這些物件的目標類似:只允許您將物件套用至具有特定標籤的叢集或命名空間。

例如:

  • 使用 ClusterSelector 物件,您可以根據叢集所在的國家/地區,為各種法規制度套用不同的政策。
  • 使用 NamespaceSelector 物件,即可對內部團隊和外部承包商使用的命名空間套用不同政策。

您也可以使用 ClusterSelectorNamespaceSelector 物件,實作進階測試和發布方法,例如:

  • 政策 Canary 版本:將新政策長期部署至一小部分叢集和命名空間,研究政策的影響。
  • A/B 測試:將相同政策的不同版本部署到不同叢集,研究政策版本影響的差異,然後選擇最佳版本部署到所有位置。

舉例來說,假設某機構有多個生產叢集。 平台團隊已使用 ClusterClusterSelector 物件,建立兩類生產叢集,分別稱為 canary-prodprod (請參閱「使用 ClusterSelectors」)。

平台團隊想透過 Policy Controller 推出政策,強制在命名空間中加入團隊標籤,以識別各命名空間所屬的團隊。他們已在模擬測試模式中推出這項政策的版本,現在想在少數叢集上強制執行這項政策。他們使用 ClusterSelector 物件建立兩個不同的 K8sRequiredLabels 資源,並套用至不同叢集。

  • K8sRequiredLabels 資源會套用至 prod 類型的叢集,且 enforcementAction 參數會設為 dryrun

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sRequiredLabels
    metadata:
      name: ns-must-have-team
      annotations:
        configmanagement.gke.io/cluster-selector: prod
    Spec:
      enforcementAction: dryrun
      match:
        kinds:
          - apiGroups: [""]
            kinds: ["Namespace"]
      parameters:
        labels:
          - key: "team"
    
  • K8sRequiredLabels 資源會套用至 canary-prod 類型的叢集,且不含 enforcementAction 參數,表示政策實際上會強制執行:

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sRequiredLabels
    metadata:
      name: ns-must-have-team
      annotations:
        configmanagement.gke.io/cluster-selector: canary-prod
    spec:
      match:
        kinds:
          - apiGroups: [""]
        kinds: ["Namespace"]
      parameters:
        labels:
          - key: "team"
    

團隊可使用 configmanagement.gke.io/cluster-selector 註解,只在 canary-prod 類型的叢集中強制執行政策,避免任何非預期的副作用擴散到整個生產機群。如要進一步瞭解 Policy Controller 的試執行功能,請參閱建立限制

建議您採取以下行動:

  • 如要將設定變更套用至部分叢集或命名空間,且時間不確定或很長,請使用 ClusterSelectorNamespaceSelector 物件。
  • 如果您使用選取器推出變更,請務必謹慎。如果您使用 Git 提交,任何錯誤一次只會影響一個叢集,因為您是逐一推出叢集。但如果您使用 Git 分支,任何錯誤都可能影響使用該分支的所有叢集。如果使用選取器,錯誤可能會一次影響所有叢集。

實施審查、測試和驗證

Config Sync 的優點之一,就是以宣告方式管理所有項目,包括 Kubernetes 資源、雲端資源和政策。也就是說,原始碼控管管理系統中的檔案代表資源 (以 Config Sync 來說,就是 Git 檔案)。這項特性可讓您實作已用於應用程式原始碼的開發工作流程:審查和自動化測試。

導入評論

由於 Config Sync 是以 Git 為基礎,因此您可以使用偏好的 Git 解決方案來代管 Config Sync 存放區。您的 Git 解決方案可能具備程式碼審查功能,可用於審查對 Config Sync 存放區所做的變更。

審查存放區變更的最佳做法與一般程式碼審查相同,如下所示:

由於 Config Sync 程式碼集相當敏感,我們也建議您盡可能進行下列設定 (如果您的 Git 解決方案允許的話):

  • 保護叢集直接使用的分支。請參閱 GitHubGitLabBitbucket 的說明文件。您也可以透過 GitLab 保護標記
  • 保護分支後,您可以調整合併變更所需的核准次數:
    • 在 GitHub 上啟用必要審查
    • 如果是 GitLab,請使用「程式碼擁有者」,以檔案或目錄為單位委派核准權限。您可以透過合併要求核准,要求不同團隊的不同人員核准要求,才能合併要求。
    • 在 Bitbucket 中,將預設審查員預設合併檢查合併。(選用) 您可以透過 Atlassian Marketplace 取得 Bitbucket Server 的程式碼擁有者外掛程式,控管哪些人可以核准存放區子區段的變更。

使用這些不同功能,即可對程式碼集的所有變更要求強制執行核准程序。舉例來說,您可以確保每項變更都至少經過平台團隊 (負責運作叢集機群) 和安全團隊 (負責定義及實作安全政策) 的成員核准。

建議採取下列行動:

  • 對存放區強制執行同儕審查,並保護叢集使用的 Git 分支。

實作自動化測試

處理程式碼集時,常見的最佳做法是實作持續整合。也就是說,您會設定在建立或更新變更要求時執行自動化測試。自動化測試可以在人工審查變更要求前,找出許多錯誤。這可縮短開發人員的意見回饋循環。您可以使用相同的工具,為 Config Sync 存放區實作相同的概念。

舉例來說,您可以先在新的變更上自動執行 nomos vet 指令。這項指令會驗證 Config Sync 存放區的語法是否有效。您可以按照驗證設定教學課程,使用 Cloud Build 實作這項測試。您可以透過下列選項整合 Cloud Build:

  • Bitbucket,方法是使用建構觸發條件
  • GitHub,方法是使用 Google Cloud Build GitHub 應用程式。GitHub 也提供建構觸發條件,但建議使用 GitHub 應用程式整合。

驗證設定教學課程所示,測試是使用容器映像檔完成。因此,您可以在任何執行容器的持續整合解決方案中實作測試,不限於 Cloud Build。

如要進一步縮短意見回饋週期,可以要求使用者執行 nomos vet 指令做為 Git 預先提交勾點。但請注意,部分使用者可能無法存取 Config Sync 管理的 Kubernetes 叢集,也可能無法從工作站執行完整驗證。執行 nomos vet --clusters "" 指令,將驗證限制為語意和語法檢查。

建議採取下列行動:

  • 在持續整合管道中實作測試。
  • 對所有建議的變更執行至少 nomos vet 指令。

監控發布作業

即使您導入本文件涵蓋的所有防護措施,仍可能發生錯誤。以下是兩種常見的錯誤類型:

  • 不會對 Config Sync 本身造成問題,但會導致工作負載無法正常運作的錯誤,例如過於嚴格的 NetworkPolicy,導致工作負載的元件無法通訊。
  • 導致 Config Sync 無法將變更套用至叢集的錯誤,例如無效的 Kubernetes 資訊清單,或遭准入控制器拒絕的物件。先前說明的方法應可找出大部分這類錯誤。

在 Config Sync 層級幾乎不可能偵測到前一個項目符號所述的錯誤,因為這需要瞭解每個工作負載的狀態。因此,偵測這些錯誤的最佳方式,是透過現有的監控系統,在應用程式發生異常行為時發出警報。

如要偵測前一個項目符號所述的錯誤 (如果您已實作所有防護措施,這類錯誤應該很少發生),則需要進行特定設定。根據預設,Config Sync 會將錯誤寫入記錄檔 (預設位於 Cloud Logging)。錯誤也會顯示在 Config Sync Google Cloud 控制台頁面。通常光靠記錄或控制台不足以偵測錯誤,因為您可能不會隨時監控這些項目。如要自動偵測錯誤,最簡單的方法是執行 nomos status 指令,這個指令會指出叢集是否有錯誤。

您也可以設定更進階的解決方案,在發生錯誤時自動收到快訊。Config Sync 會以 Prometheus 格式公開指標。詳情請參閱監控 Config Sync

在監控系統中取得 Config Sync 指標後,請建立快訊,在 gkeconfig_monitor_errors 指標大於 0 時通知您。詳情請參閱「管理 Cloud Monitoring 的快訊政策」或「Prometheus 的快訊規則」。

使用 Config Sync 安全發布的機制摘要

下表彙整本文件稍早說明的各種機制。這些機制並非互斥。您可以選擇使用部分或全部的帳戶,以達成不同目的。

機制 適用場合 不適用場合 用途範例
Git 修訂版本 ID 和標記 使用特定 Git 提交 ID 或標記,精確控管要套用哪些叢集變更。 請勿使用 Git 提交 ID 或標記,來表示叢集間的長期差異。使用叢集選取器。 所有叢集都已設定為套用 12345 Git 提交。您使用要測試的新提交 abcdef 進行變更。您可以變更單一叢集的設定,使用這個新提交內容驗證變更。
Git 分支 如要將相同變更依序推出至多個環境,請使用多個 Git 分支版本。 請勿使用多個 Git 分支,來處理叢集間的長期差異。分支會大幅分歧,難以合併。 首先,請合併暫存分支中的變更,暫存叢集會擷取這些變更。
接著合併主分支中的變更,實際工作環境叢集會擷取這些變更。
叢集選取器和命名空間選取器 針對叢集和命名空間之間的長期差異使用選取器。 請勿使用選取器,在多個環境中進行階段性推出。如要先在預先發布環境中測試修改內容,然後再部署到正式環境,請使用不同的 Git 分支版本。 如果應用程式團隊需要開發叢集的完整存取權,但只需要實際工作環境叢集的唯讀存取權,請使用 ClusterSelector 物件,只對相關叢集套用正確的 RBAC 政策。
同儕評估 使用同儕審查,確保相關團隊核准變更。 人工審查員無法找出所有錯誤,尤其是語法錯誤等項目。 貴機構規定安全性團隊必須審查影響多個系統的設定變更。請資安團隊成員審查變更。
持續整合管道中的自動化測試 使用自動化測試找出建議變更中的錯誤。 自動化測試無法完全取代人工審查員。同時使用。 對所有建議變更執行 nomos vet 指令,確認存放區是有效的 Config Sync 設定。
監控同步處理錯誤 請確認 Config Sync 確實將變更套用至叢集。 只有在 Config Sync 嘗試套用無效的存放區,或 Kubernetes API 伺服器拒絕部分物件時,才會發生同步錯誤。 使用者略過所有測試和審查,將無效的變更提交至 Config Sync 存放區。這項變更無法套用至叢集。如果監控同步處理錯誤,系統會在發生錯誤時發出警示。

推出策略範例

本節會運用本文其餘部分介紹的概念,協助您為貴機構的所有叢集建立端對端推出策略。這項策略假設您有開發、測試環境和實際運作的獨立機群 (如機群範例 1 - 方法 1 所示)。

在這個情境中,您將設定每個叢集,使用特定 Git 提交與 Git 存放區同步。將變更部署至特定機群的程序分為 4 個步驟:

  1. 您會先更新叢集群組中的單一叢集 (即「金絲雀」),
  2. 您可透過執行測試及監控推出作業,驗證一切是否如預期運作。
  3. 更新機群中的其餘叢集。
  4. 再次驗證一切是否正常運作。

如要將變更部署至所有叢集,請針對每個車隊重複執行這個程序。從技術上來說,您可以將此方法套用至任何分支的任何 Git 提交。不過,建議您採用下列程序,在審查程序初期就找出問題:

  1. 當有人在 Config Sync Git 存放區中開啟變更要求時,請將該變更部署至其中一個開發叢集。
  2. 如果變更要求獲得接受並合併至主要分支,請如先前所述,在所有車隊中執行完整部署作業。

雖然部分變更可能只適用於特定車隊,但我們建議您最終將所有變更部署至所有車隊。這項策略可解決追蹤問題,也就是追蹤哪個車隊應與哪個提交內容同步。請特別留意僅以正式版機群為目標的變更,因為先前的機群無法進行適當測試。舉例來說,這表示從部署至 Canary 叢集到部署至其餘叢集之間,您需要等待更長的時間,才能發現問題。

總而言之,完整的端對端部署作業如下所示:

  1. 有人開啟變更要求。
  2. 系統會執行自動化測試和驗證,並進行人工審查。
  3. 您會手動觸發工作,將變更部署至開發機群中的 Canary 叢集。這個叢集會執行自動化端對端測試。
  4. 如果一切正常,請在主要分支版本上合併變更要求。
  5. 合併會觸發自動化工作,將新的主要分支提示提交內容部署至開發車隊中的初期測試叢集。在這個叢集中執行自動化端對端測試,偵測大約在同一時間建立及合併的兩個變更要求之間,是否有潛在的不相容問題。
  6. 下列工作會依序執行 (您可以手動觸發,或在預先定義的時間後觸發,以便使用者回報迴歸問題):
    1. 部署至開發機群的所有叢集。
    2. 在開發機群的叢集中執行測試和驗證。
    3. 部署至預先發布機群的 Canary 叢集。
    4. 在預備機群的 Canary 叢集中執行測試和驗證。
    5. 部署至預先發布機群的所有叢集。
    6. 在預備機群的叢集中執行測試和驗證。
    7. 部署至實際工作環境機群的 Canary 叢集。
    8. 在正式版機群的 Canary 叢集中執行測試和驗證。
    9. 部署至實際工作環境機群的所有叢集。
    10. 在正式版機群的叢集中執行測試和驗證。

全面推出程序。

後續步驟