系列目录
前面我们讲解了如何搭建 nexus 服务器, 以及如何使用 nexus 搭建 docker 私有镜像仓库, 示例中我们都是手动 docker login 登陆私服, 然后通过命令拉取镜像然后运行容器. 然而这种做法在 kubernetes 集群中是不可行的. 第一, 项目规模不同, 每天产生的镜像数量也不同, 如果每天产生大量仓库都要手动执行 docker pull 来拉取, 非常麻烦也非常容易出错. 第二, 集群规模不同, 节点数量也不同, 少则三五个, 多则成百上千甚至更多. 我们一台台拉取显然非常麻烦, 即便使用 ansible 脚本批量执行命令也同样存在问题: 因为不同的容器分布在不同的节点上. 把所有镜像都用批量脚本拉到所有服务器上显然会浪费非常多的资源, 并且集群扩容或者缩容器都需要更改脚本, 很容易出现错误. 这时候我们更倾向使用 kubernetes 自身的强大管理功能. 其实 kubernetes 可以把 docker 的登陆信息做成 secrets, 在容器编排时显式指定要用到的 secret,kubernetes 就会自动去拉取私服上编排时指定的镜像. 大大方便我们自动化的流程. 下面我们就讲解如何如何制作 docker 私仓拉取 secrets 以及如何在拉取镜像时使用.
我们在拉取公仓镜像的时候, 是不需要输入账户密码的. 但是私仓往往都是要登陆以后才能拉取里面的镜像. 前面讲解 nexus docker 私服的时候我们也讲到过, 所有操作的前提就是使用 docker login -u 用户名 -p 密码 服务器首先登陆私服. 我们登陆过一次后下次再次登陆其实不用指定用户名和密码, 比如, 我可以使用以下命令直接登陆:
- [root@k8s-node1 ~]# docker login 192.168.124.43:8002
- Authenticating with existing credentials...
- WARNING! Your password will be stored unencrypted in /root/.docker/config.JSON.
- Configure a credential helper to remove this warning. See
- https://docs.docker.com/engine/reference/commandline/login/#credentials-store
- Login Succeeded
- [root@k8s-node1 ~]#
可以看到没有指定用户名和密码我们也同样登陆了. 实际上, 我们首次登陆成功后, docker 便把登陆信息存在了~/.docker/config.JSON 这个文件里, 我们可以看一下
- [root@k8s-node1 ~]# .
- {
- "auths": {
- "192.168.124.43:8002": {
- "auth": "YWRtaW46YWRtaW4xMjM="
- }
- },
- "HttpHeaders": {
- "User-Agent": "Docker-Client/18.09.4 (linux)"
- }
- }[root@k8s-node1 ~]#
基于现有 docker 登陆信息创建 kubernetes 密钥
命令如下
- kubectl create secret generic regcred \
- --from-file=.dockerconfigjson= ~/.docker/config.JSON \
- --type=kubernetes.io/dockerconfigjson
以上方法同其它创建 kubernetes 密钥的方法并没有区别, 这里的关键是. docker 目录下的 config.JSON 文件.
当然, 如果你想对生成出来的 secrets 有更多的控制, 比如指定这个 secrets 的名称空间, 可以使用 YAML 文件来声明式创建. 步骤与上面略有不同, 如下
data 字段的名称必须设置为. dockerconfigjson
对 config.JSON 文件进行 base64 编码, 然后把编码后的内容复制到. dockerconfigjson 字段
类型设置为 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
上面是使用 docker 存储的已经登陆的信息创建的 secret, 如果没有使用 docker 登陆, 也可以直接通过命令行来创建 secret, 命令格式如下:
kubectl create secret docker-registry regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
下面对上面字段做简要描述:
docker 私服地址
登陆名
登陆密码
邮箱, 此字段为非必填项
这里仍然基于前面搭建的 nexus docker 私仓为例:
kubectl create secret docker-registry regcred --docker-server=192.168.124.43:8002 --docker-username=admin --docker-password=admin123
便可以创建 secret 了.
查看密钥信息
可以使用以下命令查看刚创建的密钥:
- kubectl get secret regcred --output=YAML
- [CentOS@k8s-master trackingapi]$ kubectl get secret regcred --output=YAML
- apiVersion: v1
- data:
- .dockerconfigjson: eyJhdXRocyI6eyIxOTIuMTY4LjEyNC40Mzo4MDAyIjp7IlVzZXJuYW1lIjoiYWRtaW4iLCJQYXNzd29yZCI6ImFkbWluMTIzIiwiRW1haWwiOiIifX19
- kind: Secret
- metadata:
- creationTimestamp: "2019-04-12T05:53:19Z"
- name: regcred
- namespace: default
- resourceVersion: "3763835"
- selfLink: /API/v1/namespaces/default/secrets/regcred
- uid: 46028dd4-5ce7-11e9-bc12-0050568417a2
- type: kubernetes.io/dockerconfigjson
- [CentOS@k8s-master trackingapi]$
其中. dockerconfigjson 字段为 docker 的登陆信息, 我们可以通过 base64 解码来查看它:
- kubectl get secret regcred --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
- [CentOS@k8s-master trackingapi]$ kubectl get secret regcred --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
- {
- "auths":{
- "192.168.124.43:8002":{
- "Username":"admin","Password":"admin123","Email":""
- }
- }
- }[CentOS@k8s-master trackingapi]$
可以看到以上正信息与我们创建密码时输入的信息吻合
注 以上是我们通过命令行生成的, 如果是通过 config.JSON 生成的则解码后的信息与以上略有不同. 通过 config.JSON 生成的密钥解码后有 个 auth 字段, 它仍然是 base64 编码形式存在的, 我们需要再次对其解码才能查看到信息
比如
- [CentOS@k8s-master trackingapi]$ echo "YWRtaW46YWRtaW4xMjM="|base64 --decode
- admin:admin123
- [CentOS@k8s-master trackingapi]$
创建 pod 使用密钥拉取私仓镜像
编排文件示例如下:
- apiVersion: v1
- kind: Pod
- metadata:
- name: Ubuntu-demo
- spec:
- restartPolicy: Never
- containers:
- - name: u-demo
- image: 192.168.124.43:8002/Ubuntu
- imagePullPolicy: IfNotPresent
- command: ["printenv"]
- args: ["HOSTNAME"]
- imagePullSecrets:
- - name: regcred
以上示例我们使用了预先上传到私服里的一个 Ubuntu 镜像来创建一个 pod, 由于以上镜像创建完成后马上就结束了. 因此我们让打印一个环境变量信息, 然后再使用 log 命令来查看, 以证明操作是成功的.
镜像创建完成以后, 我们查看 pod 的状态
- [CentOS@k8s-master trackingapi]$ kubectl get po
- NAME READY STATUS RESTARTS AGE
- busybox 1/1 Running 552 23d
- consul-0 1/1 Running 2 28h
- consul-1 1/1 Running 3 28h
- consul-2 1/1 Running 2 28h
- helloworld-7fdc8d9855-ncfdz 1/1 Running 3 30d
- hostaliases-pod 1/1 Running 0 3h42m
- Ubuntu-demo 0/1 Completed 0 50m
可以看到 pod 已处于完成状态, 我们使用 kubectl logs 来查看它是否打印了信息
- [CentOS@k8s-master trackingapi]$ kubectl logs Ubuntu-demo
- Ubuntu-demo
可以看到, 输出了 host 的名称.
来源: https://www.cnblogs.com/tylerzhou/p/11112086.html