问题描述
我正在使用 this yaml 文件创建部署。它创建了 4 个 busyBox pod 的副本。到这里一切都好。
但是当我使用命令 kubectl edit deployment my-dep2
编辑此部署时,仅将 busyBox 映像的版本更改为 1.31(降级但从 K8s 的角度来看仍然是更新),replicaset 并未完全替换。>
kubectl get all --selector app=my-dep2
发布编辑后的输出是:
NAME READY STATUS RESTARTS AGE
pod/my-dep2-55f67b974-5k7t9 0/1 ErrImagePull 2 5m26s
pod/my-dep2-55f67b974-wjwfv 0/1 CrashLoopBackOff 2 5m26s
pod/my-dep2-dcf7978b7-22khz 0/1 CrashLoopBackOff 6 12m
pod/my-dep2-dcf7978b7-2q5lw 0/1 CrashLoopBackOff 6 12m
pod/my-dep2-dcf7978b7-8mmvb 0/1 CrashLoopBackOff 6 12m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/my-dep2 0/4 2 0 12m
NAME DESIRED CURRENT READY AGE
replicaset.apps/my-dep2-55f67b974 2 2 0 5m27s
replicaset.apps/my-dep2-dcf7978b7 3 3 0 12m
从上面的输出可以看出,有 2 个 replicaset 并行存在。我希望旧的 replicaset 被新的 replicaset(包含 1.31 版本的 busyBox)完全取代。但这并没有发生。我在这里错过了什么?
解决方法
您忽略了错误 ErrImagePull
和 CrashLoopBackOff
。这些是在告诉您无法运行新容器(在 docker 注册表中找不到该映像),因此保留旧容器以确保服务运行(蓝绿色默认/滚动更新)。
编辑
此外,您的 Busybox 容器启动并没有运行(据我所知)然后完成,这会导致 Kubernetes 重新启动它并且永远不会到达 alive
状态。也许你最好运行一些 sleep 300
到它的入口点?
正如@emi 所说,如果您给出明确的命令,busybox 和 alpine 等不会做任何事情。 Kubernetes 尝试继续运行,但默认容器不执行任何操作,最后,Kubernetes 说好的,出了点问题,无需一次又一次地尝试重新启动容器。出于测试目的,它可能如下所示。
kind: Pod
apiVersion: v1
metadata:
name: my-test-pod
spec:
containers:
- image: nginx
name: enginx
- image: alpine
name: alpine
command: ["sleep","3600"]
,
这是完全正常的,预期的结果,与kubernetes
中的Rolling Update机制有关快速查看以下工作示例,其中我使用了 sample nginx Deployment
。部署后,我运行:
kubectl edit deployments.apps nginx-deployment
并删除了实际上等同于对 nginx:latest
执行更新的图像标记。应用更改后,您可以立即看到以下内容:
$ kubectl get all --selector=app=nginx
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-574b87c764-bvmln 0/1 Terminating 0 2m6s
pod/nginx-deployment-574b87c764-zfzmh 1/1 Running 0 2m6s
pod/nginx-deployment-574b87c764-zskkk 1/1 Running 0 2m7s
pod/nginx-deployment-6fcf476c4-88fdm 0/1 ContainerCreating 0 1s
pod/nginx-deployment-6fcf476c4-btvgv 1/1 Running 0 3s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx-deployment ClusterIP 10.3.247.159 <none> 80/TCP 6d4h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 3/3 2 3 2m7s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-574b87c764 2 2 2 2m7s
replicaset.apps/nginx-deployment-6fcf476c4 2 2 1 3s
如您所见,在某个时间点,两个副本中都有正在运行的 Pod。正是因为提到了滚动更新机制,它可以确保您的应用在更新时可用。
当更新过程结束时,旧 replicaset
中的副本计数减少到 0,因此没有正在运行的 Pod,由此 replicaset
管理,因为新的 $ kubectl get all --selector=app=nginx
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-6fcf476c4-88fdm 1/1 Running 0 10s
pod/nginx-deployment-6fcf476c4-btvgv 1/1 Running 0 12s
pod/nginx-deployment-6fcf476c4-db5z7 1/1 Running 0 8s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx-deployment ClusterIP 10.3.247.159 <none> 80/TCP 6d4h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 3/3 3 3 2m16s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-574b87c764 0 0 0 2m16s
replicaset.apps/nginx-deployment-6fcf476c4 3 3 3 12s
达到其所需状态:
$ kubectl rollout history deployment nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
您可能会问自己:为什么它仍然存在?为什么在新的准备好后没有立即删除它。请尝试以下操作:
$ kubectl rollout undo deployment nginx-deployment
deployment.apps/nginx-deployment rolled back
如您所见,我们对此次部署的部署进行了 2 次修订。所以现在我们可能只想撤消最近的更改:
$ kubectl get all --selector=app=nginx
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-574b87c764-6j7l5 0/1 ContainerCreating 0 1s
pod/nginx-deployment-574b87c764-m7956 1/1 Running 0 4s
pod/nginx-deployment-574b87c764-v2r75 1/1 Running 0 3s
pod/nginx-deployment-6fcf476c4-88fdm 0/1 Terminating 0 3m25s
pod/nginx-deployment-6fcf476c4-btvgv 1/1 Running 0 3m27s
pod/nginx-deployment-6fcf476c4-db5z7 0/1 Terminating 0 3m23s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx-deployment ClusterIP 10.3.247.159 <none> 80/TCP 6d4h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 3/3 3 3 5m31s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-574b87c764 3 3 2 5m31s
replicaset.apps/nginx-deployment-6fcf476c4 1 1 1 3m27s
现在,当我们查看我们的副本时,我们可以观察到一个相反的过程:
replicaset
注意,没有必要创建第三个 $ kubectl get all --selector=app=nginx
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-574b87c764-6j7l5 1/1 Running 0 40s
pod/nginx-deployment-574b87c764-m7956 1/1 Running 0 43s
pod/nginx-deployment-574b87c764-v2r75 1/1 Running 0 42s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx-deployment ClusterIP 10.3.247.159 <none> 80/TCP 6d4h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 3/3 3 3 6m10s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-574b87c764 3 3 3 6m10s
replicaset.apps/nginx-deployment-6fcf476c4 0 0 0 4m6s
,因为仍然有旧的可以用来撤消我们最近的更改。最终结果如下:
replicaset
我希望上面的例子能帮助您了解为什么这个旧的 </img>
没有被立即删除,以及它还有什么用处。