当前位置: 首页 > news >正文

使用Deployment运行无状态应用

使用Deployment运行无状态应用

文章目录

  • 使用Deployment运行无状态应用
    • @[toc]
    • 一、工作负载资源与控制器
    • 二、ReplicationController、ReplicaSet和Deployment
      • 1. ReplicationController(已淘汰)
      • 2. ReplicaSet(ReplicationController 的增强版)
      • 3. Deployment(管理 ReplicaSet 的高级抽象)
    • 三、Deployment的应用场景
      • 1.无状态服务的标准化部署
      • 2.持续交付与滚动更新
      • 3.弹性伸缩与负载均衡
      • 4.多版本发布策略
      • 5.临时任务与测试环境管理
    • 四、Deployment的基本用法
    • 五、创建Deployment
      • 1.编写Deployment配置文件
      • 2.基于配置文件创建Deployment
      • 3.测试Deployment及其部署的应用程序
    • 六、测试Deployment的自我修复功能
    • 七、更新Deployment
    • 八、回滚Deployment
    • 九、暂停、恢复Deployment的更新
    • 十、扩缩容Deployment

Pod本身并不能自愈,一个Pod所在的节点发生故障,Pod将被删除;节点资源不够或需要进行维护时,Pod也会从节点上被驱逐,从而被删除。为此,Kubernetes引入控制器来管理Pod副本。管理员很少会直接创建一个Pod,大多数情况下会通过控制器完成对一组Pod的创建、调度及全生命周期的自动管控任务。Deployment时常用的控制器,适合用来管理集群中的无状态应用程序。

一、工作负载资源与控制器

Pod只能管理自身,直接创建的Pod是一种自主式Pod,一旦删除就不会自动重建,没有自我修复功能。Pod具有确定的生命周期,如果运行Pod的节点发生致命错误,则该节点上的所有Pod的状态都会失效,即使该节点后来恢复正常运行,也需要管理员重新创建新的Pod以恢复应用程序。当集群中有大量Pod时,或者同一个Pod有多个副本时,人工监控和管理每个Pod会变得极其困难。为此,Kubernetes在Pod的基础之上,引入工作负载资源来帮助用户统一管理一组Pod。

工作负载资源自动实时监控和管理指派给它的Pod,并确保处于运行状态的Pod的数量是正确的,Pod的状态与用户所期望的保持一致,如果出现异常,则会自动修复。

考虑到不同的应用程序具有不同的特征,为满足不同业务场景需求,Kubernetes提供多种类型的内置工作负载资源

资源类型功能
Deployment管理集群中的无状态应用程序,如Web服务
StatefulSet管理集群中的有状态应用程序,如MongoDB
DaemonSet管理集群中的守护进程集,确保所有节点运行同一个Pod,如日志收集组件
Job运行一次性任务
CronJob运行周期性任务

除了Kubernetes内置的工作负载资源类型,管理员还可以通过使用定制资源定义,添加第三方工作负载资源。

这些工作负载资源具体是通过配置控制器来实现的。控制器用于工作负载资源的部署和管理,在更高层次上部署和管理Pod,因此又称为Pod控制器。Kubernetes的许多重要特性都是依靠控制器来实现的。

控制器功能

  • 管理Pod对象。
  • 使用标签与Pod关联。
  • 实现Pod的运维。

二、ReplicationController、ReplicaSet和Deployment

在 Kubernetes 中,ReplicationControllerReplicaSetDeployment 是用于管理 Pod 副本的控制器,它们通过不同层级的抽象实现应用的高可用性和更新管理。以下是三者的核心关系和区别:


1. ReplicationController(已淘汰)

  • 核心作用:确保指定数量的 Pod 副本始终运行(如保证 3 个副本)。
  • 工作原理
    • 持续监控 Pod 数量,若实际副本数少于期望值(如 Pod 崩溃),自动创建新 Pod。
    • 仅支持简单的等值标签选择器(例如 app=nginx),无法匹配复杂标签规则。
  • 缺点
    • 更新机制笨拙:直接替换所有旧 Pod,导致服务中断。
    • 无法实现滚动更新、版本回滚等高级操作。
  • 现状:已被 ReplicaSet 取代,仅用于旧版本兼容。

2. ReplicaSet(ReplicationController 的增强版)

  • 核心改进
    • 支持集合标签选择器matchExpressions),例如 app in (nginx, web)env notin (prod)
    • 可配合 Deployment 实现滚动更新,但仍需手动管理更新过程。
  • 典型用途
    • 作为 Deployment 的底层实现,一般不直接操作。
    • 直接使用时适用于需要精细控制 Pod 标签的场景。
  • 局限性
    • 无法自动管理更新历史,需手动维护新旧 ReplicaSet。
    • 缺少版本回滚等高级功能。

