本页面可帮助您解决 Google Kubernetes Engine (GKE) 中的映像拉取流程问题。如果您使用映像流式传输,请改为参阅排查映像流式传输问题,获取相关建议。本页重点介绍标准映像拉取。
本页面适用于希望确保应用成功部署的应用开发者,以及希望了解映像拉取失败的根本原因并验证平台配置的平台管理员和运维人员。如需详细了解我们在 Trusted Cloud by S3NS 内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和任务。
映像拉取流程是指 Kubernetes(因此也是 GKE)从注册表中检索容器映像的方式。当映像拉取失败时,您可能会注意到应用运行缓慢,或者应用根本无法运行。
如需确定映像拉取是否是导致应用无法正常运行的原因,此页面可帮助您查找并了解相关的错误消息,从而诊断映像拉取失败问题。然后,您将学习如何解决以下常见的映像拉取失败原因:
- 身份验证设置:您的集群缺少访问容器映像注册表所需的权限。
- 网络连接:由于 DNS 问题、防火墙规则或使用网络隔离的集群中缺少互联网访问权限,您的集群无法连接到注册表。
- Image not found in registry:指定的映像名称或标记不正确、映像已被删除,或者注册表不可用。
- 性能限制:映像过大、磁盘 I/O 速度过慢或网络拥塞可能会导致拉取速度过慢或超时。
- 映像架构不兼容:映像是为与 GKE 节点池不同的 CPU 架构构建的。
- 架构版本不兼容:您可能在使用 containerd 2.0 或更高版本,但使用的是不受支持的 v1 Docker 架构。
如果您已看到特定事件消息,请在此页面中搜索该消息,然后按照列出的问题排查步骤操作。如果您还没有看到消息,请按顺序完成以下各部分中的步骤。如果问题仍然存在,请与 Cloud Customer Care 团队联系。
了解映像拉取
在开始问题排查之前,最好先详细了解一下图片的生命周期以及可以在哪些位置托管图片。
映像生命周期
创建 Pod 时,kubelet 会收到 Pod 定义,其中包括映像的规范。kubelet 需要此映像,以便基于该映像运行容器。在拉取映像之前,kubelet 会检查容器运行时,以查看映像是否存在。kubelet 还会检查 Pod 的映像拉取政策。如果映像不在容器运行时的缓存中,或者映像拉取政策要求拉取映像,则 kubelet 会指示容器运行时 (containerd) 从注册表中拉取指定的映像。映像拉取失败会阻止 Pod 中的容器启动。
成功拉取映像后,容器运行时会解压缩该映像,以创建容器的只读基础文件系统。容器运行时会存储此映像,只要运行的容器引用该映像,该映像就会一直存在。如果没有正在运行的容器引用某个映像,该映像便符合垃圾回收的条件,并且 kubelet 最终会将其移除。
图片托管选项
我们建议您使用以下任一选项来托管图片:
Artifact Registry:Artifact Registry 是 Google 的全托管式软件包管理器。Artifact Registry 可与其他 Trusted Cloud by S3NS服务紧密集成,并提供精细的访问权限控制。如需了解详情,请参阅 Artifact Registry 文档中的使用容器映像。
自行托管的注册数据库:自行托管的注册数据库可让您拥有更多控制权,但也需要您管理注册数据库。如果您有 Artifact Registry 无法满足的特定合规性或安全性需求,请考虑此选项。
诊断映像拉取失败问题
如需诊断映像拉取失败问题,请执行以下部分中详述的调查:
- 查看 Pod 状态和事件。
- 了解状态的含义。
- 使用事件消息查找映像拉取失败的原因。
- 查看 Logs Explorer 日志。
查看 Pod 状态和事件
为了帮助您验证映像拉取是否失败,GKE 会记录 Pod 的以下状态:
ImagePullBackOff
ErrImagePull
ImageInspectError
InvalidImageName
RegistryUnavailable
SignatureValidationFailed
ImagePullBackOff
和 ErrImagePull
是最常见的此类状态。
除了这些状态之外,Kubernetes 事件还可以帮助您找到映像拉取失败的原因。
如需确认映像拉取是否失败,请检查状态消息,然后选择以下选项之一来读取事件消息:
控制台
请完成以下步骤:
在 Trusted Cloud 控制台中,前往工作负载页面。
选择要调查的工作负载。如果您不确定需要检查哪个工作负载,请查看状态列。 此列用于指明哪些工作负载遇到了问题。
在工作负载的详细信息页面中,找到代管式 Pod 部分,然后点击状态指示映像拉取失败的 Pod 的名称。
在 Pod 的详细信息页面中,点击事件标签页。
查看表格中的信息。消息列列出了 Kubernetes 事件,其中显示了有关映像拉取失败的更多信息。原因列会列出 Pod 状态。
kubectl
请完成以下步骤:
查看 Pod 的状态:
kubectl get pods -n NAMESPACE
将
NAMESPACE
替换为您的 Pod 运行所在的命名空间。输出类似于以下内容:
NAME READY STATUS RESTARTS AGE POD_NAME_1 2/2 Running 0 7d5h POD_NAME_2 0/1 ErrImagePull 0 7d5h
Status
列指示哪些 Pod 遇到了映像拉取失败问题。查看映像拉取失败的 Pod 的事件:
kubectl describe POD_NAME -n NAMESPACE
将
POD_NAME
替换为您在上一步中确定的 Pod 的名称。Events
部分会显示有关任何失败的映像拉取的更多信息。输出类似于以下内容:
... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning Failed 5m (x4 over 7m) kubelet, NODE Failed to pull image "IMAGE_ADDRESS": rpc error: code = Unknown desc = Error response from daemon: repository IMAGE_ADDRESS not found Warning Failed 5m (x4 over 7m) kubelet, NODE Error: ErrImagePull Normal BackOff 5m (x6 over 7m) kubelet, NODE Back-off pulling image "IMAGE_ADDRESS" Warning Failed 2m (x20 over 7m) kubelet, NODE Error: ImagePullBackOff
在此输出中,
IMAGE_ADDRESS
是映像的完整地址。例如us-west1-docker.pkg.dev/my-project/my-repo/test:staging
。
了解状态含义
如需更好地了解不同状态的含义,请参阅以下说明:
ImagePullBackOff
:kubelet 未能拉取映像,但会继续重试,重试延迟时间(或退避时间)最多为 5 分钟。ErrImagePull
:映像拉取过程中的一般性不可恢复错误。ImageInspectError
:容器运行时在尝试检查容器映像时遇到问题。InvalidImageName
:Pod 定义中指定的容器映像名称无效。RegistryUnavailable
:注册表无法访问。这通常是网络连接问题。SignatureValidationFailed
:无法验证容器映像的数字签名。
使用事件消息查找映像拉取失败的原因
下表列出了与映像拉取失败相关的事件消息,以及在发现其中一条消息时应遵循的问题排查步骤。
与映像拉取失败相关的消息通常具有以下前缀:
Failed to pull image "IMAGE_ADDRESS": rpc error: code = CODE = failed to pull and unpack image "IMAGE_ADDRESS": failed to resolve reference "IMAGE_ADDRESS":
此消息包含以下值:
IMAGE_ADDRESS
:映像的完整地址。例如us-west1-docker.pkg.dev/my-project/my-repo/test:staging
。CODE
:与日志消息关联的错误代码。例如NotFound
或Unknown
。
某些映像拉取失败的原因没有相关的事件消息。如果您没有看到下表中的任何事件消息,但仍然遇到映像拉取问题,我们建议您继续阅读本页的其余内容。
事件消息 | 详细的问题排查 |
---|---|
身份验证 | |
|
|
|
|
网络连接 | |
|
|
|
|
|
|
未找到映像 | |
|
|
映像超时 | |
|
|
架构不兼容 | |
|
查看 Logs Explorer 日志
如需检查历史映像拉取事件或将映像拉取失败与其他组件活动相关联,请使用 Logs Explorer 查看日志:
在 Trusted Cloud 控制台中,前往 Logs Explorer 页面。
在查询窗格中,输入以下查询:
log_id("events") resource.type="k8s_pod" resource.labels.cluster_name="CLUSTER_NAME" jsonPayload.message=~"Failed to pull image"
将
CLUSTER_NAME
替换为出现映像拉取错误的 Pod 运行所在的集群的名称。点击运行查询,然后查看结果。
调查身份验证设置
以下部分可帮助您验证 GKE 环境是否具有适当的身份验证设置,以便从代码库拉取映像。
如需检查是否存在导致映像拉取问题的身份验证问题,请执行以下各部分中详述的调查:
- 验证对映像的访问权限。
- 验证 imagePullSecret 配置和 Deployment 规范。
- 验证节点服务账号的活跃状态。
- 验证节点对专用 Artifact Registry 制品库的访问范围
- 验证 VPC Service Controls 设置,以访问 Artifact Registry。
验证对图片的访问权限
如果您遇到 403 Forbidden
映像拉取错误,请验证所需组件是否可以访问容器映像。
验证并应用必要角色以授予所需访问权限的方法因存储映像的存储库类型而异。如需验证并授予访问权限,请选择以下选项之一:
Artifact Registry
如果您使用 imagePullSecret,则与该 Secret 关联的服务账号需要对相应代码库拥有读取权限。否则,节点池的服务账号需要获得相应权限。
- 按照 IAM 文档中的说明查看分配给服务账号的角色。
如果您的服务账号没有 Artifact Registry Reader (
roles/artifactregistry.reader
) IAM 角色,请授予该角色:gcloud artifacts repositories add-iam-policy-binding REPOSITORY_NAME \ --location=REPOSITORY_LOCATION \ --member=serviceAccount:SERVICE_ACCOUNT_EMAIL \ --role="roles/artifactregistry.reader"
替换以下内容:
REPOSITORY_NAME
:您的 Artifact Registry 代码库的名称。REPOSITORY_LOCATION
:您的 Artifact Registry 代码库的区域。SERVICE_ACCOUNT_EMAIL
:必需的服务账号的电子邮件地址。如果您不知道该地址,请使用gcloud iam service-accounts list
命令列出项目中的所有服务账号电子邮件地址。
Container Registry
如果您使用 imagePullSecret,则与该 Secret 关联的服务账号需要对相应代码库拥有读取权限。否则,节点池的服务账号需要获得相应权限。
- 按照 IAM 文档中的说明查看分配给服务账号的角色。
如果您的服务账号没有 Storage Object Viewer (
roles/storage.objectViewer
) IAM 角色,请授予该角色,以便服务账号可以从存储分区中读取数据:gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \ --member=serviceAccount:SERVICE_ACCOUNT_EMAIL \ --role=roles/storage.objectViewer
替换以下内容:
SERVICE_ACCOUNT_EMAIL
:所需服务账号的电子邮件地址。您可以使用gcloud iam service-accounts list
命令列出项目中的所有服务账号。BUCKET_NAME
:包含您的映像的 Cloud Storage 存储桶的名称。您可以使用gcloud storage ls
命令列出项目中的所有存储分区。
如果您的注册表管理员在 Artifact Registry 中设置 gcr.io
代码库,以存储 gcr.io
网域(而非 Container Registry)的映像,您必须授予对 Artifact Registry(而不是 Container Registry)的读取权限。
自行托管的注册数据库
根据您配置自托管注册表的方式,您可能需要密钥、证书或同时需要两者才能访问映像。
如果您使用密钥,请使用 imagePullSecret。imagePullSecret 是一种安全的方式,可为集群提供访问自托管注册表所需的凭据。如需查看有关如何配置 imagePullSecret 的示例,请参阅 Kubernetes 文档中的从私有注册表中拉取映像。
为了确保与注册表的 HTTPS 连接安全,您可能还需要证书来验证与远程服务器的连接是否完整。我们建议您使用 Secret Manager 来管理自己的自签名证书授权机构。如需了解详情,请参阅使用私有 CA 证书访问私有注册表。
验证 imagePullSecret 配置和 Deployment 规范
如果您使用 imagePullSecret,请确保您已创建用于保存拉取映像的身份验证凭据的 Secret,并且所有 Deployment 都指定了您定义的 Secret。如需了解详情,请参阅 Kubernetes 文档中的在 Pod 上指定 imagePullSecrets。
验证节点服务账号的活跃状态
如果您遇到 401 Unauthorized
映像拉取错误,请验证节点服务账号是否处于活跃状态。即使权限配置正确,如果账号处于停用状态,也会出现此错误。如需验证节点服务账号的有效状态,请选择以下选项之一:
控制台
找到节点使用的服务账号的名称:
在 Trusted Cloud 控制台中,前往集群页面。
在集群列表中,点击您要检查的集群的名称。
查找节点服务账号的名称。
- 对于 Autopilot 模式集群,在安全部分中,找到服务账号字段。
- 对于 Standard 模式集群,执行以下操作:
- 点击节点标签页。
- 在节点池表格中,点击节点池名称。此时会打开节点池详情页面。
- 在安全部分中,找到服务账号字段。
如果服务账号字段中的值为
default
,则表示节点使用 Compute Engine 默认服务账号。如果此字段中的值不是default
,则表示节点使用自定义服务账号。
检查节点服务账号是否已停用:
在 Trusted Cloud 控制台中,打开服务账号页面。
选择一个项目。
查找您在上一步中确定的服务账号名称。
查看相应账号的状态列。如果服务账号已停用,则该账号的状态为
Disabled
。
gcloud
找到节点使用的服务账号的名称:
- 对于 Autopilot 模式集群,请运行以下命令:
gcloud container clusters describe CLUSTER_NAME \ --location=LOCATION \ --flatten=autoscaling.autoprovisioningNodePoolDefaults.serviceAccount
- 对于 Standard 模式集群,请运行以下命令:
gcloud container clusters describe CLUSTER_NAME \ --location=LOCATION \ --format="table(nodePools.name,nodePools.config.serviceAccount)"
如果输出为
default
,则表示节点使用 Compute Engine 默认服务账号。如果输出不是default
,则表示节点使用自定义服务账号。检查节点服务账号是否已停用:
gcloud iam service-accounts list --filter="email:SERVICE_ACCOUNT_NAME AND disabled:true" \ --project=PROJECT_ID
如果该命令返回输出,则表示服务账号已停用。
如果服务账号已停用,请启用节点服务账号。
验证节点对专用 Artifact Registry 制品库的访问范围
如果您将容器映像存储在私有 Artifact Registry 代码库中,您的节点可能没有正确的访问范围。如果发生这种情况,您可能会注意到 401 Unauthorized
映像拉取错误。
如需验证访问权限范围并在需要时授予该权限,请按以下步骤操作:
确定运行 Pod 的节点:
kubectl describe pod POD_NAME | grep "Node:"
将
POD_NAME
替换为发生映像拉取失败的 Pod 的名称。验证您在上一步中确定的节点是否具有正确的存储范围:
gcloud compute instances describe NODE_NAME \ --zone="COMPUTE_ZONE" \ --format="flattened(serviceAccounts[].scopes)"
替换以下内容:
NODE_NAME
:您在上一步中标识的节点的名称。COMPUTE_ZONE
:节点所属的 Compute Engine 可用区。
输出应包含以下至少一个访问权限范围:
serviceAccounts[0].scopes[0]: https://www.googleapis.com/auth/devstorage.read_only
serviceAccounts[0].scopes[0]: https://www.googleapis.com/auth/cloud-platform
如果节点不包含以上范围之一,则映像拉取会失败。
使用足够的范围重新创建节点所属的节点池。 由于您无法修改现有节点,因此必须使用正确的范围重新创建节点。
我们建议您使用
gke-default
范围创建节点池。 此范围可提供对以下范围的访问权限:https://www.googleapis.com/auth/devstorage.read_only
https://www.googleapis.com/auth/logging.write
https://www.googleapis.com/auth/monitoring
https://www.googleapis.com/auth/service.management.readonly
https://www.googleapis.com/auth/servicecontrol
https://www.googleapis.com/auth/trace.append
如果
gke-default
范围不合适,请向节点池授予devstorage.read_only
范围,该范围仅允许访问读取数据。gke-default
创建具有
gke-default
范围的节点池:gcloud container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --scopes="gke-default"
替换以下内容:
NODE_POOL_NAME
:新节点池的名称。CLUSTER_NAME
:现有集群的名称。CONTROL_PLANE_LOCATION
:集群控制平面的 Compute Engine 位置。为区域级集群提供区域,或为可用区级集群提供可用区。
devstorage.read_only
创建具有
devstorage.read_only
范围的节点池:gcloud container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION \ --scopes="https://www.googleapis.com/auth/devstorage.read_only"
替换以下内容:
NODE_POOL_NAME
:新节点池的名称。CLUSTER_NAME
:现有集群的名称。CONTROL_PLANE_LOCATION
:集群控制平面的 Compute Engine 位置。为区域级集群提供区域,或为可用区级集群提供可用区。
验证 VPC Service Controls 设置以访问 Artifact Registry
如果您使用 VPC Service Controls,请确保服务边界允许访问 Artifact Registry。如需了解详情,请参阅 Artifact Registry 文档中的在服务边界内保护代码库。
调查网络连接
在拉取映像期间,网络连接问题可能会导致该进程无法完成。
如需检查网络连接问题是否导致了映像拉取问题,请执行以下部分中详述的调查:
- 调查 DNS 解析。
- 调查防火墙配置。
- 调查外部注册表端点的互联网连接。
- 调查与 Google API 的连接是否超时。
调查 DNS 解析
如果您看到 server misbehaving
映像拉取错误,则 DNS 解析可能是映像拉取失败的原因。
如需调查 DNS 解析问题,请尝试以下解决方案:
- 排查元数据服务器问题。 节点的元数据服务器会解析所有 DNS 查询。涉及此服务器的任何问题都可能会中断名称解析,导致无法连接到代码库,并导致映像拉取失败。
- 如果您使用 Cloud DNS 进行 DNS 解析,请确保您的 Cloud DNS 代管专用区域、转发区域、对等互连区域和响应政策已正确配置。这些方面的配置错误可能会中断 DNS 解析。如需详细了解 Cloud DNS,请参阅使用 Cloud DNS for GKE。 如需有关如何排查 GKE 中的 Cloud DNS 问题的建议,请参阅排查 GKE 中的 Cloud DNS 问题。
- 如果您使用 kube-dns 进行 DNS 解析,请确保它正常运行。如需有关排查 kube-dns 问题的建议,请参阅排查 GKE 中的 kube-dns 问题。
- 如果集群的节点没有外部 IP 地址(如果您使用网络隔离,通常会是这种情况),请在集群使用的子网上启用专用 Google 访问通道,并确保满足网络要求。 如果您使用 Cloud NAT,Trusted Cloud by S3NS 会自动启用专用 Google 访问通道。
调查防火墙配置
如果防火墙出现问题,导致映像拉取失败,您可能会看到以下错误消息:
Failed to start Download and install k8s binaries and configurations
诊断防火墙问题
如果您使用的是 Standard 集群,并且想要确认防火墙问题是否会导致拉取映像时出现问题,请按以下步骤操作:
使用 SSH 连接到出现问题的节点:
gcloud compute ssh NODE_NAME --zone=ZONE_NAME
替换以下内容:
NODE_NAME
:节点的名称。ZONE_NAME
:节点创建所在的 Compute Engine 可用区。
将
kube-node-installation.service
和kube-node-configuration.service
服务的最新日志发送到名为kube-node-installation_status.txt
和kube-node-configuration_status.txt
的文本文件:systemctl status kube-node-installation.service > kube-node-installation_status.txt systemctl status kube-node-configuration.service > kube-node-configuration_status.txt
如果这些日志不包含映像拉取失败时的信息,请生成日志的完整副本:
sudo journalctl -u kube-node-installation.service > kube-node-installation_logs.txt sudo journalctl -u kube-node-configuration.service > kube-node-configuration_logs.txt
查看
kube-node-installation_status.txt
和kube-node-configuration_status.txt
的内容以及文件。如果您在输出中看到i/o timeout
,则问题很可能出在防火墙上。
解决防火墙配置问题
如需解决防火墙问题,请尝试以下解决方案:
找出并解决任何屏蔽网络流量的防火墙规则。例如,您可能有一条规则会阻止向存储映像的注册表的流量。
访问 VPC 流日志:
在 Trusted Cloud 控制台中,前往 Logs Explorer 页面。
在查询窗格中,输入以下查询:
resource.type="gce_subnetwork" logName="projects/PROJECT_ID/logs/[compute.googleapis.com%2Fvpc_flows](http://compute.googleapis.com%2Fvpc_flows)" resource.labels.subnetwork_name="SUBNET_NAME",
替换以下内容:
PROJECT_ID
:您的 Trusted Cloud 项目的 ID。SUBNET_NAME
:子网的名称。
如需了解详情,请参阅 VPC 文档中的使用查询访问流日志。
如果您发现任何防火墙规则会阻止所需流量,请更新这些规则。
如果集群的节点没有外部 IP 地址(如果您使用网络隔离,通常会是这种情况),请在集群使用的子网上启用专用 Google 访问通道,并确保满足网络要求。 如果您使用 Cloud NAT,Trusted Cloud by S3NS 会自动启用专用 Google 访问通道。
调查外部注册表端点的互联网连接情况
如果您的网络配置将流量定向到外部注册表端点,则该端点可能没有互联网连接。如果端点缺少访问权限,映像拉取可能会失败,并且您会看到 i/o timeout
映像拉取错误。
如需检查从外部注册表端点到注册表的网络连接,请使用 ping
或 traceroute
:
ping REGISTRY_ENDPOINT
或
traceroute REGISTRY_ENDPOINT
将 REGISTRY_ENDPOINT
替换为注册表端点。
此值可以是主机名或 IP 地址。
如果您发现连接存在错误,请查看 VPC 路由:
在 Trusted Cloud 控制台中,前往路由。
查看优先级列,确保优先级最高的路由指向有权访问注册表的来源。 值越小,优先级越高。
调查与 Google API 的连接是否超时
如果您使用网络隔离,可能会遇到与 Google API 和服务的连接超时错误,从而导致 i/o timeout
映像拉取错误。
出现此错误的原因是,节点在尝试从注册表拉取映像时无法访问以下某个 API:
containerregistry.googleapis.com
artifactregistry.googleapis.com
为确保您可以连接到所需的 API,请尝试以下解决方案:
- 启用专用 Google 访问通道。 没有外部 IP 地址的节点需要专用 Google 访问通道才能访问 Google API 和服务的外部 IP 地址。
- 使用受支持的网域。
检查防火墙政策:
在 Trusted Cloud 控制台中,前往“防火墙政策”。
验证您是否具有任何规则,用于阻止端口
443
上到199.36.153.4/30
、199.36.153.8/30
或所选网域用于 Google API 和服务的任何 IP 地址范围的出站 TCP 流量。IP 地址范围199.36.153.4/30
和199.36.153.8/30
分别用于专用 Google 访问通道和受限 Google 访问通道。端口443
上流向这些范围的 TCP 流量用于访问 Google API 和服务。如果您发现任何此类规则,请创建出站防火墙规则以允许此类流量。
如果您使用 Artifact Registry,请确保您的环境满足要求,以便在网络隔离的情况下使用 Artifact Registry。
验证虚拟 IP 地址 (VIP)(
199.36.153.4/30
或199.36.153.8/30
)是否已配置 VPC 路由:在 Trusted Cloud 控制台中,前往 VPC 网络。
在名称列中,点击默认。
在“VPC 网络详情”页面中,点击路由标签页。
查看“路由”表。
如果您的 VPC 网络包含默认路由(目标
0.0.0.0/0
或::0/0
),并且该路由的下一个跃点是默认互联网网关(网络默认),请使用该路由通过 VIP 访问 Google API 和服务。如果您已将默认路由替换为下一个跃点不是默认互联网网关的自定义路由,则可以使用自定义路由来满足 Google API 和服务的路由要求。
调查 kubelet 找不到映像的原因
如果 kubelet 找不到您的映像,您可能会看到 image not found
错误,并遇到映像拉取失败的情况。
为帮助 kubelet 找到您的映像,请尝试以下解决方案:
- 查看 Pod 的清单,确保映像名称和映像标记拼写正确无误。任何拼写或格式错误都会导致映像拉取失败。
- 验证映像是否仍然存在于您存储它的注册表中。如果映像具有完整的注册表路径,请验证它是否存在于您使用的 Docker 注册表中。如果仅提供映像名称,请检查 Docker Hub 注册表。
- 如果您的集群使用网络隔离,请尝试以下解决方案:
- 启用专用 Google 访问通道。
- 验证您的服务边界是否已正确配置。
调查映像拉取超时或映像拉取缓慢的原因
如果您为 GKE 工作负载使用非常大的映像,映像拉取可能会超时并导致 context cancelled
错误。虽然图片没有明确的大小限制,但 context cancelled
错误通常表示图片大小是导致问题的原因。
您可能还会注意到,拉取映像操作不会失败,但所用时间比平时长得多。如果您想了解常规的映像拉取时间基准,请查看 Successfully pulled image
日志条目。例如,以下日志消息显示映像拉取耗时 30.313387996 秒:
Successfully pulled image "IMAGE_ADDRESS" in 30.313387996s.
超时和映像拉取缓慢有许多相同的原因。如需解决这些问题,请尝试以下解决方案:
- 检查是否存在服务中断。如果您仅在特定时间段内注意到此问题,请检查是否存在任何 Trusted Cloud by S3NS 中断。
- 检查磁盘性能。磁盘 I/O 速度慢可能会增加映像拉取时间。
考虑升级到使用 SSD 的永久性磁盘 (
pd-ssd
),或使用更大的磁盘来提高性能。如需更多建议,请参阅排查磁盘性能问题。 - 缩减图片大小。例如,您或许可以将部分数据从容器映像移至 Persistent Volume。
- 利用映像缓存缩短 Pod 启动时间。 GKE 会在节点上缓存映像。在拉取映像期间,容器运行时只会下载缓存中尚不存在的层。为了最大限度地提高此缓存机制的有效性并尽可能缩短映像拉取时间,请设计 Dockerfile 的结构,将映像中经常更改的部分(例如应用代码)放在文件末尾,并使用较小的基础映像。
- 启用映像流式传输。此功能可加快 Pod 启动速度和映像下载速度。如需了解详情,请参阅使用映像流式传输拉取容器映像。
- 确保默认服务账号具有必要的权限。修改分配给默认服务账号的角色可能会中断工作负载(包括拉取映像)。如需更多建议,请参阅识别节点服务账号缺少关键权限的集群。
- 检查代理配置。如果您的 GKE 集群与非 Google 管理的代码库之间存在代理,则可能会导致延迟。
- 检查第三方软件。某些第三方软件可能会干扰映像拉取。调查最近安装的工具是否可能导致冲突。
验证映像清单是否使用了正确的架构
如果您尝试拉取的映像是为与节点池所用计算机架构不同的计算机架构构建的,则映像拉取会失败。
如需确认映像清单是否使用了正确的架构,请按以下步骤操作:
如需确认映像使用的架构,请查看映像的清单。例如,如需查看 Docker 映像,请运行以下命令:
docker manifest inspect --verbose IMAGE_NAME
将
IMAGE_NAME
替换为您要查看的映像的名称。输出类似于以下内容:
... "Platform": { "architecture": "amd64", "os": "linux" } ...
在此示例中,支持的架构为
amd64
。查看节点池使用的机器类型:
gcloud container node-pools list --cluster CLUSTER_NAME --location CONTROL_PLANE_LOCATION
替换以下内容:
CLUSTER_NAME
:出现映像拉取错误的 Pod 所运行的集群的名称。CONTROL_PLANE_LOCATION
:集群控制平面的 Compute Engine 位置。为区域级集群提供区域,或为可用区级集群提供可用区。
输出类似于以下内容:
NAME: example-node-pool MACHINE_TYPE: e2-standard-2 DISK_SIZE_GB: 100 NODE_VERSION: 1.30.8-gke.1162000
在此示例中,机器类型为
e2-standard-2
。比较
architecture
和MACHINE_TYPE
字段中的值,并确保这两个值兼容。例如,如果映像具有amd64
架构,则它将与使用e2-standard-2
作为机器类型的节点池兼容。不过,如果所用的节点池为t2a-standard-1
(一种基于 Arm 的机器类型),则此机器类型会导致失败。如果映像的架构与节点池的机器类型不兼容,请重建映像以定位到所需的架构。
验证映像架构版本兼容性
将 containerd 2.0 与 v1 Docker 架构映像搭配使用会导致映像拉取失败,因为 containerd 2.0 在 GKE 1.33 中移除了对拉取 Docker Schema 1 映像的支持。如果此问题是导致映像拉取失败的原因,您可能会看到以下错误消息:
Failed to get converter for "IMAGE_ADDRESS": Pulling Schema 1 images have been deprecated and disabled by default since containerd v2.0. As a workaround you may set an environment variable `CONTAINERD_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE=1`, but this will be completely removed in containerd v2.1.
如需解决此问题,请按照从 Docker Schema 1 映像迁移中的说明识别并迁移这些映像。
后续步骤
如果您在文档中找不到问题的解决方案,请参阅获取支持以获取进一步的帮助,包括以下主题的建议:
- 请与 Cloud Customer Care 联系,以提交支持请求。
- 通过在 StackOverflow 上提问并使用
google-kubernetes-engine
标记搜索类似问题,从社区获得支持。您还可以加入#kubernetes-engine
Slack 频道,以获得更多社区支持。 - 使用公开问题跟踪器提交 bug 或功能请求。