【云原生kubernets】Deployment的功能与应用

 一、导读

所有的 Deployment 对象都是由 Kubernetes 集群中的 DeploymentController 进行管理,DeploymentController 会在启动时通过 Informer 监听三种不同资源的通知,Pod、ReplicaSet 和 Deployment,这三种资源的变动都会触发 DeploymentController 中的回调。

不同的事件最终都会在被过滤后进入控制器持有的队列,等待工作进程的消费,下面的这些事件都会触发:

  • Deployment 的同步;
  • Deployment 的变动;
  • Deployment 相关的 ReplicaSet 变动;
  • Deployment 相关的 Pod 数量为 0 时,Pod 的删除事件;

二、Deployment的控制流程 

 2.1.Deployment 的yaml文件定义:

Deployment 定义的 template 字段,在 Kubernetes 项目中有一个专有的名字,叫作 PodTemplate即Pod 模板。后面提到的大多数控制器,都会使用 PodTemplate 来统一定义它所要管理的 Pod。 Deployment 这样的一个控制器,实际上都是由上半部分的控制器定义,包括期望状态,加上下半部分的被控制对象的模板组成的。nginx-deployment 所直接控制的,就是 Pod 对象么?不是,而是ReplicaSet。

2.2.控制流程:

(1)Deployment 控制器从 Etcd 中获取到所有携带了“app: nginx”标签的 Pod,然后统计它们的数量,这就是实际状态;
(2)Deployment 对象的 Replicas 字段的值就是期望状态;
(3)Deployment 控制器将两个状态做比较,然后根据比较结果,确定是创建 Pod,还是删除已有的 Pod。

2.3.Deployment控制器与ReplicaSet控制器关系:

Deployment控制器建立在ReplicaSet控制器之上,管理多个ReplicaSet,每次更新镜像版本,都会生成一个新的ReplicaSet,把旧的ReplicaSet替换掉,多个ReplicaSet同时存在,但只运行一个ReplicaSet。

ReplicaSet V1版本控制了三个Pod,ReplicaSet V1版本删除一个Pod,会在ReplicaSet V2版本新建一个Pod,以此类推,直到ReplicaSet V2版本完全替换完。如果ReplicaSet V2版本更新上去存在问题,还可以回滚,Deployment建立在ReplicaSet之上,多个ReplicaSet组成一个Deployment,但只有一个ReplicaSet处于活跃状态。

2.4.Deployment资源清单:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-deployment-1
  labels:
    env: uat
spec:
  replicas: 3
  minReadySeconds: 10  # 更新场景,等待时间,如果没有设置K8S会假设该容器启动起来后就提供服务了
  paused:  # 暂停,当更新Pod时,先暂停,而不是立马更新
  progressDeadlineSeconds: 60 # 更新场景,等待时间超过此值,状态标记False,并说明原因,但是它并不会阻止 Deployment 继续进行卡住后面的操作 
  strategy:
    rollingUpdate:        # 滚动更新,定义滚动更新方式,也就是pod能多几个,少几个
      maxSurge: 20%       # 允许更新中,最多超过Pod数值
      maxUnavailable: 20% # 允许更新中,最多允许几个不可用
  selector:
    matchLabels:
      app: demo-nginx
  template:
    metadata: 
      labels:
        app: demo-nginx
    spec:
      containers:
      - name: demo-nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        startupProbe:      # 启动探测
          tcpSocket:
            port: 80
        livenessProbe:     # 存活探测 
          httpGet:
            port: 80
            path: /index.html
        readinessProbe:    # 就绪探测
          httpGet:
            port: 80
            path: "/index.html"

2.4.2.核心参数讲解:

  • spec.minReadySeconds:更新场景,等待时间,如果没有设置K8S会假设该容器启动起来后就提供服务了。
  • spec.paused: 暂停,当更新Pod时,先暂停,而不是立马更新,后面金丝雀发布要用到
  • spec.progressDeadlineSeconds:更新场景,等待时间超过此值,状态标记False,并说明原因,但是它并不会阻止 Deployment 继续进行卡住后面的操作
  • spec.strategy.rollingUpdate:滚动更新,定义滚动更新方式,也就是pod能多几个,少几个
  • spec.strategy.rollingUpdate.maxSurge:指定在更新期间可以创建的新Pod的最大数量。例如,如果maxSurge设置为1,而Deployment中有3个Pod,则在更新期间可以创建4个Pod,其中3个是旧的Pod,1个是新的Pod。
  • spec.strategy.rollingUpdate.maxUnavailable:指定在更新期间可以同时停止的旧Pod的最大数量。例如,如果maxUnavailable设置为1,而Deployment中有3个Pod,则在更新期间可以停止1个Pod。
     
2.5.Deployment更新策略:

(1)Recreate:重建式更新,把Pod全部删除,在重新创建,风险很大,不建议使用

(2)rollingUpdate:滚动式更新,批量替换更新,平滑升级,用户无感知

三、功能与特点

(1)声明式更新机制: 使用Deployment定义应用的期望状态,系统将自动调整Pod数量和配置,以确保应用达到用户所定义的期望状态。这种声明式的特性使得部署和更新应用变得简单和可预测。

(2)副本管理: Deployment控制器通过ReplicaSet来管理Pod的副本数量。用户可以指定所需的副本数,并且控制器会自动调整Pod数量以保持与期望状态一致。

(3)滚动更新: Deployment支持滚动更新策略,允许逐步替换旧版本的Pod实例,从而实现应用的平滑升级。这确保了应用在更新过程中的高可用性和稳定性。

