• pod控制器


    概述:

    pod控制器可以确保pod以一定的数量和副本数运行,并且能能够处理不同的启动和终止情况

    Pod控制器是Kubernetes(K8s)中的一种核心组件,用于管理和控制Pod对象的生命周期。Pod是Kubernetes中最小的可调度和可部署的计算单元,它可以包含一个或多个容器,并共享相同的网络和存储资源。

    Pod控制器负责创建、更新和删除Pod实例,以及确保所需数量的Pod正常运行。它监控Pod的健康状态,并在发生故障或需要扩展时采取适当的操作。

    Pod控制器及其功用

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

    pod控制器有多种类型:

    1、ReplicaSet:

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

    ReplicaSet主要三个组件组成:

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

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

    2、Deployment:

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

    3、DaemonSet:

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

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

    4、StatefulSet:管理有状态应用

    有状态副本集):StatefulSet控制器用于管理具有唯一标识和稳定网络标识符的有状态Pod。它确保有序的创建、更新和删除Pod,并提供稳定的网络标识符和持久化存储。

    5、Job:只要完成就立即退出,不需要重启或重建
    6、Cronjob:周期性任务控制,不需要持续后台运行
     

    在Kubernetes(k8s)中,有两种常见的应用部署模式:

    //总结
    无状态:
    1)deployment 认为所有的pod都是一样的
    2)不用考虑顺序的要求
    3)不用考虑在哪个node节点上运行
    4)可以随意扩容和缩容 

    有状态
    1)实例之间有差别,每个实例都有自己的独特性,元数据不同,例如etcd,zookeeper
    2)实例之间不对等的关系,以及依靠外部存储的应用。

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

    有状态应用和无状态应用

    1、有状态应用:

    1. 有状态应用是指依赖持久化数据存储的应用程序。这些应用通常需要保持特定的状态和数据,并且需要在容器重启或迁移时能够保留数据。例如,关系型数据库(如MySQL)或分布式存储系统(如Cassandra)都属于有状态应用。
    2. 在Kubernetes中,有状态应用可以使用StatefulSet这个资源对象进行管理。StatefulSet会为每个Pod分配一个稳定的网络标识符和持久化卷,确保每个Pod具有唯一的身份和状态。

    2、无状态应用:

    1. 无状态应用是指不依赖持久化数据存储的应用程序。这些应用可以根据需要水平扩展,并且对于容器的停止、重启或迁移没有特殊需求。例如,Web服务器(如Nginx)或服务应用程序都属于无状态应用。
    2. 在Kubernetes中,无状态应用可以使用Deployment这个资源对象进行管理。Deployment可以定义应用程序的副本数量,Kubernetes会自动调度和管理Pod的创建、销毁和水平扩展

    无论是有状态应用还是无状态应用,Kubernetes都提供了适当的资源对象和功能来管理和运行它们。根据应用程序的需求,选择适合的部署模式可以更好地利用Kubernetes的优势和特性。

    Pod与控制器之间的关系

    controllers:在集群上管理和运行容器的 pod 对象, pod 通过 label-selector 相关联。
    Pod 通过控制器实现应用的运维,如伸缩,升级等。
     

    1、Deployment

    部署无状态应用的 管理 ReplicaSet (RS)和pod创建pod ,维护副本数目与期望状态相同

    创建和删除pod时是并行执行的,升级时是先创建一部分再删除一部分


    部署无状态应用
    管理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-01
    8. spec:
    9. replicas: 3
    10. selector:
    11. matchLabels:
    12. app: nginx-01
    13. template:
    14. metadata:
    15. labels:
    16. app: nginx-01
    17. spec:
    18. containers:
    19. - image: nginx:1.14
    20. name: nginx
    21. ports:
    22. - containerPort: 80

    创建完成,查看结果

    查看控制器配置

    kubectl edit deployment/nginx-deployment

     示例

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

    查看历史版本

    更改版本:

    可以通过在下面的进行修改

    kubectl edit deployment/nginx-deployment

    deployment.apps/nginx-deployment
    

    2、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. apiVersion: v1
    2. kind: Service
    3. metadata:
    4. name: nginx
    5. labels:
    6. app: nginx
    7. spec:
    8. ports:
    9. - port: 80
    10. na me: web
    11. clusterIP: None
    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 # has to match .spec.template.metadata.labels
    23. serviceName: "nginx"
    24. replicas: 3 # by default is 1
    25. template:
    26. metadata:
    27. labels:
    28. app: nginx # has to match .spec.selector.matchLabels
    29. spec:
    30. terminationGracePeriodSeconds: 10
    31. containers:
    32. - name: nginx
    33. image: k8s.gcr.io/nginx-slim:0.8
    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: "my-storage-class"
    46. resources:
    47. requests:
    48. storage: 1Gi

    从上面的应用场景可以发现,StatefulSet由以下几个部分组成:

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

     为什么要有headless?

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

    为什么要有volumeClainTemplate?

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

    服务发现:就是应用服务之间相互定位的过程。
    应用场景:

    1. 动态性强:Pod会飘到别的node节点
    2. 更新发布频繁:互联网思维小步快跑,先实现再优化,老板永远是先上线再慢慢优化,先把idea变成产品挣到钱然后再慢慢一点一点优化
    3. 支持自动伸缩:一来大促,肯定是要扩容多个副本

    K8S里服务发现的方式---DNS,使K8S集群能够自动关联Service资源的“名称”和“CLUSTER-IP”,从而达到服务被集群自动发现的目的。
     

    实现K8S里DNS功能的插件:

    1. skyDNS:Kubernetes 1.3之前的版本
    2. kubeDNS:Kubernetes 1.3至Kubernetes 1.11
    3. CoreDNS:Kubernetes 1.11开始至今

    实例:

    1. apiVersion: v1
    2. kind: Service
    3. metadata:
    4. name: sts-svc
    5. namespace: default
    6. labels:
    7. app: myapp-svc
    8. spec:
    9. clusterIP: None
    10. ports:
    11. - name: http
    12. port: 80
    13. protocol: TCP
    14. targetPort: 80
    15. selector:
    16. app: myapp-svc
    17. sessionAffinity: None
    18. type: ClusterIP

    //清单定义StatefulSet
    如上所述,一个完整的 StatefulSet 控制器由一个 Headless Service、一个 StatefulSet 和一个 volumeClaimTemplate 组成。如下资源清单中的定义:
     

    1. apiVersion: apps/v1
    2. kind: StatefulSet
    3. metadata:
    4. name: myapp-sts
    5. spec:
    6. serviceName: myapp-svc
    7. replicas: 3
    8. selector:
    9. matchLabels:
    10. app: myapp-svc
    11. template:
    12. metadata:
    13. labels:
    14. app: myapp-svc
    15. spec:
    16. containers:
    17. - name: myapp
    18. image: nginx
    19. ports:
    20. - containerPort: 80
    21. name: web
    22. volumeMounts:
    23. - name: www
    24. mountPath: /usr/share/nginx/html
    25. volumeClaimTemplates:
    26. - metadata:
    27. name: www
    28. spec:
    29. accessModes: ["ReadWriteOnce"]
    30. storageClassName: "nfs-client-storgeclass"
    31. resources:
    32. requests:
    33. storage: 1Gi

    3、DaemonSet:

    概述;

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

    使用 DaemonSet 的一些典型用法:

    1. 运行集群存储 daemon,例如在每个 Node 上运行 glusterd、ceph。
    2. 在每个 Node 上运行日志收集 daemon,例如fluentd、logstash。
    3. 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond。
      应用场景:Agent

    官方案例(监控)

    https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
     

    实例:

    1. apiVersion: apps/v1
    2. kind: DaemonSet
    3. metadata:
    4. name: nginx-daemonset
    5. labels:
    6. app: nginx
    7. spec:
    8. selector:
    9. matchLabels:
    10. app: nginx
    11. template:
    12. metadata:
    13. labels:
    14. app: nginx
    15. spec:
    16. containers:
    17. - image: nginx:1.14
    18. name: nginx
    19. ports:
    20. - containerPort: 80

    创建完成:

    在node02和node02节点上分别创建

    4、Job

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

    应用场景:

    数据库迁移、批处理脚本、kube-bench扫描、离线数据处理,视频解码等业务
     

    https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/    
     

    参数解释

    .spec.template.spec.restartPolicy

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

    .spec.backoffLimit

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

    实例

    1. apiVersion: batch/v1
    2. kind: Job
    3. metadata:
    4. name: busybox
    5. spec:
    6. template:
    7. spec:
    8. containers:
    9. - name: busybox
    10. image: busybox
    11. imagePullPolicy: IfNotPresent
    12. command: ["/bin/sh", "-c", "sleep 10;date;"]
    13. restartPolicy: Never
    14. backoffLimit: 2

     显示“Completed”表示正常,表示完成

    以下为表示没有完成的

    若在配置文件中添加“exit 2 ”则时没完成

    如果修改完之后从新创建可能会报错(我是报的这个错误)

    修改metadata.name

    1. apiVersion: batch/v1
    2. kind: Job
    3. metadata:
    4. name: my-01
    5. spec:
    6. template:
    7. spec:
    8. containers:
    9. - name: busybox
    10. image: nginx
    11. imagePullPolicy: IfNotPresent
    12. command: ["/bin/sh", "-c", "sleep 10;date;exit 1"]
    13. restartPolicy: Never
    14. backoffLimit: 2

    状态码“0”代表正常,非0不正常,后面如果加exit“1或则2” 待表不增长,就会重启容器,重启容器就会包"Error"

    5、CronJob 

    周期性任务,像Linux的Crontab一样。
    周期性任务
     

    应用场景:通知,备份

    https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/
     

    cronjob其它可用参数的配置
    spec:
      concurrencyPolicy: Allow            #要保留的失败的完成作业数(默认为1)
      schedule: '*/1 * * * *'            #作业时间表。在此示例中,作业将每分钟运行一次
      startingDeadlineSeconds: 15        #pod必须在规定时间后的15秒内开始执行,若超过该时间未执行,则任务将不运行,且标记失败
      successfulJobsHistoryLimit: 3        #要保留的成功完成的作业数(默认为3)
      terminationGracePeriodSeconds: 30    #job存活时间 默认不设置为永久
      jobTemplate:                        #作业模板。这类似于工作示例

    实例:

    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: nginx
    14. imagePullPolicy: IfNotPresent
    15. args:
    16. - /bin/sh
    17. - -c
    18. - date; echo Hello from the Kubernetes cluster
    19. restartPolicy: OnFailure

    创建完成

    kubectl get cronjob

    每分钟执行一次

    报错解决办法

    1. 如果报错:Error from server (Forbidden): Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) ( pods/log hello-1621587780-c7v54)
    2. //解决办法:绑定一个cluster-admin的权限
    3. kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous

  • 相关阅读:
    为什么建议大家尽可能选择自研公司
    php 打包下载
    【CSS应用篇】——CSS如何实现圆角边框
    @Transactional 注解导致跨库查询失效的问题
    springboot毕设项目大学生创新项目运维系统9y232(java+VUE+Mybatis+Maven+Mysql)
    服务器扩容步骤
    DevOps jenkins实现持续集成、持续部署
    论文阅读《2022ICLR:Are Message Passing Neural Networks Really Helpful for Knowledge Graph Completion? 》
    Azure DevOps (四) 创建第一条流水线
    TypeScript(基础篇)day01
  • 原文地址:https://blog.csdn.net/Breeze_nebula/article/details/134265575