7. 镜像拉取策略(image PullPolicy)
Pod 的核心是运行容器,必须指定容器引擎,比如 Docker,启动容器时,需要拉取镜像,k8s 的镜像拉取策略可以由用户指定:
● IfNotPresent:在镜像已经存在的情况下,kubelet 将不再去拉取镜像,仅当本地缺失时才从仓库中拉取,默认的镜像拉取策略
● Always:每次创建 Pod 都会重新拉取一次镜像;
● Never:Pod 不会主动拉取这个镜像,仅使用本地镜像。
注意:对于标签为“:latest”的镜像文件,其默认的镜像获取策略即为“Always”;而对于其他标签的镜像,其默认策略则为“IfNotPresent”。
7.1 官方示例
https://kubernetes.io/docs/concepts/containers/images
创建使用私有镜像的 Pod 来验证
| kubectl apply -f - <<EOF | |
| apiVersion: v1 | |
| kind: Pod | |
| metadata: | |
| name: private-image-test-1 | |
| spec: | |
| containers: | |
| - name: uses-private-image | |
| image: $PRIVATE_IMAGE_NAME | |
| imagePullPolicy: Always | |
| command: [ "echo", "SUCCESS" ] | |
| EOF |
输出类似于
pod/private-image-test-1 created
如果一些顺利,那么一段时间后你可以执行
kubectl logs private-image-test-1
然后可以看到SUCCESS
如果你怀疑命令失败了,可以运行
kubectl describe pods/private-image-test-1 | grep 'Failed'
如果命令确实失败了,输出类似于
Fri, 26 Jun 2015 15:36:13 -0700 Fri, 26 Jun 2015 15:39:13 -0700 19 {kubelet node-i2hq} spec.containers{uses-private-image} failed Failed to pull image "user/privaterepo:v1": Error: image user/privaterepo:v1 not found
必须确保集群中所有节点的 .docker/config.json 文件内容相同。 否则,Pod 会能在一些节点上正常运行而无法在另一些节点上启动。 例如,如果使用节点自动扩缩,那么每个实例模板都需要包含 .docker/config.json, 或者挂载一个包含该文件的驱动器。
在 .docker/config.json 中配置了私有仓库密钥后,所有 Pod 都将能读取私有仓库中的镜像。
7.2 不指定版本号,查看默认拉取策略
7.2.1 不指定版本号创建pod
kubectl run nginx-test1 --image=nginx
| [root@master test]# kubectl run nginx-test1 --image=nginx | |
| kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead. | |
| deployment.apps/nginx-test1 created |
7.2.2 查看默认拉取策略
kubectl edit pod nginx-test1-7c4c56845c-hndnk
| [root@master test]# kubectl get pod | |
| NAME READY STATUS RESTARTS AGE | |
| nginx-test1-7c4c56845c-hndnk 1/1 Running 0 75s | |
| [root@master test]# kubectl edit pod nginx-test1-7c4c56845c-hndnk | |
| ...... | |
| spec: | |
| containers: | |
| - image: nginx | |
| imagePullPolicy: Always | |
| #不指定版本号,即使用缺省值latest最新版本,默认拉取策略为Always | |
| name: nginx-test1 | |
| ...... |
7.2.3 查看创建过程
kubectl describe pod nginx-test1
| [root@master test]# kubectl describe pod nginx-test1 | |
| ...... | |
| Events: | |
| Type Reason Age From Message | |
| ---- ------ ---- ---- ------- | |
| Normal Scheduled 5m35s default-scheduler Successfully assigned default/nginx-test1-7c4c56845c-hndnk to node01 | |
| Normal Pulling 5m34s kubelet, node01 Pulling image "nginx" | |
| Normal Pulled 5m19s kubelet, node01 Successfully pulled image "nginx" | |
| Normal Created 5m19s kubelet, node01 Created container nginx-test1 | |
| Normal Started 5m19s kubelet, node01 Started container nginx-test1 |
由于拉取策略为Always,因此不管本地有没有对应镜像,kubelet都会前往公有/私有仓库下载最新版本应用
7.3 测试案例(非循环命令)
7.3.1 创建测试案例nginx-test1.yaml
| [root@master test]# vim nginx-test1.yaml | |
| apiVersion: v1 | |
| kind: Pod | |
| metadata: | |
| name: nginx-test1 | |
| spec: | |
| containers: | |
| - name: nginx | |
| image: nginx | |
| imagePullPolicy: Always | |
| command: [ "echo","SUCCESS" ] |
7.3.2 生成nginx-test1配置资源
kubectl apply -f nginx-test1.yaml
| [root@master test]# kubectl apply -f nginx-test1.yaml | |
| pod/nginx-test1 created |
7.3.3 查看pod状态
kubectl get pod -o wide
| [root@master test]# kubectl get pod -o wide | |
| NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES | |
| nginx-test1 0/1 CrashLoopBackOff 1 51s 10.244.1.48 node01 <none> <none> |
该pod状态为CrashLoopBackOff,说明pod进入了异常循环状态
原因是 echo 执行完进程终止,容器生命周期也就结束了
7.3.4 查看创建过程
kubectl describe pod nginx-test1
| [root@master test]# kubectl describe pod nginx-test1 | |
| ...... | |
| Events: | |
| Type Reason Age From Message | |
| ---- ------ ---- ---- ------- | |
| Normal Scheduled 3m54s default-scheduler Successfully assigned default/nginx-test1 to node01 | |
| Normal Created 2m8s (x4 over 3m38s) kubelet, node01 Created container nginx | |
| Normal Started 2m8s (x4 over 3m38s) kubelet, node01 Started container nginx | |
| Warning BackOff 100s (x7 over 3m21s) kubelet, node01 Back-off restarting failed container | |
| Normal Pulling 86s (x5 over 3m53s) kubelet, node01 Pulling image "nginx" | |
| Normal Pulled 71s (x5 over 3m38s) kubelet, node01 Successfully pulled image "nginx" |
可以发现 Pod 中的容器在生命周期结束后,由于 Pod 的重启策略为 Always,容器再次重启了,并且又重新开始拉取镜像
7.3.5 修改nginx-test1.yaml
| [root@master test]# vim nginx-test1.yaml | |
| apiVersion: v1 | |
| kind: Pod | |
| metadata: | |
| name: nginx-test1 | |
| spec: | |
| containers: | |
| - name: nginx | |
| ##指定nginx版本为1.14 | |
| image: nginx:1.14 | |
| imagePullPolicy: Always | |
| ##注释掉命令 | |
| #command: [ "echo","SUCCESS" ] |
7.3.6 生成新的nginx-tets1.yaml配置资源
删除原有的资源
kubectl delete -f nginx-test1.yaml
| [root@master test]# kubectl delete -f nginx-test1.yaml | |
| pod "nginx-test1" deleted |
生成新的资源
kubectl apply -f nginx-test1.yaml
| [root@master test]# kubectl apply -f nginx-test1.yaml | |
| pod/nginx-test1 created |
7.3.7 查看pod状态
kubectl get pod -o wide
| [root@master test]# kubectl get pod -o wide | |
| NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES | |
| nginx-test1 1/1 Running 0 50s 10.244.1.49 node01 <none> <none> |
pod创建成功
7.3.8 查看pod的应用版本
curl -I 10.244.1.49
| [root@master test]# curl -I 10.244.1.49 | |
| HTTP/1.1 200 OK | |
| Server: nginx/1.14.2 | |
| #版本重设为1.14.2 | |
| Date: Thu, 04 Nov 2021 15:04:43 GMT | |
| Content-Type: text/html | |
| Content-Length: 612 | |
| Last-Modified: Tue, 04 Dec 2018 14:44:49 GMT | |
| Connection: keep-alive | |
| ETag: "5c0692e1-264" | |
| Accept-Ranges: bytes |
7.4 测试案例(循环命令)
7.4.1 修改nginx-test1.yaml
| [root@master test]# vim nginx-test1.yaml | |
| apiVersion: v1 | |
| kind: Pod | |
| metadata: | |
| name: nginx-test1 | |
| spec: | |
| containers: | |
| - name: nginx | |
| #修改镜像版本为最新版本 | |
| image: nginx | |
| #设置镜像拉取策略为IfNotPresent | |
| imagePullPolicy: IfNotPresent | |
| #设置循环命令,使得pod不会自动关闭 | |
| command: [ "sh","while true;do echo SUCCESS;done;" ] |
7.4.2 生成新的nginx-tets1.yaml配置资源
删除原有的资源
kubectl delete -f nginx-test1.yaml
| [root@master test]# kubectl delete -f nginx-test1.yaml | |
| pod "nginx-test1" deleted |
生成新的资源
kubectl apply -f nginx-test1.yaml
| [root@master test]# kubectl apply -f nginx-test1.yaml | |
| pod/nginx-test1 created |
7.4.2 查看pod状态
kubectl get pod -o wide
| [root@master test]# kubectl get pod -o wide | |
| NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES | |
| nginx-test1 0/1 CrashLoopBackOff 3 67s 10.244.1.50 node01 <none> <none> |
再次进入异常循环状态
7.4.3 查看创建过程
kubectl describe pod nginx-test1
| [root@master test]# kubectl describe pod nginx-test1 | |
| ...... | |
| Events: | |
| Type Reason Age From Message | |
| ---- ------ ---- ---- ------- | |
| Normal Scheduled 2m59s default-scheduler Successfully assigned default/nginx-test1 to node01 | |
| Normal Pulled 95s (x5 over 2m59s) kubelet, node01 Container image "nginx" already present on machine | |
| Normal Created 95s (x5 over 2m59s) kubelet, node01 Created container nginx | |
| Normal Started 95s (x5 over 2m59s) kubelet, node01 Started container nginx | |
| Warning BackOff 70s (x10 over 2m57s) kubelet, node01 Back-off restarting failed container |
发现错误发生在command步骤
7.4.4 查看pod日志
kubectl logs nginx-test1
| [root@master test]# kubectl logs nginx-test1 | |
| sh: 0: Can't open while true;do echo SUCCESS;done; |
发现是命令错误
7.4.5 再次修改nginx-test1.yaml
| [root@master test]# vim nginx-test1.yaml | |
| apiVersion: v1 | |
| kind: Pod | |
| metadata: | |
| name: nginx-test1 | |
| spec: | |
| containers: | |
| - name: nginx | |
| image: nginx | |
| imagePullPolicy: IfNotPresent | |
| #发现缺少了“-c”选项,添加后保存退出 | |
| command: [ "sh","-c","while true;do echo SUCCESS;done;" ] |
7.4.6 再次生成新的nginx-tets1.yaml配置资源
删除原有的资源
kubectl delete -f nginx-test1.yaml
| [root@master test]# kubectl delete -f nginx-test1.yaml | |
| pod "nginx-test1" deleted |
生成新的资源
kubectl apply -f nginx-test1.yaml
| [root@master test]# kubectl apply -f nginx-test1.yaml | |
| pod/nginx-test1 created |
7.4.7 再次查看pod状态
kubectl get pod -o wide
| [root@master test]# kubectl get pod -o wide | |
| NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES | |
| nginx-test1 1/1 Running 0 7s 10.244.1.51 node01 <none> <none> |
pod运行成功
7.4.8 查看创建过程
kubectl describe pod nginx-test1
| [root@master test]# kubectl describe pod nginx-test1 | |
| ...... | |
| Events: | |
| Type Reason Age From Message | |
| ---- ------ ---- ---- ------- | |
| Normal Scheduled 108s default-scheduler Successfully assigned default/nginx-test1 to node01 | |
| Normal Pulled 107s kubelet, node01 Container image "nginx" already present on machine | |
| Normal Created 107s kubelet, node01 Created container nginx | |
| Normal Started 107s kubelet, node01 Started container nginx |
由于镜像拉取策略设定的是IfNotPresent,因此kubelet会先检查本地镜像仓库,如果有对应版本镜像就直接使用,没有的话才会前往镜像仓库拉取。
7.4.9 查看pod日志
kubectl describe pod nginx-test1 | grep "Image"
| [root@master test]# kubectl describe pod nginx-test1 | grep "Image" | |
| Image: nginx | |
| Image ID: docker-pullable://nginx@sha256:644a70516a26004c97d0d85c7fe1d0c3a67ea8ab7ddf4aff193d9f301670cf36 |
8. harbor登录凭据操作
8.1 部署harbor
部署步骤详见往期博客
8.2 查看登录凭证
cat /root/.docker/config.json | base64 -w 0
node01
| [root@node01 ~]# cat /root/.docker/config.json | base64 -w 0 | |
| #base64 -w 0:进行 base64 加密并禁止自动换行 | |
| ewoJImF1dGhzIjogewoJCSJodWIudGVzdC5jb20iOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9Cn0= |
8.3 创建harbor登录凭据资源清单
master
| [root@master ~]# vim harbor-pull-secret.yaml | |
| apiVersion: v1 | |
| kind: Secret | |
| metadata: | |
| name: harbor-pull-secret | |
| data: | |
| .dockerconfigjson: ewoJImF1dGhzIjogewoJCSJodWIudGVzdC5jb20iOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9Cn0= | |
| #复制粘贴上述查看的登陆凭据 | |
| type: kubernetes.io/dockerconfigjson |
8.4 创建secret资源
kubectl create -f harbor-pull-secret.yaml
master
| [root@master test]# kubectl create -f harbor-pull-secret.yaml | |
| secret/harbor-pull-secret created |
8.5 查看secret资源
kubectl get secret
master
| [root@master test]# kubectl get secret | |
| NAME TYPE DATA AGE | |
| default-token-7lsdx kubernetes.io/service-account-token 3 3d5h | |
| harbor-pull-secret kubernetes.io/dockerconfigjson 1 2m3s |
8.6 创建资源从harbor中下载镜像
master
| [root@master test]# vim nginx-deployment.yaml | |
| apiVersion: extensions/v1beta1 | |
| kind: Deployment | |
| metadata: | |
| name: my-nginx | |
| spec: | |
| replicas: 2 | |
| template: | |
| metadata: | |
| labels: | |
| app: my-nginx | |
| spec: | |
| #添加拉取secret资源选项 | |
| imagePullSecrets: | |
| #指定secret资源名称 | |
| - name: harbor-pull-secret | |
| containers: | |
| - name: my-nginx | |
| #指定harbor中的镜像名 | |
| image: hub.test.com/library/nginx:v1 | |
| ports: | |
| - containerPort: 80 | |
| --- | |
| apiVersion: v1 | |
| kind: Service | |
| metadata: | |
| name: my-nginx | |
| spec: | |
| type: NodePort | |
| ports: | |
| - port: 8080 | |
| targetPort: 8080 | |
| nodePort: 11111 | |
| selector: | |
| app: my-nginx |
8.7 删除之前在node节点下载的nginx镜像
node01
docker rmi -f hub.test.com/library/nginx:v1
| [root@node01 ~]# docker images | |
| REPOSITORY TAG IMAGE ID CREATED SIZE | |
| nginx latest 87a94228f133 3 weeks ago 133MB | |
| hub.test.com/library/nginx v1 87a94228f133 3 weeks ago 133MB | |
| k8s.gcr.io/kube-apiserver v1.15.1 68c3eb07bfc3 2 years ago 207MB | |
| k8s.gcr.io/kube-proxy v1.15.1 89a062da739d 2 years ago 82.4MB | |
| registry.aliyuncs.com/google_containers/kube-proxy v1.15.1 89a062da739d 2 years ago 82.4MB | |
| k8s.gcr.io/kube-controller-manager v1.15.1 d75082f1d121 2 years ago 159MB | |
| k8s.gcr.io/kube-scheduler v1.15.1 b0b3c4c404da 2 years ago 81.1MB | |
| nginx 1.15 53f3fd8007f7 2 years ago 109MB | |
| nginx 1.14 295c7be07902 2 years ago 109MB | |
| wl/flannel v0.11.0-amd64 ff281650a721 2 years ago 52.6MB | |
| k8s.gcr.io/coredns 1.3.1 eb516548c180 2 years ago 40.3MB | |
| registry.aliyuncs.com/google_containers/coredns 1.3.1 eb516548c180 2 years ago 40.3MB | |
| wl/kubernetes-dashboard-amd64 v1.10.1 f9aed6605b81 2 years ago 122MB | |
| k8s.gcr.io/etcd 3.3.10 2c4adeb21b4f 2 years ago 258MB | |
| nginx 1.15.4 bc26f1ed35cf 3 years ago 109MB | |
| busybox 1.28 8c811b4aec35 3 years ago 1.15MB | |
| k8s.gcr.io/pause 3.1 da86e6ba6ca1 3 years ago 742kB | |
| registry.aliyuncs.com/google_containers/pause 3.1 da86e6ba6ca1 3 years ago 742kB | |
| [root@node01 ~]# docker rmi -f hub.test.com/library/nginx:v1 | |
| Untagged: hub.test.com/library/nginx:v1 | |
| Untagged: hub.test.com/library/nginx@sha256:7250923ba3543110040462388756ef099331822c6172a050b12c7a38361ea46f |
8.8 创建资源
master
kubectl apply -f nginx-deployment.yaml
| [root@master test]# kubectl apply -f nginx-deployment.yaml | |
| deployment.extensions/my-nginx created | |
| service/my-nginx created |
8.9 查看pod信息
master
kubectl get pods -o wide
| [root@master test]# kubectl get pods -o wide | |
| NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES | |
| my-nginx-74f9bccc8c-5z9nv 1/1 Running 0 49s 10.244.2.30 node02 <none> <none> | |
| my-nginx-74f9bccc8c-txkg9 1/1 Running 0 49s 10.244.1.52 node01 <none> <none> |
8.10 查看pod描述信息
kubectl describe pod my-nginx-74f9bccc8c-txkg9
| [root@master test]# kubectl describe pod my-nginx-74f9bccc8c-txkg9 | |
| ...... | |
| Events: | |
| Type Reason Age From Message | |
| ---- ------ ---- ---- ------- | |
| Normal Scheduled 4m38s default-scheduler Successfully assigned default/my-nginx-74f9bccc8c-txkg9 to node01 | |
| #镜像从harbor仓库中拉取而来 | |
| Normal Pulling 4m37s kubelet, node01 Pulling image "hub.test.com/library/nginx:v1" | |
| Normal Pulled 4m37s kubelet, node01 Successfully pulled image "hub.test.com/library/nginx:v1" | |
| Normal Created 4m37s kubelet, node01 Created container my-nginx | |
| Normal Started 4m37s kubelet, node01 Started container my-nginx |
kubectl describe pod my-nginx-74f9bccc8c-txkg9 | grep "Image:"
| [root@master test]# kubectl describe pod my-nginx-74f9bccc8c-txkg9 | grep "Image:" | |
| Image: hub.test.com/library/nginx:v1 |
8.11 刷新harbor页面,可以看到镜像的下载次数增加了
