本部分介绍如何排查常见的 Container Registry 和 Docker 问题。
网域级项目
如果您收到 invalid reference format
错误,一个可能问题是您的项目被限定在某一网域范围内。
如果您的项目被限定在您的网域范围内,那么项目 ID 应包含相应域名和一个英文冒号 (example.com:my-project
:)。请参阅网域级项目,了解如何使用含有域名的项目 ID。
错误:状态 405:v1 Registry API is disabled.
如果您在拉取或推送映像时不断遇到诸如“v1 Registry API is disabled”之类的错误,请确保主机名、项目 ID、映像名称以及标记或摘要拼写正确。
要查看映像的标记和摘要,请运行以下命令:
gcloud container images list-tags [HOSTNAME]/[PROJECT-ID]/[IMAGE]
例如:
gcloud container images list-tags gcr.io/my-project/my-image
如需详细了解如何列出映像标记和摘要,请参阅管理映像。
权限问题
以下部分介绍了针对特定权限问题的解决方案。 请始终确保您具有推送或拉取所需的权限。 请参阅权限和角色。
与统一存储分区级访问权限相关的权限问题
如果您对 Container Registry 使用的存储分区启用了统一存储分区级访问权限,则在推送和拉取到 Container Registry 时您可能会遇到访问权限问题。
如需解决访问权限问题,请确保您拥有所需的推送或拉取权限。权限和角色中列出了这些权限。
与本地机器上的 Docker 设置相关的权限问题
如果您遇到 permission denied
错误(如以下示例所示):
FATA[0000] Post http://var/run/docker.sock/v1.17/images/gcr.io/container-engine-docs/example/push?tag=: dial unix /var/run/docker.sock: permission denied
ERROR: (gcloud.docker) A Docker command did not run successfully.
Tried to run: 'docker push gcr.io/container-engine-docs/example'
Exit code: 1
您可能需要将自己添加到 docker
用户群组中。
在 shell 或终端窗口中运行以下命令:
sudo usermod -a -G docker ${USER}
在将您自己添加到 docker
用户群组后,请重启系统。
与 Container Registry 通信时的权限问题
如果您遇到如下所示的权限错误:
Permission denied: Unable to create the repository, please check that you have access to do so
验证是否已为您的项目启用结算功能。
验证您的访问权限:
通过运行以下命令,确保您已通过
gcloud
身份验证:gcloud init
通过运行以下命令,确保将 Docker 配置为使用
gcloud
作为 Container Registry 凭据帮助程序:gcloud auth configure-docker
验证
docker-credential-gcloud
能否执行:docker-credential-gcloud list
您应该会看到一个以您的目标注册表作为一个键的 JSON 对象。例如:
{ "https://asia.gcr.io": "oauth2accesstoken", "https://eu.gcr.io": "oauth2accesstoken", "https://gcr.io": "oauth2accesstoken", "https://us.gcr.io": "oauth2accesstoken" }
接下来,检查您是否有权对项目中要向其推送内容的 Cloud Storage 执行写入操作。如果您没有相关权限,请向管理员请求为您的用户授予访问权限,然后重试。
如果在获得正确权限后此问题依然存在,则说明在获取您的访问令牌时可能缺少以下范围:
https://www.googleapis.com/auth/devstorage.read_write
https://www.googleapis.com/auth/devstorage.full_control
要验证这一点,请先自行获取访问令牌。具体获取方式因应用而异,例如,如果您使用 Compute Engine 默认服务账号中的访问令牌,则可以按照此处的说明获取该令牌。
自行获取访问令牌后,您可以使用以下命令来查看获取访问令牌时使用的范围:
curl -H "Authorization: Bearer <your access token>" https://www.googleapis.com/oauth2/v1/tokeninfo
如果未包含上述范围,请修复问题以确保在代码中获取访问令牌时包含这些范围。例如,对于专门为 Compute Engine 虚拟机上的默认服务账号生成的令牌,您将需要修正该虚拟机的范围设置并重新创建该令牌。
推送和拉取映像的权限问题
如需访问 Container Registry 存储分区,您必须为推送或拉取映像的虚拟机实例正确配置所需的 IAM 权限和访问权限范围。如需了解所需设置,请参阅将 Container Registry 与 Google Cloud 搭配使用。
Google Kubernetes Engine 中的 ImagePullBackoff 错误
如果 GKE 无法从注册表中拉取映像,则会返回 ImagePullBackoff
错误。如果找不到映像,或者您的节点没有从注册表拉取的权限,则可能会发生此错误。默认情况下,当注册表与您的节点属于同一 Google Cloud 项目时,GKE 节点有权从 Container Registry 拉取映像。
GKE 文档包含确定根本原因并解决问题的步骤。
组织政策强制执行
组织政策限制条件会应用于 Container Registry 使用的服务,因此可能会影响 Container Registry 的使用,包括要求使用客户管理的加密密钥 (CMEK) 的限制条件。
推送图片时出现“Bad Request”错误
当 Cloud Storage API 位于限制条件 constraints/gcp.restrictNonCmekServices
的 Deny
政策列表中时,如果底层存储分区未使用 CMEK 加密,您将无法将映像推送到 Container Registry。系统会返回以下消息:
unknown: Bad Request
配置 constraints/gcp.restrictCmekCryptoKeyProjects
后,必须使用允许的项目、文件夹或组织中的 CryptoKey 对存储分区进行加密。默认情况下,不合规的现有存储分区必须配置为使用所需的密钥。
如需对存储分区进行加密,请参阅 Cloud Storage 说明。注册表主机的存储桶名称采用以下格式之一:
- 对于存储在主机
gcr.io
上的映像,名称采用artifacts.PROJECT-ID.appspot.com
格式 STORAGE-REGION.artifacts.PROJECT-ID.appspot.com
(适用于存储在asia.gcr.io
、eu.gcr.io
或us.gcr.io
上的图片)。
系统未自动创建 gcr Pub/Sub 主题
当您在 Google Cloud 项目中激活 Container Registry API 时,Container Registry 会尝试使用 Google 管理的加密密钥自动创建主题 ID 为 gcr
的 Pub/Sub 主题。
当 Pub/Sub API 位于限制条件 constraints/gcp.restrictNonCmekServices
的 Deny
政策列表中时,必须使用 CMEK 对主题进行加密。创建不使用 CMEK 加密的主题的请求将失败。
如需使用 CMEK 加密创建 gcr
主题,请参阅 Pub/Sub 有关加密主题的说明。
配额限制
如果超出了 Container Registry 的配额限制,您可能会看到如下错误消息:
Error: Status 429 trying to pull repository [...] "Quota Exceeded."
为避免超出固定配额限制,您可以采取以下措施:
- 增加与 Container Registry 通信的 IP 地址数量。 配额以每个 IP 地址为单位。
- 添加引入延迟的重试机制。例如,您可以使用指数退避算法。
注册表端点对 boot2docker 无效
如果您在 boot2docker 环境中无法访问 Container Registry:
docker push gcr.io/example/sample
Error response from daemon: invalid registry endpoint https://gcr.io/v0/:
unable to ping registry endpoint https://gcr.io/v0/
v2 ping attempt failed with error: Get https://gcr.io/v2/:
x509: certificate has expired or is not yet valid
v1 ping attempt failed with error: Get https://gcr.io/v1/_ping:
x509: certificate has expired or is not yet valid.
If this private registry supports only HTTP or HTTPS with an unknown CA
certificate, please add `--insecure-registry gcr.io` to the daemon's
arguments. In the case of HTTPS, if you have access to the registry's CA
certificate, no need for the flag; simply place the CA certificate at
/etc/docker/certs.d/gcr.io/ca.crt
您可能需要重新启动 boot2docker:
boot2docker stop
boot2docker start
有关推送根级映像的错误
当您尝试推送容器映像时,推送会失败,并显示一条消息,其中包含:
Pushing to root-level images is disabled
此消息表示您使用主机名和映像为映像添加了标记,但未添加项目 ID。
使用正确的图片路径格式标记图片:
HOSTNAME/PROJECT-ID/IMAGE:TAG
例如:gcr.io/web-project/web-app:1.0
。
在 Mac 上使用 Docker
如果在 Mac 上使用 Docker 时遇到任何问题,您可能需要尝试解决这个问题。 错误可能包括 Docker 推送/拉取操作无响应或类似如下的网络错误:
Post https://us.gcr.io/v2/[repo name]/blobs/uploads/: dial tcp xx.xxx.xx.xx:xxx: i/o timeout
如果您遇到这些错误,请尝试以下步骤:
在 Mac 终端中运行
docker-machine restart default
命令以重启 Docker 守护进程。确保 Docker 的“偏好设置”菜单中未启用“将 docker 登录安全存储到 macOS 钥匙串” (Securely store docker logins in macOS keychain)。
确保您运行的是最新 Docker 版本。