一、Deployment 无状态调度
1.1 关系
Deployment 与 ReplicaSet 的核心关系
Deployment:一般用于部署公司的无状态服务,这个也是最常用的控制
器,因为企业内部现在都是以微服务为主,而微服务实现无状态化也是最佳
实践,可以利用Deployment的高级功能做到无缝迁移、自动扩容缩容、自动
灾难恢复、一键回滚等功能
- Replication Controller:Replication Controller可以确保Pod副本数达到期望值,也就是RC定义的数量。换句话说,Replication Controller可以确保一个Pod或一组同类Pod总是可用的。
ReplicaSet 是 支 持 基 于 集 合 的 标 签 选 择 器 的 下 一 代 Replication
Controller , 它 主 要 用 作 Deployment 协 调 创 建 、 删 除 和 更 新 Pod , 和Replication Controller唯一的区别是,ReplicaSet支持标签选择器
1、Deployment 与 ReplicaSet 的核心关系
你想理清 Deployment、Replication Controller(RC)、ReplicaSet(RS)和 Pod 这四者之间的创建与管理关系,核心是要区分 RC 和 RS 的定位,以及 Deployment 如何通过它们管控 Pod。
2.核心关系总览
首先明确一个关键前提:Replication Controller(RC)是 Kubernetes 早期的 Pod 副本控制器,ReplicaSet(RS)是 RC 的升级版,而
Deployment 是 RS 的控制器(不会直接管理 RC)。四者的核心关系链路是:
Deployment → ReplicaSet (取代了 Replication Controller) → Pod
Deployment 不会创建 RC(仅兼容但不主动创建),只会创建 RS;RS 作为 RC 的替代方案,是管理 Pod 副本的核心,具体拆解如下:
- Replication Controller(RC):被淘汰的 "前辈"
- RC 是 Kubernetes 最早的 Pod 副本控制器,核心功能是保证指定数量的 Pod 副本始终运行,支持基于标签的 Pod 选择。
- 关键缺陷:仅支持等值匹配的标签选择器(如 app=nginx),不支持集合匹配(如 app in (nginx, apache)),灵活性差。
- Deployment 与 RC 的关系:Deployment 是为 RS 设计的,不会主动创建 RC;如果集群中存在旧的 RC,Deployment 也不会管理它,仅能通过手动方式迁移到 RS/Deployment。
- ReplicaSet(RS):RC 的 "升级版"+ Deployment 的 "执行层"
- RS 完全兼容 RC 的所有功能,且新增了集合型标签选择器(更灵活),是 Kubernetes 目前推荐的 Pod 副本控制器。
- Deployment 是 RS 的 "上层控制器",所有对 Pod 的副本管理、版本更新,都通过创建 / 删除 / 扩缩 RS 来实现,不会直接操作 Pod:
- 首次创建 Deployment:自动生成一个 RS(命名格式:deployment名-随机哈希),由该 RS 创建指定数量的 Pod。
- 更新 Deployment(如改镜像、资源):Deployment 不会修改现有 RS,而是新建一个 RS,并逐步将 Pod 从旧 RS 迁移到新 RS(滚动更新)。
- 回滚 Deployment:Deployment 会缩容新 RS 的 Pod 数到 0,重新扩容旧 RS 的 Pod 数到目标值。
-
实操验证:看 Deployment 只创建 RS 不创建 RC
1. 创建一个 Deployment
kubectl create deployment nginx-deploy --image=nginx:1.21 --replicas=3
2. 查看 Deployment、RS、RC、Pod
kubectl get deploy,rs,rc,pod -l app=nginx-deploy
输出示例(仅能看到 Deployment、RS、Pod,无 RC)
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deploy 3/3 3 3 10sNAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deploy-7f987d6b9 3 3 3 10sNAME READY STATUS RESTARTS AGE
pod/nginx-deploy-7f987d6b9-2x89k 1/1 Running 0 10s
pod/nginx-deploy-7f987d6b9-5m78z 1/1 Running 0 10s
pod/nginx-deploy-7f987d6b9-8s27k 1/1 Running 0 10s3. 更新 Deployment 镜像,看是否新建 RS
kubectl set image deployment/nginx-deploy nginx=nginx:1.22
kubectl get rs -l app=nginx-deploy输出示例(新增一个 RS,旧 RS 保留)
NAME DESIRED CURRENT READY AGE
nginx-deploy-7f987d6b9 0 0 0 20s # 旧 RS
nginx-deploy-8d76f897c 3 3 3 5s # 新 RS
核心区别:RC vs RS(为什么 RS 取代 RC)

