IBM Cloud Docs
為何映像檔無法從登錄取回時發生 ImagePullBackOff 或授權錯誤?

為何映像檔無法從登錄取回時發生 ImagePullBackOff 或授權錯誤?

Virtual Private Cloud 標準基礎架構

當您部署工作負載從 IBM Cloud Container Registry 取回映像檔時,您的 Pod 會失敗並處於 ImagePullBackOff 狀態。

kubectl get pods
NAME         READY     STATUS             RESTARTS   AGE
<pod_name>   0/1       ImagePullBackOff   0          2m

當您說明 Pod 時,您會看到類似下列的鑑別錯誤。

kubectl describe pod <pod_name>
Failed to pull image "<region>.icr.io/<namespace>/<image>:<tag>" ... unauthorized: authentication required
Failed to pull image "<region>.icr.io/<namespace>/<image>:<tag>" ... 401 Unauthorized
Failed to pull image "registry.ng.bluemix.net/<namespace>/<image>:<tag>" ... unauthorized: authentication required
Failed to pull image "registry.ng.bluemix.net/<namespace>/<image>:<tag>" ... 401 Unauthorized
...
Failed to pull image "<image>:<tag>" ... Manifest for <image>:<tag> not found

您的叢集使用儲存在 映像檔取回密碼 中的 API 金鑰,以授權叢集從 IBM Cloud Container Registry取回映像檔,或者具有特定標籤的映像檔不存在於儲存庫中。

依預設,新叢集具有使用 API 金鑰的映像檔取回密碼,以讓叢集可從已部署至 icr.io Kubernetes 名稱空間之容器的任何地區 default 登錄中取回映像檔。

  1. 驗證您在部署 YAML 檔案中使用映像檔的正確名稱和標籤。

    ibmcloud cr images
    
  2. 檢查取回資料流量及儲存空間配額。 如果達到限制,請釋放使用的儲存空間,或要求登錄管理者增加配額。

    ibmcloud cr quota
    
  3. 取得失敗 Pod 的 Pod 配置檔,並尋找 imagePullSecrets 區段。

    kubectl get pod <pod_name> -o yaml
    

    輸出範例

    ...
    imagePullSecrets:
    - name: all-icr-io
    ...
    
  4. 如果未列出任何映像檔取回密碼,請在名稱空間中設定映像檔取回密碼。

    1. 驗證 default 名稱空間是否具有用於要使用的每個地區登錄的 icr-io 映像檔取回密碼。 如果名稱空間中未列出任何 icr-io 密碼,請 使用 ibmcloud ks cluster pull-secret apply --cluster <cluster_name_or_ID> 指令,在 default 名稱空間中建立映像檔取回密碼。
      kubectl get secrets -n default | grep "icr-io"
      
    2. all-icr-io 映像檔取回密碼從 default Kubernetes 名稱空間複製到您要在其中部署工作量的名稱空間
    3. 將映像檔取回密碼新增至此 Kubernetes 名稱空間的服務帳戶,以便該名稱空間中的所有 Pod 都能使用映像檔取回密碼認證。
  5. 如果 Pod 中列出映像檔取回密碼,請確定用於存取 IBM Cloud Container Registry 的認證類型。

對使用 API 金鑰的映像檔取回密碼進行疑難排解

如果您的 Pod 配置具有使用 API 金鑰的映像檔取回密碼,請檢查是否正確設定 API 金鑰認證。

