发布于 2026-01-06 0 阅读
0

Kubernetes 101,第四部分:部署

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


Enter fullscreen mode Exit fullscreen mode

乍一看,它的工作方式与 ReplicaSet 完全相同。让我们检查deployment一下这个对象kubectl



$ kubectl get deployments
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   2/2     2            2           11s


Enter fullscreen mode Exit fullscreen mode

输出结果显示我们有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


Enter fullscreen mode Exit fullscreen mode

请注意,与 ReplicaSet 类似,每个 Pod 在集群中都会获得一个随机的唯一 ID(分别为sk28kf25nc)。

部署资源

到目前为止,它与 ReplicaSet 完全一样,没有任何区别。现在是时候看看它们之间的差异了

更新部署

Deployment 允许在不停机的情况下进行更新。以我们的NGINX示例为例,让我们演示一个简单的更新,例如更改 Pod 中的 NGINX 版本

首先,通过进入 Deployment 中的某个 Pod 并执行以下命令来检查当前的 NGINX 版本nginx -v



$ kubectl exec -it deploy/nginx -- nginx -v
nginx version: nginx/1.23.3


Enter fullscreen mode Exit fullscreen mode

接下来,我们通过 Deployment执行以下命令来更改 Pod 镜像kubectl set image



$ kubectl set image deployment/nginx nginx=nginx:1.22.1
deployment.apps/nginx image updated


Enter fullscreen mode Exit fullscreen mode

检查 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


Enter fullscreen mode Exit fullscreen mode

然后,在所有 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


Enter fullscreen mode Exit fullscreen mode

想确认一下吗?



kubectl exec -it deploy/nginx -- nginx -v
nginx version: nginx/1.22.1


Enter fullscreen mode Exit fullscreen mode

太棒了! 🚀

奖励:发布状态

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


Enter fullscreen mode Exit fullscreen mode

Kubernetes真是太棒了不是吗

🖼️ 没图没真相

好的,有时候用图片来解释有助于更好地理解。

👉 部署控制器开始创建一个新的 Pod:

创建一个新的 pod

👉 然后,其中一个旧副本开始终止,并开始创建一个新的副本:

部署的第二步

👉 最后阶段,我们有两个新的运行副本,以及两个已终止的旧副本:

第三阶段

👉 最后,该应用程序已成功上线:

成功推出

↩️ 回滚

这种情况并不少见,当更新版本存在缺陷时,我们可能需要回滚到应用程序的早期版本。

kubectl rollout命令history用于持久化给定部署的所有 Kubernetes 版本:



$ kubectl rollout history deployment/nginx
deployment.apps/nginx
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         <none>
4         <none>


Enter fullscreen mode Exit fullscreen mode

人们自然会认为当前版本是最新版本(4),但我们可以通过以下方式进行验证kubectl describe



$ kubectl describe deployment/nginx | grep revision
Annotations:            deployment.kubernetes.io/revision: 4


Enter fullscreen mode Exit fullscreen mode

回滚到之前的版本(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


Enter fullscreen mode Exit fullscreen mode

😱 难以置信!😱 Kubernetes 中的回滚操作如此简单,我们没有任何理由在需要时不进行回滚。

为什么系统回滚如此重要

我见过很多项目在回滚方面遇到困难。有时是因为回滚流程非常复杂,有时是因为人们缺乏管理回滚的熟练程度。

许多人更喜欢使用 Git 回滚而不是应用程序回滚。

恕我直言,这是个非常错误的举动

由于冲突, Git 回滚可能很困难。回滚需要重新经过整个 CI/CD 流水线,耗时较长。在回滚被接受并部署到生产环境之前,应用程序会不断出现一些无法接受的错误

投入时间和资源建立一个完善的回滚系统。如果你在使用 Kubernetes,那就没有理由不执行回滚,自己体验一下就知道它有多么简单。

在部署中扩展副本

此外,我们可以根据部署情况增加(或减少)副本数量:



$ kubectl scale deployment/nginx --replicas=5
deployment.apps/nginx scaled


Enter fullscreen mode Exit fullscreen mode

然后检查 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


Enter fullscreen mode Exit fullscreen mode

总结

这篇文章主要关注部署以及如何在 Kubernetes 中轻松执行更新而无需停机

接下来,我们将了解如何使用StatefulSets在 Kubernetes 中管理有状态应用程序

敬请关注!

文章来源:https://dev.to/leandronsp/kubernetes-101-part-iv-deployments-20m3