• kubernetes工作负载之控制器


    目录

    ​一、概述

    二、Deployment 控制器

    2.1Deployment 部署应用

    2.2Deployment滚动升级

    2.2.1应用部署完成

    2.2.2更新镜像三种方式

    2.3 Deployment 发布失败回滚

    2.4Deployment 水平扩容

    三、DaemonSet控制器

    四、Job控制器

    4.1Job一次性执行

    4.2定时任务(CronJob)

    五、总结


    一、概述


     在Kubernetes中,Pod是最小的管理单元,是一组紧密关联的容器组合。

    但是,单独的Pod并不能保障总是可用,比如我们创建一个nginx的Pod,因为某些原因,该Pod被意外删除,我们希望其能够自动新建一个同属性的Pod。很遗憾,单纯的Pod并不能满足需求。

    为此,Kubernetes实现了一系列控制器来管理Pod,使Pod的期望状态和实际状态保持一致

    工作负载控制器(Workload Controllers)是K8s的一个抽象概念,用于更高级层次对象,部署和管理Pod。常用工作负载控制器:

    Deployment :无状态应用部署

    StatefulSet :有状态应用部署

    DaemonSet :确保所有Node运行同一个Pod

    Job :一次性任务

    Cronjob :定时任务

    控制器的作用

    • 管理Pod对象

    • 使用标签与Pod关联

    • 控制器实现了Pod的运维,例如滚动更新、伸缩、副本管理、维护Pod状态等。

    Deployment的功能:

    • 管理Pod和ReplicaSet

    • 具有上线部署、副本设定、滚动升级、回滚等功能

    • 提供声明式更新,例如只更新一个新的Image 应用场景:网站、API、微服务


    二、Deployment 控制器


    2.1Deployment 部署应用


    deployment部署一个应用,副本数为3

    1. apiVersion: apps/v1
    2. kind: Deployment
    3. metadata:
    4. name: web
    5. namespace: default
    6. spec:
    7. replicas: 3 # 副本数量
    8. selector:
    9. matchLabels:
    10. app: nginx
    11. template:
    12. metadata:
    13. labels:
    14. app: nginx # Pod副本的标签
    15. spec:
    16. containers:
    17. - name: web
    18. image: nginx:1.15

    pod 副本为3 , 成功调度到 node1和node2两个节点上

    服务暴露出来,查询对用的服务端口

    kubectl expose deployment web --port=80 --target-port=80 --type=NodePort

    三个节点的任意 IP加上 31812端口 都可以访问

    2.2Deployment滚动升级


    业务应用基本都是通过Deployment的方式部署在Kubernetes中的,应用的更新和回滚是常态的工作,特别是在互联网企业,快速迭代抓住用户的一个重要途径。

    但是,并不是每一次的迭代都是100%正常的,如果异常,如何快速恢复也是要考虑的事情。为适应这种场景,Deployment提供滚动更新和快速回滚的能力。

    Deployment默认的更新方式就是滚动更新,可以通过strategy.type来指定更新方式。

    • Recreate:先删除所有的Pod,再创建
    • RollingUpdate:先启动新的Pod,再替换老的Pod

    2.2.1应用部署完成

    1. ## 部署应用
    2. kubectl apply -f deployment.yaml
    3. ## 暴露应用服务的端口
    4. kubectl expose deployment web --port=80 --target-port=80 --type=NodePort

    2.2.2更新镜像三种方式

    • kubectl apply -f xxx.yaml

    • kubectl set image deployment/web nginx=nginx:1.16

    • kubectl edit deployment/web

     滚动升级:K8s对Pod升级的默认策略,通过使用新版本Pod逐步更新旧版本Pod,实现零停机发布,用户无感知。

    查看三个pod 服务 对应的 IP和端口

    1. [root@k8s-master1 ~]# kubectl get ep
    2. NAME ENDPOINTS AGE
    3. kubernetes 192.168.2.117:6443,192.168.2.119:6443 7d2h
    4. pod-check 6h
    5. web 10.244.159.134:80,10.244.224.10:80,10.244.36.74:80 32m

    nginx:1.15 镜像升级到 nginx:1.16

    1. apiVersion: apps/v1
    2. kind: Deployment
    3. metadata:
    4. name: web
    5. namespace: default
    6. spec:
    7. replicas: 3
    8. selector:
    9. matchLabels:
    10. app: nginx
    11. template:
    12. metadata:
    13. labels:
    14. app: nginx
    15. spec:
    16. containers:
    17. - name: web
    18. image: nginx:1.16

    replicas 一个一个升级创建一个新的删除旧的,具体的策略可以,自行配置

    导出 web deployment, 查看完整的 Deployment 配置

    1. kubectl get deployment web -o yaml > deploy.yaml
    2. apiVersion: apps/v1
    3. kind: Deployment
    4. metadata:
    5. annotations:
    6. deployment.kubernetes.io/revision: "7"
    7. kubectl.kubernetes.io/last-applied-configuration: |
    8. {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"kubernetes.io/change-cause":"web.v1-nginx-1.17"},"name":"web","namespace":"default"},"spec":{"replicas":3,"selector":{"matchLabels":{"app":"nginx"}},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx:1.17","name":"web"}]}}}}
    9. kubernetes.io/change-cause: web.v1-nginx-1.17
    10. creationTimestamp: "2022-11-12T09:11:15Z"
    11. generation: 8
    12. managedFields:
    13. - apiVersion: apps/v1
    14. fieldsType: FieldsV1
    15. fieldsV1:
    16. f:metadata:
    17. f:annotations:
    18. .: {}
    19. f:kubectl.kubernetes.io/last-applied-configuration: {}
    20. f:spec:
    21. f:progressDeadlineSeconds: {}
    22. f:replicas: {}
    23. f:revisionHistoryLimit: {}
    24. f:selector:
    25. f:matchLabels:
    26. .: {}
    27. f:app: {}
    28. f:strategy:
    29. f:rollingUpdate:
    30. .: {}
    31. f:maxSurge: {}
    32. f:maxUnavailable: {}
    33. f:type: {}
    34. f:template:
    35. f:metadata:
    36. f:labels:
    37. .: {}
    38. f:app: {}
    39. f:spec:
    40. f:containers:
    41. k:{"name":"web"}:
    42. .: {}
    43. f:imagePullPolicy: {}
    44. f:name: {}
    45. f:resources: {}
    46. f:terminationMessagePath: {}
    47. f:terminationMessagePolicy: {}
    48. f:dnsPolicy: {}
    49. f:restartPolicy: {}
    50. f:schedulerName: {}
    51. f:securityContext: {}
    52. f:terminationGracePeriodSeconds: {}
    53. manager: kubectl-client-side-apply
    54. operation: Update
    55. time: "2022-11-12T10:33:02Z"
    56. - apiVersion: apps/v1
    57. fieldsType: FieldsV1
    58. fieldsV1:
    59. f:metadata:
    60. f:annotations:
    61. f:kubernetes.io/change-cause: {}
    62. f:spec:
    63. f:template:
    64. f:spec:
    65. f:containers:
    66. k:{"name":"web"}:
    67. f:image: {}
    68. manager: kubectl
    69. operation: Update
    70. time: "2022-11-12T10:33:12Z"
    71. - apiVersion: apps/v1
    72. fieldsType: FieldsV1
    73. fieldsV1:
    74. f:metadata:
    75. f:annotations:
    76. f:deployment.kubernetes.io/revision: {}
    77. f:status:
    78. f:availableReplicas: {}
    79. f:conditions:
    80. .: {}
    81. k:{"type":"Available"}:
    82. .: {}
    83. f:lastTransitionTime: {}
    84. f:lastUpdateTime: {}
    85. f:message: {}
    86. f:reason: {}
    87. f:status: {}
    88. f:type: {}
    89. k:{"type":"Progressing"}:
    90. .: {}
    91. f:lastTransitionTime: {}
    92. f:lastUpdateTime: {}
    93. f:message: {}
    94. f:reason: {}
    95. f:status: {}
    96. f:type: {}
    97. f:observedGeneration: {}
    98. f:readyReplicas: {}
    99. f:replicas: {}
    100. f:updatedReplicas: {}
    101. manager: kube-controller-manager
    102. operation: Update
    103. time: "2022-11-12T10:33:21Z"
    104. name: web
    105. namespace: default
    106. resourceVersion: "1262530"
    107. selfLink: /apis/apps/v1/namespaces/default/deployments/web
    108. uid: 7b334d04-b47e-4023-bb3f-8043fd1474e2
    109. spec:
    110. progressDeadlineSeconds: 600
    111. replicas: 3
    112. revisionHistoryLimit: 10
    113. selector:
    114. matchLabels:
    115. app: nginx
    116. strategy:
    117. rollingUpdate:
    118. maxSurge: 25% ###
    119. maxUnavailable: 25% ###
    120. type: RollingUpdate ###
    121. template:
    122. metadata:
    123. creationTimestamp: null
    124. labels:
    125. app: nginx
    126. spec:
    127. containers:
    128. - image: nginx:1.17
    129. imagePullPolicy: IfNotPresent
    130. name: web
    131. resources: {}
    132. terminationMessagePath: /dev/termination-log
    133. terminationMessagePolicy: File
    134. dnsPolicy: ClusterFirst
    135. restartPolicy: Always
    136. schedulerName: default-scheduler
    137. securityContext: {}
    138. terminationGracePeriodSeconds: 30
    139. status:
    140. availableReplicas: 3 ###
    141. conditions:
    142. - lastTransitionTime: "2022-11-12T09:23:15Z"
    143. lastUpdateTime: "2022-11-12T09:23:15Z"
    144. message: Deployment has minimum availability.
    145. reason: MinimumReplicasAvailable
    146. status: "True"
    147. type: Available
    148. - lastTransitionTime: "2022-11-12T09:11:15Z"
    149. lastUpdateTime: "2022-11-12T10:33:21Z"
    150. message: ReplicaSet "web-76f5f6d7f5" has successfully progressed.
    151. reason: NewReplicaSetAvailable
    152. status: "True"
    153. type: Progressing
    154. observedGeneration: 8
    155. readyReplicas: 3
    156. replicas: 3
    157. updatedReplicas: 3
    • maxSurge: 表示升级过程中最多可以比原先设置多出的pod数量,如上maxSurge=1,replicas:3 就表示kubennetes会先启动一个新的pod,然后删除掉一个旧的pod,整个升级过程中最多会有3+1pod
    • maxUnavailable: 表示升级过程中最多有多少个pod处于无法提供服务的状态,当manSurge不为0时,该值也不能为0,maxUnavailable =1 表示kubernetes整个升级过程中最多会有一个pod处于无法服务的状态
    • minReadySeconds: 表示kubernetes在等待设置时间后才进行升级,如果没有设置该值kubernete会假设容器启动起来就提供服务了,如果没有设置该值,在某些极端情况下可能会造成服务不正常运行,默认值是0
    • type:RollingUpdate表示,设置更新策略为滚动更新,可以设置为recreate和RollingUpdate两个值,recreate表示全部重新创建,默认值就是RollingUpdate

    当然,这时候应在Pod中加上health check检查应用的健康状态,而不是简单的依赖容器的running状态。配置相应的健康检查可以确保服务的可靠性和延续性。

    2.3 Deployment 发布失败回滚


    发布失败恢复正常版本

    1. # 查看历史发布版本
    2. kubectl rollout history deployment/web
    3. # 回滚上一个版本
    4. kubectl rollout undo deployment/web
    5. # 回滚历史指定版本
    6. kubectl rollout undo deployment/web --to-revision=2

    ngnix 版本可自由改动 ,尝试 升级和回滚

    1. apiVersion: apps/v1
    2. kind: Deployment
    3. metadata:
    4. name: web
    5. namespace: default
    6. annotations: # 记录回滚参数
    7. kubernetes.io/change-cause: "web.v1-nginx-1.17" #记录到revision中的内容,记录版本号
    8. spec:
    9. replicas: 3
    10. selector:
    11. matchLabels:
    12. app: nginx
    13. template:
    14. metadata:
    15. labels:
    16. app: nginx
    17. spec:
    18. containers:
    19. - name: web
    20. image: nginx:1.17

     注:回滚是重新部署某一次部署时的状态,即当时版本所有配置

    查看正在运行的服务版本,镜像是 nginx: 1.17

    回滚到上个版本,镜像是 nginx: 1.16

    2.4Deployment 水平扩容


    ReplicaSet控制器用途:

    • Pod副本数量管理,不断对比当前Pod数量与期望Pod数量

    • Deployment每次发布都会创建一个RS作为记录,用于实现回滚

    1. # 查看RS记录
    2. kubectl get rs
    3. # 版本对应RS记录
    4. kubectl rollout history deployment web
    5. # 命令直接修改副本个数,或者 修改yaml重新应用下
    6. kubectl scale deployment web --replicas 5 deployment.apps/web scaled
    7. ## 也可以直接修改 ep 文件
    8. kubectl edit ep web -o yaml

    新增两个 pod


    三、DaemonSet控制器


    DaemonSet保证在每个Node上都运行一个Pod,如果新增一个Node,这个Pod也会运行在新增的Node上,如果删除这个DadmonSet,就会清除它所创建的Pod。常用来部署一些集群日志收集,监控等全局应用。

    DaemonSet也是支持更新和回滚的,具体操作和Deployment类似。

    常见的场景如下:

    1、运行存储集群daemon,比如ceph,glusterd等;

    2、运行一个日志收集daemon,比如logstash,fluentd等;

    3、运行监控daemon,比如Prometheus Node Exporter,collectd,New Relic agent,Ganglia gmond等;

     部署一个日志采集程序,因为使用 kubeadm 安装 所以 master 节点打了污点,下面filebeat 配置污点容忍,使其在 master 节点 也可以调度成功。

    1. apiVersion: apps/v1
    2. kind: DaemonSet
    3. metadata:
    4. name: filebeat
    5. namespace: kube-system
    6. spec:
    7. selector:
    8. matchLabels:
    9. name: filebeat
    10. template:
    11. metadata:
    12. labels:
    13. name: filebeat
    14. spec:
    15. tolerations:
    16. - effect: NoSchedule
    17. operator: Exists
    18. containers:
    19. - name: log
    20. image: elastic/filebeat:7.3.2

     三个 节点成功部署 filebeat


    四、Job控制器


    4.1Job一次性执行


    计算圆周率

    1. apiVersion: batch/v1
    2. kind: Job
    3. metadata:
    4. name: pi
    5. spec:
    6. template:
    7. spec:
    8. containers:
    9. - name: pi
    10. image: perl # 自定义的一次性需要运行的镜像
    11. command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
    12. restartPolicy: Never

    4.2定时任务(CronJob)


    应用场景:离线数据处理,视频解码等业务

    1. apiVersion: batch/v1beta1
    2. kind: CronJob
    3. metadata:
    4. name: hello
    5. spec:
    6. schedule: "*/1 * * * *"
    7. jobTemplate:
    8. spec:
    9. template:
    10. spec:
    11. containers:
    12. - name: hello
    13. image: busybox
    14. args:
    15. - /bin/sh
    16. - -c
    17. - date; echo Hello kangll
    18. restartPolicy: OnFailure

     需要注意的是,由于cron的特殊性,有时候会存在由于上一个定时任务还没有执行完成,新的定时任务又开始了的情况,我们可以通过定义spec.concurrencyPolicy字段来定义规则,比如:

    • concurrencyPolicy=Allow:表示这些Job可以同时存在
    • concurrencyPolicy=Firbid:表示不会创建新的Job,也就是这个定时任务被跳过
    • concurrencyPolicy=Replace:表示产生的新Job会替代旧的Job

    五、总结


    上面介绍的是日常工作中常用的控制器,其中Deployment和DaemonSet的使用频率最高,熟练掌握这些控制器,并且学会在什么时候选择什么样的控制器,合理使用使工作效率最高。

  • 相关阅读:
    神经网络 深度神经网络,主流的神经网络的框架
    线程崩溃为什么不会导致 JVM 崩溃
    图神经网络
    Vue3 - 使用 mitt.js 进行组件通信(兄弟关系)
    杰出与平庸的差距, 是如何一点点被拉开的, 不要掉入 3 个心理学陷阱, 解读《异类》
    七、SSM 框架整合
    BigDecimal保留两位小数失败问题
    基于C++实现平台类对战游戏
    Python学习笔记--自定义元类
    YOLO目标检测——红外人员数据集【含对应voc、coco和yolo三种格式标签+划分脚本】
  • 原文地址:https://blog.csdn.net/qq_35995514/article/details/128062173