RedCloud Help

7.Deployment控制器:概念/原理解读

7.1 Deployment概述

Deployment 是kubernetes 中最常用的资源对象,为ReplicaSet 和Pod 的创建提供了 一种声明式的定义方法,在Deployment 对象中描述一个期望的状态,Deployment 控制器就 会按照一定的控制速率把实际状态改成期望状态,通过定义一个Deployment 控制器会创建 一个新的ReplicaSet 控制器,通过ReplicaSet 创建pod,删除Deployment 控制器,也会 删除Deployment 控制器下对应的ReplicaSet 控制器和pod 资源.

使用Deployment 而不直接创建ReplicaSet 是因为Deployment 对象拥有许多 ReplicaSet 没有的特性,例如滚动升级、金丝雀发布、蓝绿部署和回滚。

扩展:声明式定义是指直接修改资源清单yaml 文件,然后通过kubectl apply -f 资源 清单yaml 文件,就可以更改资源

扩展:声明式定义是指直接修改资源清单yaml 文件,然后通过kubectl apply -f 资源 清单yaml 文件,就可以更改资源

image_22.png

rs v1 控制三个pod,删除一个pod,在rs v2 上重新建立一个,依次类推,直到全部都 是由rs v2 控制,如果rs v2 有问题,还可以回滚,Deployment 是建构在rs 之上的,多个 rs 组成一个Deployment,但是只有一个rs 处于活跃状态.

7.1.1 Deployment 工作原理:如何管理rs 和Pod?

Deployment 可以使用声明式定义,直接在命令行通过纯命令的方式完成对应资源版本的 内容的修改,也就是通过打补丁的方式进行修改;Deployment 能提供滚动式自定义自控制 的更新;对Deployment 来讲,我们在实现更新时还可以实现控制更新节奏和更新逻辑。

比如说Deployment 控制5 个pod 副本,pod 的期望值是5 个,但是升级的时候需要额外 多几个pod,那我们控制器可以控制在5 个pod 副本之外还能再增加几个pod 副本;比方说 能多一个,但是不能少,那么升级的时候就是先增加一个,再删除一个,增加一个删除一个, 始终保持pod 副本数是5 个;还有一种情况,最多允许多一个,最少允许少一个,也就是最 多6 个,最少4 个,第一次加一个,删除两个,第二次加两个,删除两个,依次类推,可以 自己控制更新方式,这种滚动更新需要加readinessProbe 和livenessProbe 探测,确保pod 中容器里的应用都正常启动了才删除之前的pod。

启动第一步,刚更新第一批就暂停了也可以;假如目标是5 个,允许一个也不能少,允 许最多可以10 个,那一次加5 个即可;这就是我们可以自己控制节奏来控制更新的方法。

image_23.png

通过 Deployment 对象,你可以轻松的做到以下事情:

  • 创建 ReplicaSet 和 Pod

  • 滚动升级(不停止旧服务的状态下升级)和回滚应用(将应用回滚到之前的版本)

  • 平滑地扩容和缩容

  • 暂停和继续 Deployment

7.2 Deployment 资源清单文件编写技巧

