排解具特殊權限的 Autopilot 工作負載和許可清單問題

Google Kubernetes Engine (GKE) Autopilot 叢集中的具備特殊權限工作負載必須正確設定,才能避免問題。設定錯誤可能導致與許可清單同步失敗,或工作負載遭拒。這些問題可能會導致重要代理程式或服務無法以必要權限執行。

請參閱本文,排解在 Autopilot 上部署具備權限的工作負載時發生的問題。瞭解如何解決許可清單同步處理錯誤,以及診斷特殊權限工作負載遭拒的原因。

對於在 Autopilot 叢集上部署具有提升權限工作負載的平台管理員、營運人員和安全團隊而言,這項資訊非常重要。如要進一步瞭解 Google Cloud 內容中提及的常見角色和工作範例,請參閱「常見的 GKE 使用者角色和工作」。

許可清單同步問題

部署 AllowlistSynchronizer 時,GKE 會嘗試安裝並同步處理您指定的許可清單檔案。如果同步處理失敗,AllowlistSynchronizer 的 status 欄位會回報錯誤。

取得 AllowlistSynchronizer 物件的狀態:

kubectl get allowlistsynchronizer ALLOWLIST_SYNCHRONIZER_NAME -o yaml

將 ALLOWLIST_SYNCHRONIZER_NAME 替換為 AllowlistSynchronizer 的名稱。

輸出結果會與下列內容相似:

...
status:
  conditions:
  - type: Ready
    status: "False"
    reason: "SyncError"
    message: "some allowlists failed to sync: example-allowlist-1.yaml"
    lastTransitionTime: "2024-10-12T10:00:00Z"
    observedGeneration: 2
  managedAllowlistStatus:
    - filePath: "gs://path/to/allowlist1.yaml"
      generation: 1
      phase: Installed
      lastSuccessfulSync: "2024-10-10T10:00:00Z"
    - filePath: "gs://path/to/allowlist2.yaml"
      phase: Failed
      lastError: "Initial install failed: invalid contents"
      lastSuccessfulSync: "2024-10-08T10:00:00Z"

conditions.message 欄位和 managedAllowlistStatus.lastError 欄位提供錯誤的詳細資訊。請參考這些資訊解決問題。

多個 AllowlistSynchronizer

在 1.33.4-gke.1035000 之前的 GKE 叢集版本中,如果存在多個 AllowlistSynchronizer,WorkloadAllowlists 可能無法安裝。

如要解決這個問題,請只使用一個包含多個 allowlistPaths 的 AllowlistSynchronizer。

或者,您也可以將叢集升級至較新版本。

工作負載容器排序

在 1.34.0-gke.0000000 之前的 GKE 叢集版本中,如果一或多個工作負載容器映像檔與叢集內 WorkloadAllowlist 中指定的容器映像檔相符,則工作負載容器可能會以反向字母順序建立及排序。

如要解決這個問題,請嘗試下列方法:

  • 將叢集升級至 1.34.0-gke.0000000 以上版本。
  • 重新命名工作負載的容器,確保容器以正確順序排序。

部署具備特殊權限的工作負載時發生問題

成功安裝許可清單後,請在叢集中部署對應的具備權限工作負載。在某些情況下,GKE 可能會拒絕工作負載。

請嘗試下列解決方案:

  • 請確保叢集的 GKE 版本符合工作負載的版本需求。
  • 確認您部署的工作負載適用於許可清單檔案。

