kubernetes(k8s):控制器-Deployment、StatefulSet、DaemonSet、job、cronjob
- 控制器是什么?
- 控制器是k8s内置的管理工具。可以帮助用户实现pod的自动部署、自维护、扩容、滚动更新等功能的自动化程序。
- 为什么要使用控制器?
- 有大量的pod需要维护管理
- 需要维护pod的健康状态
- 控制器可以像机器人一样替用户完成维护管理的工作
Deployment
- 最常用的无状态服务控制器,由Deployment、ReplicaSet、Pod组成、支持集群扩容缩容、滚动更新、自动维护pod可用性及副本数量等功能
- ReplicaSet和Pod由Deployment自动管理,用户无需干预

资源清单文件


[root@master ~]# kubectl create deployment myweb --image=myos:httpd --dry-run=client -o yaml
[root@master ~]# vim mydeploy.yaml
---
kind: Deployment # 资源对象类型
apiVersion: apps/v1 # 版本
metadata: # 元数据
name: mydeploy # 名称
spec: # 详细定义
replicas: 3 # 副本数量
selector: # 定义标签选择器
matchLabels: # 支持 matchExpressions 表达式语法
app: deploy-httpd # 通过标签来确定那个 Pod 由它来管理
template: # 定义用来创建 Pod 的模板,以下为 Pod 定义
metadata:
labels:
app: deploy-httpd #与matchLabels保持一致
spec:
containers:
- name: apache
image: myos:httpd


# 创建控制器
[root@master ~]# kubectl apply -f mydeploy.yaml
deployment.apps/mydeploy created
[root@master ~]# kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
mydeploy 3/3 3 3 1s
# 控制器自动创建 ReplicaSet
[root@master ~]# kubectl get replicasets
NAME DESIRED CURRENT READY AGE
mydeploy-76f96b85df 3 3 3 2s
# 控制器自动创建 Pod
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mydeploy-76f96b85df-5gng9 1/1 Running 0 3s
mydeploy-76f96b85df-vsfrw 1/1 Running 0 3s
mydeploy-76f96b85df-z9x95 1/1 Running 0 3s
# 集群自维护自治理
[root@master ~]# kubectl delete pod --all
pod "mydeploy-76f96b85df-5gng9" deleted
pod "mydeploy-76f96b85df-vsfrw" deleted
pod "mydeploy-76f96b85df-z9x95" deleted
# 删除后自动重新创建
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mydeploy-76f96b85df-7dvwh 1/1 Running 0 7s
mydeploy-76f96b85df-kpbz4 1/1 Running 0 7s
mydeploy-76f96b85df-kr2zq 1/1 Running 0 7s

自动维护副本数量:

集群服务

# 创建集群服务
[root@master ~]# vim websvc.yaml
---
kind: Service
apiVersion: v1
metadata:
name: websvc
spec:
type: ClusterIP
clusterIP: 10.245.1.80
selector:
app: deploy-httpd #与deployment中匹配的标签名保持一致
ports:
- protocol: TCP
port: 80
targetPort: 80
[root@master ~]# kubectl replace --force -f websvc.yaml
service/websvc replaced
[root@master ~]# curl -m 3 http://10.245.1.80
Welcome to The Apache.
在编辑websvc.yaml的时候 末行模式输入:vsplit mydeployment.yaml


集群扩缩容
# 集群扩容
[root@master ~]# kubectl scale deployment mydeploy --replicas 10
deployment.apps/mydeploy scaled
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mydeploy-76f96b85df-kg27l 1/1 Running 0 6s
mydeploy-76f96b85df-q5fzb 1/1 Running 0 6s
mydeploy-76f96b85df-rxhp4 1/1 Running 0 6s
mydeploy-76f96b85df-szf69 1/1 Running 0 6s
mydeploy-76f96b85df-tp2xj 1/1 Running 0 6s
......
# 集群缩容
[root@master ~]# kubectl scale deployment mydeploy --replicas=2
deployment.apps/mydeploy scaled
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mydeploy-76f96b85df-7dvwh 1/1 Running 0 51s
mydeploy-76f96b85df-kr2zq 1/1 Running 0 51s

