05 Pod健康检查

2020-01-17  本文已影响0人  wangfs

现在在Pod的整个生命周期中,能影响到Pod的就只剩下健康检查这一部分了。在k8s集群当中,我们可以通过配置liveness probe(存活探针)readiness probe(可读性探针)来影响容器的生命周期。

和前面的钩子函数一样的,我们这两个探针支持下面的几种配置方式:

我们先来给大家演示下存活探针的使用方法,首先我们用exec执行命令的方式来检测容器的存活,如下:(liveness-exec.yaml)

apiVersion: v1
kind: Pod
metadata:
  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

我们这里需要用到一个新的属性:livenessProbe,下面通过exec执行一段命令:

我们在容器启动的时候,执行了如下命令:
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
意思是说在容器最开始的30s内创建一个/tmp/healthy文件,在这30s内执行cat /tmp/healthy命令都会返回一个成功的返回码。30s后,我们删除这个文件,现在执行cat /tmp/healthy是不是就会失败(默认检测失败3次才认为失败),所以这个时候就会重启容器了。

以下是过程

.......
.......
.......
Conditions:
  Type              Status
  Initialized       True
  Ready             False
  ContainersReady   False
  PodScheduled      True
Volumes:
  default-token-557h9:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-557h9
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age        From               Message
  ----    ------     ----       ----               -------
  Normal  Scheduled  <unknown>  default-scheduler  Successfully assigned default/liveness-exec to node02
  Normal  Pulling    2s         kubelet, node02    Pulling image "busybox"

##################################################################
.......
.......
.......
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-557h9:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-557h9
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age        From               Message
  ----    ------     ----       ----               -------
  Normal  Scheduled  <unknown>  default-scheduler  Successfully assigned default/liveness-exec to node02
  Normal  Pulling    10s        kubelet, node02    Pulling image "busybox"
  Normal  Pulled     4s         kubelet, node02    Successfully pulled image "busybox"
  Normal  Created    4s         kubelet, node02    Created container liveness
  Normal  Started    4s         kubelet, node02    Started container liveness
##################################################################
.......
.......
.......
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-557h9:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-557h9
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age        From               Message
  ----    ------     ----       ----               -------
  Normal  Scheduled  <unknown>  default-scheduler  Successfully assigned default/liveness-exec to node02
  Normal  Pulling    16s        kubelet, node02    Pulling image "busybox"
  Normal  Pulled     10s        kubelet, node02    Successfully pulled image "busybox"
  Normal  Created    10s        kubelet, node02    Created container liveness
  Normal  Started    10s        kubelet, node02    Started container liveness

##################################################################
.......
.......
.......
Volumes:
  default-token-557h9:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-557h9
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   Scheduled  <unknown>          default-scheduler  Successfully assigned default/liveness-exec to node02
  Normal   Pulling    64s                kubelet, node02    Pulling image "busybox"
  Normal   Pulled     58s                kubelet, node02    Successfully pulled image "busybox"
  Normal   Created    58s                kubelet, node02    Created container liveness
  Normal   Started    58s                kubelet, node02    Started container liveness
  Warning  Unhealthy  14s (x3 over 24s)  kubelet, node02    Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
  Normal   Killing    14s                kubelet, node02    Container liveness failed liveness probe, will be restarted

我们可以观察到容器是正常启动的,在隔一会,比如60s后,再查看下Pod的Event,在最下面有一条信息显示liveness probe失败了,容器将要重启。然后可以查看到Pod的RESTARTS值加1了:(我这里已经加到5了)

[root@node01 ~]# kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
hook-demo1                      1/1     Running   0          25d
init-demo                       1/1     Running   0          25d
liveness-exec                   1/1     Running   5          7m20s
nginx-deploy-745bd74b44-4k2np   1/1     Running   0          26d
nginx-deploy-745bd74b44-jr7wv   1/1     Running   0          26d
nginx-deploy-745bd74b44-ngkrg   1/1     Running   0          26d
nginx-deploy-745bd74b44-plgkw   1/1     Running   0          26d

同样的,根据 periodSeconds 属性我们可以知道 kubelet 需要每隔3秒执行一次 liveness Probe,该探针将向容器中的 server 的 8080 端口发送一个 HTTP GET 请求。如果 server 的 /healthz 路径的 handler 返回一个成功的返回码,kubelet 就会认定该容器是活着的并且很健康,如果返回失败的返回码,kubelet 将杀掉该容器并重启它。initialDelaySeconds 指定kubelet 在该执行第一次探测之前需要等待3秒钟。

apiVersion: v1
kind: Pod
metada: 
  name: liveness-http
spec:
  containers:
    - name: liveness
      image: cnych/liveness
      args:
        - /server
      livenessProbe:
        httpGet:
          path: /healthz
          port: 8080
          httpHeaders:
            - name: X-Custom-Header
              value: Awesome
        initialDelaySeconds: 3
        periodSeconds: 3

除了上面的 exec 和 httpGet 两种检测方式之外,还可以通过 tcpSocket 方式来检测端口是否正常,大家可以按照上面的方式结合kubectl explain命令自己来验证下这种方式。

另外前面我们提到了探针里面有一个initialDelaySeconds的属性,可以来配置第一次执行探针的等待时间,对于启动非常慢的应用这个参数非常有用,比如 Jenkins、Gitlab 这类应用,但是如何设置一个合适的初始延迟时间呢?这个就和应用具体的环境有关系了,所以这个值往往不是通用的,这样的话可能就会导致一个问题,我们的资源清单在别的环境下可能就会健康检查失败了,为解决这个问题,在 Kubernetes v1.16 版本官方特地新增了一个startupProbe(启动探针),该探针将推迟所有其他探针直到 Pod 完成启动为止,使用方法和存活探针一样:

startupProbe:
  httpGet:
    path: /healthz
    port: 8080
  failureThreshold: 30  # 尽量设置大点
  periodSeconds: 10

比如上面这里的配置表示我们的慢速容器最多可以有5分钟(30个检查 * 10秒= 300s)来完成启动。

有的时候,应用程序可能暂时无法对外提供服务,例如,应用程序可能需要在启动期间加载大量数据或配置文件。在这种情况下,您不想杀死应用程序,也不想对外提供服务。那么这个时候我们就可以使用readiness probe来检测和减轻这些情况。 Pod 中的容器可以报告自己还没有准备,不能处理 Kubernetes 服务发送过来的流量。readiness probe的配置跟liveness probe基本上一致的。唯一的不同是使用readinessProbe而不是livenessProbe。两者如果同时使用的话就可以确保流量不会到达还未准备好的容器,准备好过后,如果应用程序出现了错误,则会重新启动容器。对于就绪探针我们会在后面 Service 的章节和大家继续介绍。

另外除了上面的initialDelaySeconds和periodSeconds属性外,探针还可以配置如下几个参数:

上一篇下一篇

猜你喜欢

热点阅读