(4)回滚策略: 在部署新版本应用后,如果发现问题,Deployment控制器可以快速回滚到之前的稳定版本,防止应用出现严重故障。

(5)版本历史记录: Deployment会自动维护版本的历史记录,包括每次更新的详情和状态。这使得用户可以随时查看和管理应用的历史版本。

四、ReplicaSet控制器

4.1.ReplicaSet控制器简要介绍

Kubernetes中用于管理Pod副本数量的重要控制器。它可以看作是Deployment控制器的底层组件,专注于维护Pod的副本数量,确保集群中的Pod实例始终符合用户定义的期望状态。

4.2.ReplicaSet控制器与Deployment控制器的差异

(1)更新策略: Deployment控制器提供了滚动更新和回滚策略,支持应用的平滑升级和快速回退。而ReplicaSet控制器并不直接支持这些功能,它主要用于维护指定数量的Pod副本,不会主动进行应用更新。

(2)声明性更新: Deployment控制器通过声明式的方式定义应用的期望状态,并自动处理Pod的创建、更新和删除。而ReplicaSet控制器相对更为底层,需要手动定义ReplicaSet的配置,更加灵活但也更加复杂。

应用场景: Deployment控制器适用于需要进行滚动更新和回滚的场景,更适合部署无状态应用。而ReplicaSet控制器适用于需要确保固定副本数量的场景,更适合部署有状态应用或无状态应用的固定版本。
 

4.3.ReplicaSet控制器的作用

ReplicaSet控制器的主要作用是确保Pod的副本数始终符合用户定义的期望状态。当集群中的Pod数量少于期望值时,ReplicaSet控制器会自动创建新的Pod实例,使得副本数达到预期。而当Pod数量超过期望值时,控制器会自动删除多余的Pod,确保集群中只有所需数量的Pod在运行。通过ReplicaSet控制器,用户可以方便地进行水平扩展和缩减,根据应用负载的变化来动态调整Pod的数量。这为应对流量高峰和负载波动提供了便利,保障应用的性能和稳定性。

五、实战案例

3.1.创建web-deployment的控制器

 编写资源清单:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
  labels:
    env: uat
spec:
  replicas: 5
  minReadySeconds: 10  
  progressDeadlineSeconds: 60 
  strategy:
    rollingUpdate:
      maxSurge: 20%       
      maxUnavailable: 20% 
  selector:
    matchLabels:
      app: web-nginx
  template:
    metadata: 
      labels:
        app: web-nginx
    spec:
      containers:
      - name: web-nginx
        image: web:v1
        imagePullPolicy: IfNotPresent
        startupProbe:
          tcpSocket:
            port: 80
        livenessProbe:
          httpGet:
            port: 80
            path: /index.html
        readinessProbe:
          httpGet:
            port: 80
            path: "/index.html"

执行YAML清单文件:

kubectl create -f web-deployment.yaml

查看创建出来的资源:

kubectl get pod,rs -l app=web-nginx

3.2.Deployment针对WEB站点扩缩容

扩容,将副本扩容至 7,根据上面YAML修改 spec.replicas=7

kubectl edit deploy web-deployment
# 修改 spec.replicas=7

缩容,将副本缩容至 3,根据上面YAML修改 spec.replicas=3

kubectl edit deploy web-deployment
# 修改 spec.replicas=3
 3.3.Deployment针对WEB站点滚动更新

滚动更新是一种自动化较高的更新方式,即一批一批的更新Pod资源,用户体验比较平滑。滚动更新使用 spec.strategy.rollingUpdate 字段来定义。只有我们对Deployment中的Template作出修改的时候,也就是修改PodTemplate时才会进行更新。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
  labels:
    env: uat
spec:
  replicas: 5
  minReadySeconds: 10  
  progressDeadlineSeconds: 60 
  strategy:
    rollingUpdate:
      maxSurge: 30%         # 5*30%=1.5(~=2), 2+5=7,更新期间最多创建7个Pod 
      maxUnavailable: 20%   # 5*20%=1, 1-5=4,更新期间最多停止4个Pod
  selector:
    matchLabels:
      app: web-nginx
  template:
    metadata: 
      labels:
        app: web-nginx
    spec:
      containers:
      - name: web-nginx
        image: web:v2    # 版本更新
        imagePullPolicy: IfNotPresent
        startupProbe:
          tcpSocket:
            port: 80
        livenessProbe:
          httpGet:
            port: 80
            path: /index.html
        readinessProbe:
          httpGet:
            port: 80
            path: "/index.html"

 查看当前ReplicaSet的信息:

kubectl replicaset 
 3.4.版本回退

查看历史版本:

kubectl rollout history deployment web-deployment

回滚版本:回滚到V1 版本

kubectl rollout undo deployment web-deployment --to-revision=1

六、总结

(1)Deployment高级控制器建立在ReplicaSet之上,每次更新镜像版本,都会生成一个新的ReplicaSet,把旧的ReplicaSet替换掉,多个ReplicaSet同时存在,但只运行一个ReplicaSet。

(2)Deployment扩缩容:直接修改replicas字段值,重新apply。

(3)Deployment滚动升级:使用字spec.strategy段定义升级策略,目前支持两种升级策略:

(4)rollingUpdate滚动更新:批量替换更新,平滑升级,用户无感知。

  • Recreate重建试更新:把Pod全部删除,在重新创建,风险很大,不建议使用。
  • Deployment版本回滚:使用rollout history 查看历史版本,使用rollout undo .... --to-revision=x指定回滚版本。
     

猜你喜欢

转载自blog.csdn.net/m0_73901077/article/details/134969545