joeの小窝

Loading...

k8s控制器详解

k8s控制器

1、deployment

1、什么是deploy?

img

  • 是一个k8s的资源对象,管理无状态的应用(就是没有顺序的,后面还有一个控制器是有状态,也就是有序的)

  • 就是一个pod管理器,确保了一定数量的pod始终运行

  • 特性

    • 支持pod的多副本

    • 支持pod的更新策略

    • 能够控制校正pod

    • 要求pod无状态,无序的,没有顺序的

    • 为pod和replicaset(rs)提供了声明式更新的能力

  • deploy核心原理

    • 就是通过标签来管理pod,不要随意的修改标签

    • 为什么一定要用标签来进行关联了?

      • 用ip来进行关联的话,这个pod如果被删除了,pod的ip就会变动

      • 只需要用标签来关联一组pod即可

2、deploy创建

  • 通过命令行生成配置文件 kubectl create
[root@master01 test]# kubectl create deployment web1 --image=nginx --replicas 3 --dry-run=client -o yaml > web1.yml

# 查看deploy和rs资源
[root@master01 test]# kubectl get deployments.apps 
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web1   3/3     3            3           5s
[root@master01 test]# kubectl get rs
NAME              DESIRED   CURRENT   READY   AGE
web1-5756d98cd9   3         3         3       27s

# 查看pod
[root@master01 test]# kubectl get pod -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP              NODE   NOMINATED NODE   READINESS GATES
web1-5756d98cd9-gxwbt   1/1     Running   0          33s   10.246.73.161   node   <none>           <none>
web1-5756d98cd9-lhc7m   1/1     Running   0          33s   10.246.73.163   node   <none>           <none>
web1-5756d98cd9-mrklt   1/1     Running   0          33s   10.246.73.162   node   <none>           <none>

3、deploy的字段

[root@master01 test]# cat web1.yml 
apiVersion: apps/v1
kind: Deployment
metadata:  # deploy的元数据
  creationTimestamp: null
  labels:  # deploy的标签,用这个来关联一组pod
    app: web1
  name: web1   # deploy的名字
spec:
  replicas: 3  # 副本数量,3个pod
  selector:  # 标签选择器
    matchLabels:  # 匹配的规则
      app: web1  # app=web1
  strategy: {}
  template:  # pod模版
    metadata:  # pod的描述信息   pod不需要name和namesapce,因为多个pod中name是唯一的,所以不能写name,否则都是这个名字,ns也是上面就定义了的,不能跨多个命名空间管理pod
      creationTimestamp: null
      labels:   # pod的标签,一定要与之前的一样,这样deploy才能关联这个pod
        app: web1
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}



# 查看deploy和rs



4、修改副本数量

  • edit在线修改,但是不会保存到配置文件,适用于测试环境,想要立即生效的

  • 可以查看当前运行pod的yml文件

[root@master01 test]# kubectl edit deployments.apps web1 

# 修改副本数量为2

  replicas: 2

[root@master01 test]# kubectl get deployments.apps 
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web1   2/2     2            2           11m

[root@master01 test]# kubectl get rs
NAME              DESIRED   CURRENT   READY   AGE
web1-5756d98cd9   2         2         2       11m

[root@master01 test]# kubectl get pod 
NAME                    READY   STATUS    RESTARTS   AGE
web1-5756d98cd9-lhc7m   1/1     Running   0          11m
web1-5756d98cd9-mrklt   1/1     Running   0          11m

  • 命令行修改
[root@master01 test]# kubectl scale deployment --replicas=3 web1 
deployment.apps/web1 scaled
[root@master01 test]# kubectl get pod 
NAME                    READY   STATUS    RESTARTS   AGE
web1-5756d98cd9-9l5x4   1/1     Running   0          3s
web1-5756d98cd9-lhc7m   1/1     Running   0          12m
web1-5756d98cd9-mrklt   1/1     Running   0          12m
[root@master01 test]# 

  • 修改yaml文件,然后apply应用文件即可

