一、背景
与同事在通过容器云平台(公司采购的某国内商业产品)部署某系统平台时,同事对文件做了修改并重新构建镜像但没有更改Tag。部署应用时,发现没有起效,一开始以为是容器云平台的Bug,后来感觉有可能是Kubernetes的问题,因此动手进行了验证。
二、原因分析
初步粗略判断,出问题的地方可能有:
- 1、镜像没上传成功,或者镜像仓库有问题
- 2、容器云平台的问题
- 3、kubernetes自身的镜像更新判断机制
通过查看、对比镜像 Image ID,确认镜像上传和镜像仓库均没问题。
与供应商沟通,确认若容器云平台前端界面进行修改,则相当于更新yaml文件给Kubernetes执行,中间并没有再加工处理。而同事除了更新镜像内容,还修改过启动命令,因此容器云平台也没有问题。且通过在Kubernetes集群导出应用的yaml文件,确认使用的镜像拉取策略为imagePullPolicy: IfNotPresent,即本地若有镜像则不会重新拉取。
那最后就是Kubernetes自身的镜像更新判断机制了,这个可以通过动手实验来验证下。
三、实践验证
验证思路:构建Nginx镜像,创建Pod并定义imagepullpolicy:ifNotPresent,通过修改index.html内容,来分别实现【重新构建镜像内容但不更改Tag】和【重新构建镜像内容且更改Tag】,进行验证。
- 编辑Dockersfile。主要是使用Nginx做为基础镜像,复制一个网页文件进去重新构建验证镜像。
[root@masterserver imagepullpolicy]# vi Dockerfile FROM harbor.xxx.com.cn/library/nginx:1.13.8-alpine COPY index.html /usr/share/nginx/html/
- Docker Build构建镜像
[root@masterserver imagepullpolicy]# docker build -t mynginx:1.1 . Sending build context to Docker daemon 4.096kB Step 1/2 : FROM harbor.xxx.com.cn/library/nginx:1.13.8-alpine ---> bb00c21b4edf Step 2/2 : COPY index.html /usr/share/nginx/html/ ---> be86871a6bce Successfully built be86871a6bce Successfully tagged mynginx:1.1
- 使用kubectl run –dry-run且带上imagepullpolicy参数,输出yaml文件。
[root@masterserver imagepullpolicy]# kubectl run testnginx --image=mynginx:1.1 --dry-run=client --image-pull-policy=IfNotPresent -o yaml > testnginx.yaml [root@masterserver imagepullpolicy]# cat testnginx.yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: testnginx name: testnginx spec: containers: - image: mynginx:1.1 imagePullPolicy: IfNotPresent name: testnginx resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {}
- 通过kubectl apply -f nginx.yaml,运行pod。
- 修改index.html内容,重新构建镜像但不修改tag,再重新kubectl apply。查看pod事件
[root@masterserver imagepullpolicy]# kubectl describe po mynginx Name: mynginx Namespace: default Priority: 0 Node: node1/192.168.56.104 Start Time: Wed, 05 Aug 2020 11:02:41 +0800 Labels: run=mynginx Annotations: Status: Running IP: 10.244.1.12 IPs: IP: 10.244.1.12 Containers: mynginx: Container ID: docker://6aebe0a359144afa5cd9da4e04d8837e62d7c26118b64933d4b71af50cab07f2 Image: harbor.xxx.com.cn/test_dmgtest/mynginx:1.1 Image ID: docker-pullable://harbor.xxx.com.cn/test_dmgtest/mynginx@sha256:09a2064d81e1ffbb9c126320d5a3c1173585969da9160e26559bbb777ba2ed4d Port: <none> Host Port: <none> State: Running Started: Wed, 05 Aug 2020 11:04:07 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-768sh (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-768sh: Type: Secret (a volume populated by a Secret) SecretName: default-token-768sh Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned default/mynginx to node1 Normal Pulling 34s (x3 over 78s) kubelet, node1 Pulling image "harbor.infinitus.com.cn/test_dmgtest/mynginx:1.1" Normal Pulled <invalid> kubelet, node1 Container image "harbor.xxx.com.cn/test_dmgtest/mynginx:1.1" already present on machine Normal Created <invalid> kubelet, node1 Created container mynginx Normal Started <invalid> kubelet, node1 Started container mynginx
在pod事件中,可以看到 【Container image "harbor.xxx.com.cn/test_dmgtest/mynginx:1.1" already present on machine 】。
而通过Docker images,可以查看image id是两个不同的id。
四、结论
通过实践验证,可以得出结论:当pod定义了imagepullpolicy: IfNotPresent,判断运行pod的node本地有没有镜像。进一步,这个判断机制Kubernetes原生是这样设置的:会根据tag来判断,而不是根据sha id来判断。
所以即使镜像内容变化重新构建镜像但Tag没有更改的话,kubernetes是不会去重新拉取镜像的。