Kubernetes存活探针(Liveness Probe)

存活探针

Kubernetes提供了自愈的能力,具体就是能感知到容器崩溃,然后能够重启这个容器。但是有时候例如Java程序内存泄漏了,程序无法正常工作,但是JVM进程却是一直运行的,对于这种应用本身业务出了问题的情况,Kubernetes提供了Liveness Probe机制,通过检测容器响应是否正常来决定是否重启,这是一种很好的健康检查机制。

毫无疑问,每个Pod最好都定义Liveness Probe,否则Kubernetes无法感知Pod是否正常运行。

Kubernetes支持如下三种探测机制。

  • HTTP GET:Probe向容器发送HTTP GET请求,如果Probe收到2xx或3xx,说明容器是健康的。
  • TCP Socket:Probe尝试与容器指定端口建立TCP连接,如果连接成功建立,说明容器是健康的。
  • Exec:Probe执行容器中的命令并检查命令退出的状态码,如果状态码为0,说明容器是健康的。

注意 1:与存活探针对应的还有一个就绪探针(Readiness Probe),详细介绍请参见《Kubernetes 就绪探针(Readiness Probe)》这篇博文。

HTTP GET

HTTP GET方式是最常见的探测方法,其具体机制是向容器发送HTTP GET请求,如果Probe(探头,Kubelet中创建的HTTP客户端)收到2xx或3xx,说明容器是健康的。

httpGet配置项:

  • host:连接的主机名,默认连接到pod的IP。你可能想在http header中设置”Host”而不是使用IP。
  • scheme:连接使用的schema,默认HTTP。
  • path: 访问的HTTP server的path。
  • httpHeaders:自定义请求的header。HTTP运行重复的header。
  • port:访问的容器的端口名字或者端口号。端口号必须介于1和65535之间。
apiVersion: v1
kind: Pod
metadata:
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: nginx:alpine
    livenessProbe:           # liveness probe
      httpGet:               # HTTP GET定义
        path: /
        port: 80
  imagePullSecrets: 
  - name: default-secret

创建这个Pod。

$ kubectl create -f liveness-http.yaml
pod/liveness-http created

如上,这个Probe往容器的80端口发送HTTP GET请求,如果请求不成功,Kubernetes通常会重启容器。

注意 1: Pod存活探针检测失败后是否重启容器,主要看Pod重启策略,详情请参见《Kubernetes Pod重启策略 》这篇博文,如果Pod是默认的Always重启策略,那么Pod存活探针检查失败肯定是会重启容器的。

查看Pod详情。

$ kubectl describe po liveness-http
Name:               liveness-http
......
Containers:
  liveness:
    ......
    State:          Running
      Started:      Mon, 03 Aug 2020 03:08:55 +0000
    Ready:          True
    Restart Count:  0
    Liveness:       http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-vssmw (ro)
......

可以看到Pod当前状态是Running,Restart Count为0,说明没有重启。如果Restart Count不为0,则说明已经重启。

TCP Socket

TCP Socket(Kubelet中创建的TCP客户端)尝试与容器在指定端口上建立TCP连接。 如果它可以建立连接,则容器被认为是健康的;否则被认为是不健康的。

如果您有HTTP探针或Command探针不能正常工作的情况,TCP探测器会派上用场。 例如,gRPC或FTP服务是此类探测的主要候选者。

TCP 的配置项(tcpSocket):

  • host:探测的主机,默认为本pod ip。
  • port:端口,1到65535。
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-tcp
spec:
  containers:
  - name: liveness
    image: nginx:alpine
    livenessProbe:           # liveness probe
      tcpSocket:
        port: 80
  imagePullSecrets: 
  - name: default-secret

Exec

Exec即执行具体命令,具体机制是Probe执行容器中的命令(Kubelet调用CRI接口进入容器内部执行命令)并检查命令退出的状态码。 如果命令以退出代码0返回,则容器标记为健康; 否则,它被标记为不健康。 当您不能或不想运行HTTP服务时,此类型的探针则很有用,但是必须是运行可以检查您的应用程序是否健康的命令。

Exec 的配置项(exec):

  • command:需要执行的命令,需要符合命令的格式。
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: nginx:alpine
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:           # liveness probe
      exec:                  # Exec定义
        command:
        - cat
        - /tmp/healthy
  imagePullSecrets: 
  - name: default-secret

上面定义在容器中执行cat /tmp/healthy命令,如果成功执行并返回0,则说明容器是健康的。上面定义中,30秒后命令会删除/tmp/healthy,这会导致Liveness Probe判定Pod处于不健康状态,这时候通常会重启容器。

Liveness Probe高级配置

上面liveness-http的describe命令回显中有如下行。

Liveness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3

这一行表示Liveness Probe的具体参数配置,其含义如下:

  • delay:延迟,delay=0s,表示在容器启动后立即开始探测,没有延迟时间
  • timeout:超时,timeout=1s,表示容器必须在1s内进行响应,否则这次探测记作失败
  • period:周期,period=10s,表示每10s探测一次容器
  • success:成功,#success=1,表示连续1次成功后记作成功
  • failure:失败,#failure=3,表示连续3次失败后会重启容器

以上存活探针表示:容器启动后立即进行探测,如果1s内容器没有给出回应则记作探测失败。每次间隔10s进行一次探测,在探测连续失败3次后重启容器。

这些是创建时默认设置的,您也可以手动配置,如下所示。
apiVersion: v1
kind: Pod
metadata:
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: nginx:alpine
    livenessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 10    # 容器启动后多久开始探测
      timeoutSeconds: 2          # 表示容器必须在2s内做出相应反馈给probe,否则视为探测失败
      periodSeconds: 30          # 探测周期,每30s探测一次
      successThreshold: 1        # 连续探测1次成功表示成功
      failureThreshold: 3        # 连续探测3次失败表示失败

initialDelaySeconds一般要设置大于0,这是由于很多情况下容器虽然启动成功,但应用就绪也需要一定的时间,需要等就绪时间之后才能返回成功,否则就会导致probe经常失败。

另外failureThreshold可以设置多次循环探测,它定义了在多少次连续失败后认为应用程序不再健康。如果将其设置为多次循环探测,意味着在实际应用中,系统会进行多次探测以确定应用程序是否健康。这一点在开发应用时需要注意。

配置有效的Liveness Probe

  • Liveness Probe应该检查什么

    一个好的Liveness Probe应该检查应用内部所有关键部分是否健康,并使用一个专有的URL访问,例如/health,当访问/health时执行这个功能,然后返回对应结果。这里要注意不能做鉴权,不然probe就会一直失败导致陷入重启的死循环。

    另外检查只能限制在应用内部,不能检查依赖外部的部分,例如当前端web server不能连接数据库时,这个就不能看成web server不健康。

  • Liveness Probe必须轻量

    Liveness Probe不能占用过多的资源,且不能占用过长的时间,否则所有资源都在做健康检查,这就没有意义了。例如Java应用,就最好用HTTP GET方式,如果用Exec方式,JVM启动就占用了非常多的资源。

posted @ 2021-12-07 08:32  人艰不拆_zmc  阅读(114)  评论(0编辑  收藏  举报