k8s学习笔记6——Controller控制器
- k8s内建多种controller,相当于状态机,用来控制pod的具体状态和行为
- k8s有5种控制器,分别对应处理 无状态应用、有状态应用、守护型应用和批处理应用
- Deployment
- StatefulSet
- DaemonSet
- Job
- CronJob
一. Deployment
- 无状态服务控制器,由Deployment、ReplicaSet、Pod组成,支持集群扩缩容、滚动更新、版本回滚以及自动维护Pod可用性和副本数量 等功能
- ReplicaSet和Pod 由 Deployment 自动管理,用户无需干预

需要了解的配置项就是spec下面几个选项:
- replicas:指定副本数量,其实就是当前rs创建出来的pod的数量,默认为1
- selector:选择器,它的作用是建立pod控制器和pod之间的关联关系,采用的Label Selector机制,在pod模板上定义label,在控制器上定义选择器,就可以表明当前控制器能管理哪些pod了
- template:模板,就是当前控制器创建pod所使用的模板
imagePullPolicy: 是确保容器总是使用最新版本的镜像
- IfNotPresent: 仅当镜像在本地不存在时,才被拉取
- Never: 设镜像已经存在于本地,不会尝试拉取镜像
- always: 确保每次容器启动时都会拉取最新的镜像
1)Deployment控制器的资源清单文件:
1 [root@master ~]# vim mydeploy.yaml 2 --- 3 kind: Deployment # 资源对象类型 4 apiVersion: apps/v1 # 版本 5 metadata: # 元数据 6 name: myweb # 名称 7 spec: # 详细定义 8 replicas: 2 # 副本数量 9 strategy: # 策略 10 type: RollingUpdate # 滚动更新策略 11 rollingUpdate: # 滚动更新 12 maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数 13 maxUnavailable: 30% # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数 14 selector: # 定义标签选择器 15 matchLabels: # 支持 matchExpressions 表达式语法 16 app: httpd # 通过标签来确定那个 Pod 由它来管理 17 template: # 定义用来创建 Pod 的模板,以下为 Pod 定义 18 metadata: # Pod元数据 19 labels: # 名称由控制器生成 20 app: httpd # 这里只能定义标签 21 spec: # Pod的详细定义 22 restartPolicy: Always # 重启策略 23 containers: # 容器定义 24 - name: webserver # 容器名称 25 image: myos:httpd # 创建容器使用的容器 26 imagePullPolicy: Always # 镜像下载策略
2)扩缩容
1 [root@master ~]# kubectl scale deployment myweb(Deployment名字) --replicas=3(指定Pod数量) 2 3 # 1、创建deployment 4 [root@master ~]# kubectl create -f nginx-deployment.yaml --record=true 5 deployment.apps/nginx-deployment created 6 7 # 2、查看deployment 8 # UP-TO-DATE 最新版本的pod的数量 9 # AVAILABLE 当前可用的pod的数量 10 # - your_namespace 你的命名空间名称 11 [root@master ~]# kubectl get deploy myweb -n your_spacename 12 NAME READY UP-TO-DATE AVAILABLE AGE 13 nginx-deployment 3/3 3 3 15s 14 15 [root@master ~]# kubectl get pods -n your_namespace 16 NAME READY STATUS RESTARTS AGE 17 nginx-deployment-6696798b78-d2c8n 1/1 Running 0 4m19s 18 nginx-deployment-6696798b78-jxmdq 1/1 Running 0 94s 19 nginx-deployment-6696798b78-mktqv 1/1 Running 0 93s
3)镜像更新
- deployment支持2种更新策略:重建更新 & 滚动更新
strategy:指定新的Pod替换旧的Pod的策略, 支持两个属性: type:指定策略类型,支持两种策略 Recreate:在创建出新的Pod之前会先杀掉所有已存在的Pod RollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本Pod rollingUpdate:当type为RollingUpdate时生效,用于为RollingUpdate设置参数,支持两个属性: maxUnavailable:用来指定在升级过程中不可用Pod的最大数量,默认为25%。 maxSurge: 用来指定在升级过程中可以超过期望的Pod的最大数量,默认为25%。
4)滚动更新
- deployment支持版本升级过程中的暂停、继续功能以及版本回退等诸多功能,下面具体来看.
- kubectl rollout: 版本升级相关功能,支持下面的选项
- status 显示当前升级状态
- history 显示 升级历史记录
- pause 暂停版本升级过程
- resume 继续已经暂停的版本升级过程
- restart 重启版本升级过程
- undo 回滚到上一级版本(可以使用–to-revision回滚到指定版本)
# 修改镜像,滚动更新集群 [root@master ~]# kubectl set image deployment myweb webserver=myos:nginx deployment.apps/myweb image updated # 给新版本添加注释信息 [root@master ~]# kubectl annotate deployments myweb kubernetes.io/change-cause="nginx.v1" deployment.apps/myweb annotated # 查看历史版本信息 [root@master ~]# kubectl rollout history deployment myweb deployment.apps/myweb REVISION CHANGE-CAUSE 1 httpd:v1 2 nginx.v1 # 访问验证服务 [root@master ~]# curl -m 3 http://10.245.1.80 Nginx is running !
5)金丝雀发布
- Deployment控制器支持控制更新过程中的控制,如“暂停(pause)”或“继续(resume)”更新操作。
- 比如有一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新版本的Pod应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布。
# 1、更新deployment的版本,并配置暂停deployment [root@master ~]# kubectl set image deploy your_deploy_name nginx=nginx:1.17.4 -n your_namespace && kubectl rollout pause deployment your_deploy_name -n your_namespace deployment.apps/nginx-deployment image updated deployment.apps/nginx-deployment paused # 2、观察更新状态 # - your_deploy_name 你的deploy名称 # - your_namespace 你的命名空间名称 [root@master ~]# kubectl rollout status deploy your_deploy_name -n your_namespace Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 4 new replicas have been updated... # 3、监控更新的过程,可以看到已经新增了一个资源,但是并未按照预期的状态去删除一个旧的资源,就是因为使用了pause暂停命令 # - your_namespace 你的命名空间名称 [root@master ~]# kubectl get rs -n your_namespace -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES nginx-deployment-5d89bdfbf9 3 3 3 19m nginx nginx:1.17.1 nginx-deployment-675d469f8b 0 0 0 14m nginx nginx:1.17.2 nginx-deployment-6c9f56fcfb 2 2 2 3m16s nginx nginx:1.17.4 # - your_namespace 你的命名空间名称 [root@master ~]# kubectl get pods -n your_namespace NAME READY STATUS RESTARTS AGE nginx-deployment-5d89bdfbf9-rj8sq 1/1 Running 0 7m33s nginx-deployment-5d89bdfbf9-ttwgg 1/1 Running 0 7m35s nginx-deployment-5d89bdfbf9-v4wvc 1/1 Running 0 7m34s nginx-deployment-6c9f56fcfb-996rt 1/1 Running 0 3m31s nginx-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 3m31s # 4、确保更新的pod没问题了,继续更新 # - your_deploy_name 你的deploy名称 # - your_namespace 你的命名空间名称 [root@master ~]# kubectl rollout resume deploy your_deploy_name -n your_namespace deployment.apps/nginx-deployment resumed # 5、查看最后的更新情况 # - your_namespace 你的命名空间名称 [root@master ~]# kubectl get rs -n your_namespace -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES nginx-deployment-5d89bdfbf9 0 0 0 21m nginx nginx:1.17.1 nginx-deployment-675d469f8b 0 0 0 16m nginx nginx:1.17.2 nginx-deployment-6c9f56fcfb 4 4 4 5m11s nginx nginx:1.17.4 # - your_namespace 你的命名空间名称 [root@master ~]# kubectl get pods -n your_namespace NAME READY STATUS RESTARTS AGE nginx-deployment-6c9f56fcfb-7bfwh 1/1 Running 0 37s nginx-deployment-6c9f56fcfb-996rt 1/1 Running 0 5m27s nginx-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 5m27s nginx-deployment-6c9f56fcfb-rf84v 1/1 Running 0 37s
6)删除控制器
# 删除控制器方法1 [root@master ~]# kubectl delete deployments myweb deployment.apps "myweb" deleted # 删除控制器方法2 [root@master ~]# kubectl delete -f mydeploy.yaml deployment.apps "myweb" deleted
二. DaemonSet
DaemonSet控制器
- 无法自定义副本数量
- 所创建的Pod与node节点绑定
- 每个node上都会允许一个Pod
- 当有新Node加入集群时,会为他新增Pod副本,当Node从集群移除时,这些Pod也会被回收,典型应用:kube-proxy

