zoukankan      html  css  js  c++  java
  • 傲视Kubernetes(六):Pod管理及控制器

    本文主要内容:

    1、Kubernetes如何管理Pod?

    2、Kubernetes Control Plane组件有哪几种?作用效果是什么?

    一、Kubernetes如何管理Pod

    Kubernetes中的Pod根据创建方式的不同,可以分为两种:一种是直接创建的Pod,比如自己写了一个Pod的yaml文件,通过kubectl create命令创建的Pod;一种是通过控制器,也就是Control Plane创建的Pod。

    对于第一种Pod,也就是自己创建的Pod,创建完成之后由它所在的Node节点上的Kubelet管理。第二种Pod由控制器Control Plane管理。

    Kubelet管理Pod

    Kubelet管理Pod的手段很简单,就是重启大法。每个Pod创建时,都可以给配置存活探针,如下所示,创建Pod之后Kubernetes会每隔一段时间调用一次这个存活探针,也就是请求,如果执行失败或者没有响应,Kubelet则重启Pod

    ...
    spec:
      containers:
      -  image:xxx
         livenessProbe:
           httpGet: /
           port: 8080

    Kubernetes提供了三种探针类型,上面示例中的是httpGet(返回的状态码是2xx或3xx则会被认定成功),还有两种是TCP套接字探针和Exec探针。常用的一般都是HttpGet类型。

    注意,如果不设置存活探针,kubelet只会根据容器进程是否存在来判断进程是否健康,也就是没有了健康检查应有的效果(因为比如OOM这样的异常发生时,JVM进程仍然运行),所以存活探针基本是一个必须的配置项。

    在存活探针的配置项livenessProbe的同一级,还可以配置探针的其他属性,比如delay、timeout、period等,还有一个参数叫初始延迟initialDelaySeconds一般来说也需要配置上。如果不配置初始延迟参数,探针将在容器启动时就探测容器,这很容易失败,因为应用还没完成启动。配置这个参数就能有效避免这种情况的发生。

    到此为止,都是在讲Pod出异常之后的重启处理,但如果Pod所在的Node节点出异常导致宕机呢?此时Node节点上的kubelet也就挂了,从而那些我们自己创建的依赖于Kubelet管理的Pod也就彻底GG了。

    遇到这种情况该怎么办呢?这时候Kubernetes Control Plane就可以发挥作用了。

    Control Plane管理Pod

     Kubernetes的控制器,也就是Control Plane组件,有很多种,比如ReplicationController、ReplicationSet、DaemonSet、Job等。

    在创建这些控制器的时候,会指定对应非副本数,控制器创建完成之后就会检测实际运行的pod数是否跟副本数一致,如果实际运行的少了(Pod出异常挂掉了或者Pod所在的节点挂了),控制器会根据配置的模板创建新的Pod;如果实际运行的多了,则会删掉多余的Pod。总之控制器会控制实际运行的Pod数与配置的副本数目一致

    当然,如果这些控制器所属Pod的探针存活检测异常,还是由Pod所在节点的kubelet来重启容器。即kubelet负责重启,控制器负责创建/删除

    二、Kubernetes Control Plane的组件有哪些?作用各是什么?

    下面分别对五种Control Plane的作用进行说明,其实除此之外还有两种最常用的Deployment和StatefulSet,这两种会在后面着重学习。

    1、ReplicationController

    ReplicationController顾名思义,副本的控制器。它主要由三部分组成: 标签选择器(label selector)、副本个数(replica count)、pod模板(pod template)。ReplicationController的yaml配置示例如下:

    apiVersion: v1
    kind: ReplicationController
    metadata:
       name: kubia
    spec:
       replicas: 3  # 副本数
       selector:  # 标签选择器
          app: kubia
       template: # pod模板
          metadata:
             labels:
                app: kubia
          spec:
             containers:
             -  name: kubia
                image: xxx/kubia
                port:
                -  containerPort:8080

    标签选择器用户查询并监控所有拥有这个标签的Pod;而副本数则用户控制跟标签选择器匹配上的Pod的数量;如果Pod数量少于副本数,则会按照Pod模板创建新的Pod。所以这里的标签选择器必须要与pod模板中的标签一致,当然也可以不指定标签选择器,此时会默认按照pod模板中的标签来选择。

    从上面就可以知道很重要的一点:Kubernetes是通过标签与标签选择器实现的控制器与Pod的归属关系

    具体操作的指令如下,很多操作跟操作其他对象没什么差别:

    kubectl create -f kubia-rc.yaml  # 根据yaml文件创建ReplicationController
    
    kubectl get rc   # 查看ReplicationController
    
    kubectl delete pod kubia-xxx # 删掉一个pod后再用get pod会看到正在创建新pod

    kubectl delete rc kubia # 删除kubia这个rc,此时连它所对应的Pod也都会被删掉

    kubectl delete rc kubia --cascade=false # 删除kubia这个rc,但它所对应的Pod会被保留下来 kubectl describe rc kubia # 查看ReplicationController的详细信息

    kubectl label pod kubia-xxx app=kulet --overwrite # 改变pod的标签,此时rs会创建一个新Pod来达到3个的副本数

    kubectl get pods -L app # 查看pod的标签

    kubectl edit rc kubia # 进入修改名为kubia的rc的页面,修改后会立即生效,如果改了pod模板,只会对从此以后新创建的pod有效,不会影响已有pod

    kubectl scale rc kubia --replicas=4 # 将副本数置为4,此时如果实际pod数少了则会新建

    注意,如果是一个Node节点不可用导致的Pod失效,Kubernetes会等待一段时间(几分钟)来等待Node的恢复,如果几分钟后仍未恢复,才会创建新Pod来代替之前失效的Pod。

    2、ReplicationSet

     ReplicationSet是ReplicationController的升级版,前者rs拥有rc所有的功能,而且还有更富表达力的标签选择器,所以后者现在完全可以弃之不用。

    ReplicationSet的yaml示例:

    apiVersion: apps/v1beta2
    kind: ReplicationSet
    metadata:
       name: kubia
    spec:
       replicas: 3  # 副本数
       selector:  # 标签选择器
          matchLabels:
             app: kubia
       template: # pod模板
          metadata:
             labels:
                app: kubia
          spec:
             containers:
             -  name: kubia
                image: xxx/kubia
                port:
                -  containerPort:8080

    对比ReplicationController可以看到有两处有区别:一是apiVersion不再是v1了(此处的apps是api组,后面的v1beta2是实际的api版本),二是选择器那里中间又加了一级matchLabels。

    上面所有对ReplicationController的指令都可以用于ReplicationSet,只需将rc替换为rs即可。

     下面着重看看ReplicationSet对于标签选择器的升级:

    1)、matchLabels

    具体用法已经在上面的yaml示例中体现了,它的作用跟ReplicationController中的标签选择器相同,即完全匹配key和value(允许有其他的标签)。

    2)matchExpressions

    使用方式如下:

    selector:
       matchExpressions:
         - key: app 
           operator: In
           values:
             - kubia   # 表示标签的值必须是kubia

    matchExpressions下面必须有key和operator标签,而value标签有还是无取决于operator的值。operator有如下几种:

    In: 此时需要有values标签,表示pod必须有与其中一个指定的values匹配的标签

    NotIn:此时需要有values标签,表示pod必须的标签与任何指定的values不匹配

    Exists:不需要values标签,表示pod必须包含指定key的标签,不关注value

    DoesNotExist:不需要values标签,表示pod不得包含有指定key的标签

    需要注意的是,selector下面可以指定多个标签表达式,即matchLabels和matchExpressions可以有一个也可以有多个也可以混合,此时这多个match的关系是与的关系,即都为true的pod才满足要求。一般不建议设置多个。

    3、DaemonSet

     该控制器可以达到一种效果,即在每个Node节点上创建一个Pod。如果Node有增加或减少,相应的Pod也增加减少。DaemonSet的yaml配置如下所示:

    apiVersion: apps/v1beta2
    kind: DaemonSet
    metadata:
       name: kubia-monitor
    spec:
       selector:  # 标签选择器
          matchLabels:
             app: kubia-monitor
       template: # pod模板
          metadata:
             labels:
                app: kubia-monitor
          spec:
             nodeSelector: # 节点选择器
                disk: ssd
             containers:
             -  name: kubia-monitor
                image: xxx/kubia-monitor
                port:
                -  containerPort:8080

    可以看到,DaemonSet不需要设置副本数,因为每个Node节点只有一个Pod。在上面的配置中,还多了一个节点选择器nodeSelector,它是用于控制只在满足节点选择器的节点上创建Pod,即对节点做一个过滤。注意,DaemonSet对Pod的创建是绕过了调度器的,所以即使对节点设置了不可调度,只要满足DaemonSet的节点选择器,则仍然可以在上面创建一个Pod

    对DaemonSet的create、get、describe、delete等操作与其他控制器相同,就不在此赘述了,只需将对应的描述改成ds即可。

    4、Job

    上面介绍的三种控制器都是启动后一直运行的,而Job是用于执行一次性任务的,执行完之后就会被自动删掉。Job的yaml文件示例如下:

    apiVersion: batch/v1  #Job属于batch API组,版本为v1
    kind: Job
    metadata:
       name: kubia-job
    spec:
       template: # pod模板
          metadata:
             labels:
                app: kubia-job
          spec:
             restartPolicy: OnFailure  # 设置重启策略
             containers:
             -  name: main
                image: xxx/kubia-job
                port:
                -  containerPort:8080

    着重看一下重启策略 restartPolicy。重启策略一共有三种:Always(总是重启,即执行完成之后会再次启动,一直这样进行下去)、OnFailure(失败重启)、Never(不重启,即使执行失败)。一般来说只会用

    后两者,不会用Always。

    Job执行完之后,通过kubectl get pod是无法查看到它的,需要用 kubectl get pod -a ,状态是Completed。

    Job还支持运行多次和并行执行,配置方式如下:

    apiVersion: batch/v1  
    kind: Job
    metadata:
       name: kubia-job
    spec:
       completions: 5
       parallelism: 2
       template: # pod模板
           ...

    completions配置的数目,表示要执行多少次。如果未配置parallelism,则默认并行度是1,即同一时间只有一个Pod在运行,运行完这个Pod再创建第二个,一直运行完5个为止。

    若如上所示,配置了parallelism=2,则同一时间会有两个Pod在运行,其中一个执行完之后再创建一个,一直执行完5个为止。

    在Job运行时更改parallelism的指令:

    kubectl scale job kubia-job --replicas=3

    可以看到,跟扩容指令相同。

    为应对异常情况,Job还有两个属性配置:

    spec.activeDeadlineSeconds: 设置超时时间,Job实例运行时间超过这个配置时间,会被标记为失败,pod被终止运行。

    spec.backoffLimit:重试次数,未配置时默认为6次。

    5、CronJob

     熟悉定时任务的,应该不难猜到,该类型的控制器用于精确控制Pod定期执行的。配置的yaml如下所示:

    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
       name: kubia-cronjob
    spec:
       schedule: "0,15,30,45 * * * *"
       startingDeadlineSeconds: 15  #表示如果离预定时间15s后还未启动Job,则本次任务不会执行
       jobTemplate: 
          metadata:
             labels:
                app: kubia-cronjob
          spec:
             restartPolicy: OnFailure  # 设置重启策略
             containers:
             -  name: main
                image: xxx/kubia-cronjob
                port:
                -  containerPort:8080

    CronJob创建后,会在每个指定的cron表达式时间点创建一个新的Job。但有点坑的地方在于,它可能一下子创建两个Job,也可能一个不创建。所以需要在业务侧进行兼容,一方面是可以幂等,另一方面后面运行的任务需将前面未运行的任务未做的事情给做了。

    本文到这里就结束了,下一节将一起学习Kubernetes中的服务。

  • 相关阅读:
    selenium之css定位
    selenium之Xpath定位
    配置JAVA_HOME踩得坑 。。
    linux 怎么查看系统的环境变量 与设置jdk 系统环境变量
    jenkins添加环境变量 ,win 10的 环境变量如下,win7 就是不加也可以运行,不报 “python 不是内部命令 ” 的错误。
    win7 bat copy 一个文件 到另外的文件夹内,路径得用引号哦
    路由器原理
    mven入门
    局域网内和局域网间的通信
    详解DNS域名解析全过程
  • 原文地址:https://www.cnblogs.com/zzq6032010/p/14321751.html
Copyright © 2011-2022 走看看