3.总结
- 层级核心:Deployment 只管理 ReplicaSet(RS),不创建 / 管理 Replication Controller(RC);RS 取代 RC 成为管控 Pod 副本的核心,直接创建和维护 Pod。
- 版本逻辑:Deployment 通过 "新建 RS + 缩容旧 RS" 实现 Pod 版本更新,旧 RS 保留用于回滚,全程不直接操作 Pod。
- RC 定位:RC 是早期产物,功能单一且不灵活,已被 RS 完全取代,与 Deployment 无关联,仅用于兼容旧集群。
1.2 清单示例
Replication Controller

ReplicaSet 示例

Replication Controller和ReplicaSet的创建、删除和Pod并无太大区
别 , Replication Controller 目 前 几 乎 已 经 不 在 生 产 环 境 中 使 用 ,ReplicaSet 也 很 少 单 独 被 使 用 , 都 是 使 用 更 高 级 的 资 源 Deployment 、DaemonSet、StatefulSet管理Pod。
Deployment 示例

从Kubernetes 1.16版本开始,彻底废弃了其他的APIVersion,只能使用
apps/v1,1.16以下的版本可以使用extension等。

1.3 清单使用命令
Deployment 创建
使用kubectl create创建此Deployment
kubectl create -f dp-nginx.yaml
deployment.apps/nginx-deployment created
查看此Deployment的状态:
使用kubectl get或者kubectl describe查看此Deployment的状态:

NAME:集群中Deployment的名称。
- DESIRED:应用程序副本数。
- CURRENT:当前正在运行的副本数。
- UP-TO-DATE:显示已达到期望状态的被更新的副本数。
- AVAILABLE:显示用户可以使用的应用程序副本数,当前为1,因为
部分Pod仍在创建过程中。 - AGE:显示应用程序运行的时间。
查看Deployment创建的状态
kubectl rollout status deployment/nginx-deployment
deployment "nginx-deployment" successfully rolled out

更新Deployment
当且仅当Deployment的Pod模板(即.spec.template)更改时,才会触发
Deployment更新,例如更改内存、CPU配置或者容器的image。
回滚Deployment
当更新的版本不稳定或配置不合理时,可以对其进行回滚操作,假设我
们又进行了几次更新(此处以更新镜像版本触发更新,更改配置效果类
似)
kubectl set image deployment nginx-deployment
nginx=dotbalo/canary:v1 --record
# kubectl set image deployment nginx-deployment
nginx=dotbalo/canary:v2 --record
使用kubectl rollout history查看更新历史:

查看Deployment某次更新的详细信息,使用--revision指定某次更新的
版本号

暂停和恢复Deployment更新

更新Deployment的注意事项

