【问题标题】:Error pulling docker image from GCR into GKE "Failed to pull image .... 403 Forbidden"将 docker 映像从 GCR 拉入 GKE 时出错“无法拉取映像 .... 403 Forbidden”
【发布时间】:2021-09-30 10:55:42
【问题描述】:

​​背景:

我有一个 GKE 集群,它突然无法从 GCR 拉取我的 docker 镜像;两者都在同一个 GCP 项目中。几个月来一直运行良好,拉取图像没有问题,现在在没有进行任何更改的情况下开始抛出错误。

(注意:我通常是我团队中唯一一个访问 Google Cloud 的人,尽管我团队中的其他人完全有可能在没有意识到的情况下进行了更改/无意中进行了更改)。

我看过其他一些关于这个主题的帖子,但其他人提供的解决方案没有帮助。其中两个帖子对我来说尤其突出,因为它们都是在大约 13/14 天前我的问题开始的同一天发布的。这到底是不是巧合,谁知道呢。。

This post 和我有同样的问题;不确定发布的 cmets 是否帮助他们解决了问题,但对我来说并没有解决。 This post好像也是同样的问题,不过发帖人说等了一段时间自己解决了。

问题:

几天前我第一次注意到集群上的问题。通过将镜像推送到 GCR 然后弹跳 pod kubectl rollout restart deployment 来部署新镜像。

然后所有的 pod 都返回 ImagePullBackOff,说他们无法从 GCR 获取图像:

kubectl get pods:

XXX-XXX-XXX     0/1     ImagePullBackOff   0          13d
XXX-XXX-XXX     0/1     ImagePullBackOff   0          13d
XXX-XXX-XXX     0/1     ImagePullBackOff   0          13d
...

kubectl describe pod XXX-XXX-XXX:

Normal   BackOff           20s                kubelet                                Back-off pulling image "gcr.io/<GCP_PROJECT>/XXX:dev-latest"
Warning  Failed            20s                kubelet                                Error: ImagePullBackOff
Normal   Pulling           8s (x2 over 21s)   kubelet                                Pulling image "gcr.io/<GCP_PROJECT>/XXX:dev-latest"
Warning  Failed            7s (x2 over 20s)   kubelet                                Failed to pull image "gcr.io/<GCP_PROJECT>/XXX:dev-latest": rpc error: code = Unknown desc = failed to pull and unpack image "gcr.io/<GCP_PROJECT>/XXX:dev-latest": failed to resolve reference "gcr.io/<GCR_PROJECT>/XXX:dev-latest": unexpected status code [manifests dev-latest]: 403 Forbidden
Warning  Failed            7s (x2 over 20s)   kubelet                                Error: ErrImagePull

我知道图片肯定存在于GCR中-

  • 我可以将镜像拉到我自己的机器上(还从我的机器上删除了所有 docker 镜像以确认它确实在拉取)
  • 如果我在 chrome 上查看 GCR UI,我可以看到标记的图像。

我已经通过 SSH 连接到一个集群节点并尝试手动 docker pull,但没有成功:

docker pull gcr.io/<GCP_PROJECT>/XXX:dev-latest
Error response from daemon: unauthorized: You don't have the needed permissions to perform this operation, and you may have invalid credentials. To authenticate your request, follow the steps in: https://cloud.google.com/container-registry/docs/advanced-authentication

(还对公共 mongodb 映像进行了 docker pull 以确认 正在工作,并且它特定于 GCR)。

所以这让我相信这是服务帐户没有正确权限的问题,如“错误 400/403”部分下的in the cloud docs。这似乎表明服务帐户已被删除或手动编辑。

在我的故障排除过程中,我试图准确地找出 GKE 使用哪个服务帐户从 GCR 中提取。在文档中概述的步骤中,它说:The name of your Google Kubernetes Engine service account is as follows, where PROJECT_NUMBER is your project number:

service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com

我找到了服务帐户并检查了政策 - 它确实有一个 roles/container.serviceAgent,但没有像我从文档中的描述中所期望的那样特别提到 kubernetes。'Kubernetes Engine 服务代理角色'(除非那是他们正在描述的那个,在这种情况下,无论如何我都不会更好......)。

一定没有正确的角色,所以我按照步骤重新启用(禁用然后启用 Kubernetes API)。再次运行cloud projects get-iam-policy &lt;GCP_PROJECT&gt; 并比较两个输出(之前/之后),唯一的区别是“@cloud-filer...”的服务帐户已被删除。

认为错误可能是其他原因,我想我会尝试启动一个新集群。同样的错误 - 无法提取图像。

发送帮助..

我一直在绞尽脑汁试图排除故障,但现在我没有想法!非常感谢任何和所有帮助!

【问题讨论】:

  • 计算引擎默认服务账号用于拉取镜像。该帐户是否具有roles/storage.objectViewer 权限?
  • Compute Engine Service Agent 有Storage Object Admin,Kubernetes Engine Service Agent 有Storage Object Viewer。我可以看到这两个分别有roles/storage.objectAdminroles/storage.objectViewer
  • 转到节点池并检查安全部分中的服务帐户是什么。授予该服务帐户的存储权限。还要检查应该有错误的服务帐户的访问日志

标签: docker kubernetes google-cloud-platform google-kubernetes-engine google-container-registry


【解决方案1】:

现在已经解决了。

服务帐户具有正确的角色/权限,但由于某种原因停止工作。

我为该服务帐户手动创建了一个密钥,将该密钥添加到 kube 集群中,并将服务帐户设置为使用该密钥。

仍然不知道为什么它还没有这样做,或者为什么它突然停止工作,但它正在工作......

修复来自 this guide,来自“创建和使用 GCR 凭据”部分。

【讨论】:

    【解决方案2】:

    docs计算引擎默认服务账号访问容器注册中心拉取镜像而不是Kubernetes引擎服务账号。你可以去节点池查看安全部分的服务账号名称。查看服务的访问日志帐户以查看错误,然后向服务帐户提供必要的权限。

    【讨论】:

    • 服务帐户显示为具有所有正确的权限,所以我不确定为什么这不起作用。进入该服务帐户的日志,没有任何显示。 (不仅仅是“与错误无关”,而且实际上日志中没有任何内容......奇怪。我现在通过从该服务帐户手动创建一个令牌并将其强制在集群上解决了这个问题。
    • 你的集群升级了吗?
    【解决方案3】:

    我相信正确的解决方案是将“roles/artifactregistry.reader”角色添加到节点池配置使用的服务帐户中。 在 terraform 中可以通过

    resource "google_project_iam_member" "allow_image_pull" {
      project = var.project_id
      role   = "roles/artifactregistry.reader"
      member = "serviceAccount:${var.service_account_email}"
    }
    

    【讨论】:

      猜你喜欢
      • 2023-04-06
      • 1970-01-01
      • 2017-09-22
      • 2021-08-26
      • 2019-10-21
      • 2023-03-17
      • 2021-02-03
      • 2023-03-07
      • 1970-01-01
      相关资源
      最近更新 更多