• kubernetes--Pod控制器详解


    目录

    一、Pod控制器及其功用:

    二、pod控制器的多种类型:

     1、ReplicaSet: 

     1.1 ReplicaSet主要三个组件组成:

     2、Deployment:

     3、DaemonSet:

     4、StatefulSet:

     5、Job:

     6、Cronjob:

    三、Deployment控制器:

    示例:

     查看控制器配置

     查看历史版本

    四、SatefulSet:

     1. 示例:

     2. StatefulSet的组成部分:

     3. 为什么要有headless:

     4. 为什么要有volumeClaimTemplate:

     5. 常规service和无头服务区别:

     6. 总结:

    五、DaemonSet:

     1. DaemonSet 的一些典型用法:

     2. 示例:

     3. 总结:

    六、Job:

     1. 示例:

     2. 参数解释

     3. backoffLimit:

     4. 总结:

    七、CronJob :

     1. 示例:

     2. cronjob其它可用参数的配置:

     3. 总结:


    一、Pod控制器及其功用:

    Pod控制器,又称之为工作负载(workload),是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试进行重启,当根据重启策略无效,则会重新新建pod的资源。

    二、pod控制器的多种类型:

     1、ReplicaSet: 

    代用户创建指定数量的pod副本,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能。

     1.1 ReplicaSet主要三个组件组成:

    1. 用户期望的pod副本数量
    2. 标签选择器,判断哪个pod归自己管理
    3. 当现存的pod数量不足,会根据pod资源模板进行新建

    帮助用户管理无状态的pod资源,精确反应用户定义的目标数量,但是RelicaSet不是直接使用的控制器,而是使用Deployment。

     2、Deployment:

    • 工作在ReplicaSet之上,用于管理无状态应用,目前来说最好的控制器。支持滚动更新和回滚功能,还提供声明式配置。
    • ReplicaSet 与Deployment 这两个资源对象逐步替换之前RC的作用。

     3、DaemonSet:

    用于确保集群中的每一个节点只运行特定的pod副本,通常用于实现系统级后台任务。比如ELK服务

    特性:服务是无状态的
               服务必须是守护进程

     4、StatefulSet:

         管理有状态应用

     5、Job:

    只要完成就立即退出,不需要重启或重建

     6、Cronjob:

    周期性任务控制,不需要持续后台运行

    三、Deployment控制器:

    • 部署无状态应用
    • 管理Pod和ReplicaSet
    • 具有上线部署、副本设定、滚动升级、回滚等功能
    • 提供声明式更新,例如只更新一个新的image
    • 应用场景:web服务

    示例:

    1. vim nginx-deployment.yaml
    2. apiVersion: apps/v1
    3. kind: Deployment
    4. metadata:
    5. name: nginx-deployment
    6. labels:
    7. app: nginx
    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: nginx
    20. image: nginx:1.15.4
    21. ports:
    22. - containerPort: 80
    23. kubectl create -f nginx-deployment.yaml
    24. kubectl get pods,deploy,rs

     查看控制器配置

    1. kubectl edit deployment/nginx-deployment
    2. apiVersion: apps/v1
    3. kind: Deployment
    4. metadata:
    5. annotations:
    6. deployment.kubernetes.io/revision: "1"
    7. creationTimestamp: "2021-04-19T08:13:50Z"
    8. generation: 1
    9. labels:
    10. app: nginx #Deployment资源的标签
    11. name: nginx-deployment
    12. namespace: default
    13. resourceVersion: "167208"
    14. selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deployment
    15. uid: d9d3fef9-20d2-4196-95fb-0e21e65af24a
    16. spec:
    17. progressDeadlineSeconds: 600
    18. replicas: 3 #期望的pod数量,默认是1
    19. revisionHistoryLimit: 10
    20. selector:
    21. matchLabels:
    22. app: nginx
    23. strategy:
    24. rollingUpdate:
    25. maxSurge: 25% #升级过程中会先启动的新Pod的数量不超过期望的Pod数量的25%,也可以是一个绝对值
    26. maxUnavailable: 25% #升级过程中在新的Pod启动好后销毁的旧Pod的数量不超过期望的Pod数量的25%,也可以是一个绝对值
    27. type: RollingUpdate #滚动升级
    28. template:
    29. metadata:
    30. creationTimestamp: null
    31. labels:
    32. app: nginx #Pod副本关联的标签
    33. spec:
    34. containers:
    35. - image: nginx:1.15.4 #镜像名称
    36. imagePullPolicy: IfNotPresent #镜像拉取策略
    37. name: nginx
    38. ports:
    39. - containerPort: 80 #容器暴露的监听端口
    40. protocol: TCP
    41. resources: {}
    42. terminationMessagePath: /dev/termination-log
    43. terminationMessagePolicy: File
    44. dnsPolicy: ClusterFirst
    45. restartPolicy: Always #容器重启策略
    46. schedulerName: default-scheduler
    47. securityContext: {}
    48. terminationGracePeriodSeconds: 30
    49. ......

     查看历史版本

    1. kubectl rollout history deployment/nginx-deployment
    2. deployment.apps/nginx-deployment
    3. REVISION CHANGE-CAUSE
    4. 1

    四、SatefulSet:

    • 部署有状态应用
    • 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
    • 稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
    • 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
    • 有序收缩,有序删除(即从N-1到0)

    常见的应用场景:数据库
    https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/

     1. 示例:

    1. apiVersion: v1
    2. kind: Service
    3. metadata:
    4. name: nginx
    5. labels:
    6. app: nginx
    7. spec:
    8. ports:
    9. - port: 80
    10. name: web
    11. clusterIP: None #不创建custerip,也就是无头服务的service
    12. selector:
    13. app: nginx
    14. ---
    15. apiVersion: apps/v1
    16. kind: StatefulSet
    17. metadata:
    18. name: web
    19. spec:
    20. selector:
    21. matchLabels:
    22. app: nginx
    23. serviceName: "nginx"
    24. replicas: 3 #三个副本
    25. template: #定义容器的模板
    26. metadata:
    27. labels:
    28. app: nginx
    29. spec:
    30. terminationGracePeriodSeconds: 10 #10秒内pod没关闭,就强制杀死
    31. containers:
    32. - name: nginx
    33. image: nginx:1.14.1
    34. ports:
    35. - containerPort: 80
    36. name: web
    37. volumeMounts: #容器内挂载
    38. - name: www
    39. mountPath: /usr/share/nginx/html
    40. volumeClaimTemplates: #存储卷的申请模板
    41. - metadata:
    42. name: www
    43. spec:
    44. accessModes: [ "ReadWriteOnce" ] #可读可写,仅能一个节点挂载
    45. storageClassName: "nfs-client-storageclass" #使用动态创建的pv
    46. resources: #设置请求的资源大小
    47. requests:
    48. storage: 2Gi

    由于StatefulSet资源依赖于一个实现存在的Headless类型的Service资源,所以需要先定义一个名为nginx的Headless Service资源,用于为关联到每个Pod资源创建DNS资源记录。接着定义了一个名为web的StatefulSet资源,它通过Pod模板创建了3个Pod资源副本,并基于volumeClaimTemplates向存储类进行了请求大小为2Gi的专用存储卷。

     2. StatefulSet的组成部分:

    • Headless Service(无头服务):用于为Pod资源标识符生成可解析的DNS记录。
    • volumeClaimTemplates(存储卷申请模板):基于静态或动态PV供给方式为Pod资源提供专有的固定存储。
    • StatefulSet:用于管控Pod资源。

     3. 为什么要有headless:

        在deployment中,每一个pod是没有名称,是随机字符串,是无序的。而statefulset中是要求有序的,每一个pod的名称必须是固定的。当节点挂了,重建之后的标识符是不变的,每一个节点的节点名称是不能改变的。pod名称是作为pod识别的唯一标识符,必须保证其标识符的稳定并且唯一。为了实现标识符的稳定,这时候就需要一个headless service 解析直达到pod,还需要给pod配置一个唯一的名称。

     4. 为什么要有volumeClaimTemplate:

        大部分有状态副本集都会用到持久存储,比如分布式系统来说,由于数据是不一样的,每个节点都需要自己专用的存储节点。而在 deployment中pod模板中创建的存储卷是一个共享的存储卷,多个pod使用同一个存储卷,而statefulset定义中的每一个pod都不能使用同一个存储卷,由此基于pod模板创建pod是不适应的,这就需要引入volumeClaimTemplate,当在使用statefulset创建pod时,会自动生成一个PVC,从而请求绑定一个PV,从而有自己专用的存储卷。

     5. 常规service和无头服务区别:

    • service:一组Pod访问策略,提供cluster-IP群集之间通讯,还提供负载均衡和服务发现。
    • Headless service:无头服务,不需要cluster-IP,而是直接以DNS记录的方式解析出被代理Pod的IP地址。

     6. 总结:

    • 部署有状态应用(有实时的数据需要存储)
    • 每个Pod名称标识都是唯一且固定不变的
    • 每个Pod都可以有自己专属的持久化存储(基于PVC模板volumeClaimTemplates实现的)
    • 需要提前创建一个Headless Service资源(无头服务,ClusterIP可以为Node),并在StatefulSet资源清单配置中使用serviceName字段指定Headless Service资源名称
    • 可以在Pod内通过..<命名空间>[.svc.cluster.local]格式解析出PodIP(基于Headless Service和CoreDNS实现的)
    • 创建、滚动升级、扩容、缩容Pod副本时都是有序进行的(默认为串行执行的,由spec.podManagementPolicy字段决定的,默认值为OrderedReady,为Parallel则并行执行)
    • 创建、扩容是升序执行的(顺序为Pod标识号从0到n-1)   滚动升级、缩容是倒序执行的(顺序为Pod标识号从n-1到0)

    五、DaemonSet:

    DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个 Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。

     1. DaemonSet 的一些典型用法:

    • 运行集群存储 daemon,例如在每个 Node 上运行 glusterd、ceph。
    • 在每个 Node 上运行日志收集 daemon,例如fluentd、logstash。
    • 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond。

    应用场景:Agent
    //官方案例(监控)
    https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/

     2. 示例:

    1. vim ds.yaml
    2. apiVersion: apps/v1
    3. kind: DaemonSet
    4. metadata:
    5. name: nginx-daemonSet
    6. labels:
    7. app: nginx
    8. spec:
    9. selector:
    10. matchLabels:
    11. app: nginx
    12. template:
    13. metadata:
    14. labels:
    15. app: nginx
    16. spec:
    17. containers:
    18. - name: nginx
    19. image: nginx:1.15.4
    20. ports:
    21. - containerPort: 80
    1. kubectl apply -f ds.yaml
    2. //DaemonSet会在每个node节点都创建一个Pod

     3. 总结:

    • 通常用于部署daemon级别的无状态应用
    • 理论上可以在K8S所有node节点上创建相同的Pod资源,无论node节点什么时候加入到K8S集群(需要考虑到污点和cordon不可调度的影响)
    • 不需要配置Pod副本数字段replicas

    六、Job:

    Job分为普通任务(Job)和定时任务(CronJob),常用于运行那些仅需要执行一次的任务

    应用场景:数据库迁移、批处理脚本、kube-bench扫描、离线数据处理,视频解码等业务
    https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/

     1. 示例:

    1. vim job.yaml
    2. apiVersion: batch/v1
    3. kind: Job
    4. metadata:
    5. name: pi
    6. spec:
    7. template:
    8. spec:
    9. containers:
    10. - name: pi
    11. image: perl
    12. command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
    13. restartPolicy: Never
    14. backoffLimit: 4

     2. 参数解释

    .spec.template.spec.restartPolicy该属性拥有三个候选值:OnFailure,Never和Always。默认值为Always。它主要用于描述Pod内容器的重启策略。在Job中只能将此属性设置为OnFailure或Never,否则Job将不间断运行。

    .spec.backoffLimit用于设置job失败后进行重试的次数,默认值为6。默认情况下,除非Pod失败或容器异常退出,Job任务将不间断的重试,此时Job遵循 .spec.backoffLimit上述说明。一旦.spec.backoffLimit达到,作业将被标记为失败。

    • 在所有node节点下载perl镜像,因为镜像比较大,所以建议提前下载好
    1. docker pull perl
    2. kubectl apply -f job.yaml
    3. kubectl get pods
    4. //结果输出到控制台
    5. kubectl logs pi-bqtf7
    6. 3.14159265......
    7. //清除job资源
    8. kubectl delete -f job.yaml

     3. backoffLimit:

    1. vim job-limit.yaml
    2. apiVersion: batch/v1
    3. kind: Job
    4. metadata:
    5. name: busybox
    6. spec:
    7. template:
    8. spec:
    9. containers:
    10. - name: busybox
    11. image: busybox
    12. imagePullPolicy: IfNotPresent
    13. command: ["/bin/sh", "-c", "sleep 10;date;exit 1"]
    14. restartPolicy: Never
    15. backoffLimit: 2
    1. kubectl apply -f job-limit.yaml
    2. kubectl get job,pods
    3. NAME COMPLETIONS DURATION AGE
    4. job.batch/busybox 0/1 4m34s 4m34s
    5. NAME READY STATUS RESTARTS AGE
    6. pod/busybox-dhrkt 0/1 Error 0 4m34s
    7. pod/busybox-kcx46 0/1 Error 0 4m
    8. pod/busybox-tlk48 0/1 Error 0 4m21s
    9. kubectl describe job busybox
    10. ......
    11. Warning BackoffLimitExceeded 43s job-controller Job has reached the specified backoff limit

     4. 总结:

    • 部署一次性的短期任务的Pod资源,Pod不会持久运行
    • 任务正常完成后Pod容器会正常退出且不再重启(restartPolicy字段需要设置为Never或OnFailure),并也不会再重建Pod
    • 如果任务执行失败导致Pod容器异常退出,Job会根据backoffLimit字段决定重建Pod重试任务的次数(默认值为6)

    七、CronJob :

            周期性任务 类似Linux的Crontab。

    应用场景:通知,备份
    https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/

     1. 示例:

    1. //每分钟打印hello
    2. vim cronjob.yaml
    3. apiVersion: batch/v1beta1
    4. kind: CronJob
    5. metadata:
    6. name: hello
    7. spec:
    8. schedule: "*/1 * * * *"
    9. jobTemplate:
    10. spec:
    11. template:
    12. spec:
    13. containers:
    14. - name: hello
    15. image: busybox
    16. imagePullPolicy: IfNotPresent
    17. args:
    18. - /bin/sh
    19. - -c
    20. - date; echo Hello from the Kubernetes cluster
    21. restartPolicy: OnFailure

     2. cronjob其它可用参数的配置:

    1. spec:
    2. concurrencyPolicy: Allow #声明了 CronJob 创建的任务执行时发生重叠如何处理(并发性规则仅适用于相同 CronJob 创建的任务)。spec仅能声明下列规则中的一种:
    3. ●Allow (默认):CronJob 允许并发任务执行。
    4. ●Forbid:CronJob 不允许并发任务执行;如果新任务的执行时间到了而老任务没有执行完,CronJob 会忽略新任务的执行。
    5. ●Replace:如果新任务的执行时间到了而老任务没有执行完,CronJob 会用新任务替换当前正在运行的任务。
    6. startingDeadlineSeconds: 15 #它表示任务如果由于某种原因错过了调度时间,开始该任务的截止时间的秒数。过了截止时间,CronJob 就不会开始任务,且标记失败.如果此字段未设置,那任务就没有最后期限。
    7. successfulJobsHistoryLimit: 3 #要保留的成功完成的任务数(默认为3)
    8. failedJobsHistoryLimit:1 #要保留多少已完成和失败的任务数(默认为1)
    9. suspendtrue #如果设置为 true ,后续发生的执行都会被挂起。 这个设置对已经开始的执行不起作用。默认是 false。
    10. schedule: '*/1 * * * *' #必需字段,作业时间表。在此示例中,作业将每分钟运行一次
    11. jobTemplate: #必需字段,作业模板。这类似于工作示例
    1. kubectl create -f cronjob.yaml
    2. kubectl get cronjob
    3. NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
    4. hello */1 * * * * False 0 25s

     3. 总结:

    • 部署周期性的短期任务的Pod资源,Pod不会持久运行
    • 任务正常完成后Pod容器会正常退出且不再重启(restartPolicy字段需要设置为Never或OnFailure),并也不会再重建Pod
    • 必须要配置schedule字段设置任务执行的周期表,格式为 "分 时 日 月 周"
  • 相关阅读:
    lambda表达式
    Python Tensorflow1.x升级到2.x低阶API实践
    无胁科技-TVD每日漏洞情报-2022-10-31
    关于std::vector<std::string>的操作
    ORACLE逻辑存储结构
    gRPC入门学习之旅(四)
    一文讲清场景工程方法论及运维组织能力内化
    C语言-入门-宏定义(十七)
    C语言之文件操作(万字详解)
    OSG学习之三:坐标变换
  • 原文地址:https://blog.csdn.net/2301_78106979/article/details/134495242