3. Deployment(管理 ReplicaSet 的高级抽象)

  • 核心功能
    • 通过声明式配置(如定义副本数、镜像版本)管理应用。
    • 滚动更新:逐步替换旧 Pod(例如先启动新 Pod,再终止旧 Pod),确保服务不中断。
    • 版本回滚:保留历史 ReplicaSet,随时回退到任意旧版本。
    • 自动扩缩容:结合 Horizontal Pod Autoscaler(HPA)动态调整副本数。
  • 工作原理
    • 每次更新(如修改镜像版本)会创建新的 ReplicaSet,并逐步迁移 Pod。
    • 旧 ReplicaSet 保留以便快速回滚。
  • 典型用途:管理无状态应用(如 Web 服务、API 服务),是 Kubernetes 中最常用的工作负载资源。

三者的层级关系

Deployment (管理者)
│
└─ ReplicaSet 1 (管理 v1 版本的 Pod)└─ Pod 1, Pod 2, Pod 3
│
└─ ReplicaSet 2 (管理 v2 版本的 Pod)└─ Pod 4, Pod 5, Pod 6
  • Deployment 控制多个 ReplicaSet(每个对应一个应用版本)。
  • ReplicaSet 控制多个 Pod(确保副本数符合期望)。

关键区别总结

特性ReplicationControllerReplicaSetDeployment
标签选择器等值匹配(=集合匹配(In/NotIn继承 ReplicaSet 的选择器
更新策略全量替换手动滚动更新自动滚动更新
版本回滚不支持不支持支持
使用场景旧系统兼容直接控制 Pod 标签无状态应用管理
推荐程度已淘汰间接使用首选方案
  • ReplicationController 是过时的副本控制器,ReplicaSet 是其升级版,而 Deployment 通过封装 ReplicaSet 提供了声明式更新、版本控制等高级功能,是管理无状态应用的终极工具。
    直接使用 Deployment 即可,无需手动操作 ReplicaSet 或 ReplicationController。

三、Deployment的应用场景

在 Kubernetes 中,Deployment 是管理无状态应用的核心工作负载资源,其设计目标是通过声明式配置实现应用的自动化部署、更新和扩展。以下是 Deployment 的典型应用场景及技术细节,结合多个来源的搜索结果整理:


1.无状态服务的标准化部署

核心场景
Deployment 适用于运行无状态应用,这类应用的特点是每个实例(Pod)功能相同、无持久化数据依赖,且实例可随时被替换或重建。
典型用例

  • Web 服务器:如 Nginx、Apache 等,通过 Deployment 快速部署多个副本以应对高并发请求。
  • API 服务:微服务架构中的后端服务(如 RESTful API),通过副本扩展提升吞吐量。
  • 数据处理管道:如批处理任务的前置服务,利用 Deployment 动态调整资源。

技术优势

  • 副本一致性:通过 ReplicaSet 确保指定数量的 Pod 始终运行。
  • 轻量级替换:Pod 故障时自动重建,无需手动干预。

2.持续交付与滚动更新

核心场景
在持续集成/持续交付(CI/CD)流程中,Deployment 支持零停机更新和版本回滚,适用于频繁迭代的敏捷开发环境。
典型用例

  • 镜像版本升级:例如从 nginx:1.14 升级到 nginx:1.20,Deployment 逐步替换旧 Pod,确保服务不中断。
  • 配置热更新:修改环境变量或资源限制后,自动触发滚动更新。

技术优势

  • 滚动更新策略:分批次创建新 Pod 并终止旧 Pod,默认更新速率为 25% 的 Pod 同时替换。
  • 版本历史记录:保留旧 ReplicaSet 的配置,支持快速回退到任意历史版本(通过 kubectl rollout undo)。

3.弹性伸缩与负载均衡

核心场景
结合 Horizontal Pod Autoscaler (HPA),Deployment 可根据 CPU、内存等指标自动扩缩容,应对流量波动。
典型用例

  • 流量高峰应对:电商大促期间自动扩展 Web 服务副本数。
  • 资源优化:低峰期减少副本数量以节省计算资源。

技术实现

  • 动态调整副本数:通过 kubectl scale 或 YAML 定义 replicas 字段手动调整。
  • HPA 集成:定义自动扩缩规则(如 CPU 使用率超过 80% 时扩容)。

4.多版本发布策略

核心场景
Deployment 支持蓝绿部署金丝雀发布,降低新版本上线风险。
典型用例

  • 蓝绿部署:创建两个独立的 Deployment(旧版本和新版本),通过 Service 切换流量。
  • 金丝雀发布:逐步将少量流量导向新版本 Pod,验证稳定性后再全量切换。

技术实现

  • 多 Deployment 共存:通过标签选择器区分不同版本的应用。
  • 流量权重控制:结合 Istio 或 Kubernetes Service 的流量分配策略实现精细化控制。

5.临时任务与测试环境管理

核心场景
快速创建和销毁临时环境,用于测试、预发布或实验性功能验证。
典型用例

  • 开发测试环境:为每个开发分支创建独立的 Deployment,模拟生产环境。
  • A/B 测试:同时运行不同版本的 Deployment,收集用户行为数据。

技术优势

  • 快速部署:通过 YAML 模板一键创建完整应用栈。
  • 环境隔离:利用命名空间(Namespace)隔离不同环境的资源。

总结与选型建议

Deployment 是 Kubernetes 中无状态应用管理的黄金标准,其核心价值在于通过声明式配置实现自动化运维。
适用条件

  • 应用无状态(无持久化数据依赖)
  • 需要高可用性、弹性伸缩或频繁更新
  • 需支持版本回退或多版本发布

不适用场景

  • 有状态应用(如数据库):需改用 StatefulSet。
  • 节点级守护进程(如日志收集):需使用 DaemonSet。

通过合理选择 Deployment 的配置策略(如滚动更新速率、HPA 规则),可以显著提升应用的可靠性和运维效率。


四、Deployment的基本用法

直接使用命令,这种方式一般只用于测试,实际应用中主要使用配置文件来创建Deployment。

kubectl create deployment 名称 --image=镜像 [选项]

创建一个YAML格式的Deployment资源定义文件。

使用kubectl create或kubectl apply命令基于该文件创建资源。

kubectl create deployment webserver --image=nginx --dry-run=client -o yaml

可以使用“干跑”(dry-run)模式生成一个Deployment的YAML格式的原始配置,然后在此配置上进行定制修改参数

五、创建Deployment

nginx是一个高性能的HTTP和反向代理Web服务器,属于无状态应用程序。

1.编写Deployment配置文件

与其他Kubernetes对象的定义一样,Deployment配置文件中需要apiVersion、kind、metadata和spec字段。spec字段中只有template和selector这两个子字段是必需的。template字段定义Pod模板,与Pod定义的语法规则完全相同,由于它是嵌套的,其中不需要再定义apiVersion或kind字段。selector字段定义Deployment资源如何查找要管理的Pod,可以选择在Pod模板中定义的标签,还可以定义更复杂的选择规则,前提是Pod模板本身能够满足所定义的规则。注意,不要直接创建与此规则匹配的Pod。

spec字段中常用的可选子字段有replicas和strategy。replicas指定期望的Pod副本数,默认值是1。strategy指定新旧Pod替换的策略。

[root@master ~]# vim nginx-deploy.yaml
[root@master ~]# cat nginx-deploy.yaml 
apiVersion: apps/v1                # 版本号
kind: Deployment                   # 类型为Deployment
metadata:                          # 元数据name: nginx-deploy          labels:                          # 标签app: nginx
spec:                              # 详细信息replicas: 3                      # 副本数量strategy:                        # 策略type: RollingUpdate            # 滚动更新策略rollingUpdate:          	   # 滚动更新设置maxSurge: 25%        		   # 更新过程中允许超出期望Pod副本数的Pod数量,用百分比或整数表示maxUnavailable: 25% 		   # 更新过程中不可用的Pod数量上限,用百分比或整数表示selector:                        # 选择器,指定该控制器管理哪些PodmatchLabels:                   # 匹配规则app: nginxtemplate:                        # 定义模板,当副本数量不足时会根据模板定义创建Pod副本metadata:labels:app: nginx                 # Pod的标签spec:containers:                  # 容器列表(本例仅定义一个容器)- name: nginx                # 容器的名称image: nginx:1.14.2        # 容器所用的镜像ports:- containerPort: 80        # 容器需要暴露的端口

本例创建名为nginx-deploy(由.metadata.name字段指定)的Deployment,需要运行3个Pod副本(由.spec.replicas字段定义)。

2.基于配置文件创建Deployment

创建Kubernetes对象时可以使用kubectl create命令,也可以使用kubectl apply命令。使用kubectl create命令创建新的资源时,如果再次运行该命令则会出现错误,因为资源名称在名称空间中应该是唯一的。kubectl apply命令将配置文件应用于资源,如果资源不存在,那么它将被创建,否则该命令将配置文件应用于现有资源。如果基于单个文件创建资源,两者基本相同。但是,kubectl apply命令还可以用于基于多个文件同时创建和修复资源。

本例使用kubectl apply命令创建Deployment。

[root@master ~]# kubectl apply -f nginx-deploy.yaml 
deployment.apps/nginx-deploy created

结果显示Deployment已成功创建,应用程序成功上线。

3.测试Deployment及其部署的应用程序

(1)执行以下命令检查该Deployment的状态。

[root@master ~]# kubectl get deployments -o wide
NAME           READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES         SELECTOR
nginx-deploy   3/3     3            3           93s   nginx        nginx:1.14.2   app=nginx

这里使用-o wide选项以输出额外的信息。Deployment各字段的说明如下:

  • NAME:集群中Deployment的名称。
  • READY:应用程序的可用副本数。显示模式是“可用副本数/期望副本数”。期望副本数由.spec.replicas字段设置。虽然Deployment已成功创建,但是部署Pod副本有一个过程,刚开始时还没有一个成功部署的副本。
  • UP-TO-DATE:为达期望状态已经更新的副本数。
  • AVAILABLE:可供用户使用的应用程序副本数。
  • AGE:应用程序运行的时间。
  • CONTAINERS:应用程序运行的容器。
  • IMAGES:容器所用的镜像。
  • SELECTOR:Deployment的选择规则。

(2)执行以下命令检查该Deployment的当前部署状态,也就是上线状态。

[root@master ~]# kubectl rollout status deployment/nginx-deploy
deployment "nginx-deploy" successfully rolled out

结果表明应用程序已成功部署。

(3)再次检查该Deployment的状态。

[root@master ~]# kubectl get deployment -o wide
NAME           READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES         SELECTOR
nginx-deploy   3/3     3            3           12m   nginx        nginx:1.14.2   app=nginx

结果表明已经创建3个副本,并且所有副本都是最新且可用的。

(4)执行以下命令查看Deployment创建的ReplicaSet。

[root@master ~]# kubectl get rs
NAME                      DESIRED   CURRENT   READY   AGE
nginx-deploy-86dcfdf4c6   3         3         3       14m

Deployment控制器并不直接管理Pod,而是通过管理ReplicaSet来间接管理Pod。

此处显示的ReplicaSet各字段的说明如下:

  • NAME:ReplicaSet的名称。
  • DESIRED:显示期望的应用程序副本数,即在创建Deployment时所定义的值。
  • CURRENT:显示当前运行状态中的应用程序副本数。
  • READY:显示有多少个应用程序副本可以为用户提供服务。
  • AGE:显示应用程序已经运行的时间。

本例创建3个ReplicaSet,ReplicaSet的名称是自动生成的,格式为“Deployment名称-哈希值”。其中的哈希(Hash)值是根据Pod模板标签(pod-template-hash)生成的,该标签会被添加到Deployment所创建的每个ReplicaSet中,可确保Deployment的ReplicaSet不重叠。

(5)查看Deployment创建的Pod。

[root@master ~]# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
nginx-deploy-86dcfdf4c6-4729k   1/1     Running   0          21m   10.244.166.154   node1   <none>           <none>
nginx-deploy-86dcfdf4c6-66dcp   1/1     Running   0          21m   10.244.166.155   node1   <none>           <none>
nginx-deploy-86dcfdf4c6-mxvwx   1/1     Running   0          21m   10.244.104.8     node2   <none>           <none>

可以发现,本例创建了3个Pod,分别在node01和node02两个节点上运行。Pod名称也是自动生成的,由ReplicaSet名称和自动产生的哈希值组成。

(6)访问nginx应用程序进行实际测试。

每个Pod都分配了IP地址,可以通过其发布的端口来访问。本例部署的是HTTP服务,发布的是默认的端口80,可以使用每个Pod的IP地址来访问。

[root@master ~]# curl http://10.244.166.154
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>body {width: 35em;margin: 0 auto;font-family: Tahoma, Verdana, Arial, sans-serif;}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>

还可以根据需要执行以下命令查看该Deployment的详细信息。

[root@master ~]# kubectl describe deployment nginx-deploy
Name:                   nginx-deploy
Namespace:              default
CreationTimestamp:      Thu, 03 Apr 2025 21:01:24 +0800
Labels:                 app=nginx
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=nginx
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:Labels:  app=nginxContainers:nginx:Image:        nginx:1.14.2Port:         80/TCPHost Port:    0/TCPEnvironment:  <none>Mounts:       <none>Volumes:        <none>
Conditions:Type           Status  Reason----           ------  ------Available      True    MinimumReplicasAvailableProgressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx-deploy-86dcfdf4c6 (3/3 replicas created)
Events:Type    Reason             Age   From                   Message----    ------             ----  ----                   -------Normal  ScalingReplicaSet  26m   deployment-controller  Scaled up replica set nginx-deploy-86dcfdf4c6 to 3

如果Deployment创建不成功,可以通过查看事件信息来查找原因。


六、测试Deployment的自我修复功能

Deployment具有自我修复功能,下面在上述实验的基础上测试该功能。

(1)将node01主机关机以模拟故障。

[root@node1 ~]# poweroff

(2)稍等片刻,查看Deployment部署的ReplicaSet,可以发现只有1个ReplicaSet正常运行(READY值为1),node01节点上的ReplicaSet暂时不能提供服务。

[root@master ~]# kubectl get rs
NAME                      DESIRED   CURRENT   READY   AGE
nginx-deploy-86dcfdf4c6   3         3         1       30m

(3)稍等一会,再次查看ReplicaSet,可以发现已经恢复为3个ReplicaSet正常运行(READY值为3)。

[root@master ~]# kubectl get rs
NAME                      DESIRED   CURRENT   READY   AGE
nginx-deploy-86dcfdf4c6   3         3         3       35m

(4)进一步查看Deployment部署的Pod。

[root@master ~]# kubectl get pods -o wide
NAME                            READY   STATUS        RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
nginx-deploy-86dcfdf4c6-4729k   1/1     Terminating   0          35m   10.244.166.154   node1   <none>           <none>
nginx-deploy-86dcfdf4c6-66dcp   1/1     Terminating   0          35m   10.244.166.155   node1   <none>           <none>
nginx-deploy-86dcfdf4c6-hbsfc   1/1     Running       0          17s   10.244.104.10    node2   <none>           <none>
nginx-deploy-86dcfdf4c6-kms6l   1/1     Running       0          17s   10.244.104.9     node2   <none>           <none>
nginx-deploy-86dcfdf4c6-mxvwx   1/1     Running       0          35m   10.244.104.8     node2   <none>           <none>

可以发现,node01节点上的Pod副本正常被终止运行,而node02节点上自动增加了新的Pod副本。

(5)启动node01主机以模拟故障恢复。稍等片刻,再次查看Pod副本,会发现3个副本仍然都在node02节点上运行,这表明Deployment完成了资源的自动修复,始终保持Pod副本数符合期望值,但是并不会将Pod恢复到原有节点上。

[root@master ~]# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP              NODE    NOMINATED NODE   READINESS GATES
nginx-deploy-86dcfdf4c6-hbsfc   1/1     Running   0          4m16s   10.244.104.10   node2   <none>           <none>
nginx-deploy-86dcfdf4c6-kms6l   1/1     Running   0          4m16s   10.244.104.9    node2   <none>           <none>
nginx-deploy-86dcfdf4c6-mxvwx   1/1     Running   0          39m     10.244.104.8    node2   <none>           <none>

七、更新Deployment

通过Deployment部署应用程序后,拖过Deployment配置文件被更改,或者镜像版本发送更迭,则可以更新或升级Deployment。注意,仅当Deployment的Pod模板定义(.spec.template字段)发生改变时,如模板的标签或容器镜像被更改,才会触发Deployment的更新,其他修改(如增减副本数)并不会触发更新。

Deployment定义的.spec.strategy.type字段值决定两种更新方式:

一种是Recreate,表示重新创建,即在创建新的pod之前,终止所有现有的pod,待这些pod被重新移除之后,才会创建新版本的Pod;

另一种是RollingUpdate,即滚动更新,这是默认设置。采用滚动更新方式时,可以定义maxUnavaiable和maxSurge字段来控制滚动更新过程。maxUnavailable指定滚动更新时允许不可用的Pod数量上限,可以用绝对数表示;也可以用百分比表示,指不可用的Pod副本数与所期望的Pod副本数的比例,值越小,越能保证服务稳定,更新越平滑。maxSurge指定滚动更新时可以创建的超出期望的Pod数量,可以用绝对数表示;也可以用百分比表示,指允许可用的Pod副本数与所期望的Pod副本数的比例,值越大,更新速度越快。这两者的默认值均为25%。

下面在前面例子的基础上示范升级容器镜像的更新操作。

(1)执行以下命令将运行nginx的Pod所使用的镜像升级为nginx:1.16.1。

[root@master ~]# kubectl set image deployment.v1.apps/nginx-deploy nginx=nginx:1.16.1
deployment.apps/nginx-deploy image updated

结果表明改Deployment的镜像已被更新。上述命令也可改用以下用法(采用Deployment的另一种标识)。

kubectl set image deployment/nginx-deploy nginx=nginx:1.16.1

我们还可以使用kubectl edit命令打开Deployment配置文件的编辑界面(如kubectl edit deployment/nginx-deploy),完成Pod模板定义的修改后,自动触发Deployment更新。

[root@master ~]# kubectl edit deployment/nginx-deploy

(2)执行以下命令查看改Deployment的更新状态(过程)。

[root@master ~]# kubectl rollout status deployment/nginx-deploy
deployment "nginx-deploy" successfully rolled out

更新过程中会发生新旧交替,创建新的副本,终止旧的副本。

(3)执行以下命令查看Deployment创建的ReplicaSet。

[root@master ~]# kubectl get rs
NAME                      DESIRED   CURRENT   READY   AGE
nginx-deploy-848dd6cfb5   3         3         3       12m
nginx-deploy-86dcfdf4c6   0         0         0       73m

可以发现,更新Deployment的过程中,创建新的ReplicaSet并将其扩容到3个副本,并将旧的ReplicaSet缩容到0个副本。

(4)执行以下命令查看Deployment资源更新之后新创建的Pod。

[root@master ~]# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP               NODE    NOMINATED NODE   READINESS GATES
nginx-deploy-848dd6cfb5-6hsxz   1/1     Running   0          9m53s   10.244.104.11    node2   <none>           <none>
nginx-deploy-848dd6cfb5-6v49j   1/1     Running   0          8m40s   10.244.166.157   node1   <none>           <none>
nginx-deploy-848dd6cfb5-86ktn   1/1     Running   0          14m     10.244.166.156   node1   <none>           <none>

可以发现,原有的Pod被终止并被删除了,新的Pod重新部署到node01和node02节点上。

(5)执行命令查看该Deployment的详细信息。

[root@master ~]# kubectl describe deployment nginx-deploy
kubectl describe deployment nginx-deploy
Name:                   nginx-deploy
Namespace:              default
CreationTimestamp:      Thu, 03 Apr 2025 21:01:24 +0800
Labels:                 app=nginx
Annotations:            deployment.kubernetes.io/revision: 2
Selector:               app=nginx
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:Labels:  app=nginxContainers:nginx:Image:        nginx:1.16.1Port:         80/TCPHost Port:    0/TCPEnvironment:  <none>Mounts:       <none>Volumes:        <none>
Conditions:Type           Status  Reason----           ------  ------Available      True    MinimumReplicasAvailableProgressing    True    NewReplicaSetAvailable
OldReplicaSets:  nginx-deploy-86dcfdf4c6 (0/0 replicas created)
NewReplicaSet:   nginx-deploy-848dd6cfb5 (3/3 replicas created)
Events:Type    Reason             Age   From                   Message----    ------             ----  ----                   -------Normal  ScalingReplicaSet  17m   deployment-controller  Scaled up replica set nginx-deploy-848dd6cfb5 to 1Normal  ScalingReplicaSet  12m   deployment-controller  Scaled down replica set nginx-deploy-86dcfdf4c6 to 2 from 3Normal  ScalingReplicaSet  12m   deployment-controller  Scaled up replica set nginx-deploy-848dd6cfb5 to 2 from 1Normal  ScalingReplicaSet  10m   deployment-controller  Scaled down replica set nginx-deploy-86dcfdf4c6 to 1 from 2Normal  ScalingReplicaSet  10m   deployment-controller  Scaled up replica set nginx-deploy-848dd6cfb5 to 3 from 2Normal  ScalingReplicaSet  10m   deployment-controller  Scaled down replica set nginx-deploy-86dcfdf4c6 to 0 from 1

滚动更新过程详解

启动新版本 Pod(nginx-deploy-848dd6cfb5):

17 分钟前:
新的副本集(ReplicaSet,即 nginx-deploy-848dd6cfb5)被创建,并启动 1 个新版本的 Pod。这是更新的初始阶段。

逐步替换旧版本 Pod:

12 分钟前:

缩减旧版本:旧的副本集(nginx-deploy-86dcfdf4c6)从 3 个 Pod 缩容到 2 个 Pod。
扩展新版本:新副本集的 Pod 数量从 1 个扩容到 2 个。
此时新旧版本共存,总 Pod 数保持为 4(2 旧 + 2 新),确保服务不中断。

继续替换直至完成:

10 分钟前:

再次缩减旧版本:旧副本集从 2 个 Pod 缩容到 1 个 Pod。
扩展新版本:新副本集的 Pod 数量从 2 个扩容到 3 个。
此时新旧版本共存,总 Pod 数保持为 4(1 旧 + 3 新)。

彻底淘汰旧版本:

10 分钟前(与上一步同一时间):

旧副本集最后一个 Pod 被终止(从 1 个缩容到 0 个)。
新副本集的 Pod 数量保持为 3 个,完全接管流量。


八、回滚Deployment

如果发现更新后的版本运行不稳定,或配置不合理,则可以回滚Deployment。默认情况下,Deployment的所有更新记录都保留在系统中,以便可以随时回滚。下面在前面的例子的基础上示范回滚操作。

用户可以在Deployment配置文件中使用.spec.revisionHistoryLimit字段指定可保留的ReplicaSet的个数,默认为10,多余的ReplicaSet将被清理。这是实现回滚的基础。如果将此字段值设置为0,将导致Deployment的所有历史记录被清空,Deployment也就无法实现回滚。

(1)执行以下命令检查Deployment的修订版本历史。

[root@master ~]# kubectl rollout history deployment/nginx-deploy
deployment.apps/nginx-deploy 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

此命令用于显示每次部署的版本号。CHANGE-CAUSE字段值是从Deployment的kubernetes.io/change-cause注解中复制过来的,创建修订版本时会自动记录。例如,用户可以通过以下方式设置CHANGE-CAUSE消息,以便为Deployment添加注解。

[root@master ~]# kubectl annotate deployment/nginx-deploy kubernetes.io/change-cause="image updated to 1.16.1"
deployment.apps/nginx-deploy annotated

(2)执行以下命令查看指定版本的详细信息(–revision选项指定版本号)。

[root@master ~]# kubectl rollout history deployment/nginx-deploy --revision=2
deployment.apps/nginx-deploy with revision #2
Pod Template:Labels:       app=nginxpod-template-hash=848dd6cfb5Annotations:  kubernetes.io/change-cause: image updated to 1.16.1Containers:nginx:Image:      nginx:1.16.1Port:       80/TCPHost Port:  0/TCPEnvironment:        <none>Mounts:     <none>Volumes:      <none>[root@master ~]# 

(3)执行以下命令回滚到以前的版本,这里是版本1。

[root@master ~]# kubectl rollout undo deployment/nginx-deploy --to-revision=1
deployment.apps/nginx-deploy rolled back

如果要回滚到当前版本的上一版本,也可以使用kubectl rollout undo命令,例如

kubectl rollout undo deployment/nginx-deploy

(4)执行以下命令检查回滚是否成功以及Deployment是否正在运行

[root@master ~]# kubectl get deployment nginx-deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   3/3     3            3           111m

(5)执行命令查看该Deployment的详细信息。

[root@master ~]# kubectl describe deployment nginx-deploy
Name:                   nginx-deploy
Namespace:              default
CreationTimestamp:      Thu, 03 Apr 2025 21:01:24 +0800
Labels:                 app=nginx
Annotations:            deployment.kubernetes.io/revision: 4kubernetes.io/change-cause: image updated to 1.16.1
Selector:               app=nginx
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:Labels:  app=nginxContainers:nginx:Image:        nginx:1.16.1Port:         80/TCPHost Port:    0/TCPEnvironment:  <none>Mounts:       <none>Volumes:        <none>
Conditions:Type           Status  Reason----           ------  ------Available      True    MinimumReplicasAvailableProgressing    True    NewReplicaSetAvailable
OldReplicaSets:  nginx-deploy-86dcfdf4c6 (0/0 replicas created)
NewReplicaSet:   nginx-deploy-848dd6cfb5 (3/3 replicas created)
Events:Type    Reason             Age                From                   Message----    ------             ----               ----                   -------Normal  ScalingReplicaSet  51m                deployment-controller  Scaled up replica set nginx-deploy-848dd6cfb5 to 1Normal  ScalingReplicaSet  45m                deployment-controller  Scaled up replica set nginx-deploy-848dd6cfb5 to 3 from 2Normal  ScalingReplicaSet  45m                deployment-controller  Scaled down replica set nginx-deploy-86dcfdf4c6 to 1 from 2Normal  ScalingReplicaSet  45m                deployment-controller  Scaled down replica set nginx-deploy-86dcfdf4c6 to 0 from 1Normal  ScalingReplicaSet  3m28s              deployment-controller  Scaled up replica set nginx-deploy-86dcfdf4c6 to 1 from 0Normal  ScalingReplicaSet  3m26s              deployment-controller  Scaled down replica set nginx-deploy-848dd6cfb5 to 2 from 3Normal  ScalingReplicaSet  3m26s              deployment-controller  Scaled up replica set nginx-deploy-86dcfdf4c6 to 2 from 1Normal  ScalingReplicaSet  3m25s              deployment-controller  Scaled down replica set nginx-deploy-848dd6cfb5 to 1 from 2Normal  ScalingReplicaSet  3m25s              deployment-controller  Scaled up replica set nginx-deploy-86dcfdf4c6 to 3 from 2Normal  ScalingReplicaSet  3m24s              deployment-controller  Scaled down replica set nginx-deploy-848dd6cfb5 to 0 from 1Normal  ScalingReplicaSet  52s                deployment-controller  Scaled up replica set nginx-deploy-848dd6cfb5 to 1 from 0Normal  ScalingReplicaSet  50s (x2 over 46m)  deployment-controller  Scaled up replica set nginx-deploy-848dd6cfb5 to 2 from 1Normal  ScalingReplicaSet  50s (x2 over 46m)  deployment-controller  Scaled down replica set nginx-deploy-86dcfdf4c6 to 2 from 3Normal  ScalingReplicaSet  47s (x3 over 48s)  deployment-controller  (combined from similar events): Scaled down replica set nginx-deploy-86dcfdf4c6 to 0 from 1

(6)执行以下命令检查Deployment回滚之后的Pod。

[root@master ~]# kubectl get pod
NAME                            READY   STATUS    RESTARTS   AGE
nginx-deploy-848dd6cfb5-cs82c   1/1     Running   0          112s
nginx-deploy-848dd6cfb5-dxt4m   1/1     Running   0          110s
nginx-deploy-848dd6cfb5-nj2mt   1/1     Running   0          108s

可以发现,Pod的名称改变了,回滚之后又重新创建了Pod,不过ReplicaSet恢复原来的名称。


九、暂停、恢复Deployment的更新

前面的更新都是立即触发更新,实际应用中可能涉及多个修改,为避免触发不必要的更新操作,可以在触发一个或多个更新之前先暂停Deployment的更新(上线),也就是临时禁用的更新功能,完成修改之后再重新恢复Deployment的更新。注意,暂停更新的Deployment并不影响用户的访问,仅是对Pod模板做的任何修改都不会触发更新的部署。下面在前面例子的基础上进行相应的操作。

(1)执行kubectl rollout pause命令暂停Deployment的更新。

[root@master ~]# kubectl rollout pause deployment/nginx-deploy
deployment.apps/nginx-deploy paused

(2)查看Deployment的ReplicaSet。

[root@master ~]# kubectl get rs -o wide
NAME                      DESIRED   CURRENT   READY   AGE    CONTAINERS   IMAGES         SELECTOR
nginx-deploy-848dd6cfb5   0         0         0       60m    nginx        nginx:1.16.1   app=nginx,pod-template-hash=848dd6cfb5
nginx-deploy-86dcfdf4c6   3         3         3       121m   nginx        nginx:1.14.2   app=nginx,pod-template-hash=86dcfdf4c6

可以发现,当前Deployment使用的是nginx:1.14.2镜像。

(3)执行以下命令更新Deployment的镜像。

[root@master ~]# kubectl set image deployment/nginx-deploy nginx=nginx:1.17.1
deployment.apps/nginx-deploy image updated

(4)再次查看Deployment的ReplicaSet。

[root@master ~]# kubectl get rs -o wide
NAME                      DESIRED   CURRENT   READY   AGE    CONTAINERS   IMAGES         SELECTOR
nginx-deploy-848dd6cfb5   0         0         0       62m    nginx        nginx:1.16.1   app=nginx,pod-template-hash=848dd6cfb5
nginx-deploy-86dcfdf4c6   3         3         3       123m   nginx        nginx:1.14.2   app=nginx,pod-template-hash=86dcfdf4c6

可以发现,没有创建新的ReplicaSet,镜像都是原来的,说明没有更新部署被触发。

(5)继续执行其他更新操作,执行以下命令修改配额限制。

[root@master ~]# kubectl set resources deployment/nginx-deploy -c=nginx --limits=cpu=200m,memory=512Mi
deployment.apps/nginx-deploy resource requirements updated

这里将该Deployment的nginx容器的CPU限制为“200m”,内存设置为“512Mi”。

目前Deployment的更新处于暂停状态,所有的更新都不会产生任何效果。

(6)执行以下命令恢复Deployment的更新(上线)。

[root@master ~]# kubectl rollout resume deployment/nginx-deploy
deployment.apps/nginx-deploy resumed

(7)执行以下命令观察新的ReplicaSet的创建过程,其中包含应用程序的所有更新。

[root@master ~]# kubectl get rs -o wide -w
NAME                      DESIRED   CURRENT   READY   AGE    CONTAINERS   IMAGES         SELECTOR
nginx-deploy-5877f89444   1         1         0       48s    nginx        nginx:1.17.1   app=nginx,pod-template-hash=5877f89444
nginx-deploy-848dd6cfb5   0         0         0       67m    nginx        nginx:1.16.1   app=nginx,pod-template-hash=848dd6cfb5
nginx-deploy-86dcfdf4c6   3         3         3       128m   nginx        nginx:1.14.2   app=nginx,pod-template-hash=86dcfdf4c6

观察完毕,使用Ctrl+C组合键退出监视状态。


十、扩缩容Deployment

随着业务量的变化,通常需要对应用程序进行扩容或缩容,也就是增减Pod副本数。扩缩容Deployment主要有两种方法。一种方法是修改YAML配置文件中的.spec.replicas字段的值,再执行kubectl apply命令实现Pod副本数的动态调整。

另一种方法是使用kubectl scale命令直接扩缩容,使用–replicas选项指定要达到的Pod副本数。这里在前面例子的基础上进行操作,执行以下命令将Pod副本数扩容到5。

[root@master ~]# kubectl scale deployment/nginx-deploy --replicas=5
deployment.apps/nginx-deploy scaled

检查Deploymnet状态,可以发现目前已有5个副本。

[root@master ~]# kubectl get deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   5/5     5            5           136m

进一步检查Pod,可以发现有两个Pod副本是被添加到ReplicaSet中的。

[root@master ~]# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP               NODE    NOMINATED NODE   READINESS GATES
nginx-deploy-5877f89444-7lcjb   1/1     Running   0          2m1s    10.244.166.163   node1   <none>           <none>
nginx-deploy-5877f89444-js9cm   1/1     Running   0          92s     10.244.166.164   node1   <none>           <none>
nginx-deploy-5877f89444-n4qkd   1/1     Running   0          9m28s   10.244.104.16    node2   <none>           <none>
nginx-deploy-5877f89444-pgs8j   1/1     Running   0          2m1s    10.244.104.18    node2   <none>           <none>
nginx-deploy-5877f89444-q5vm5   1/1     Running   0          90s     10.244.104.19    node2   <none>           <none>

Deployment部署的应用程序的声明周期中的主要状态包括Progressing(进行中), Complete(已完成)和Failed(失败)。失败的Deployment无法继续运行,但是也可以对其执行扩缩容、回滚到以前的修订版本等操作;或者在需要对Deployment的Pod模板做多项调整时,将Deployment暂停更新。

完成以上实验后,执行以下命令删除该Deployment,以清理实验环境。

[root@master ~]# kubectl delete deployment nginx-deploy
deployment.apps "nginx-deploy" deleted

删除Deployment会清除它创建的所有ReplicaSet和Pod。


http://www.mrgr.cn/news/96957.html

相关文章:

  • 部署大模型实战:如何巧妙权衡效果、成本与延迟?
  • Apache httpclient okhttp
  • Git与SVN的区别以及各自的优势
  • Linux基础指令(一)
  • [C++面试] 智能指针面试点(重点)续4
  • Debian/Ubuntu的networking的`/etc/network/interfaces`配置文件,如何禁用ipv6的route路由网关?
  • 电子电气架构 --- 智能座舱域控设计
  • 电子电气架构 --- 域控制器和EE架构关系
  • Go语言学习(15)结构体标签与反射机制
  • WPS宏开发手册——Excel常用Api
  • 在win11 环境下 新安装 WSL ubuntu + 换国内镜像源 + ssh + 桌面环境 + Pyhton 环境 + vim 设置插件安装
  • 红日靶场一实操笔记
  • 第一期:Spring Web MVC 入门 [特殊字符](基础概念 + 环境搭建)
  • 【408--考研复习笔记】操作系统----知识点速览
  • <贪心算法>
  • 打包python文件生成exe
  • 电子电气架构 --- 控制器级架构
  • C#实现HiveQL建表语句中特殊数据类型的包裹
  • Spring 核心技术解析【纯干货版】- XVIII:Spring 网络模块 Spring-WebSocket 模块精讲
  • leetcode-热题100(3)