GKE - 来自Google Container Registry的ErrImagePull

问题描述 投票:2回答:3

我有一个Google Kubernetes Engine集群,直到最近才开始从Google Container Registry桶中提取私有容器图像。我没有改变任何东西,但现在当我更新我的Kubernetes Deployments时,它无法启动新的pod,我得到以下事件:

Normal   Pulling  14s                kubelet, <node-id>  pulling image "gcr.io/cloudsql-docker/gce-proxy:latest"
Normal   Pulling  14s                kubelet, <node-id>  pulling image "gcr.io/<project-id>/backend:62d634e"
Warning  Failed   14s                kubelet, <node-id>  Failed to pull image "gcr.io/<project-id>/backend:62d634e": rpc error: code = Unknown desc = unauthorized: authentication required
Warning  Failed   14s                kubelet, <node-id>  Error: ErrImagePull
Normal   Pulled   13s                kubelet, <node-id>  Successfully pulled image "gcr.io/cloudsql-docker/gce-proxy:latest"
Normal   Created  13s                kubelet, <node-id>  Created container
Normal   Started  13s                kubelet, <node-id>  Started container
Normal   BackOff  11s (x2 over 12s)  kubelet, <node-id>  Back-off pulling image "gcr.io/<project-id>/backend:62d634e"
Warning  Failed   11s (x2 over 12s)  kubelet, <node-id>  Error: ImagePullBackOff

我检查过以下的事情,这些事情似乎都是应该的:

  • 容器及其标签实际上是存在的,并且是正确的。
  • GKE集群的节点池/ VM实例具有storage-ro权限
  • Google Container Registry存储桶和GKE集群位于同一个项目中

我也尝试过禁用和重新启用container.googleapis.com和containerregistry.googleapis.com服务,但这没有帮助。

Container Registry的Google文档说明:

Kubernetes Engine集群自动配置为可以从同一项目中的Container Registry中提取私有映像。如果注册表和群集位于同一个Cloud项目中,则无需执行其他步骤来配置身份验证。

但事实似乎并非如此。

任何人都可以了解可能发生的事情吗?或者尝试其他步骤?

google-kubernetes-engine google-container-registry
3个回答
5
投票

在我的例子中,问题是由最小规范文件生成的节点池缺少可以访问注册表的oauth2范围。添加

nodePools:
  config:
    oauthScopes:
    - https://www.googleapis.com/auth/devstorage.read_only
    - https://www.googleapis.com/auth/servicecontrol
    - https://www.googleapis.com/auth/service.management.readonly
    - https://www.googleapis.com/auth/trace.append

我的规格固定的东西。我认为这是重要的devstorage范围,但我不确定,因为我只是从Web控制台生成的规范中复制粘贴整个范围列表。


3
投票

好吧,这结果很棘手,但原因是:

我使用Terraform为GKE集群中的节点设置服务帐户,但是我没有使用email资源的google_service_account输出来指定服务帐户,而是使用了unique_id输出。 Terraform和Google Cloud API都接受了这一点。

当Kubernetes(和其他东西)试图访问每个节点上的内部元数据API以获得它可以使用的令牌时,它正在接收Service account is invalid/disabled的响应和403状态。

使用正确指定的服务帐户重新创建节点池可解决此问题。


0
投票

当我创建一个带有terraform的集群时,我遇到了同样的问题。首先,我只在service_account中指定了node_config,因此节点池的OAuth范围太小。明确地写下service_accountoauth_scope,如下所示,节点能够从私人GCR存储库中提取图像。

resource "google_container_node_pool" "primary_preemptible_nodes" {
  node_config {
    service_account = "${google_service_account.gke_nodes.email}"

    oauth_scopes = [
      "storage-ro",
      "logging-write",
      "monitoring"
    ]
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.