Kubernetes 101,第四部分:部署
在第三部分中,我们更进一步,学习了 Kubernetes 如何通过利用ReplicaSet等工作负载资源,使用控制器模式来实现自我修复功能。
然而,众所周知,大多数应用程序都需要经常更新。
副本集仅适用于不需要不断更新/部署的应用程序。几乎在所有情况下,我们都需要 Kubernetes 提供的另一个工作负载资源对象:部署对象。
🚀 部署
Kubernetes Deployment 对象引入了一个Deployment Controller,其行为类似于ReplicaSet Controller,但除此之外,它还允许各种更新策略,因此应用程序不会遭受任何停机时间。
创建部署
我们将遵循与ReplicaSet相同的流程,但引用方式kind: Deployment有所不同:
kind: Deployment
apiVersion: apps/v1
metadata:
name: nginx
labels:
app: nginx
spec:
### The number of replicas of the same identical Pod
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
乍一看,它的工作方式与 ReplicaSet 完全相同。让我们检查deployment一下这个对象kubectl:
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 2/2 2 2 11s
输出结果显示我们有2 个副本(Pod)已准备就绪。
检查舱体:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-76d6c9b8c-sk28k 1/1 Running 0 7s
nginx-76d6c9b8c-f25nc 1/1 Running 0 7s
请注意,与 ReplicaSet 类似,每个 Pod 在集群中都会获得一个随机的唯一 ID(分别为sk28k和f25nc)。
到目前为止,它与 ReplicaSet 完全一样,没有任何区别。现在是时候看看它们之间的差异了。
更新部署
Deployment 允许在不停机的情况下进行更新。以我们的NGINX示例为例,让我们演示一个简单的更新,例如更改 Pod 中的 NGINX 版本。
首先,通过进入 Deployment 中的某个 Pod 并执行以下命令来检查当前的 NGINX 版本nginx -v:
$ kubectl exec -it deploy/nginx -- nginx -v
nginx version: nginx/1.23.3
接下来,我们通过 Deployment执行以下命令来更改 Pod 镜像kubectl set image:
$ kubectl set image deployment/nginx nginx=nginx:1.22.1
deployment.apps/nginx image updated
检查 Pod,我们可以看到新的 Pod 正在创建,而当前的 Pod 仍在运行。
因此,应用程序已启动并运行,没有停机时间!
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-76d6c9b8c-sk28k 1/1 Running 0 14m
nginx-76d6c9b8c-f25nc 1/1 Running 0 14m
nginx-756fbff4c9-t2pjb 0/1 ContainerCreating 0 8s
然后,在所有 Pod 都成功更新后:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-756fbff4c9-t2pjb 1/1 Running 0 19s
nginx-756fbff4c9-44g6w 1/1 Running 0 8s
想确认一下吗?
kubectl exec -it deploy/nginx -- nginx -v
nginx version: nginx/1.22.1
太棒了! 🚀
奖励:发布状态
kubectl提供一个名为的命令rollout status,可在部署期间使用,因此该命令会一直阻塞,直到部署完成。
它在CI/CD 系统中非常有用:
### Update the image
$ kubectl set image deployment/nginx nginx=nginx:1.23.1
deployment.apps/nginx image updated
### Check the rollout deployment (blocks until it is finished)
$ kubectl rollout status deployment/nginx
Waiting for deployment "nginx" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
deployment "nginx" successfully rolled out
### Checking the NGINX version
$ kubectl exec -it deploy/nginx -- nginx -v
nginx version: nginx/1.23.1
Kubernetes真是太棒了,不是吗?
🖼️ 没图没真相
好的,有时候用图片来解释有助于更好地理解。
👉 部署控制器开始创建一个新的 Pod:
👉 然后,其中一个旧副本开始终止,并开始创建一个新的副本:
👉 最后阶段,我们有两个新的运行副本,以及两个已终止的旧副本:
👉 最后,该应用程序已成功上线:
↩️ 回滚
这种情况并不少见,当更新版本存在缺陷时,我们可能需要回滚到应用程序的早期版本。
该kubectl rollout命令history用于持久化给定部署的所有 Kubernetes 版本:
$ kubectl rollout history deployment/nginx
deployment.apps/nginx
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
4 <none>
人们自然会认为当前版本是最新版本(4),但我们可以通过以下方式进行验证kubectl describe:
$ kubectl describe deployment/nginx | grep revision
Annotations: deployment.kubernetes.io/revision: 4
回滚到之前的版本(3)怎么样?
## Rollback to the previous version
$ kubectl rollout undo deployment/nginx
deployment.apps/nginx rolled back
### Or simply going to a specific version
$ kubectl rollout undo deployment/nginx --to-revision=3
### Follow the deployment
$ kubectl rollout status deployment/nginx
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
deployment "nginx" successfully rolled out
### Check the NGINX version
$ kubectl exec -it deploy/nginx -- nginx -v
nginx version: nginx/1.23.3
😱 难以置信!😱 Kubernetes 中的回滚操作如此简单,我们没有任何理由在需要时不进行回滚。
为什么系统回滚如此重要
我见过很多项目在回滚方面遇到困难。有时是因为回滚流程非常复杂,有时是因为人们缺乏管理回滚的熟练程度。
许多人更喜欢使用 Git 回滚而不是应用程序回滚。
恕我直言,这是个非常错误的举动。
由于冲突, Git 回滚可能很困难。回滚需要重新经过整个 CI/CD 流水线,耗时较长。在回滚被接受并部署到生产环境之前,应用程序会不断出现一些无法接受的错误。
投入时间和资源建立一个完善的回滚系统。如果你在使用 Kubernetes,那就没有理由不执行回滚,自己体验一下就知道它有多么简单。
在部署中扩展副本
此外,我们可以根据部署情况增加(或减少)副本数量:
$ kubectl scale deployment/nginx --replicas=5
deployment.apps/nginx scaled
然后检查 Pods:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-799c5dd65b-5ncg2 1/1 Running 0 4m12s
nginx-799c5dd65b-qm2vb 1/1 Running 0 4m8s
nginx-799c5dd65b-pfngc 1/1 Running 0 8s
nginx-799c5dd65b-w49q4 1/1 Running 0 8s
nginx-799c5dd65b-ph6wv 1/1 Running 0 8s
总结
这篇文章主要关注部署以及如何在 Kubernetes 中轻松执行更新而无需停机。
接下来,我们将了解如何使用StatefulSets在 Kubernetes 中管理有状态应用程序。
敬请关注!
文章来源:https://dev.to/leandronsp/kubernetes-101-part-iv-deployments-20m3