如要瞭解特權工作負載遭拒的原因,請向 GKE 要求提供有關許可清單違規事項的詳細資訊:

  1. 取得叢集中已安裝的允許清單清單:

    kubectl get workloadallowlist
    

    找出應套用至特殊權限工作負載的許可清單名稱。

  2. 在文字編輯器中開啟特殊權限工作負載的 YAML 資訊清單。如果無法存取 YAML 資訊清單 (例如工作負載部署程序使用其他工具),請與工作負載供應商聯絡,提出問題。略過其餘步驟。

  3. 在特殊權限工作負載 Pod 規格的 spec.metadata.labels 部分,新增下列標籤:

    labels:
      cloud.google.com/matching-allowlist: ALLOWLIST_NAME
    

    將 ALLOWLIST_NAME 替換為您在上一個步驟中取得的允許清單名稱。請使用 kubectl get workloadallowlist 指令輸出內容中的名稱,而非許可清單檔案的路徑。

  4. 儲存資訊清單,並將工作負載套用至叢集:

    kubectl apply -f WORKLOAD_MANIFEST_FILE
    

    將 WORKLOAD_MANIFEST_FILE 替換為資訊清單檔案的路徑。

    輸出內容會提供詳細資訊,說明工作負載中的哪些欄位與指定的允許清單不符,如下列範例所示:

    Error from server (GKE Warden constraints violations): error when creating "STDIN": admission webhook "warden-validating.common-webhooks.networking.gke.io" denied the request:
    
    ===========================================================================
    Workload Mismatches Found for Allowlist (example-allowlist-1):
    ===========================================================================
    HostNetwork Mismatch: Workload=true, Allowlist=false
    HostPID Mismatch: Workload=true, Allowlist=false
    Volume[0]: data
             - data not found in allowlist. Verify volume with matching name exists in allowlist.
    Container[0]:
    - Envs Mismatch:
            - env[0]: 'ENV_VAR1' has no matching string or regex pattern in allowlist.
            - env[1]: 'ENV_VAR2' has no matching string or regex pattern in allowlist.
    - Image Mismatch: Workload=k8s.gcr.io/diff/image, Allowlist=k8s.gcr.io/pause2. Verify that image string or regex match.
    - SecurityContext:
            - Capabilities.Add Mismatch: the following added capabilities are not permitted by the allowlist: [SYS_ADMIN SYS_PTRACE]
    - VolumeMount[0]: data
            - data not found in allowlist. Verify volumeMount with matching name exists in allowlist.
    

    在這個範例中,發生了下列違規情形:

    • 工作負載指定 hostNetwork: true,但許可清單未指定 hostNetwork: true。
    • 工作負載指定 hostPID: true,但允許清單未指定 hostPID: true。
    • 工作負載指定了名為 data 的磁碟區,但許可清單未指定名為 data 的磁碟區。
    • 容器指定名為 ENV_VAR1 和 ENV_VAR2 的環境變數,但許可清單未指定這些環境變數。
    • 容器指定映像檔 k8s.gcr.io/diff/image,但允許清單指定 k8s.gcr.io/pause2。
    • 容器新增了 SYS_ADMIN 和 SYS_PTRACE 功能,但許可清單不允許新增這些功能。
    • 容器指定名為 data 的磁碟區掛接點,但允許清單未指定名為 data 的磁碟區掛接點。

如果您部署的第三方供應商擁有工作負載,請向該供應商回報問題,以解決違規事項。在問題中提供上一個步驟的輸出內容。

GKE 版本不相容

如果許可清單指定的最低 GKE 版本高於叢集 GKE 版本,GKE 可能會拒絕工作負載。

  1. 檢查許可清單是否指定 GKE 最低版本:

    kubectl describe workloadallowlist ALLOWLIST_NAME | grep "minGKEVersion"
    

    將 ALLOWLIST_NAME 替換為許可清單名稱。

    如果輸出內容空白,表示許可清單未指定最低 GKE 版本。略過這個部分。如果輸出內容是值,許可清單會指定最低 GKE 版本。

  2. 檢查叢集的 GKE 版本:

    gcloud container clusters describe CLUSTER_NAME \
        --location=CLUSTER_LOCATION \
        --format="value(currentMasterVersion)"
    

    更改下列內容:

    • CLUSTER_NAME:叢集名稱。
    • CLUSTER_LOCATION:叢集的 Google Cloud 位置。

    輸出結果會與下列內容相似:

    1.32.3-gke.1006000
    
  3. 如果叢集的 GKE 版本低於許可清單的最低 GKE 版本,請將叢集升級至許可清單的最低 GKE 版本或更新版本。詳情請參閱「升級叢集」。

升級完成後,請嘗試將工作負載部署至叢集。

字串不符

WorkloadAllowlist 規格中的特定欄位,必須與工作負載規格中的對應欄位完全相符。

  1. 開啟 WorkloadAllowlist CustomResourceDefinition (CRD) 參考資料頁面。
  2. 針對 WorkloadAllowlist 規格中的每個欄位,檢查 CRD 是否需要完全相符的字串。
  3. 針對每個需要完全符合字串的欄位,請檢查 WorkloadAllowlist 規格中的值是否與工作負載規格中的對應值相符。

    舉例來說,容器執行的每個指令都必須與許可清單中的指令完全相符。只要與確切指令有任何偏差,就會遭到拒絕。

如果不相符,請更新 WorkloadAllowlist 規格,使其與工作負載規格相符。

規則運算式不相符

