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

虛擬私有雲 經典基礎架構

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

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

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

oc 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 "<image>:<tag>" ... Manifest for <image>:<tag> not found

您的群集使用儲存於 影像拉取秘訣 中的 API 金鑰,授權群集從 IBM Cloud Container Registry 拉取影像,或具有特定標籤的影像不存在於儲存庫中。

預設情況下,新建立的叢集會使用 API 金鑰作為映像檔拉取密鑰,以便叢集能從任何區域性的 icr.io 註冊表中拉取映像檔,供部署至 default Red Hat OpenShift 專案的容器使用。

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

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

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

    oc get pod <pod_name> -o yaml
    

    輸出範例

    ...
    imagePullSecrets:
    - name: all-icr-io
    ...
    
  4. 如果未列出任何映像拉取密鑰,請在您的專案中設定映像拉取密鑰。

    1. 請確認「default」專案是否已為您欲使用的每個區域性註冊表,設定了 icr-io 映像檔的拉取密鑰。 如果專案中未列出任何 icr-io 機密, 請使用 ibmcloud oc cluster pull-secret apply --cluster <cluster_name_or_ID> 指令在 default 專案中建立映像拉取機密。
      oc get secrets -n default | grep "icr-io"
      
    2. 將 all-icr-io 映像檔取回密碼從 default Red Hat OpenShift 專案複製到您要在其中部署工作量的專案。
    3. 將映像拉取密鑰新增至此 Red Hat OpenShift 專案的服務帳戶,以便專案中的所有 Pod 都能使用該映像拉取密鑰的憑證。
  5. 如果 Pod 中列出映像檔取回密碼,請確定用於存取 IBM Cloud Container Registry 的認證類型。

使用 API 金鑰的圖片拉取密鑰疑難排解

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

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

  1. 檢閱說明,以尋找 API 金鑰針對映像檔取回密碼所使用的服務 ID。 隨叢集建立的服務識別碼名為 cluster-<cluster_ID>,並用於 default Red Hat OpenShift 專案中。 如果您建立另一個服務識別碼(例如用於存取不同的 Red Hat OpenShift 專案,或用於修改 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 <project>                                                                                                                                         false
    
  2. 請確認該服務 ID 至少已被指派一個「IBM Cloud」IAM 角色 讀者 服務存取角色政策適用於 IBM Cloud Container Registry。 如果服務 ID 沒有「Reader」服務存取角色,請編輯 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」選項。

      oc get secret <image_pull_secret_name> -o yaml [-n <project>]
      
    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 Red Hat OpenShift 專案中運行的容器,為每個區域性註冊表網域名稱設定映像檔拉取祕密。 不過,如果您修改了預設設定,或是正在使用不同的 Red Hat OpenShift 專案,您可能沒有針對區域註冊表的映像拉取密鑰。 針對地區登錄網域名稱,複製映像檔取回密碼。

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

      docker login -u iamapikey -p <password_string> <region>.icr.io
      
      1. 請重新建立在 default Red Hat OpenShift 專案中運行的容器的叢集服務 ID、IBM Cloud IAM 政策、API 金鑰以及映像檔拉取密鑰。
        ibmcloud oc cluster pull-secret apply --cluster <cluster_name_or_ID>
        
      2. 請在 default Red Hat OpenShift 專案中重新建立您的部署。 如果您仍看到授權錯誤訊息,請使用新的映像檔取回密碼,重複步驟 1-5。 如果仍然無法登入,請 開啟 IBM Cloud 支援案例。
    6. 如果登入成功,請在本端取回映像檔。 如果指令失敗且發生 access denied 錯誤,則登錄帳戶所在的 IBM Cloud 帳戶不同於叢集所在的帳戶。 建立映像檔取回密碼以在其他帳戶中存取映像檔。 如果您能將圖片下載到本地電腦,則表示您的 API 金鑰擁有正確的權限,但您在叢集中的 API 設定有誤。

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