【问题标题】:GKE - ErrImagePull pulling from Google Container RegistryGKE - ErrImagePull 从 Google Container Registry 中提取
【发布时间】:2019-03-05 07:39:06
【问题描述】:

我有一个 Google Kubernetes Engine 集群,直到最近它还在愉快地从 Google Container Registry 存储桶中提取私有容器映像。我没有更改任何内容,但是现在当我更新我的 Kubernetes 部署时,它无法启动新的 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


【解决方案1】:

在我的情况下,问题原来是由最小规范文件生成的节点池缺少可以访问注册表的 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 控制台生成的规范中复制粘贴了整个范围列表。

【讨论】:

  • 我认为它也只是需要https://www.googleapis.com/auth/devstorage.read_only。至少这是我添加到我正在使用的服务帐户的全部内容。
  • “我刚刚从 web 控制台生成的规范中复制粘贴了整个范围列表”你是怎么做到的?
  • 转到“创建集群”向导,然后在屏幕底部查找“等效 REST”按钮。
【解决方案2】:

好的,这很棘手,但原因是这样的:

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

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

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

【讨论】:

  • 对我来说,事实证明我的 terraform 模板 google_bcuket_acl 实际上正在删除服务帐户的 ACL,即使模板中的任何地方都没有引用它。把它放在这里,以防有人落入同一个陷阱。
【解决方案3】:

我在使用 terraform 创建集群时遇到了同样的问题。首先,我只在node_config 中指定了service_account,因此节点池的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"
    ]
  }
}

【讨论】:

  • 感谢@translucens,我们遇到了这个问题,您的回答解决了!
  • 您是如何指定服务帐户的?我有同样的问题,但上面没有解决它。我使用 project_no-compute 服务帐号。
  • @Mike 如果删除了service_account = "${google_service_account.gke_nodes.email}",将使用您的服务帐户(默认计算服务帐户)。
【解决方案4】:

就我而言,设置正确的 oAuth 范围不起作用。所以我只是通过将imagePullSecrets 添加到我的 Pod Spec 来为任何其他私有存储库配置它。

Kubernetes Docs | Pull an Image from a Private Registry

在管道中生成注册表凭据的示例脚本

如果您现在不将基础架构作为代码进行管理,您也可以手动执行此操作。

# Setup registry credentials so we can pull images from gcr
gcloud auth print-access-token | docker login -u oauth2accesstoken --password-stdin https://gcr.io

kubectl create secret generic regcred \
    --namespace=development \
    --from-file=.dockerconfigjson="${HOME}/.docker/config.json" \
    --type=kubernetes.io/dockerconfigjson \
    --output yaml --dry-run | kubectl apply -f - # create or update if already created

示例部署文件

(不要介意所有的替换)。那不相关。只需检查yaml 文件的最后一行。

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: ${NAMESPACE}
  name: ${PROJECT_PREFIX}-${PROJECT_TYPE}-${PROJECT_NAME}
  labels:
    name: ${PROJECT_PREFIX}-${PROJECT_TYPE}-${PROJECT_NAME}
spec:
  replicas: ${REPLICA_COUNT}
  selector:
    matchLabels:
      name: ${PROJECT_PREFIX}-${PROJECT_TYPE}-${PROJECT_NAME}
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
  template:
    metadata:
      labels:
        name: ${PROJECT_PREFIX}-${PROJECT_TYPE}-${PROJECT_NAME}
    spec:
      containers:
        - name: ${PROJECT_PREFIX}-${PROJECT_TYPE}-${PROJECT_NAME}
          image: gcr.io/${GOOGLE_PROJECT_ID}/${PROJECT_TYPE}-${PROJECT_NAME}:${GITHUB_SHA}
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: ${PORT}
              protocol: TCP
          readinessProbe:
            httpGet:
              path: /${PROJECT_NAME}/v1/health
              port: ${PORT}
            initialDelaySeconds: 0
            timeoutSeconds: 10
            periodSeconds: 10
          resources:
            requests:
              cpu: ${RESOURCES_CPU_REQUEST}
              memory: ${RESOURCES_MEMORY_REQUEST}
            limits:
              cpu: ${RESOURCES_CPU_LIMIT}
              memory: ${RESOURCES_MEMORY_LIMIT}
          env:
            - name: NODE_ENV
              value: ${NODE_ENV}
            - name: PORT
              value: '${PORT}'
      imagePullSecrets:
        - name: regcred

【讨论】:

    【解决方案5】:

    检查节点事件中的实际错误。 对我来说,它说:

    Failed to pull image "gcr.io/project/image@sha256:c8e91af54fc17faa1c49d2a05def5cbabf8f0a67fc558eb6cbca138061b8400a":
     rpc error: code = Unknown desc = error pulling image configuration: unknown blob
    

    原来是图像消失或损坏。 再次推送图像后,它工作正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-07
      • 2015-09-04
      • 1970-01-01
      • 2018-12-08
      • 2020-10-10
      • 2017-06-03
      • 1970-01-01
      • 2018-10-31
      相关资源
      最近更新 更多