kubectl explain deployment
KIND: Deployment VERSION: apps/v1 DESCRIPTION: Deployment enables declarative updates for Pods and ReplicaSets. FIELDS: apiVersion <string> 该资源使用的api版本 kind <string> 创建的资源是什么 metadata <Object> 元数据,包括资源的名字和名称空间 spec <Object> 定义容器的 status <Object> 状态,不可以修改
kubectl explain deployment.spec
KIND: Deployment VERSION: apps/v1 RESOURCE: spec <Object> DESCRIPTION: Specification of the desired behavior of the Deployment. DeploymentSpec is the specification of the desired behavior of the Deployment. FIELDS: minReadySeconds <integer> #kubernetes在等待设置的时间后才进行升级,如果没有设置该值,kubernetes会假设该容器启动起来后就提供服务了 paused <boolean> 暂停,当我们更新的时候创建pod先暂停,不是立即更新 progressDeadlineSeconds <integer> # k8s在升级过程中有可能由于各种原因升级卡住(这个时候还没有明确的升级失败),比如在拉取被墙的镜像,权限不够等错误。那么这个时候就需要有个deadline,在deadline之内如果还卡着,那么就上报这个情况,这个时候这个Deployment状态就被标记为False,并且注明原因。但是它并不会阻止Deployment继续进行卡住后面的操作。完全由用户进行控制 replicas <integer> 副本数 revisionHistoryLimit <integer> 保留的历史版本,默认是10 selector <Object> -required- 标签选择器,选择它关联的pod strategy <Object> 更新策略 template <Object> -required- 定义的pod模板
kubectl explain deploy.spec.strategy
KIND: Deployment VERSION: apps/v1 RESOURCE: strategy <Object> DESCRIPTION: The deployment strategy to use to replace existing pods with new ones. DeploymentStrategy describes how to replace existing pods with new ones. FIELDS: rollingUpdate <Object> Rolling update config params. Present only if DeploymentStrategyType =RollingUpdate. type <string> Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate. # 支持两种更新,Recreate和RollingUpdate # Recreate是重建式更新,删除一个更新一个
kubectl explain deploy.spec.strategy.rollingUpdate
KIND: Deployment VERSION: apps/v1 RESOURCE: rollingUpdate <Object> DESCRIPTION: Rolling update config params. Present only if DeploymentStrategyType = RollingUpdate. Spec to control the desired behavior of rolling update. FIELDS: maxSurge <string> 我们更新过程中最多允许超过的指定的目标副本数有几个,他有两种取值方式,第一种直接给定数量,第二种根据百分比,百分比表示远不是5个,最多可以超过20%,那就允许多一个,最多可以超过40%,那就允许多两个 maxUnavailable <string> 最多允许几个不可用,假设有5个副本,最多一个不可用,就表示最多有4个可用
# 查看Deployment下spec.template字段,template为定义pod的模板,Deployment通过模板创建Pod kubectl explain deploy.spec.template
KIND: Deployment VERSION: apps/v1 RESOURCE: template <Object> DESCRIPTION: Template describes the pods that will be created. PodTemplateSpec describes the data a pod should have when created from a template FIELDS: metadata <Object> 定义模板的名字 spec <Object> deployment.spec.template为pod定义的模板,和pod定义不太一样,template中不包含apiVersion和Kind属性,要求必须有metadata。 deployment.spec.template.spec 为容器属性信息,其他定义内容和pod一直。

7.3 3、Deployment 使用案例:创建一个web 站点

cat deploy-demo.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-v1 spec: replicas: 2 selector: matchLabels: app: myapp version: v1 template: metadata: labels: app: myapp version: v1 spec: containers: - name: myapp image: janakiramm/myapp:v1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 startupProbe: periodSeconds: 5 initialDelaySeconds: 20 timeoutSeconds: 10 httpGet: scheme: HTTP port: 80 path: / livenessProbe: periodSeconds: 5 initialDelaySeconds: 20 timeoutSeconds: 10 httpGet: scheme: HTTP port: 80 path: / readinessProbe: periodSeconds: 5 initialDelaySeconds: 20 timeoutSeconds: 10 httpGet: scheme: HTTP port: 80 path: /
# 更新资源清单文件 kubectl apply -f deploy-demo.yaml # 查看deploy状态 kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE myapp-v1 0/2 2 0 13s 1.NAME : 列出名称空间中deployment的名称。 2.READY:显示deployment有多少副本数。它遵循ready/desired模式。 3.UP-TO-DATE: 显示已更新到所需状态的副本数。 4.AVAILABLE: 显示你的可以使用多少个应用程序副本。 5.AGE: 显示应用程序已运行的时间。 kubectl get rs NAME DESIRED CURRENT READY AGE myapp-v1-6c756c6cf4 2 2 2 3m23s 创建deploy的使用也会创建一个rs(replicaset),6c756c6cf4这个随机数字是我们引用pod的模板template的名字的hash值。 1.NAME: 列出名称空间中 ReplicaSet 资源 2.DESIRED:显示应用程序的所需副本数,这些副本数是在创建时定义的。这是 所需的状态。 3.CURRENT: 显示当前正在运行多少个副本。 4.READY: 显示你的用户可以使用多少个应用程序副本。 5.AGE :显示应用程序已运行的时间。 请注意,ReplicaSet 的名称始终设置为[DEPLOYMENT-NAME]-[RANDOM-STRING]。

