本页展示了如何创建一个 Pod,该 Pod 使用 Secret 从私有容器镜像仓库或存储库拉取镜像。目前有很多私有仓库在使用中。本任务以 Docker Hub 作为仓库示例。
你需要有一个 Kubernetes 集群,并且必须配置 kubectl 命令行工具以与你的集群通信。建议在至少有两个节点的集群上运行本教程,且这些节点不能作为控制平面主机。如果你还没有集群,可以通过 minikube 创建一个,或者使用以下 Kubernetes 演练场之一。
要完成此练习,你需要 docker 命令行工具,以及一个你已知密码的 Docker ID。
如果你使用的是其他私有容器仓库,则需要该仓库的命令行工具以及任何该仓库的登录信息。
在你的笔记本电脑上,你必须向仓库进行身份验证,以便拉取私有镜像。
使用 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"
}
}
}
auth 条目,而是会看到一个 credsStore 条目,其值为存储的名称。在这种情况下,你可以直接创建一个 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。请确保:
.dockerconfigjsondata[".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,命名为 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 设置在集群中。
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 设置在集群中。
这是示例 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 因 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,每个都可以包含多个凭据。
镜像拉取将尝试使用与仓库匹配的每个凭据。如果没有任何凭据与仓库匹配,则镜像拉取将尝试在不进行授权的情况下,或使用自定义运行时特定的配置进行。
imagePullSecrets 字段