下列步驟假設 API 金鑰會儲存服務 ID 的認證。 如果您將映像檔取回密碼設為使用個別使用者的 API 金鑰,則必須驗證使用者的 IBM Cloud IAM 許可權及認證。

  1. 檢閱說明,以尋找 API 金鑰針對映像檔取回密碼所使用的服務 ID。 使用叢集建立的服務 ID 名為 cluster-<cluster_ID>,並在 default Kubernetes 名稱空間中使用。 如果您建立另一個服務 ID 來存取不同的 Kubernetes 名稱空間,或修改 IBM Cloud IAM 許可權,則要自訂說明。

    ibmcloud iam service-ids
    

    輸出範例

    UUID                Name               Created At              Last Updated            Description                                                                                                                                                                                         Locked
    ServiceId-aa11...   <service_ID_name>  2019-02-01T19:01+0000   2019-02-01T19:01+0000   ID for <cluster_name>                                                                                                                                         false
    ServiceId-bb22...   <service_ID_name>  2019-02-01T19:01+0000   2019-02-01T19:01+0000   Service ID for IBM Cloud Container Registry in Kubernetes cluster <cluster_name> namespace <namespace>                                                                                                                                         false
    
  2. 驗證至少已指派 IBM Cloud IAM 讀者 IBM Cloud Container Registry 的服務存取角色原則。 如果服務 ID 沒有 讀者 服務存取角色,請 編輯 IAM 原則。 如果原則正確,請繼續下一步,以查看認證是否有效。

    ibmcloud iam service-policies <service_ID_name>
    

    輸出範例

    Policy ID:   a111a111-b22b-333c-d4dd-e555555555e5
    Roles:       Reader
    Resources:
                  Service Name       container-registry
                  Service Instance
                  Region
                  Resource Type      namespace
                  Resource           <registry_namespace>
    
  3. 檢查映像檔取回密碼認證是否有效。

    1. 取得映像檔取回密碼配置。 如果 Pod 不在 default 名稱空間中,請包括 -n 選項。

      kubectl get secret <image_pull_secret_name> -o yaml [-n <namespace>]
      
    2. 在輸出中,複製 .dockerconfigjson 欄位的 base64 編碼值。

      apiVersion: v1
      kind: Secret
      data:
        .dockerconfigjson: eyJyZWdp...==
      ...
      
    3. 解碼 base64 字串。 例如,在 OS X 上,您可以執行下列指令。

      echo -n "<base64_string>" | base64 --decode
      

      輸出範例

      {"auths":{"<region>.icr.io":{"username":"iamapikey","password":"<password_string>","email":"<name@abc.com>","auth":"<auth_string>"}}}
      
    4. 比較映像檔取回密碼地區登錄網域名稱與您在容器映像檔中指定的網域名稱。 依預設,對於在 default Kubernetes 名稱空間中執行的容器,新叢集具有其中每個地區登錄網域名稱的映像檔取回密碼。 不過,如果您修改了預設值,或使用不同的 Kubernetes 名稱空間,則可能沒有地區登錄的映像檔取回密碼。 針對地區登錄網域名稱,複製映像檔取回密碼

    5. 從您的本端機器,使用映像檔取回密碼中的 usernamepassword 來登入登錄。 如果您無法登入,則可能需要修正服務 ID。

      docker login -u iamapikey -p <password_string> <region>.icr.io
      
      1. 針對在 default Kubernetes 名稱空間中執行的容器,重建其叢集服務 ID、IBM Cloud IAM 原則、API 金鑰及映像檔取回密碼。
        ibmcloud ks cluster pull-secret apply --cluster <cluster_name_or_ID>
        
      2. default Kubernetes 名稱空間中,重建部署。 如果您仍看到授權錯誤訊息,請使用新的映像檔取回密碼,重複步驟 1-5。 如果仍然無法登入,請 開啟 IBM Cloud 支援案例
    6. 如果登入成功,請在本端取回映像檔。 如果指令失敗且發生 access denied 錯誤,則登錄帳戶所在的 IBM Cloud 帳戶不同於叢集所在的帳戶。 建立映像檔取回密碼以在其他帳戶中存取映像檔。 如果您可以將映像檔取回至本端機器,則您的 API 金鑰具有正確的許可權,但叢集裡的 API 設定不正確。

      docker pull <region>icr.io/<namespace>/<image>:<tag>
      
    7. 請檢查是否直接從部署或從部署使用的服務帳戶參照取回密碼。 如果您仍然無法解決問題,請 聯絡支援中心