5、deploy更新的策略

  • 有2种更新策略

    • 一个是重建,就是先删除之前所有pod,再次创建新的pod

    • 一个是滚动更新,逐步替换旧pod,创建新的pod,保证了服务的持续可用,这个是默认的deploy更新的策略

  • 更新的话,这个rs会有多个版本

  • 重建策略

[root@master01 test]# cat web1.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web1
  name: web1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web1
  strategy:
    type: Recreate  # 策略为重建
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web1
    spec:
      containers:
      - image: httpd
        name: nginx


# 如果后续更新镜像的话,就会先删除所有的容器,然后再次创建新的pod
  • 滚动更新

    • maxSurge 先创建多少个,再删除多少个,更新的时候,允许超过副本数的最大pod数, 设置1 副本数量为3 最多可以同时存在4个pod

    • maxUnavailable 先删除多少个,再创建多少个 更新时,允许不可用最大pod数, 设置为0 则必须保证至少3个pod可用

    • 默认值是25% 2个都是最优的,默认这个情况最优解

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # 最多可超出期望副本数的 Pod 数量(绝对数或百分比)
      maxUnavailable: 0  # 更新期间最多不可用的 Pod 数量(绝对数或百分比)
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: nginx
        image: nginx:1.21

6、镜像升级和回滚

  • 主要应用于镜像升级,就是镜像的版本更换

  • 回滚用的很少

  • 镜像更新的方式

    • edit,yaml文件修改

    • kubectl set image 修改

[root@master01 test]# kubectl set  image deploy web1 nginx=nginx:1.9
deployment.apps/web1 image updated

# 查看这个deploy的更新的历史记录
[root@master01 test]# kubectl rollout  history deployment web1
deployment.apps/web1 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

[root@master01 test]# kubectl get rs
NAME             DESIRED   CURRENT   READY   AGE
web1-9b456b48f   0         0         0       112s
web1-9f7649757   2         2         2       74s

[root@master01 test]# kubectl get pod 
NAME                   READY   STATUS    RESTARTS   AGE
web1-9f7649757-p8wv2   1/1     Running   0          82s
web1-9f7649757-xtv4s   1/1     Running   0          73s

  • 回滚的操作

    • 在升级的时候,打个标记,这样的话,容易标识

    • kubectl rollout 选项

      • status 显示当前升级的状态

      • history 显示升级的记录

      • pause 暂停版本升级

      • resume 继续已经暂停的版本升级过程

      • restart 重启版本升级过程

      • undo 回滚到上一级版本, --to-revison 回滚到指定的版本

# 打上标记
[root@master01 test]# kubectl set image deploy web1 nginx=nginx:latest --record=true
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/web1 image updated

# 查看镜像版本历史信息
[root@master01 test]# kubectl rollout history deployment web1 
deployment.apps/web1 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         kubectl set image deploy web1 nginx=nginx:latest --record=true

# 回滚到上一个版本

[root@master01 test]# kubectl rollout undo deployment web1
deployment.apps/web1 rolled back
# 发现回滚了
[root@master01 test]# kubectl get deployments.apps -o wide
NAME   READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES      SELECTOR
web1   2/2     2            2           7m    nginx        nginx:1.9   app=web1

# 更加精确的撤销,指定版本的话

[root@master01 test]# kubectl rollout undo deployment web1 --to-revision=1
deployment.apps/web1 rolled back
[root@master01 test]# kubectl get ^C
[root@master01 test]# kubectl get deployments.apps -o wide
NAME   READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS   IMAGES   SELECTOR
web1   2/2     2            2           9m2s   nginx        httpd    app=web1

7、金丝雀发布(灰度发布)

  • 就是在镜像的升级过程中,一部分新创建的pod出来后,暂停更新,测试这个新版本的pod接收流量,如果可以预期的运行,就继续滚动更新,否则就回滚

  • 降低了风险,平滑无感回滚,实现真正的真实环境验证

