kubenetes从入门到上天系列第十二篇:Kubernetes的Deployment控制器

一:Deployment控制器

Deployment 是 Kubernetes 中用于控制 Pod 的核心资源对象,提供声明式应用更新与回滚能力,简化应用部署、副本管理与自动化运维。

修改了资源清单文件之后,apply -f 所有pod都可以滚动更新,也可以设置先创建新的,新的提供好服务之后,在删除掉旧的。

1:工作方式

  1. 定义 Pod 模板配置 Pod 运行所需参数:容器镜像、副本数、环境变量、资源限制、启动命令等。

  2. 创建与管理 Pod基于模板创建指定数量的 Pod 副本,确保集群中始终保持目标副本数。

  3. 滚动更新与升级 更新配置时,基于新模板逐步创建新 Pod、终止旧 Pod,实现无中断滚动更新;同时支持快速回滚到历史版本。

  4. 维持应用状态

    Deployment 控制器会检查所创建 Pod 的运行状态和可用性,并根据应用监控功能检查这些 Pod 是否工作正常。如果 Pod 出现故障,控制器会自动重新创建运行中的 Pod 集合。

  5. 提供更新和回滚策略

    Deployment 控制器提供了自动化的更新和回滚策略,能够更好地适应应用开发和运维的需求。可以使用新版本镜像将 Pod 版本逐步升级至新版本,并能够快速、回滚至升级之前的版本信息,从而降低整个应用因升级操作而造成的可用性中断。

2:总结

综上所述,Deployment 控制器是 Kubernetes 中重要的控制器之一,能够提供应用的自动化部署和回滚功能。可以管理和维护应用程序的运行状态,保证应用的稳定性、可用性和可靠性。

Kubernetes 中 DaemonSet、Deployment、StatefulSet 这三个核心控制器是我们平时玩的最多的。

二:deployment是如何管理Replicaset的

当你创建一个 Deployment 资源对象时,它基于定义的 Pod 模板创建对应的 ReplicaSet 控制器 ,因此可以把 Deployment 视为 ReplicaSet 的一个高级封装,提供更高级别的 Pod 缩放、滚动更新等控制。

Deployment 通过使用 ReplicaSet 控制器来维持一组目标 Pod 副本的数量。当你更新 Deployment 资源中的 Pod 模板时,Deployment 控制器会使用新的 Pod 模板创建一个新的 ReplicaSet,然后逐步将原先的 ReplicaSet 中的 Pod 副本转换为新 ReplicaSet 中的 Pod 副本,以实现滚动更新或回滚功能,在该过程中自动保证目标 Pod 副本数量不过多或过少。

更新策略:先删除后创建,先创建后删除,这个更新策略,都是可以定义的。

通过这种方式,Deployment 能够实现自动化、流程化的部署、升级和回滚,提供简单而灵活的管理方式,同时也保证了 Pod 的高可用性和稳定性。除此之外,Deployment 还能够应对突发事件如故障恢复,能够自动扩展和缩减 Pod 副本数量,从而在更大范围应用场景下提供给应用更强的处理能力。

三:Delopyment更新节奏和更新逻辑

比如部署 Deployment 控制 5 个 pod 副本,pod 的期望数量是 5 个,但是在升级的时候需要额外多几个 pod,那么这个控制器可以控制在 5 个 pod 副本之外还能多增加几个 pod 副本。比如说最多多一个,但是是不能少的,那么升级的时候就是先增加一个,再删除一个,增加一个再删除一个,始终保持 pod 副本数是 5 个。

还有一种情况,最多最多多一个,最少最少少一个,也就是最多 6 个,最少 4 个。第一次增加一个,再删除两个,第二次增加两个,再删除两个,以此类推,可以自由控制更新方式。这种滚动更新需要加 readinessProbe 和 livenessProbe 探测,确保 pod 中容器里的应用正常后才删除之前的 pod。

四:Deployment定义详解

字段 类型 说明
apiVersion String API 版本
kind String 资源类型
metadata Object 元数据
metadata.name String 控制器名称
metadata.namespace String 所属命名空间,默认 default
metadata.labels []List 自定义标签列表
spec.annotations Object 自定义注解
spec.replicas Integer Pod 副本数量
spec.revisionHistoryLimit Integer 保留历史版本数,默认 10
spec.minReadySeconds Integer 新 Pod 就绪等待时间,再删除旧 Pod
spec.strategy Object 更新策略
spec.strategy.type String 更新类型:Recreate(重建)、RollingUpdate(滚动更新)
spec.strategy.rollingUpdate Object 滚动更新配置
spec.strategy.rollingUpdate.maxSurge String 最大额外副本数(绝对值 / 百分比)
spec.strategy.rollingUpdate.maxUnavailable String 最大不可用 Pod 数(绝对值 / 百分比)
spec.selector Object 标签选择器
spec.selector.matchLabels map[string]string 匹配 Pod 标签,需与 template.labels 一致
spec.template Object Pod 模板
spec.template.metadata Object Pod 元数据
spec.template.metadata.labels map[string]string Pod 标签定义

