从私有仓库拉取镜像

本页展示了如何创建一个 Pod,该 Pod 使用 Secret 从私有容器镜像仓库或存储库拉取镜像。目前有很多私有仓库在使用中。本任务以 Docker Hub 作为仓库示例。

🛇 此项目链接到不属于 Kubernetes 本身的第三方项目或产品。 更多信息

开始之前

  • 你需要有一个 Kubernetes 集群,并且必须配置 kubectl 命令行工具以与你的集群通信。建议在至少有两个节点的集群上运行本教程,且这些节点不能作为控制平面主机。如果你还没有集群,可以通过 minikube 创建一个,或者使用以下 Kubernetes 演练场之一。

  • 要完成此练习,你需要 docker 命令行工具,以及一个你已知密码的 Docker ID

  • 如果你使用的是其他私有容器仓库,则需要该仓库的命令行工具以及任何该仓库的登录信息。

登录 Docker Hub

在你的笔记本电脑上,你必须向仓库进行身份验证,以便拉取私有镜像。

使用 docker 工具登录 Docker Hub。有关更多信息,请参见 Docker ID 账户登录部分。

docker login

出现提示时,输入你的 Docker ID,然后输入你要使用的凭据(访问令牌或 Docker ID 的密码)。

登录过程会创建或更新一个包含授权令牌的 config.json 文件。请查看 Kubernetes 如何解析此文件

查看 config.json 文件

cat ~/.docker/config.json

输出包含一个类似于此的部分

{
    "auths": {
        "https://index.docker.io/v1/": {
            "auth": "c3R...zE2"
        }
    }
}

说明

如果你使用 Docker 凭据存储,则不会看到该 auth 条目,而是会看到一个 credsStore 条目,其值为存储的名称。在这种情况下,你可以直接创建一个 secret。请参见 通过命令行提供凭据创建 Secret

根据现有凭据创建 Secret

Kubernetes 集群使用 kubernetes.io/dockerconfigjson 类型的 Secret 向容器仓库进行身份验证,以拉取私有镜像。

如果你已经运行了 docker login,你可以将该凭据复制到 Kubernetes 中

kubectl create secret generic regcred \
    --from-file=.dockerconfigjson=<path/to/.docker/config.json> \
    --type=kubernetes.io/dockerconfigjson

如果你需要更多控制权(例如,设置命名空间或为新 secret 添加标签),则可以在存储之前自定义 Secret。请确保:

  • 将数据项的名称设置为 .dockerconfigjson
  • 对 Docker 配置文件进行 base64 编码,然后将该字符串作为 data[".dockerconfigjson"] 字段的值粘贴进去,中间不要有换行
  • type 设置为 kubernetes.io/dockerconfigjson

示例

apiVersion: v1
kind: Secret
metadata:
  name: myregistrykey
  namespace: awesomeapps
data:
  .dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg==
type: kubernetes.io/dockerconfigjson

如果你收到错误消息 error: no objects passed to create,这可能意味着 base64 编码的字符串无效。如果你收到类似于 Secret "myregistrykey" is invalid: data[.dockerconfigjson]: invalid value ... 的错误消息,则表示数据中的 base64 编码字符串已成功解码,但无法被解析为 .docker/config.json 文件。

通过命令行提供凭据创建 Secret

创建此 Secret,命名为 regcred

kubectl create secret docker-registry regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>

其中

  • <your-registry-server> 是你的私有 Docker 仓库 FQDN。对于 DockerHub,请使用 https://index.docker.io/v1/
  • <your-name> 是你的 Docker 用户名。
  • <your-pword> 是你的 Docker 密码。
  • <your-email> 是你的 Docker 电子邮件地址。

你已成功将 Docker 凭据作为名为 regcred 的 Secret 设置在集群中。

说明

在命令行输入 secret 可能会将其未加密地存储在 shell 历史记录中,并且在 kubectl 运行时,其他用户也可能在你的 PC 上看到这些 secret。

检查 regcred Secret