# 将镜像升级并暂停更新
[root@master01 test]# kubectl set image deploy web1 nginx=nginx:latest && kubectl rollout pause deployment web1 

# 查看更新状态,有一个更新完成了,还是一个没有更新好
[root@master01 test]# kubectl rollout status deployment web1
Waiting for deployment "web1" rollout to finish: 1 out of 2 new replicas have been updated...

# 多创建了一个
[root@master01 test]# kubectl get pod -w
NAME                    READY   STATUS    RESTARTS   AGE
b1                      1/1     Running   0          8m27s
web1-7d54584655-rkpq7   1/1     Running   0          16s
web1-7d54584655-xmjcj   1/1     Running   0          16s


web1-65cc44b58-bffbw    0/1     Pending   0          0s
web1-65cc44b58-bffbw    0/1     Pending   0          0s
web1-65cc44b58-bffbw    0/1     ContainerCreating   0          0s
web1-65cc44b58-bffbw    0/1     ContainerCreating   0          1s
web1-65cc44b58-bffbw    1/1     Running             0          2s

# 三个pod
[root@master01 test]# kubectl get pod 
NAME                    READY   STATUS    RESTARTS   AGE
b1                      1/1     Running   0          10m
web1-65cc44b58-bffbw    1/1     Running   0          106s
web1-7d54584655-rkpq7   1/1     Running   0          2m37s
web1-7d54584655-xmjcj   1/1     Running   0          2m37s

# 测试在新的pod上面访问

[root@master01 test]# kubectl get pod web1-65cc44b58-bffbw -o wide
NAME                   READY   STATUS    RESTARTS   AGE    IP              NODE   NOMINATED NODE   READINESS GATES
web1-65cc44b58-bffbw   1/1     Running   0          3m5s   10.246.73.187   node   <none>           <none>

[root@master01 test]# curl 10.246.73.187 -I
HTTP/1.1 200 OK

# 继续更新

[root@master01 test]# kubectl rollout resume deployment web1
deployment.apps/web1 resumed

# 之前的pod被删除了
# 现在运行的全是新创建的pod
[root@master01 test]# kubectl get pod 
NAME                   READY   STATUS    RESTARTS   AGE
b1                     1/1     Running   0          14m
web1-65cc44b58-bffbw   1/1     Running   0          4m58s
web1-65cc44b58-tgkgh   1/1     Running   0          18s

2、Statefulset控制器

  • 管理的是有序的

    • 就是每个pod的都有唯一的标识符

    • 0-N-1的序号,顺序创建,sts-0 sts-1 sts-2

    • 串行的,就是先启动第一个pod,然后再启动第二个pod,删除也是一样的

    • 有序更新

    • 滚动更新这个pod名字还是保持不变的,还是0-n-1的序号

  • 如果规模非常的大,删除和创建的速度特别的慢

  • 要求,需要这个headless service

    • 就是需要提供这个service

    • 提供稳定的网络标识(dns),即使pod重建ip变化,dns名称保持不变

    • 就是为每个pod创建dns A记录

    • 支持Pod之间的相互发现

    • 保证了有序启动和关闭,依靠这个服务,解析每一个pod的dns,确保按照顺序创建

[root@master01 test]# cat web1.yml 
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  clusterIP: None  # 设置为none就是 headless svc
  selector:
     app: web1
  ports:
    - port: 80
      targetPort: 80

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  creationTimestamp: null
  labels:
    app: web1
  name: web1
spec:
  replicas: 2 
  selector:
    matchLabels:
      app: web1
  serviceName: "nginx"
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web1
    spec:
      containers:
      - image: nginx
        name: nginx


[root@master01 test]# kubectl get pod 
NAME     READY   STATUS    RESTARTS   AGE
b1       1/1     Running   0          2m44s
web1-0   1/1     Running   0          3m37s
web1-1   1/1     Running   0          3m34s


root@web1-0:/# cat /etc/hosts 
# Kubernetes-managed hosts file.
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
fe00::0	ip6-mcastprefix
fe00::1	ip6-allnodes
fe00::2	ip6-allrouters
10.246.73.181	web1-0.nginx.default.svc.cluster.local	web1-0

