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页面,可以看到镜像的下载次数增加了