要了解你创建的 regcred Secret 的内容,首先以 YAML 格式查看该 Secret

kubectl get secret regcred --output=yaml

输出类似于此

apiVersion: v1
kind: Secret
metadata:
  ...
  name: regcred
  ...
data:
  .dockerconfigjson: eyJodHRwczovL2luZGV4L ... J0QUl6RTIifX0=
type: kubernetes.io/dockerconfigjson

.dockerconfigjson 字段的值是你 Docker 凭据的 base64 表示。

要了解 .dockerconfigjson 字段中的内容,将 secret 数据转换为可读格式

kubectl get secret regcred --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode

输出类似于此

{"auths":{"your.private.registry.example.com":{"username":"janedoe","password":"xxxxxxxxxxx","email":"jdoe@example.com","auth":"c3R...zE2"}}}

要了解 auth 字段中的内容,将 base64 编码的数据转换为可读格式

echo "c3R...zE2" | base64 --decode

输出(用户名和密码以 : 连接)类似于此

janedoe:xxxxxxxxxxx

注意,Secret 数据中包含类似于你本地 ~/.docker/config.json 文件的授权令牌。

你已成功将 Docker 凭据作为名为 regcred 的 Secret 设置在集群中。

创建一个使用你 Secret 的 Pod

这是示例 Pod 的清单,该 Pod 需要访问 regcred 中的 Docker 凭据

apiVersion: v1
kind: Pod
metadata:
  name: private-reg
spec:
  containers:
  - name: private-reg-container
    image: <your-private-image>
  imagePullSecrets:
  - name: regcred

将上述文件下载到你的计算机上

curl -L -o my-private-reg-pod.yaml https://k8s.io/examples/pods/private-reg-pod.yaml

在文件 my-private-reg-pod.yaml 中,将 <your-private-image> 替换为私有仓库中镜像的路径,例如

your.private.registry.example.com/janedoe/jdoe-private:v1

要从私有仓库拉取镜像,Kubernetes 需要凭据。配置文件中的 imagePullSecrets 字段指定 Kubernetes 应从名为 regcred 的 Secret 中获取凭据。

创建一个使用你 Secret 的 Pod,并验证 Pod 正在运行

kubectl apply -f my-private-reg-pod.yaml
kubectl get pod private-reg

说明

要为 Pod(或 Deployment,或其他使用 pod 模板的对象)使用镜像拉取 secret,你需要确保相应的 Secret 确实存在于正确的命名空间中。要使用的命名空间与你定义 Pod 的命名空间相同。

此外,如果 Pod 因 ImagePullBackOff 状态而启动失败,请查看 Pod 事件

kubectl describe pod private-reg

如果你随后看到一个原因为 FailedToRetrieveImagePullSecret 的事件,则说明 Kubernetes 找不到名为 regcred(本例中)的 Secret。

确保你指定的 Secret 存在,并且名称拼写正确。

Events:
  ...  Reason                           ...  Message
       ------                                -------
  ...  FailedToRetrieveImagePullSecret  ...  Unable to retrieve some image pull secrets (<regcred>); attempting to pull the image may not succeed.

使用来自多个仓库的镜像

一个 pod 可以有多个容器,每个容器镜像可以来自不同的仓库。你可以在一个 pod 中使用多个 imagePullSecrets,每个都可以包含多个凭据。

镜像拉取将尝试使用与仓库匹配的每个凭据。如果没有任何凭据与仓库匹配,则镜像拉取将尝试在不进行授权的情况下,或使用自定义运行时特定的配置进行。

接下来


最后修改时间:2024年11月20日 凌晨12:22 (PST): 澄清镜像拉取 secret 文档 (#48718) (22030b43ef)

此页面上的项目涉及提供 Kubernetes 所需功能的第三方产品或项目。Kubernetes 项目作者不对这些第三方产品或项目负责。有关详细信息,请参阅 CNCF 网站指南

在提出添加额外的第三方链接的更改之前,您应该阅读 内容指南