五:Pod中添加域名解析和DNS

1:Pod中添加域名解析

hostAliases 字段用于为一些主机设置别名,Pod 内的容器可以通过这些别名来访问主机上的服务。

目标:给 Pod 容器增加域名解析,实现修改容器内的 /etc/hosts。

就是给Pod容器添加本地域名解析。

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-hosts
  labels:
    app: web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx-hosts
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        hostAliases:
        - ip: "192.168.128.11"
          hostnames:
          - "zyf.qq.com"
          - "zyf.test.com"

查看结果如下:

2:Pod中添加DNS配置

目标:在Pod容器中天啊及dns解析,实际操作容器的/etc/resolv.conf文件。

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-hosts
  labels:
    app: web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx-hosts
        image: nginx:latest
        imagePullPolicy: IfNotPresent
      dnsPolicy: None
      dnsConfig:
        nameservers:
        - 192.168.128.71
        searches:
        - natvsc.cluster.local
        - my.dns.search.nat

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-hosts
  labels:
    app: web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx-hosts
        image: nginx:latest
        imagePullPolicy: IfNotPresent
      # 新增:设置Pod的DNS策略为None,表示不使用集群默认的DNS配置,完全使用下面自定义的dnsConfig
      dnsPolicy: None
      # 新增:自定义DNS配置块,替代集群默认DNS设置
      dnsConfig:
        # 自定义DNS服务器地址列表,Pod解析域名时会优先使用这些DNS服务器
        nameservers:
        - 192.168.128.71
        # 自定义DNS搜索域,当解析短域名时,会自动拼接这些搜索域进行完整域名解析
        searches:
        - natvsc.cluster.local  # 集群内部DNS搜索域
        - my.dns.search.nat     # 自定义业务DNS搜索域

3:总结

我们单纯使用Pod配置域名解析和DNS配置也是生效的。

Pod 的 dnsPolicy 默认值是 ClusterFirst,此时:

  • Pod 的 /etc/resolv.conf 会自动指向 CoreDNS 的 ClusterIP(通常是 10.96.0.10);
  • 所有域名解析请求都会先发给 CoreDNS,CoreDNS 负责解析集群内域名(如 xxx.default.svc.cluster.local),集群外域名则转发到宿主机 DNS。

你配置的 dnsPolicy: None 场景

  • 这个配置会完全绕过 CoreDNS,Pod 不会再使用 CoreDNS 的地址;
  • Pod 的 /etc/resolv.conf 会被你配置的 dnsConfig 覆盖(只包含 192.168.128.71 和对应的搜索域);
  • 此时 Pod 的所有域名解析请求都会直接发给 192.168.128.71,和 CoreDNS 没有任何关系,集群内的 Service 域名(如 nginx.default.svc)也无法解析 (除非 192.168.128.71 能处理这些域名)。

补充:常用的 dnsPolicy 与 CoreDNS 的关系

dnsPolicy 类型 与 CoreDNS 的关系
ClusterFirst(默认) 优先使用 CoreDNS,集群外域名转发
ClusterFirstWithHostNet 主机网络的 Pod 优先用 CoreDNS
Default 使用宿主机 DNS,不使用 CoreDNS
None 完全自定义 DNS,和 CoreDNS 无关(你的场景)

六:Deployment控制创建一个web站点

Deployment 是一个三层结构,Deployment 管理 ReplicaSet,ReplicaSet 管理 Pod。

1:编写资源文件

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

2:查看结果

复制代码
-rw-r--r--. 1 root root 384 Mar 11 12:18 test-nginx.yaml
[root@k8s-node1 deployment]# kubectl apply -f test-nginx.yaml
deployment.apps/nginx created
[root@k8s-node1 deployment]# kubectl get deployment
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
nginx        2/2     2            2           22s
[root@k8s-node1 deployment]# kubectl get rs
NAME                    DESIRED   CURRENT   READY   AGE
nginx-b4cbbbbf9         2         2         2       35s
[root@k8s-node1 deployment]# kubectl get pods
NAME                          READY   STATUS     RESTARTS        AGE
nginx-b4cbbbbf9-6nbnc         1/1     Running    0               43s
nginx-b4cbbbbf9-j5pc2         1/1     Running    0               43s
[root@k8s-node1 deployment]#

replicaset的name=deployment.name + 字符串

pod的name=replicaset的name+字符串。

3:动态扩容

1:通过yaml文件来实现(推荐)

修改资源文件:将数量改成3个。

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

多开几个视口,-w进行监视。

复制代码
[root@k8s-node1 deployment]# kubectl apply -f test-nginx.yaml
deployment.apps/nginx configured
[root@k8s-node1 deployment]#


[root@k8s-node1 ~]# kubectl get deployment -w
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
nginx        2/2     2            2           8m6s
nginx        2/3     2            2           10m
nginx        2/3     2            2           10m
nginx        2/3     2            2           10m
nginx        2/3     3            2           10m
nginx        3/3     3            3           10m


