从私有仓库拉取镜像
本页介绍了如何创建一个 Pod,该 Pod 使用 Secret 来从私有容器镜像仓库或代码库中拉取镜像。目前有很多私有仓库正在使用中。本任务使用 Docker Hub 作为仓库示例。
开始之前
你需要有一个 Kubernetes 集群,并且 kubectl 命令行工具已被配置为与你的集群通信。建议在至少有两个非控制平面主机的节点上运行本教程。如果你还没有集群,可以使用 minikube 创建一个,或者使用以下 Kubernetes 练习场之一:
要完成此练习,你需要
docker
命令行工具,以及一个你知道密码的 Docker ID。如果你使用的是不同的私有容器镜像仓库,则需要该仓库的命令行工具和任何登录信息。
登录 Docker Hub
在你的笔记本电脑上,你必须通过仓库认证才能拉取私有镜像。
使用 docker
工具登录 Docker Hub。更多信息请参阅 Docker ID 账户中的 log in 部分。
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
运行时,这些 Secret 也可能对你 PC 上的其他用户可见。查看 Secret regcred
要理解你创建的 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
下面是一个需要访问 regcred
中 Docker 凭证的示例 Pod 的清单:
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 找不到指定名称的 Secret(在本例中为 regcred
)。
请确保你指定的 Secret 存在,并且名称拼写正确。
Events:
... Reason ... Message
------ -------
... FailedToRetrieveImagePullSecret ... Unable to retrieve some image pull secrets (<regcred>); attempting to pull the image may not succeed.
使用来自多个仓库的镜像
一个 Pod 可以有多个容器,每个容器镜像可以来自不同的仓库。你可以在一个 Pod 中使用多个 imagePullSecrets
,并且每个 Secret 可以包含多个凭证。
将尝试使用每个与仓库匹配的凭证进行镜像拉取。如果没有凭证与仓库匹配,将尝试在不进行身份认证或使用自定义运行时特定配置的情况下进行镜像拉取。
接下来
- 了解更多关于 Secret 的信息。
- 或者阅读 Secret 的 API 参考。
- 了解更多关于使用私有仓库的信息。
- 了解更多关于为 Service Account 添加镜像拉取 Secret 的信息。
- 请参阅 kubectl create secret docker-registry。
- 请参阅 Pod 的容器定义中的
imagePullSecrets
字段。
本页上的内容涉及为 Kubernetes 提供所需功能的第三方产品或项目。Kubernetes 项目作者不对这些第三方产品或项目负责。更多详细信息请参阅 CNCF 网站指南。
在提出添加额外第三方链接的变更之前,你应该阅读内容指南。