zoukankan      html  css  js  c++  java
  • Kubernetes学习笔记(三):部署托管的Pod -- 存活探针、ReplicationController、ReplicaSet、DaemonSet、Job、CronJob

    存活探针

    Kubernetes可以通过存活探针(liveness probe)检查容器是否存活。如果探测失败,Kubernetes将定期执行探针并重新启动容器。
    官方文档请见:https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
    存活探针分为三种:

    • exec:在容器内执行任意命令,并检查命令的退出状态码,为0则成功,否则失败。
    • httpGet:执行http get请求,http code大于等于200并且小于400表示成功,否则失败。
    • tcp:尝试与指定端口建立socket连接,建立成功则探测成功,否则失败。

    exec探针

    从官网复制个yaml,但是要将image从k8s.gcr.io/busybox更改为busybox。

    -> [root@kube0.vm] [~] cat exec-liveness.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        test: liveness
      name: liveness-exec
    spec:
      containers:
      - name: liveness
        image: busybox
        args:
        - /bin/sh
        - -c
        - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 5
          periodSeconds: 5
    

    运行然后30秒后查看

    -> [root@kube0.vm] [~] k create -f exec-liveness.yaml
    pod/liveness-exec created
    
    -> [root@kube0.vm] [~] k describe po liveness-exec
    .......
        Liveness:       exec [cat /tmp/healthy] delay=5s timeout=1s period=5s #success=1 #failure=3
    .......
    Events:
      Type     Reason     Age                            From               Message
      ----     ------     ----                           ----               -------
      Normal   Scheduled  <unknown>                      default-scheduler  Successfully assigned default/liveness-exec to kube1.vm
      Normal   Pulling    <invalid>                      kubelet, kube1.vm  Pulling image "busybox"
      Normal   Pulled     <invalid>                      kubelet, kube1.vm  Successfully pulled image "busybox"
      Normal   Created    <invalid>                      kubelet, kube1.vm  Created container liveness
      Normal   Started    <invalid>                      kubelet, kube1.vm  Started container liveness
      Warning  Unhealthy  <invalid> (x3 over <invalid>)  kubelet, kube1.vm  Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
      Normal   Killing    <invalid>                      kubelet, kube1.vm  Container liveness failed liveness probe, will be restarted
    

    前30秒,/tmp/healthy是存在的,探针返回成功。30秒后,因为/tmp/healthy不存在了,所以一直失败,直到失败3次后重启。

    livenessProbe下的字段

    这时候kubectl explain po.spec.containers.livenessProbe就派上了用场。

    • exec:exec探针配置
    • httpGet:httpGet探针配置
    • tcpSocket:tcpSocket探针配置
    • initialDelaySeconds:初始延迟时间,在此时间内不进行探测,给程序预留启动时间。
    • periodSeconds:探测周期,默认10s
    • timeoutSeconds:超时时间,默认1s
    • failureThreshold:被认为失活的最小连续失败次数,默认3次
    • successThreshold:失败后被认为存活的最小连续成功次数,默认为1次。

    这些参数在上面的kubectl describe的结果中的Liveness字段有:

    exec [cat /tmp/healthy] delay=5s timeout=1s period=5s #success=1 #failure=3
    

    注意事项

    • 一定要检查程序的内部,而没有外界因素影响。
      例如,当服务器无法连接到数据库时,前端服务的探针不应返回失败。因为问题在数据库,重启前端服务也无法解决问题。
    • 无须再探针中实现重试
    • 探针要轻量

    ReplicationController

    ReplicationController是一种Kubernetes资源,可以确保他的pod始终处于运行状态。

    ReplicationController描述文件分为三大部分:

    • label selector(标签选择器):用于确定ReplicationController管理哪些pod
    • replica count(副本个数):指定运行pod的数量
    • pod template(pod模板):用于创建pod

    ReplicationController的目的就是创建和管理若干个pod副本,它会持续监控正在运行的pod列表,保证标签选择器匹配的pod数量与副本个数一致。如果少于副本数量,就要根据pod模板创建新的副本;如果多余副本数量,就要删除多余的pod。

    数量少的原因可能是:

    • 增加了副本个数
    • pod所在的工作节点出现故障
    • pod的标签更改了,导致pod与ReplicationController的标签选择器不再匹配了。此时,如果它不被任何ReplicationController的标签选择器匹配,它就称为一个孤儿了。

    数量多的原因可能是:

    • 减少了副本个数
    • 新建的pod与该ReplicationController的标签选择器匹配
    • 已存在的pod标签修改后与该ReplicationController的标签选择器匹配

    nginx-rc.yaml

    API服务器会检查模板中的标签是否与selector匹配,如果不匹配是无法创建的。可以不指定selector,它会根据模板中的labels自动配置。

    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: nginx-rc
    spec:
      replicas: 3	# 副本数量
      selector:	# pod选择器,决定RC的操作对象
        app: nginx
      template:	# pod模板
        metadata:
          labels:
            app: nginx
        spec:
          containers:
            - name: nginx
              image: nginx
              ports:
                - containerPort: 80
    

    使用ReplicationController

    创建ReplicationController

    -> [root@kube0.vm] [~] k create -f nginx-rc.yaml
    replicationcontroller/nginx-rc created
    

    查看pod,确实新建了3个pod。

    -> [root@kube0.vm] [~] k get po --show-labels
    NAME             READY   STATUS              RESTARTS   AGE   LABELS
    nginx-rc-2c47w   0/1     ContainerCreating   0          5s    app=nginx
    nginx-rc-jrcl2   0/1     ContainerCreating   0          5s    app=nginx
    nginx-rc-qgchh   0/1     ContainerCreating   0          5s    app=nginx
    

    查看ReplicationController,rc是ReplicationController的简写。

    -> [root@kube0.vm] [~] k get rc
    NAME       DESIRED   CURRENT   READY   AGE
    nginx-rc   3         3         3       5m58s
    

    查看详情

    -> [root@kube0.vm] [~] k describe rc nginx-rc
    Name:         nginx-rc
    Namespace:    default
    Selector:     app=nginx
    Labels:       app=nginx
    Annotations:  <none>
    Replicas:     3 current / 3 desired				# 当前数量、期望数量
    Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed	# 各种状态下的数量
    Pod Template:
      Labels:  app=nginx
      Containers:
       nginx:
        Image:        nginx
        Port:         80/TCP
        Host Port:    0/TCP
        Environment:  <none>
        Mounts:       <none>
      Volumes:        <none>
    Events:
      Type    Reason            Age    From                    Message
      ----    ------            ----   ----                    -------
      Normal  SuccessfulCreate  7m26s  replication-controller  Created pod: nginx-rc-2c47w
      Normal  SuccessfulCreate  7m26s  replication-controller  Created pod: nginx-rc-jrcl2
      Normal  SuccessfulCreate  7m26s  replication-controller  Created pod: nginx-rc-qgchh
    

    可以搞一些破坏,比如更改、删除pod的标签,或者干脆删除pod。ReplicationController会因为当前数量与期望数量不符而创建新的副本。

    控制器如何创建的pod

    控制器通过创建一个新的副本代替被删除的副本时,它并没有对删除本身做出反应,而是针对由此产生的状态——副本数量不足做出反应。
    虽然控制器会立即受到pod被删除的通知,但这并不是它创建新副本的原因。该通知会触发控制器检查实际的副本数量并采取相应措施。

    kubectl edit

    kubectl edit rc nginx-rc可以在编辑器中打开nginx-rc的yaml配置,修改在保存后会立刻做出改变。

    -> [root@kube0.vm] [~] k edit rc nginx-rc
    replicationcontroller/nginx-rc edited
    通过KUBE_EDITOR环境变量可以指定用什么编辑器打开。
    

    kubectl scale

    可以使用kubectl scale命令进行扩缩容。

    -> [root@kube0.vm] [~] k scale rc nginx-rc --replicas=6
    replicationcontroller/nginx-rc scaled
    

    以上操作会修改spec.replicas字段,就像通过kubectl edit修改一样。

    删除ReplicationController

    使用 kubectl delete 删除ReplicationController时,pod也会被删除。但由于pod是被ReplicationController创建的而不是它的组成部分,所以可以通过指定--cascade=false而不删除pod。

    注意事项

    • pod永远不会被重新安置到另一个节点。
    • 虽然一个pod没有绑定在ReplicationController上,但该pod在metadata.ownerReferences引用它。

    ReplicaSet

    ReplicationController最终将要被弃用,代替它的是ReplicaSet。它们的行为完全相同,但是ReplicaSet的选择器更具有表达力。

    nginx-rs.yaml

    让我们来看一个ReplicaSet的描述文件:

    apiVersion: apps/v1	# api版本与ReplicationController不同
    kind: ReplicaSet
    metadata:
      name: nginx-rs
    spec:
      replicas: 3
      selector:		# ReplicaSet的pod选择器有matchLabels和matchExpressions,与ReplicationController的是相似的,但更强大
        matchLabels:
          app: nginx
      template:		# 模板内容是一致的
        metadata:
          labels:
            app: nginx
        spec:
          containers:
            - name: nginx
              image: nginx
              ports:
                - containerPort: 80
    

    主要区别在于pod选择器。ReplicaSet的创建于ReplicationController一样,缩写是rs,就不再赘叙了。

    matchExpressions

    上面描述文件的选择器使用matchExpressions可以改为:

      selector:
        matchExpressions:
          - key: app
            operator: In
            values:
              - nginx
    

    每个表达式都必须包含key、operator(运算符),有可能包含values(取决于运算符),运算符有以下四种:

    • In:Label的值必须与values中的一个相等
    • NotIn:Label的值不能与values中的任何一个相等
    • Exists:Pod必须包含一个指定名称的标签,values无所谓
    • DoesNotExists:Pod不得包含指定名称的标签,values不能指定

    DaemonSet

    DaemonSet与ReplicaSet的不同在于,DaemonSet可以让pod在集群的每个节点上运行,有且只有一个。

    如果节点下线,DaemonSet不会在其他地方重建pod;如果集群新加入了一个节点,DaemonSet会立刻部署一个新的pod。如果有人删除了pod,DaemonSet会建立一个新的。

    这些pod通常用于执行系统级别或基础结构相关的工作,如日志收集和资源监控。典型的例子就是Kubernetes自己的kube-proxy。

    如果想让DaemonSet只在特定节点运行pod,需要通过pod模板中的nodeSelector属性指定。

    DaemonSet中没有期望副本数的概念,它不需要。因为它的工作是确保有一个匹配它选择器的pod在节点上运行。

    nginx-ds.yaml

    可能这里用继续用nginx作为例子不太恰当,但目前我们关注的重点是DaemonSet,继续吧。。。

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: nginx-ds
    spec:			# 去掉了replicas,因为不需要
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          nodeSelector:	# 添加了一个节点的标签选择器,选择只部署地区在在北京的节点上
            region: "beijing"
          containers:
            - name: nginx
              image: nginx
              ports:
                - containerPort: 80
    

    创建DaemonSet

    先给kube1.vm打个标签

    -> [root@kube0.vm] [~] k label node kube1.vm region=beijing
    node/kube1.vm labeled
    
    -> [root@kube0.vm] [~] k get node -L region
    NAME       STATUS   ROLES    AGE   VERSION   REGION
    kube0.vm   Ready    master   40h   v1.17.3
    kube1.vm   Ready    <none>   40h   v1.17.3   beijing
    kube2.vm   Ready    <none>   40h   v1.17.3
    

    提交描述文件

    -> [root@kube0.vm] [~] k create -f nginx-ds.yaml
    daemonset.apps/nginx-ds created
    
    -> [root@kube0.vm] [~] k get ds,po -o wide
    NAME                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR    AGE   CONTAINERS   IMAGES   SELECTOR
    daemonset.apps/nginx-ds   1         1         1       1            1           region=beijing   52s   nginx        nginx    app=nginx
    
    NAME                 READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
    pod/nginx-ds-5z95c   1/1     Running   0          52s   10.244.1.24   kube1.vm   <none>           <none>
    

    给kube2.vm也打个标签

    -> [root@kube0.vm] [~] k label node kube2.vm region=beijing
    node/kube2.vm labeled
    
    -> [root@kube0.vm] [~] k get ds,po -o wide
    NAME                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR    AGE    CONTAINERS   IMAGES   SELECTOR
    daemonset.apps/nginx-ds   2         2         1       2            1           region=beijing   113s   nginx        nginx    app=nginx
    
    NAME                 READY   STATUS              RESTARTS   AGE    IP            NODE       NOMINATED NODE   READINESS GATES
    pod/nginx-ds-5z95c   1/1     Running             0          113s   10.244.1.24   kube1.vm   <none>           <none>
    pod/nginx-ds-b46lb   0/1     ContainerCreating   0          3s     <none>        kube2.vm   <none>           <none>
    

    Job

    Job可以运行一种pod,在该pod内的进程成功结束时,不再重启。一旦任务完成,pod就被认为处于完成状态。

    比如可以使用在将一些数据导出到其他地方,这个工作可能会持续几个小时。

    我们基于busybox镜像,sleep一段时间用于模拟这个操作。

    job.yaml

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: job
    spec:
      template:			# 没有指定selector,会根据pod标签中自动创建
        metadata:
          labels:
            app: job
        spec:
          restartPolicy: OnFailure	# 执行遇到异常则重启,默认为Always。
          containers:
            - name: sleepbusybox
              image: busybox
              command: ["/bin/sh","-c","sleep 60;echo this is busybox"]
    

    restartPolicy表示pod的重启策略,默认Always,其他两项为OnFailure和Never。

    运行查看

    创建job

    -> [root@kube0.vm] [~] k create -f job.yaml
    job.batch/job created
    

    60秒内查看:

    -> [root@kube0.vm] [~] k get job,pod
    NAME            COMPLETIONS   DURATION   AGE
    job.batch/job   0/1           14s        14s
    
    NAME            READY   STATUS    RESTARTS   AGE
    pod/job-4sfv4   1/1     Running   0          14s
    

    60秒后查看:

    -> [root@kube0.vm] [~] k get job,pod
    NAME            COMPLETIONS   DURATION   AGE
    job.batch/job   1/1           68s        71s
    
    NAME            READY   STATUS      RESTARTS   AGE
    pod/job-4sfv4   0/1     Completed   0          71s
    

    使用jsonpath获取 pod name 查看log

    -> [root@kube0.vm] [~] k logs $(k get po --selector=app=job --output=jsonpath={.items..metadata.name})
    this is busybox
    

    completions与parallelism

    job描述文件下的spec有两个字段:

    • completions:job要确保完成多少个pod,默认为1。
    • parallelism:最多并行运行多少个pod,默认为1。

    job-batch.yaml

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: job-batch
    spec:
      completions: 5
      parallelism: 2
      template:
        # 与job.yaml相同
    

    activeDeadlineSeconds

    job.spec.activeDeadlineSeconds属性来限制Job在集群中的存活时间,超过此值,所有的pod都被终止。Job的status变为 type: Failed,reason: DeadlineExceeded

    CronJob

    与Linux的crontab类似,使pod可以在特定时间运行,或者周期运行。

    cronjob.yaml

    这个描述文件是个套娃。。

    CronJob包含job的模板,也就是jobTemplate;job里还包含pod的模板,也就是template。

    schedule字段中的值是"分 小时 每月第几天 月份 星期几",详情请参考Linux crontab。

    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
      name: cron-job
    spec:
      schedule: "*/3 * * * * "	# 每三分钟运行一次
      jobTemplate:			# job的模板
        spec:
          template:			# pod的模板
            metadata:
              labels:
                app: job-in-cron
            spec:
              restartPolicy: OnFailure
              containers:
                - name: sleepbusybox
                  image: busybox
                  command: ["/bin/sh","-c","sleep 60;echo this is busybox"]
    

    运行

    创建cron-job

    -> [root@kube0.vm] [~] k create -f cronjob.yaml
    cronjob.batch/cron-job created
    

    等了几分钟

    -> [root@kube0.vm] [~] k get all
    NAME                            READY   STATUS      RESTARTS   AGE
    pod/cron-job-1590053040-pqhhh   0/1     Completed   0          97s
    
    NAME                            COMPLETIONS   DURATION   AGE
    job.batch/cron-job-1590053040   1/1           68s        97s
    
    NAME                     SCHEDULE       SUSPEND   ACTIVE   LAST SCHEDULE   AGE
    cronjob.batch/cron-job   */3 * * * *    False     0        105s            4m39s
    

    又等了几分钟

    -> [root@kube0.vm] [~] k get all
    NAME                            READY   STATUS              RESTARTS   AGE
    pod/cron-job-1590053040-pqhhh   0/1     Completed           0          3m4s
    pod/cron-job-1590053220-whflp   0/1     ContainerCreating   0          3s
    
    NAME                            COMPLETIONS   DURATION   AGE
    job.batch/cron-job-1590053040   1/1           68s        3m4s
    job.batch/cron-job-1590053220   0/1           3s         3s
    
    NAME                     SCHEDULE       SUSPEND   ACTIVE   LAST SCHEDULE   AGE
    cronjob.batch/cron-job   */3 * * * *    False     1        12s             6m6s
    

    可以看到就当前的描述文件而言,cron-job每次创建一个job,job创建一个pod的运行。

    startingDeadlineSeconds

    cronjob.spec.startingDeadlineSeconds规定pod必须预定时间之后的startingDeadlineSeconds秒内运行,超过此时间则不运行,并将其显示未Failed。

    小结

    • 使用存活探针检查容器是否存活。
    • ReplicationController创建并管理Pod,但并不是绑定关系。它始终保持期望数量的副本正在运行。
    • ReplicationController将被弃用,ReplicaSet拥有更强的标签选择器。
    • DaemonSet会在每个节点上保持运行有且只有一个Pod,可以通过nodeSelector让其只在特定节点运行。
    • Job创建Pod运行完成后,Pod为为Completed状态。completions与parallelism指定需要完成的数量与并行度。
    • restartPolicy:默认Always,还有OnFailure、Never。
    • CronJob创建Job,Job创建Pod。
    • 命令:edit、scale
  • 相关阅读:
    LeetCode题解——两数之和
    题解LeetCode——回文数
    汇编语言入门教程
    python基础--局部变量与全局变量
    linux--基础知识1
    python基础--函数
    字符串format函数使用
    字符串的拼接
    python基础--6 集合
    python基础--5字典
  • 原文地址:https://www.cnblogs.com/flhs/p/12925832.html
Copyright © 2011-2022 走看看