3、daemonset控制器

  • 确保每一个节点上运行一个pod副本

  • 更新,一个一个节点的更新,先删除,再创建

  • 适用场景,日志收集,监控,网络插件,安全

  • kube-proxy每个节点都会运行,网络通信的

[root@master01 test]# cat web1.yml 
apiVersion: apps/v1
kind: DaemonSet   # ds控制器
metadata:
  creationTimestamp: null
  labels:
    app: web1
  name: web1
spec:
  selector:
    matchLabels:
      app: web1
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web1
    spec:
      containers:
      - image: nginx
        name: nginx

# 为什么只有一个节点创建了呢?因为其他2个master节点有污点,无法进行调度
[root@master01 test]# kubectl get pod 
NAME         READY   STATUS    RESTARTS   AGE
b1           1/1     Running   0          5m7s
web1-w9zcn   1/1     Running   0          26s

4、job控制器

job控制器干什么的:专门用来跑任务的

  • 数据迁移

  • 备份

  • 批量计算的

保证任务成功跑完一次(或 N 次),就结束,不再重启,一定是成功的退出,而不是异常的退出

关键字段

completions:需要成功多少个 Pod 才算完成(默认 1)

parallelism:最多同时跑几个 Pod(默认 1)

backoffLimit:最多重试多少次(默认 6)

activeDeadlineSeconds:整个 Job 最多跑多久,超时就失败

restartPolicy:Pod 重启策略(只能 Never 或 OnFailure,不能 Always)

案例:要成功跑完5个pod,job才算成功

[root@kmaster deploy]# cat j1.yml 
apiVersion: batch/v1
kind: Job
metadata:
  creationTimestamp: null
  name: j1
spec:
  completions: 5  # 成功跑5个pod,才算成功
  parallelism: 2  # 允许同时运行2个pod
  backoffLimit: 2  # 最多重试2次
  template:
    metadata:
      creationTimestamp: null
    spec:
      containers:
      - image: busybox
        imagePullPolicy: IfNotPresent 
        name: j1
        command: ["sh","-c","sleep 3;echo 任务完成"]
        resources: {}
      restartPolicy: Never
status: {}

实际的情况就是

  • 先创建2个pod,正常退出后

  • 再次创建2个pod,正常退出后

  • 创建一个pod,正常退出后,知道成功5个job任务完成

5、cronjob控制器

cronjob干什么的:定时创建job任务,job再去跑pod执行任务

相当于是linux中crontab命令,只不过是跑在k8s里面

关键参数

# cron定时表达式
schedule: "*/1 * * * *"

# concurrencyPolicy 并发策略(重点)
  # Forbid 禁止并发:上一次没跑完,本次直接跳过不执行
  # Replace 替换旧任务:到点了,直接杀掉还在跑的旧任务,开新的
  # Allow 允许并发:新旧一起跑,同时存在多个任务

# startingDeadlineSeconds 比如机器挂了错过定时,超过这个时间就不再补跑

# 历史保留
  # successfulJobsHistoryLimit:保留几个成功 Job 记录
  # failedJobsHistoryLimit:保留几个失败 Job 记录 避免历史太多垃圾资源堆积


案例:每分钟执行一次

apiVersion: batch/v1
kind: CronJob
metadata:
  name: cronjob-test
spec:
  schedule: "*/1 * * * *"
  concurrencyPolicy: Forbid
  startingDeadlineSeconds: 60
  successfulJobsHistoryLimit: 2
  failedJobsHistoryLimit: 2
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: task
            image: busybox
            command: ["sh", "-c", "date; echo 我是定时任务"]
          restartPolicy: Never

执行的流程:

  • 每分钟会创建一个job,执行pod任务

  • 最多保留2个成功的job,多一个就删除之前成功的记录

posted @ 2026-03-26 16:06  乔的港口  阅读(21)  评论(0)    收藏  举报