1)DaemonSet控制器的资源清单文件
1 [root@master ~]# vim myds.yaml 2 --- 3 kind: DaemonSet # 资源对象类型 4 apiVersion: apps/v1 # 版本 5 metadata: # 元数据 6 name: myds # 名称 7 spec: # 详细定义 8 selector: # 定义标签选择器 9 matchLabels: # 支持 matchExpressions 表达式语法 10 app: httpd # 通过标签来确定那个 Pod 由它来管理 11 template: # 定义用来创建 Pod 的模板,以下为 Pod 定义 12 metadata: 13 labels: 14 app: httpd 15 spec: 16 restartPolicy: Always 17 containers: 18 - name: webserver 19 image: myos:httpd 20 imagePullPolicy: Always 21 22 [root@master ~]# kubectl apply -f myds.yaml 23 daemonset.apps/myds created 24 25 [root@master ~]# kubectl get pods -o wide 26 NAME READY STATUS RESTARTS AGE IP NODE 27 NOMINATED NODE READINESS GATES 28 myds-78b2h 1/1 Running 0 31s 10.244.153.154 node-0005 29 <none> <none> 30 myds-78pgb 1/1 Running 0 31s 10.244.243.226 node-0003 31 <none> <none> 32 myds-cg2sv 1/1 Running 0 31s 10.244.147.30 node-0002 33 <none> <none> 34 myds-pp7s6 1/1 Running 0 31s 10.244.240.162 node-0004 35 <none> <none> 36 myds-qrp82 1/1 Running 0 32s 10.244.21.155 node-0001 37 <none> <none>
2)DS控制器 受Taint污点策略影响
1 [root@master ~]# kubectl taint node node-0001 k=v:NoSchedule 2 node/node-0001 tainted 3 4 [root@master ~]# kubectl delete -f myds.yaml 5 daemonset.apps "myds" deleted 6 7 [root@master ~]# kubectl apply -f myds.yaml 8 daemonset.apps/myds created 9 10 # 有污点不会部署,特殊需求可以设置容忍策略 11 [root@master ~]# kubectl get pods 12 NAME READY STATUS RESTARTS AGE 13 myds-fxlgq 1/1 Running 0 33s 14 myds-j5779 1/1 Running 0 33s 15 myds-nb6bv 1/1 Running 0 33s 16 myds-vkk6x 1/1 Running 0 33s 17 18 # 删除污点后会立即部署 19 [root@master ~]# kubectl taint node node-0001 k=v:NoSchedule- 20 node/node-0001 untainted 21 [root@master ~]# kubectl get pods 22 NAME READY STATUS RESTARTS AGE 23 myds-bq2nv 1/1 Running 0 3s 24 myds-fxlgq 1/1 Running 0 114s 25 myds-j5779 1/1 Running 0 114s 26 myds-nb6bv 1/1 Running 0 114s 27 myds-vkk6x 1/1 Running 0 114s 28 29 # 删除控制器 30 [root@master ~]# kubectl delete -f myds.yaml 31 daemonset.apps "myds" deleted
三. Job / CronJob
1)Job
- 单任务控制器,执行一次任务
- CronJob是Job的升级版,基于时间管理的Job控制器
- restartPOlicy策略会判断exit状态码,状态为0表示正常,其他都是失败
- 任务执行出错,会重新执行该任务
[root@master ~]# vim myjob.yaml --- kind: Job apiVersion: batch/v1 metadata: name: myjob spec: template: # 以下定义 Pod 模板 spec: restartPolicy: OnFailure containers: - name: myjob image: myos:8.5 command: ["/bin/bash"] 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-plnhc 1/1 Running 0 3s myjob-plnhc 0/1 Completed 0 4s myjob-plnhc 0/1 Completed 0 5s myjob-plnhc 0/1 Completed 0 6s myjob-plnhc 0/1 Completed 0 6s [root@master ~]# kubectl get jobs.batch NAME COMPLETIONS DURATION AGE myjob 1/1 6s 91s # 删除Job控制器 [root@master ~]# kubectl delete -f myjob.yaml job.batch "myjob" deleted
2)CronJob
- 时间定义 schedule: 分 时 日 月 周
- 会按照时间周期运行
- 只保留执行三次的结果,多余被删除
[root@master ~]# vim mycj.yaml --- kind: CronJob apiVersion: batch/v1 metadata: name: mycj spec: schedule: "* * * * 1-5" jobTemplate: # 以下定义Job模板 spec: template: spec: restartPolicy: OnFailure containers: - name: myjob image: myos:8.5 command: ["/bin/bash"] 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> 14s # 按照时间周期,每分钟触发一个任务 [root@master ~]# kubectl get jobs -w NAME COMPLETIONS DURATION AGE mycj-28263259 1/1 29s 70s mycj-28263260 1/1 6s 10s mycj-28263261 0/1 0s mycj-28263261 0/1 0s 0s mycj-28263261 0/1 2s 2s mycj-28263261 0/1 5s 5s mycj-28263261 0/1 5s 5s # 保留三次结果,多余的会被删除 [root@master ~]# kubectl get jobs NAME COMPLETIONS DURATION AGE mycj-28263261 1/1 24s 2m13s mycj-28263262 1/1 27s 73s mycj-28263263 1/1 6s 13s # 删除CJ控制器 [root@master ~]# kubectl delete -f mycj.yaml cronjob.batch "mycj" deleted
四. StatefulSet
Statefulset主要是用来部署有状态应用
- 无状态应用中所有Pod之间是无法区分的,它们都是一样的,从而不需要考虑应用在哪个node上运行,能够进行随意伸缩和扩展。
- 有状态应用中每个Pod都是各不相同的,各自具有唯一的网络标识符和存储
- 对于StatefulSet中的Pod,每个Pod挂载自己独立的存储,如果一个Pod出现故障,从其他节点启动一个同样名字的Pod,要挂载上原来Pod的存储继续以它的状态提供服务。适合StatefulSet的业务包括数据库服务MySQL 和 PostgreSQL,集群化管理服务Zookeeper、etcd等有状态服务
- 使用StatefulSet,Pod仍然可以通过漂移到不同节点提供高可用,而存储也可以通过外挂的存储来提供高可靠性,StatefulSet做的只是将确定的Pod与确定的存储关联起来保证状态的连续性。

