zoukankan      html  css  js  c++  java
  • [Kubernetes]容器健康检查和恢复机制

      在Kubernetes中,可以为Pod里的容器定义一个健康检查探针(Probe),这样Kubernetes会根据这个Probe的返回值决定这个容器的状态,而不是直接以容器是否允许(来自Docker返回的信息)作为依据。

    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        test: liveness
      name: test-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

      这个Pod的容器在启动之后做的第一件事是在/tmp目录下创建一个healthy文件,以此作为自己已经正常运行的标识,而30s过后它会把这个文件删除掉。同时还定义了一个livenessProbe,类型是exec,它会在容器启动后执行指定的命令:“cat /tmp/healthy”,如果这个文件存在,这条命令返回值就是0,Pod就会认为这个容器不仅已经启动,而且是健康的,这个健康检查在启动5s后开始执行,每5s执行一次。

    $ kubectl create -f test-liveness-exec.yaml
    $ kubectl get pod
    NAME                READY     STATUS    RESTARTS   AGE
    test-liveness-exec   1/1       Running   0          10s
    
    
    ####30s后
    $ kubectl describe pod test-liveness-exec
    FirstSeen LastSeen    Count   From            SubobjectPath           Type        Reason      Message
    --------- --------    -----   ----            -------------           --------    ------      -------
    2s        2s      1   {kubelet worker0}   spec.containers{liveness}   Warning     Unhealthy   Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
    $ kubectl get pod test-liveness-exec
    NAME           READY     STATUS    RESTARTS   AGE
    liveness-exec   1/1       Running   1          1m

       可以看到,健康检查报告容器不健康,但是Pod保存了running状态,这是为什么呢?

      认真看可以发现。RESTARTS字段已经变成1了,即这个异常的容器已经被Kubernetes重启了,在这个过程中,Pod保存Running状态不变。Kubernetes没有Docker的Stop语义,所以虽然是重启,实际却是重新创建了容器,这个功能就是Kubernetes里的Pod恢复机制(restartPolicy),它是Pod的Spec部分的一个标准字段(pod.spec.restartPolicy),默认值为Always,作为用户可以设置Pod的恢复策略

      • Always:任何情况下,只要容器不在运行状态,就自动重启容器(合理设置,如果只计算1+1=2,计算完成后退出,强制重启毫无意义)
      • OnFailure:只在容器异常时才自动重启容器
      • Never:从来不重启容器(如要关心容器退出后的日志、文件和目录,就需要设置为NEVER,否则可能丢失)

      Pod的恢复过程,永远都是发送在当前节点上,而不会跑到别的节点上去,即如果这个宿主机宕机了,这个pod也不会主动迁移到其他节点上去。如果想让Pod出现在其他可用节点上,就必须用Deployment这样的控制器来管理Pod。

      Kubernetes中restartPolicy和Pod里容器的状态以及Pod状态的对应关系的基本设计原理有两个:

      • 只要Pod的restartPolicy指定的策略允许重启异常的容器(如Always),那么这个Pod就会保持running状态,并进行容器重启,否则Pod会进入Failed状态。
      • 对于包含多个容器的Pod,只有它里面所有的容器都进入异常状态后,Pod才会进入Failed状态,在此之前,Pod都是running状态,此时Pod的REDY字段会显示正常容器的个数。

      所以假如一个Pod里只有一个容器,然后这个容器异常退出了,那么只有当restartPolicy=Never时,这个Pod才会进入Failed状态,而其他情况下,由于kubernetes都可以重启这个容器,所以Pod状态保持running不变。如果这个Pod有多个容器,仅有一个容器异常退出,它始终保持Running状态,哪怕即使restartPolicy=Never,也只有当容器也异常退出之后,这个Pod才会进入Failed状态。

      除了在容器中执行命令外,livenessProbe也可以定义为发起HTTP或者TCP请求的方式,定义格式如下:

    ...
    livenessProbe:
         httpGet:
           path: /healthz
           port: 8080
           httpHeaders:
           - name: X-Custom-Header
             value: Awesome
           initialDelaySeconds: 3
           periodSeconds: 3
        ...
        livenessProbe:
          tcpSocket:
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 20
  • 相关阅读:
    Poi之Word文档结构介绍
    Cannot create PoolableConnectionFactory (ORA-28040: No matching authentication protocol
    ZipFile和ZipInputSteam解压zip文件
    Java读取其他jar包里的配置文件
    安装oracle后不能连接问题
    JDBC oracle 错误总结
    vimplugin破解
    SQL之left join、right join、inner join
    ELK之安装searchguard后默认管理员用户admin修改
    CentOS使用systemctl daemon-reload报错Error getting authority: Error initializing authority: Error calling StartServiceByName for org.freedesktop.PolicyKit1: Timeout was reached (g-io-error-quark, 24)解决办法
  • 原文地址:https://www.cnblogs.com/yuxiaoba/p/9750601.html
Copyright © 2011-2022 走看看