历史版本信息
# 查看历史版本
[root@master ~]# kubectl rollout history deployment mydeploy
deployment.apps/mydeploy
REVISION CHANGE-CAUSE
1 <none>
# 添加注释信息
[root@master ~]# kubectl annotate deployments mydeploy kubernetes.io/change-cause="httpd.v1"
deployment.apps/mydeploy annotated
[root@master ~]# kubectl rollout history deployment mydeploy
deployment.apps/mydeploy
REVISION CHANGE-CAUSE
1 httpd.v1
# 更新资源清单文件
[root@master ~]# vim mydeploy.yaml
# 在创建容器的镜像下面添加
imagePullPolicy: Always
[root@master ~]# kubectl apply -f mydeploy.yaml
deployment.apps/mydeploy patched
# 更新版本信息
[root@master ~]# kubectl annotate deployments mydeploy kubernetes.io/change-cause="httpd.v2"
deployment.apps/mydeploy annotated
[root@master ~]# kubectl rollout history deployment mydeploy
deployment.apps/mydeploy
REVISION CHANGE-CAUSE
1 httpd.v1
2 httpd.v2


滚动更新
如果在更新的过程中出现任何问题或者故障,可以回滚

Always:只使用仓库中的镜像
Never:只使用本地缓存的镜像
IfNotPresent:优先使用本地缓存的镜像,本地没有,去仓库中找

# 修改镜像,滚动更新集群
[root@master ~]# kubectl set image deployment mydeploy apache=myos:nginx
deployment.apps/mydeploy image updated
# 给新版本添加注释信息
[root@master ~]# kubectl annotate deployments mydeploy kubernetes.io/change-cause="nginx.v1"
deployment.apps/mydeploy annotated
# 查看历史版本信息
[root@master ~]# kubectl rollout history deployment mydeploy
deployment.apps/mydeploy
REVISION CHANGE-CAUSE
1 httpd.v1
2 httpd.v2
3 nginx.v1
# 访问验证服务
[root@master ~]# curl -m 3 http://10.245.1.80
Nginx is running !
重建式更新(Recreate): 节约资源,但是pod很多的情况下,耗时长: 适合资源紧张的情况

滚动式更新(RollingUpdate):按照百分比进行更新 快 适合资源宽松的情况 k8s默认方式


指定容器的名字






版本回滚
# 历史版本与回滚
[root@master ~]# kubectl rollout undo deployment mydeploy --to-revision 1
deployment.apps/mydeploy rolled back
[root@master ~]# kubectl rollout history deployment mydeploy
deployment.apps/mydeploy
REVISION CHANGE-CAUSE
2 httpd.v2
3 nginx.v1
4 httpd.v1
[root@master ~]# curl -m 3 http://10.245.1.80
Welcome to The Apache.


清理资源对象
# 删除控制器时会自动回收自己创建的 Pod
[root@master ~]# kubectl delete deployments mydeploy
deployment.apps "mydeploy" deleted