7.3.4 Deployment管理pod:扩容、缩容

直接修改副本数数量

spec: replicas: 3

7.3.5 Deployment实现pod滚动升级

在Kubernetes中,可以使用Deployment资源来管理pod的滚动g更新和回滚。Deployment是一种控制器(Controller),他提供了声明的方式来定义和管理pod的副本集,并支持滚动更新策略。

一下是一个示例Deployement的定义,展示了如何实现滚动更新和回滚:

cat deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-container image: nginx imagePullPolicy: IfNotPresent livenessProbe: httpGet: path: /index.html port: 80 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /index.html port: 80 initialDelaySeconds: 20 periodSeconds: 10 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 0 maxSurge: 1

在上述示例中,Deployment 配置包括以下关键部分:

  • replicas 定义了需要运行的 Pod 副本数量。

  • selector 指定了用于选择 Pod 副本集的标签。

  • template 定义了 Pod 的模板,包括容器和其他配置。

  • strategy 指定了滚动更新的策略,类型为rollingUpdate

  • rollingUpdate定义了滚动更新的具体参数,例如maxUnavailable便是更新期间允许的最大不可用pod数量,maxSurge表示更新期间允许的最大额外副本数量。

pod前端可以创建svc四层代理,用来对pod进行负载均衡:

apiVersion: v1 kind: Service metadata: name: deploy-nginx namespace: default spec: ports: - port: 80 targetPort: 80 selector: app: my-app type: NodePort
kubectl apply -f svc.yaml 要执行滚动更新,可以通过修改 Deployment 的 Pod 里容器的镜像来触发更新。例如,可以通过更新镜 像标签来指向新的版本,把 image: nginx 改成 image: docker.io/ikubernetes/myapp:v1,然后应用修改后的 Deployment 配置。 kubectl apply -f deployment.yaml Kubernetes 将自动逐步更新 Deployment 的 Pod 副本,并用新的镜像重新运行 pod 如果需要回滚到先前的版本,可以使用下面的命令查看历史版本: kubectl rollout history deployment my-deployment 回滚到指定版本: kubectl rollout undo deployment my-deployment --to-revision=1

7.3.6 Deployment 基于反亲和性创建pod

基于k8s 的deployment 控制器运行nginx 服务,指定pod 副本数是2,根据pod 反亲和 性让两个pod 调度到不同的工作节点。

使用背景和场景:

业务中的某个关键服务,配置了多个replicas 副本数,结果在部署时,发现多个相同的副本同 时部署在同一个主机上,结果主机故障时,所有副本同时漂移了,导致服务间断性中断

基于以上背景,实现一个服务的多个副本分散到不同的主机上,使每个主机有且只能运行服务 的一个副本,这里用到的是Pod 反亲和性,特性是根据已经运行在node 上的pod 的label,不再 将相同label 的pod 也调度到该node,实现每个node 上只运行一个副本的pod

apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - nginx topologyKey: "kubernetes.io/hostname" containers: - name: nginx image: nginx imagePullPolicy: "IfNotPresent" ports: - containerPort: 80 name: http protocol: TCP tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule

基于上面的Deployment创建的两个pod不会调度到一个node节点上。

13 February 2026