[root@k8s-node1 ~]# kubectl get rs -w
NAME                    DESIRED   CURRENT   READY   AGE
nginx-b4cbbbbf9         2         2         2       8m17s
nginx-b4cbbbbf9         3         2         2       10m
nginx-b4cbbbbf9         3         2         2       10m
nginx-b4cbbbbf9         3         3         2       10m
nginx-b4cbbbbf9         3         3         3       10m


[root@k8s-node1 ~]# kubectl get pods -w
NAME                          READY   STATUS        RESTARTS         AGE
nginx-b4cbbbbf9-6nbnc         1/1     Running       0                8m30s
nginx-b4cbbbbf9-j5pc2         1/1     Running       0                8m30s



nginx-b4cbbbbf9-ffrsj         0/1     Pending            0                0s
nginx-b4cbbbbf9-ffrsj         0/1     Pending            0                0s
nginx-b4cbbbbf9-ffrsj         0/1     ContainerCreating   0                0s
nginx-b4cbbbbf9-ffrsj         0/1     ContainerCreating   0                0s
nginx-b4cbbbbf9-ffrsj         1/1     Running             0                1s

2:通过edit编辑来实现

复制代码
^C[root@k8s-node1 ~]# kubectl get rs -w
NAME                    DESIRED   CURRENT   READY   AGE
nginx-b4cbbbbf9         4         4         4       15m
nginx-test-587f4bd885   2         2         2       12d

deployment和rs和pod都翻倍了。

3:总结

  • 核心差异 :YAML 文件方式以 "文件为源",可追溯、低风险、符合 IaC;edit 方式是直接改集群状态,即时生效但无记录、易出错;
  • 适用场景 :YAML 适合规范运维 / 团队协作,edit 仅适合临时应急操作;
  • 关键原则:无论用哪种方式扩容,最终都要保证集群配置和本地 YAML 文件一致,避免 "配置漂移"。

4:动态缩容

跟上边一样,就是修改副本数量即可。

5:滚动升级

部署的时候,使用的镜像myapp:v1,更新的时候,修改deployment文件修改镜像为myapp:v2

kubectl apply -f deply-demo.yaml之后,我们观察下。

查看控制器所有的历史版本:

复制代码
[root@k8s-node1 ~]# kubectl get deployment
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
nginx        4/4     4            4           28m
nginx-test   2/2     2            2           12d
[root@k8s-node1 ~]# kubectl rollout history deployment nginx
deployment.apps/nginx
REVISION  CHANGE-CAUSE
1         <none>

[root@k8s-node1 ~]# ^C

6:版本回退

复制代码
kubectl rollout undo deployment myapp--to-reversion=1

更新的时候,没有将rs的旧版本进行删除,如果删除了,就会滚不了了。

7:自定义滚动更新策略

  • 在 Kubernetes 中,可通过设置 Deployment 的 spec.strategy 来自定义滚动更新策略。Kubernetes 默认的滚动更新策略是 RollingUpdate,在更新新版本 Pod 的同时逐步关闭和删除旧 Pod,保证服务在整个更新期间保持可用。 RollingUpdate 有两个可选值:maxSurgemaxUnavailable,用来控制滚动更新的具体策略。

  • maxSurge新增实例数,值可以是整数或百分比。例如 10 个副本,5% 即 0.5 个,计算按 0 个。

  • maxUnavailable可用实例最大数,值可以是整数或百分比。例如 10 个副本,5% 即 0.5 个,计算按 1 个。

注意:maxSurge 和 maxUnavailable 两者不能同时为 0。

当我有 10 个副本,maxSurge=1,maxUnavailable 为 0 时,实例总数最大为 10,那么现在只有 10 个副本,无法删除。maxSurge 为 1 表示新增实例数,那么会先创建 1 个 pod,现在就有 11 个 pod。maxUnavailable 保证有 10 个实例,就会删除一个,然后反复直到完成。

相关推荐
向右看齐--2 小时前
Docker 进阶(一) Compose
docker·容器
我爱小疯喵喵2 小时前
1 Docker 完全操作指南
docker·容器·eureka
程序员Forlan2 小时前
初识云原生消息队列Pulsar
云原生
m_136873 小时前
OpenClaw v2026.3.12 离线源码构建与 Docker 部署完整教程
运维·docker·容器·openclaw
赴前尘3 小时前
docker buildx进行多架构镜像仓库迁移
docker·容器·架构
江畔何人初3 小时前
Gateway API 的核心组件与作用
运维·网络·云原生·kubernetes·gateway
劲墨难解苍生苦3 小时前
docker 和k8s 环境下达梦数据库开启ssl连接配置流程
数据库·docker·kubernetes
无级程序员4 小时前
k8s部署nacos 3.1.1服务,java.net.UnknownHostException问题终极解决方案
java·nacos·kubernetes
从入门到放弃-咖啡豆4 小时前
服务器部署docker 运行.NET 8 项目
服务器·docker·容器