deploy只关心副本数量,不关心副本创建在哪个节点上:所以,实现不了kube-proxy或calico这类服务(每个节点都必须有且只能有一个)
calico给每个节点配置网络
kube-proxy在每个节点上负责管理lvs集群和网络通讯的
新的控制器:DaemonSet来实现
StatefulSet
作用
StatefulSet,常用于部署有状态的且需要有序启动的应用程序。
Kubernetes 的 StatefulSet 是专为管理有状态应用设计的控制器,通过提供稳定的网络标识、持久化存储及有序部署能力,解决了有状态应用在集群化部署中的核心痛点。
第一个应用完成启动后,才会启动第二个应用,依此类推。
1.稳定的网络标识
StatefulSet 通过 Headless Service(无头服务)为每个 Pod 分配唯一 DNS 名称:
格式为 <pod-name>.<service-name>.<namespace>.svc.cluster.local。
例如 mysql-0.mysql.default.svc.cluster.local 的命名规则,
确保 Pod 重启或迁移后网络标识不变,为依赖固定域名的应用(如数据库集群)提供稳定通信基础。
2.持久化存储
通过 volumeClaimTemplates 动态生成持久卷声明(PVC),为每个 Pod 分配独立存储卷。以 MySQL 集群为例,主节点 mysql-0 和从节点 mysql-1 分别绑定不同 PVC,确保数据隔离。即使 Pod 被重新调度,新 Pod 仍能挂载原 PVC 访问历史数据,实现状态持久化。
3.有序部署与扩展
Pod 的创建、更新和删除严格遵循序号顺序。扩容时按 0→N-1 顺序创建,缩容时按 N-1→0 逆序终止。更新策略支持 RollingUpdate(默认)和 OnDelete:前者从高序号 Pod 开始滚动更新,确保高可用性;后者需手动删除 Pod 触发更新,适用于需要严格控制的场景。
4.自主管理的标识符
StatefulSet 为每个 Pod 分配固定序号(如 web-0、web-1),该标识符在 Pod 生命周期内保持不变,即使 Pod 迁移至其他节点。此特性为分布式系统(如 ZooKeeper 集群)提供成员身份管理的基础。
StatefulSet 的典型应用场景
1.数据库集群
MySQL、PostgreSQL 等数据库需每个实例拥有唯一标识和持久化存储。StatefulSet 通过固定 Pod 名称和独立 PVC,确保主从复制关系稳定,数据不因 Pod 迁移而丢失。
2.分布式存储系统
Cassandra、Elasticsearch 等系统要求每个节点有独立存储卷。
StatefulSet 的 volumeClaimTemplates 机制自动为每个 Pod 分配专属存储,避免数据冲突。
3.消息队列
Kafka、RabbitMQ 等消息中间件依赖有序启动和稳定标识。StatefulSet 确保 Broker 节点按序部署,并通过固定域名实现集群内部通信。
4.缓存系统
Redis 主从模式需主节点和从节点保持固定标识以维护同步关系。StatefulSet 的有序部署能力可确保主从节点按预期顺序启动。
StatefulSet 的操作要点
1.组件协同
完整 StatefulSet 应用由三部分组成:
- Headless Service:提供唯一 DNS 名称,不分配 ClusterIP。
- StatefulSet Controller:管理 Pod 生命周期和有序操作。
- volumeClaimTemplates:动态生成 PVC,绑定持久卷(PV)。
2.配置示例
以 Nginx 为例的 StatefulSet 配置片段:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "web" # 关联 Headless Service
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi



StatefulSet 的注意事项
1.Pod 启动顺序依赖
StatefulSet 默认按序号顺序启动 Pod,前一个 Pod 未就绪时,后续 Pod 不会启动。若某 Pod 启动时间过长,可能阻塞整个部署流程。可通过 podManagementPolicy: Parallel 放宽顺序限制,但需确保应用无严格依赖。
2.存储卷兼容性
volumeClaimTemplates 生成的 PVC 需与存储类(StorageClass)兼容。例如 NFS 存储类需配置 allowVolumeExpansion: true 以支持动态扩容。
3.更新策略选择
RollingUpdate 适用于高可用场景,但更新期间可能短暂降低服务容量;OnDelete 需手动干预,适用于对变更敏感的环境。需根据业务需求权衡。
4.网络标识持久性
Headless Service 的 DNS 名称依赖 CoreDNS 解析,需确保集群 DNS 服务稳定。若 DNS 故障,可能导致 Pod 间通信中断。
DaemonSet

无状态;无顺序;所有节点并发创建
- 无法自定义副本数量
- 所创建的pod与node节点绑定
- 每个node上都会运行一个pod
- 当有新node加入集群时,会为它新增pod副本,当node从集群移除时,这些pod也会被回收,典型应用为kube-proxy
DaemonSet(守护进程集,缩写为ds)和守护进程类似,它在符合匹配条件的节点上均部署一个pod。当有新节点加入集群时,也会为他们新增一个pod,当节点从集群中移除时,这些pod也会被回收,删除DaemonSet将会删除它创建的所有Pod。
- 运行集群存储daemon(守护进程),例如在每个节点上运行Glusterd、Ceph等;
- 在每个节点运行日志收集daemon,例如Fluentd、Logstash;
- 在每个节点运行监控daemon,比如Prometheus Node Exporter、Collectd、Datadog代理、New Relic代理或Ganglia gmond。
DaemonSet更新策略:OnDelete、RollingUpdate




