• 控制器是什么?
    • 控制器是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

设置时区:

更多推荐