排解 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 叢集版本中,如果存在多個 AllowlistSynchronizerWorkloadAllowlists 可能無法安裝。

如要解決這個問題,請只使用包含多個 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_VAR1ENV_VAR2 的環境變數,但允許清單未指定這些環境變數。
    • 容器指定映像檔 k8s.gcr.io/diff/image,但允許清單指定 k8s.gcr.io/pause2
    • 容器新增了 SYS_ADMINSYS_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.1k8s.gcr.io/pause@sha256:1234567890

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

逸出指令和引數中的字元

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

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

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

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

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

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

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

  1. 請按照「部署具備特殊權限的工作負載時發生問題」一節中的步驟,將 cloud.google.com/matching-allowlist 標籤新增至工作負載。
  2. 從工作負載的 YAML 資訊清單複製 spec.template
  3. 建立新的 Pod 資訊清單,然後將複製的規格貼到 spec 欄位。
  4. 在 Pod 資訊清單中設定 apiVersionkindmetadata.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. 檢查上一步的輸出內容。如果在「工作負載不符」部分看到非預期的欄位,例如額外的環境變數 (例如 DD_AGENT_HOST)、容器或磁碟區,強烈表示有其他 Webhook 正在修改 Pod。

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

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

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

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

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

後續步驟