配置案例
[root@master ~]# cp -a mydeploy.yaml myds.yaml
[root@master ~]# vim myds.yaml
---
kind: DaemonSet # 资源对象类型
apiVersion: apps/v1
metadata:
name: myds # 控制器名称
spec:
# replicas: 2 # 删除副本参数
selector:
matchLabels:
app: ds-httpd # 修改标签防止冲突
template:
metadata:
labels:
app: ds-httpd # 修改标签防止冲突
spec:
containers:
- name: apache
image: myos:httpd
imagePullPolicy: Always
[root@master ~]# kubectl apply -f myds.yaml
daemonset.apps/myds created
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS IP NODE
myds-msrcx 1/1 Running 0 10.244.1.11 node-0001
myds-lwq8l 1/1 Running 0 10.244.2.17 node-0002
myds-4wt72 1/1 Running 0 10.244.3.14 node-0003
myds-6k82t 1/1 Running 0 10.244.4.15 node-0004
myds-9c6wc 1/1 Running 0 10.244.5.19 node-0005


清理资源对象
# 删除控制器
[root@master ~]# kubectl delete daemonsets myds
daemonset.apps "myds" deleted

Job/CronJob
Job 控制器

- Job是一个单任务控制器,负责执行一次任务,保证任务在一个或多个pod上执行成功
- CronJob像是Job的升级版,它是基于时间管理的Job控制器

# 资源文件模板
[root@master ~]# kubectl create job myjob --image=myos:8.5 --dry-run=client -o yaml -- sleep 3
[root@master ~]# vim myjob.yaml
---
kind: Job
apiVersion: batch/v1
metadata:
name: myjob
spec:
template: # 以下定义 Pod 模板
metadata: {}
spec:
restartPolicy: OnFailure
containers:
- name: myjob
image: myos:8.5
command: ["/bin/sh"]
args:
- -c
- |
sleep 3
exit $((RANDOM%2))
[root@master ~]# kubectl apply -f myjob.yaml
job.batch/myjob created
# 失败了会重启
[root@master ~]# kubectl get pods -l job-name=myjob -w
NAME READY STATUS RESTARTS AGE
myjob--1-lrtbk 1/1 Running 0 2s
myjob--1-lrtbk 0/1 Error 0 4s
myjob--1-lrtbk 1/1 Running 1 (1s ago) 5s
myjob--1-lrtbk 0/1 Completed 1 9s
[root@master ~]# kubectl get jobs.batch
NAME COMPLETIONS DURATION AGE
myjob 1/1 8s 12s
# 删除Job控制器
[root@master ~]# kubectl delete -f myjob.yaml
job.batch "myjob" deleted





CronJob


# 资源对象模板
[root@master ~]# kubectl create cronjob mycj --image=myos:8.5 --schedule='* * * * *' --dry-run=client -o yaml -- sleep 3
[root@master ~]# vim mycj.yaml
---
kind: CronJob
apiVersion: batch/v1
metadata:
name: mycj
spec:
schedule: "* * * * *"
jobTemplate: # 以下定义 Job 模板
metadata: {}
spec:
template:
metadata: {}
spec:
restartPolicy: OnFailure
containers:
- name: myjob
image: myos:8.5
command: ["/bin/sh"]
args:
- -c
- |
sleep 3
exit $((RANDOM%2))
[root@master ~]# kubectl apply -f mycj.yaml
cronjob.batch/mycj created
[root@master ~]# kubectl get cronjobs
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
mycj * * * * 1-5 False 0 <none> 4s
# 按照时间周期,每分钟触发一个任务
[root@master ~]# kubectl get jobs -w
NAME READY STATUS RESTARTS
mycj-27808172--1-w6sbx 0/1 Pending 0
mycj-27808172--1-w6sbx 0/1 ContainerCreating 0
mycj-27808172--1-w6sbx 1/1 Running 0
mycj-27808172--1-w6sbx 0/1 Completed 1
# 保留三次结果,多余的会被删除
[root@master ~]# kubectl get jobs
NAME COMPLETIONS DURATION AGE
mycj-27605367 1/1 31s 3m30s
mycj-27605368 1/1 31s 2m30s
mycj-27605369 1/1 31s 90s
mycj-27605370 0/1 30s 30s
[root@master ~]# kubectl get jobs
NAME COMPLETIONS DURATION AGE
mycj-27605368 1/1 31s 2m33s
mycj-27605369 1/1 31s 93s
mycj-27605370 1/1 31s 33s
# 删除CJ控制器
[root@master ~]# kubectl delete -f mycj.yaml
cronjob.batch "mycj" deleted






设置时区:

更多推荐
所有评论(0)