六个控制器谐音记忆
1. Deployment —— "地铺门特" → "地铺"
谐音:Deployment ≈ "地铺门特",取前两个字 "地铺"
联想:打地铺的人,谁睡都一样,坏了换一个。
作用:管理无状态服务,保证副本数量,支持滚动更新和回滚。
口诀:地铺随便睡,谁睡都一样 → 无状态、可替换
2. StatefulSet —— "四抬佛赛特" → "四抬佛"
谐音:StatefulSet ≈ "四抬佛赛特",取前三个字 "四抬佛"
联想:四抬大轿抬一尊佛,每尊佛都有名字,不能乱换。
作用:管理有状态服务,Pod 有固定名字、固定存储、有序启动。
口诀:四抬佛,认人不认号 → 有状态、身份固定
3. DaemonSet —— "大门赛特" → "大门"
谐音:DaemonSet ≈ "大门赛特",取前两个字 "大门"
联想:每栋楼的大门口,都得站一个保安。
作用:保证每个节点都运行一个 Pod,新节点自动补上。
口诀:大门保安,一楼一个 → 每台机器都要有
4. Job —— "找不" → "找活"
谐音:Job 本身就是"工作",谐音记成 "找活"
联想:临时工找活干,干完就走。
作用:一次性任务,保证成功完成指定次数后结束。
口诀:找活干,干完就撤 → 一次性任务
5. CronJob —— "克隆找活" → "闹钟找活"
谐音:CronJob ≈ "克隆找活",联想成 "闹钟找活"
联想:闹钟一响,定时去找活干。
作用:定时任务,按 cron 表达式周期性执行。
口诀:闹钟一响,定时找活 → 定时任务
6. ReplicaSet —— "瑞普利卡赛特" → "瑞普"
谐音:ReplicaSet ≈ "瑞普利卡赛特",取前两个字 "瑞普"
联想:"瑞普"像个复读机,只负责数数,保证数量对。
作用:保证指定数量的 Pod 副本运行,一般被 Deployment 管着,不直接用。
口诀:瑞普复读机,只数数 → 保证副本数量
一、Pod 资源控制器
Pod 是 K8s 最小调度单元,但直接创建的 Pod 不具备自愈和扩缩容能力。因此实际生产中用控制器来管理 Pod。
1. ReplicaSet(RS)
保证指定数量的 Pod 副本始终运行
支持标签选择器(selector)匹配 Pod
一般不直接使用,而是通过 Deployment 管理
2. Deployment(最常用)
管理 ReplicaSet,实现滚动更新和版本回滚
无状态服务的首选控制器
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80常用操作:
kubectl set image deploy/nginx-deploy nginx=nginx:1.26 # 滚动更新
kubectl rollout status deploy/nginx-deploy # 查看更新状态
kubectl rollout undo deploy/nginx-deploy # 回滚
kubectl rollout history deploy/nginx-deploy # 查看历史版本3. StatefulSet(有状态)
为每个 Pod 提供稳定的网络标识和持久存储
Pod 名称有序:
web-0、web-1、web-2配合 Headless Service 和 PVC 使用
4. DaemonSet
保证每个节点(或指定节点)都运行一个 Pod
典型场景:日志采集(fluentd)、监控(node-exporter)、网络插件(calico)
5. Job / CronJob
Job:一次性任务,保证成功完成指定次数
CronJob:定时任务,按 cron 表达式周期执行
控制器对比
二、有状态 vs 无状态服务
无状态服务(Stateless)
每个请求不依赖之前的会话,实例可随意替换/扩缩
不保存本地数据,数据存外部(DB、Redis、对象存储)
Pod 名称、IP 可变化,无顺序要求
用 Deployment 管理
例子:Nginx、前端 Web、REST API
有状态服务(Stateful)
实例有唯一身份,需要持久化数据,实例间可能有主从/集群关系
需要:稳定网络标识、稳定持久存储、有序启停
用 StatefulSet 管理,需配合 Headless Service
例子:MySQL 主从、Kafka、ZooKeeper、etcd、Elasticsearch
StatefulSet 三大核心特性
稳定网络标识:
pod-name.service-name.namespace.svc.cluster.local稳定存储:每个 Pod 绑定独立 PVC(volumeClaimTemplates)
有序部署/伸缩:创建按 0→N-1,删除按 N-1→0
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx-headless" # 关联 Headless Service
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates: # 每个 Pod 独立 PVC
- metadata:
name: www
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi对比总结
三、HPA(Horizontal Pod Autoscaler)
HPA 实现 Pod 水平自动扩缩容:根据负载指标自动增减 Pod 副本数。
工作原理
HPA Controller 周期(默认15s)查询指标
↓
对比目标值与当前值,计算期望副本数
↓
desiredReplicas = ceil(currentReplicas × (currentMetric / targetMetric))
↓
调整 Deployment/StatefulSet 的 replicas指标来源
资源指标:CPU、内存(依赖 metrics-server)
自定义指标:QPS、连接数等(依赖 Prometheus Adapter)
外部指标:云服务队列长度等
前置条件
需要安装 metrics-server:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl top nodes
kubectl top podsHPA 示例
命令式创建:
kubectl autoscale deployment nginx-deploy --cpu-percent=50 --min=2 --max=10声明式(推荐):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deploy
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
behavior: # 控制扩缩容行为
scaleDown:
stabilizationWindowSeconds: 300 # 缩容冷却5分钟关键要点
必须设置 resources.requests,否则 CPU 利用率无法计算
扩容快、缩容慢(默认缩容有 5 分钟稳定窗口,防止抖动)
需要配合 Cluster Autoscaler 才能实现节点层面的扩缩容
v2 版本支持多指标、behavior 精细控制
查看 HPA
kubectl get hpa
kubectl describe hpa nginx-hpaNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
nginx-hpa Deployment/nginx-deploy 30%/50% 2 10 3模拟案例
1. Deployment(地铺)—— 部署 3 个 Nginx 副本
场景:跑一个无状态的 Web 服务,坏了自动补,升级不断服。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "64Mi"操作与验证:
kubectl apply -f nginx-deploy.yaml
kubectl get deploy
kubectl get pods -o wide # 看到 3 个 Pod
kubectl scale deploy/nginx-deployment --replicas=5 # 扩到 5 个
kubectl set image deploy/nginx-deployment nginx=nginx:1.26 # 滚动升级
kubectl rollout status deploy/nginx-deployment
kubectl rollout undo deploy/nginx-deployment # 出问题回滚关键点:必须设置 resources.requests.cpu,否则后面 HPA 算不出利用率 。
2. StatefulSet(四抬佛)—— 部署单实例 MySQL
场景:数据库这种“认人”的服务,数据要存在自己的卷上,名字不能变。
apiVersion: v1
kind: Service
metadata:
name: mysql-headless
spec:
clusterIP: None # 关键:Headless Service
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql-headless # 必须和上面 Service 同名
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
value: "root123"
ports:
- containerPort: 3306
volumeMounts:
- name: data
mountPath: /var/lib/mysql
volumeClaimTemplates: # 每个 Pod 自动生成独立 PVC
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi操作与验证:
kubectl apply -f mysql-sts.yaml
kubectl get pods # 看到 mysql-0,名字固定
kubectl get pvc # 看到 data-mysql-0,独立存储卷关键点:clusterIP: None 是 Headless Service,它不分配 ClusterIP,而是直接返回 Pod 的 DNS 记录。这样其他应用可以通过 mysql-0.mysql-headless.default.svc.cluster.local 访问到固定 Pod 。
3. DaemonSet(大门)—— 每台机器跑一个日志采集器
场景:集群里每台节点都需要一个“保安”,负责收集本机日志。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: log-collector
labels:
app: logging
spec:
selector:
matchLabels:
app: logging
template:
metadata:
labels:
app: logging
spec:
containers:
- name: collector
image: busybox
command: ["/bin/sh", "-c", "while true; do echo 'Collecting...'; sleep 30; done"]操作与验证:
kubectl apply -f daemonset.yaml
kubectl get ds
kubectl get pods -o wide # 每个节点上都有一个 log-collector关键点:DaemonSet 不需要写 replicas,Pod 数量自动跟节点数量一致。加了新节点,自动补一个;删了节点,自动撤走 。
4. Job(找活)—— 一次性数据处理任务
场景:跑一个一次性任务,干完就结束,不常驻。
apiVersion: batch/v1
kind: Job
metadata:
name: data-process
spec:
completions: 1
template:
spec:
containers:
- name: processor
image: busybox
command: ["/bin/sh", "-c", "echo 'Processing data...'; sleep 5; echo 'Done!'"]
restartPolicy: Never操作与验证:
kubectl apply -f job.yaml
kubectl get jobs
kubectl get pods # 看到 Pod 状态从 Running → Completed
kubectl logs job/data-process # 看任务输出关键点:restartPolicy 必须是 Never 或 OnFailure,不能是 Always。Job 完成后 Pod 不会自动删除,可以留着看日志,手动清理即可 。
5. CronJob(闹钟找活)—— 每天凌晨 3 点备份
场景:定时任务,每天半夜跑一次“备份”。
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-backup
spec:
schedule: "0 3 * * *" # 每天凌晨 3 点
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: busybox
command: ["/bin/sh", "-c", "echo 'Backing up...'; date"]
restartPolicy: OnFailure操作与验证:
kubectl apply -f cronjob.yaml
kubectl get cronjob
kubectl get jobs # 到点后会自动创建一个 JobCron 表达式速记:
* * * * *
│ │ │ │ └── 星期几(0-6)
│ │ │ └──── 月(1-12)
│ │ └────── 日(1-31)
│ └──────── 时(0-23)
└────────── 分(0-59)常用宏:@daily = 每天午夜,@hourly = 每小时 。
6. ReplicaSet(瑞普)—— 手动保证 4 个 Nginx
场景:了解 ReplicaSet 的底层逻辑。生产一般不直接用,但用来理解“副本数保证”机制很好。
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-rs
spec:
replicas: 4
selector:
matchLabels:
app: nginx-rs
template:
metadata:
labels:
app: nginx-rs
spec:
containers:
- name: nginx
image: nginx操作与验证:
kubectl apply -f rs.yaml
kubectl get rs
kubectl get pods -l app=nginx-rs # 看到 4 个
kubectl delete pod <其中一个> # 删除后 RS 自动补一个
kubectl scale rs/nginx-rs --replicas=2 # 缩到 2 个关键点:ReplicaSet 只管“数量对不对”,不管“版本升级”。Deployment 其实是“管着 ReplicaSet 的包工头”,升级时创建新 RS、慢慢替换旧的 。
串起来练一遍(推荐动手顺序)
# 1. 先跑 Deployment,体验自愈和扩缩容
kubectl apply -f nginx-deploy.yaml
kubectl delete pod <任意一个> # 观察自动补回来
kubectl scale deploy/nginx-deployment --replicas=5
# 2. 跑 Job,体验一次性任务
kubectl apply -f job.yaml
kubectl get pods # 看到 Completed
# 3. 跑 CronJob,等一分钟看自动创建 Job
kubectl apply -f cronjob.yaml
# 4. 跑 DaemonSet,看每个节点是不是都有一个
kubectl apply -f daemonset.yaml
kubectl get pods -o wide
# 5. 跑 StatefulSet + Headless Service(MySQL),看固定名字和独立 PVC
kubectl apply -f mysql-sts.yaml
kubectl get pvcK8s六大控制器介绍
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法