- StatefulSet控制器
- StatefulSet旨在与有状态的应用及分布式统一使用,涉及了Headless服务、存储卷、DNS等相关知识,是一个宽泛而复杂的话题
- Headless服务
- 在配置StatefulSets的时候,首先要定义一个Headless的服务
- 在创建Pod的时候会自动把<Pod名称>注册为域名
1)headless服务
在 Kubernetes 中,Headless Service(无头服务) 是一种特殊类型的 Service,其核心特点是不分配 ClusterIP,而是直接返回后端 Pod 的 DNS 记录。它专为需要直接访问 Pod 的场景设计,尤其适用于有状态应用(如数据库、分布式存储)
Headless Service与普通Service的区别
| 特性 | 普通 Service (ClusterIP) | Headless Service |
|---|---|---|
| ClusterIP | 分配虚拟 IP(如 10.96.xx.xx) |
显式设置为 None(无 ClusterIP) |
| DNS 解析 | 解析到 Service 的 ClusterIP | 直接解析到后端 Pod 的 IP 列表 |
| 负载均衡 | 通过 kube-proxy 实现负载均衡 | 无负载均衡,客户端直连 Pod |
| 适用场景 | 无状态应用(如 Web 服务) | 有状态应用(如 MySQL、Redis 集群) |
示例 YAML 配置:
# 配置 headless 服务 [root@master ~]# vim mysvc2.yaml --- kind: Service apiVersion: v1 metadata: name: mysvc2 # 服务名称 spec: type: ClusterIP clusterIP: None # 设置IP为None,表明这是一个headless服务 selector: app: httpd ports: - protocol: TCP port: 80 targetPort: 80 [root@master ~]# kubectl get service mysvc2 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mysvc2 ClusterIP None <none> 80/TCP 17s
Headless Service核心价值
1. 提供稳定的网络标识
当与 StatefulSet 结合使用时,每个 Pod 会获得一个固定且可预测的 DNS 名称,格式为: <pod-name>.<headless-service>.<namespace>.svc.cluster.local
例如:web-0.nginx-headless.default.svc.cluster.local
2. 支持 Pod 级服务发现
客户端可通过 DNS 查询获取所有后端 Pod 的 IP 地址,实现:
-
- 直接连接特定 Pod(如主从数据库)
- 自定义负载均衡逻辑(如客户端分片)
- 集群内成员发现(如 etcd 节点互连)
3. 与 StatefulSet 深度集成
StatefulSet 管理的 Pod 具有固定名称和有序部署特性,配合 Headless Service 可实现:
- 稳定的 DNS 记录(Pod 重建后 DNS 名称不变)
- 有序扩缩容(扩容时新 Pod 通过 DNS 发现现有成员)
- 持久化存储绑定(PVC 随 Pod 名称持久化)
2)StatefulSet资源配置文件
1 [root@master ~]# vim mysts.yaml 2 --- 3 kind: StatefulSet # 资源对象类型 4 apiVersion: apps/v1 # 版本 5 metadata: # 元数据 6 name: mysts # 名称 7 spec: # 详细定义 8 serviceName: mysvc2 # 关联Headless Service 9 replicas: 3 # 副本数量 10 selector: # 定义标签选择器 11 matchLabels: # 支持 matchExpressions 表达式语法 12 app: httpd # 通过标签来确定那个 Pod 由它来管理 13 template: # 定义用来创建 Pod 的模板,以下为 Pod 定义 14 metadata: 15 labels: 16 app: httpd 17 spec: 18 restartPolicy: Always 19 containers: 20 - name: webserver 21 image: myos:httpd 22 imagePullPolicy: Always 23 24 [root@master ~]# kubectl apply -f mysts.yaml 25 statefulset.apps/mysts created 26 27 [root@master ~]# kubectl get pods 28 NAME READY STATUS RESTARTS AGE 29 mysts-0 1/1 Running 0 8s 30 mysts-1 1/1 Running 0 7s 31 mysts-2 1/1 Running 0 6s 32 33 [root@master ~]# host mysts-0.mysvc2.default.svc.cluster.local 10.245.0.10 34 Using domain server: 35 Name: 10.245.0.10 36 Address: 10.245.0.10 #53 37 Aliases: 38 mysts-0.mysvc2.default.svc.cluster.local has address 10.244.153.159 39 40 [root@master ~]# host mysvc2.default.svc.cluster.local 10.245.0.10 41 Using domain server: 42 Name: 10.245.0.10 43 Address: 10.245.0.10 #53 44 Aliases: 45 mysvc2.default.svc.cluster.local has address 10.244.147.37 46 mysvc2.default.svc.cluster.local has address 10.244.153.159 47 mysvc2.default.svc.cluster.local has address 10.244.240.164 48 49 # 删除sts控制器 50 [root@master ~]# kubectl delete -f mysts.yaml -f mysvc2.yaml 51 statefulset.apps "mysts" deleted 52 service "mysvc2" deleted
总结
Headless Service 的核心本质是:
通过 DNS 暴露 Pod 的直接访问入口,而非代理层。
其核心价值在于:
✅ 为 StatefulSet 提供稳定的网络标识
✅ 支持有状态应用的集群发现与通信
✅ 实现客户端直连 Pod 的自定义逻辑
使用模式固定:
# Headless Service 声明 spec: clusterIP: None # 无 ClusterIP selector: ... # 关联 Pod # StatefulSet 引用 spec: serviceName: "your-headless-service" # 绑定 Headless Service
五. Deployment 与 StatefulSet 的区别
1)核心差异
- Deployment适用于无状态应用,不维护Pod的唯一标识和存储,通过ReplicaSet管理副本数量,支持滚动更新和回滚。
- StatefulSet适用于有状态应用,为Pod提供唯一且持久的网络标识符,绑定持久化存储,并按照定义的顺序管理Pod的创建、更新和删除。
2)具体区别
-
- 1. 状态管理
- Deployment不维护Pod的唯一身份,Pod可被任意替换且无需保持数据一致性。
- StatefulSet为每个Pod分配固定且持久的标识符(如
pod-name-0),即使重新调度也能保持唯一性。
- Deployment不维护Pod的唯一身份,Pod可被任意替换且无需保持数据一致性。
-
2. 存储与网络标识
- Deployment不绑定持久化存储,Pod数据随实例消失。
- StatefulSet通过PersistentVolumeClaim绑定存储,数据在Pod重启或重新调度时保留。
- Deployment不绑定持久化存储,Pod数据随实例消失。
-
3. 扩容与更新策略
- Deployment支持滚动更新(逐个替换Pod),确保服务高可用。
- StatefulSet通常不支持滚动更新(需考虑数据一致性),需按顺序部署或缩容。
- Deployment支持滚动更新(逐个替换Pod),确保服务高可用。
-
4. 适用场景
- Deployment适合微服务、Web应用等无需持久化存储的应用。
- StatefulSet适用于数据库集群、分布式缓存等需要稳定网络标识和持久存储的场景。
- Deployment适合微服务、Web应用等无需持久化存储的应用。
- 1. 状态管理
posted on 2025-09-18 14:56 Karlkiller 阅读(35) 评论(0) 收藏 举报
浙公网安备 33010602011771号