历史版本清理策略:
在默认情况下,revision保留10个旧的ReplicaSet,其余的将在后台进
行垃圾回收,可以在.spec.revisionHistoryLimit设置保留ReplicaSet的个
数。当设置为0时,不保留历史记录。
更新策略:
- .spec.strategy.type==Recreate:表示重建,先删掉旧的Pod,再
创建新的Pod。 - .spec.strategy.type==RollingUpdate:表示滚动更新,可以指定
maxUnavailable和maxSurge来控制滚动更新过程。
◆ .spec.strategy.rollingUpdate.maxUnavailable:指定在回滚
更新时最大不可用的Pod数量,可选字段,默认为25%,可以设
置为数字或百分比,如果maxSurge为0,则该值不能为0。
◆ .spec.strategy.rollingUpdate.maxSurge:可以超过期望值的
最大Pod数,可选字段,默认为25%,可以设置成数字或百分
比,如果maxUnavailable为0,则该值不能为0。 - Ready策略:
.spec.minReadySeconds是可选参数,指定新创建的Pod应该在没有任何
容器崩溃的情况下视为Ready(就绪)状态的最小秒数,默认为0,即一旦被创建就视为可用,通常和容器探针连用。
二、StatefulSet 无状态调度
StatefulSet的基本概念
StatefulSet主要用于管理有状态应用程序的工作负载API对象。比如在
生产环境中,可以部署ElasticSearch集群、MongoDB集群或者需要持久化的
RabbitMQ集群、Redis集群、Kafka集群和ZooKeeper集群等
一般StatefulSet用于有以下一个或者多个需求的应用程序:
- 需要稳定的独一无二的网络标识符。
- 需要持久化数据。
- 需要有序的、优雅的部署和扩展。
- 需要有序的自动滚动更新。
如果应用程序不需要任何稳定的标识符或者有序的部署、删除或者扩
展 , 应 该 使 用 无 状 态 的 控 制 器 部 署 应 用 程 序 , 比 如 Deployment 或 者
ReplicaSet 。StatefulSet是Kubernetes 1.9版本之前的beta资源,在1.5版
本 之 前 的 任 何 Kubernetes 版 本 都 没 有 。 Pod 所 用 的 存 储 必 须 由
PersistentVolume Provisioner ( 持 久 化 卷 配 置 器 ) 根 据 请 求 配 置
StorageClass,或者由管理员预先配置,当然也可以不配置存储。
为了确保数据安全,删除和缩放StatefulSet不会删除与StatefulSet关
联的卷,可以手动选择性地删除PVC和PV(关于PV和PVC可参考本书8.6节)。
Headless Service
Headless Service命名规则
StatefulSet创建的Pod一般使用Headless Service(无头服务)进行通信,
和 普 通 的 Service 的 区 别 在 于 Headless Service 没 有 ClusterIP , 它 使 用Endpoint进行互相通信,Headless一般的格式为
statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local。
配置说明:
- serviceName为Headless Service的名字,创建StatefulSet时必须
指定Headless Service名称。 - 0...N‒1为Pod所在的序号,从0开始到N‒1。
- statefulSetName为StatefulSet的名字。
- namespace为服务所在的命名空间。
- .cluster.local为Cluster Domain(集群域)。
StatefulSet 与Headless Service 关系
域名规则(必考、必用)
Service 名称:nginx-headless
Namespace:default
StatefulSet 名称:nginx-sts
nginx-sts-0
nginx-sts-1
nginx-sts-2
它们的稳定域名是:
nginx-sts-0.nginx-headless.default.svc.cluster.local
nginx-sts-1.nginx-headless.default.svc.cluster.local
nginx-sts-2.nginx-headless.default.svc.cluster.local
这个域名 Pod 重启、重建都不变 → 这就是 StatefulSet 的 "有状态"。
StatefulSet 必须依赖一个固定的 Service(Headless Service)才能工作。这个 Service 不是用来负载均衡,而是给 Pod 提供稳定的网络标识与域名解析。

Headless Service 是什么?
clusterIP: None
不做负载均衡
作用:直接解析出所有后端 Pod 的 IP 列表
给 StatefulSet 提供稳定域名
2. StatefulSet 为什么必须绑定 Service?
因为 StatefulSet 的 Pod 有两个核心特性:
稳定的网络身份(hostname + 固定域名)
稳定的存储
而稳定域名必须靠 Headless Service 来实现。

-
域名 & 网络关系(最核心)
Headless Service: nginx-sts-svc
Pod 名称 → 稳定 DNS 域名(永不变化)
sts-0 → sts-0.nginx-sts-svc.default.svc.cluster.local
sts-1 → sts-1.nginx-sts-svc.default.svc.cluster.local
sts-2 → sts-2.nginx-sts-svc.default.svc.cluster.local
一句话背下来(面试必问)
Headless Service = StatefulSet 的网络底座
StatefulSet = 有序、有稳定域名、有独立存储的 Pod 管理器
serviceName 字段必须写,否则 StatefulSet 无法创建稳定网络
资源清单
# 1. 必须先有 Headless Service
apiVersion: v1
kind: Service
metadata:
name: nginx-sts-svc
spec:
clusterIP: None # 关键:Headless
selector:
app: nginx
ports:
- port: 80
---
# 2. StatefulSet 绑定 Headless Service
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-sts
spec:
serviceName: nginx-sts-svc # 必须写!
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
# 3. 可选:对外访问用普通 Service(负载均衡)
---
apiVersion: v1
kind: Service
metadata:
name: nginx-sts-normal
spec:
type: ClusterIP
selector:
app: nginx
ports:
- port: 80