从私有仓库拉取镜像

本文介绍如何使用 Secret 从私有的镜像仓库或代码仓库拉取镜像来创建 Pod。 有很多私有镜像仓库正在使用中。这个任务使用的镜像仓库是 Docker Hub

🛇 本条目指向第三方项目或产品,而该项目(产品)不是 Kubernetes 的一部分。更多信息

准备开始

  • 你必须拥有一个 Kubernetes 的集群,且必须配置 kubectl 命令行工具让其与你的集群通信。 建议运行本教程的集群至少有两个节点,且这两个节点不能作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面的 Kubernetes 练习环境之一:

  • 要进行此练习,你需要 docker 命令行工具和一个知道密码的 Docker ID

  • 如果你要使用不同的私有的镜像仓库,你需要有对应镜像仓库的命令行工具和登录信息。

登录 Docker 镜像仓库

在个人电脑上,要想拉取私有镜像必须在镜像仓库上进行身份验证。

使用 docker 命令工具来登录到 Docker Hub。 更多详细信息,请查阅 Docker ID accounts 中的 log in 部分。

  1. docker login

当出现提示时,输入你的 Docker ID 和登录凭据(访问令牌或 Docker ID 的密码)。

登录过程会创建或更新保存有授权令牌的 config.json 文件。 查看 Kubernetes 如何解析这个文件

查看 config.json 文件:

  1. cat ~/.docker/config.json

输出结果包含类似于以下内容的部分:

  1. {
  2. "auths": {
  3. "https://index.docker.io/v1/": {
  4. "auth": "c3R...zE2"
  5. }
  6. }
  7. }

说明:

如果使用 Docker 凭据仓库,则不会看到 auth 条目,看到的将是以仓库名称作为值的 credsStore 条目。 在这种情况下,你可以直接创建一个 Secret。 请参阅在命令行上提供凭据来创建 Secret

创建一个基于现有凭据的 Secret

Kubernetes 集群使用 kubernetes.io/dockerconfigjson 类型的 Secret 来通过镜像仓库的身份验证,进而提取私有镜像。

如果你已经运行了 docker login 命令,你可以复制该镜像仓库的凭据到 Kubernetes:

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

如果你需要更多的设置(例如,为新 Secret 设置名字空间或标签), 则可以在存储 Secret 之前对它进行自定义。 请务必:

  • 将 data 项中的名称设置为 .dockerconfigjson
  • 使用 base64 编码方法对 Docker 配置文件进行编码,然后粘贴该字符串的内容,作为字段 data[".dockerconfigjson"] 的值
  • type 设置为 kubernetes.io/dockerconfigjson

示例:

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: myregistrykey
  5. namespace: awesomeapps
  6. data:
  7. .dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg==
  8. 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

  1. kubectl create secret docker-registry regcred \
  2. --docker-server=<你的镜像仓库服务器> \
  3. --docker-username=<你的用户名> \
  4. --docker-password=<你的密码> \
  5. --docker-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 历史记录中而不受保护, 并且这些 Secret 信息也可能在 kubectl 运行期间对你 PC 上的其他用户可见。

检查 Secret regcred

要了解你创建的 regcred Secret 的内容,可以用 YAML 格式进行查看:

  1. kubectl get secret regcred --output=yaml

输出和下面类似:

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. ...
  5. name: regcred
  6. ...
  7. data:
  8. .dockerconfigjson: eyJodHRwczovL2luZGV4L ... J0QUl6RTIifX0=
  9. type: kubernetes.io/dockerconfigjson

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

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

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

输出和下面类似:

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

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

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

输出结果中,用户名和密码用 : 链接,类似下面这样:

  1. janedoe:xxxxxxxxxxx

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

这样你就已经成功地将 Docker 凭据设置为集群中的名为 regcred 的 Secret。

创建一个使用你的 Secret 的 Pod

下面是一个 Pod 配置清单示例,该示例中 Pod 需要访问你的 Docker 凭据 regcred

  1. pods/private-reg-pod.yaml
  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: private-reg
  5. spec:
  6. containers:
  7. - name: private-reg-container
  8. image: <your-private-image>
  9. imagePullSecrets:
  10. - name: regcred

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

  1. 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>,例如:

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

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

创建使用了你的 Secret 的 Pod,并检查它是否正常运行:

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

说明:

要为 Pod(或 Deployment,或其他有 Pod 模板的对象)使用镜像拉取 Secret, 你需要确保合适的 Secret 确实存在于正确的名字空间中。 要使用的是你定义 Pod 时所用的名字空间。

此外,如果 Pod 启动失败,状态为 ImagePullBackOff,查看 Pod 事件:

  1. kubectl describe pod private-reg

如果你看到一个原因设为 FailedToRetrieveImagePullSecret 的事件, 那么 Kubernetes 找不到指定名称(此例中为 regcred)的 Secret。 如果你指定 Pod 需要拉取镜像凭据,kubelet 在尝试拉取镜像之前会检查是否可以访问该 Secret。

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

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

接下来