WorkloadAllowlist 規格中的特定欄位支援規則運算式比對。

  1. 在 WorkloadAllowlist 規格中,找出指定規則運算式的欄位。
  2. 請確認規則運算式語法正確無誤。WorkloadAllowlist CRD 支援 Google RE2 規則運算式語法。 確認運算式具有下列屬性:

    • 規則運算式以 ^ 字元開頭,並以 $ 字元結尾。例如:^example-auth\.google\.com\/go_[a-z0-9]+\/google\/path$。
    • 每個特殊字元都會以 \ 逸出字元逸出。檢查是否有額外或缺少的 \ 字元。
    • 許可清單中的映像檔路徑不含標記或摘要。舉例來說,請使用 k8s.gcr.io/pause,而不是 k8s.gcr.io/pause:3.1 或 k8s.gcr.io/pause@sha256:1234567890。

修正所有規則運算式問題後,請嘗試將工作負載部署至叢集。

指令和引數中的逸出字元

如果未逸出特殊字元,GKE 就無法比對指令和引數。逸出字元的要求取決於您套用許可清單的方式。舉例來說,以 YAML 或 JSON 檔案套用許可清單,與使用指令列工具建立許可清單規格時,有不同的逸出字元需求。本節說明 YAML 檔案的逸出字元需求。

即使不使用規則運算式,也請逸出 WorkloadAllowlist 規格 commands 和 args 欄位中的每個特殊字元。如要逸出特殊字元,請使用 \ 字元,例如:

  • 指令:kubectl describe \$\{POD_NAME\}
  • 引數:hostname \$NODE_NAME; dcgm-exporter --remote-hostengine-info \$\(NODE_IP\) --collectors /etc/dcgm-exporter/counters.csv

Webhook 干擾許可清單中的工作負載

在某些情況下,即使工作負載已正確設定為符合允許清單,GKE 仍可能會拒絕該工作負載。如果叢集中的其他許可控制器 (Webhook) 在許可清單允許後,修改工作負載控制器建立的 Pod,就可能發生這種情況。這些修改可能會導致 Pod 規格不再符合許可清單,進而遭 GKE Warden 許可 Webhook 拒絕。

如果第三方監控和安全代理程式將邊車容器或環境變數插入 Pod,就可能發生這個問題。

最常見的徵兆是工作負載控制器 (例如 DaemonSet 或 Deployment) 建立成功,但無法建立任何 Pod。檢查控制器事件時,您會看到訊息,指出 Pod 遭到准入 Webhook 拒絕。

  1. 請按照「部署具備權限的工作負載時發生問題」一節的步驟,將 cloud.google.com/matching-allowlist 標籤新增至工作負載。
  2. 從工作負載的 YAML 資訊清單複製 spec.template。
  3. 建立新的 Pod 資訊清單,然後將複製的規格貼到 spec 欄位。
  4. 在 Pod 資訊清單中設定 apiVersion、kind 和 metadata.name 欄位:

    apiVersion: v1
    kind: Pod
    metadata:
      name: POD_NAME
      labels:
        cloud.google.com/matching-allowlist: ALLOWLIST_NAME
    spec:
      # Paste the content of spec.template here
    

    更改下列內容:

    • POD_NAME:測試 Pod 的名稱。
    • ALLOWLIST_NAME:許可清單的名稱。
  5. 套用 Pod 資訊清單:

    kubectl apply -f YOUR_POD_MANIFEST_FILE
    

    將 YOUR_POD_MANIFEST_FILE 替換為 Pod 資訊清單檔案的路徑。

  6. 檢查上一個步驟的輸出內容。如果「Workload Mismatches」(工作負載不符) 專區中出現非預期的欄位,例如額外的環境變數 (例如 DD_AGENT_HOST)、容器或磁碟區,強烈表示有其他 Webhook 正在修改 Pod。

如要解決這個問題,請設定衝突的 Webhook,將其排除在修改已加入許可清單的工作負載的 Pod 之外。通常的做法是為工作負載或其命名空間新增標籤或註解,向 Webhook 發出訊號,表示應將其排除在變動之外。舉例來說,使用 Datadog 時,您會將 admission.datadoghq.com/enabled: "false" 標籤新增至工作負載的命名空間。

請參閱您使用的特定第三方軟體說明文件,瞭解如何從其准入控制器中排除工作負載。

防止其他 Webhook 修改 Pod,有助於確保 Pod 繼續符合許可清單,並成功部署在 Autopilot 叢集上。

特殊權限工作負載和許可清單的錯誤與功能要求

如果您執行由 GKE 合作夥伴或第三方供應商提供的具備特殊權限工作負載,該供應商有責任建立、開發及維護其具備特殊權限的工作負載和允許清單。如果遇到錯誤,或想為合作夥伴或第三方特許工作負載或許可清單提出功能要求,請與供應商聯絡。

後續步驟