健康检查

可以为Pod中的容器定义一个健康检查”探针(Probe)“,这样kubelet就会根据这个探针的返回值决定容器的状态,而不是根据容器是否运行来决定。这是生产环境中保证应用健康存活的重要手段(可能存在容器仍然运行但是无法提供服务的情况)。

给定如下Pod YAML的例子:

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

这里的容器启动后会创建一个/tmp/healthy文件,然后30s后删除。

这里定义了一个这样的livenessProbe(健康检查),类型是exec,表示启动后会执行里面的指令。这里执行cat命令来判断/tmp/healthy文件是否存在,存在则容器是健康的,在启动后5s并且每隔5s判断一次。

Pod恢复机制

启动容器,30s之后查看容器Event,就会发现Pod报告了一个错误。虽然产生了错误,但是容器仍然是running状态。不过需要注意的是,这时的容器已经是重启过的状态了,kubectl get pods可以看到RESTART字段的变化,k8s会自动重启异常容器

Note

k8s中并没有docke的stop语义,所以k8s虽然叫做RESTART,但实际上是重新创建了容器。

这就是restartPolicy,是Pod的Pod.Spec.restartPolicy字段,默认值为always,即任何时候发生了异常,容器一定会被重建。

Note

容器重启一定是在其绑定的节点上的,而不会跑到别的节点上。除非绑定发生了变化,否则就就算它绑定的主机宕机了,也不会迁移到其它节点上去。

restartPolicy除了always,还有如下策略:

  • Always:任何情况下,只要容器不在running状态,就会重启。
  • OnFailure:只在异常状态下,容器才会重启。
  • Never:从来不重启容器。

Pod里的容器状态和restartPolicy的对应关系很多,但是原则只有如下两条:

  • 只要restartPolicy允许重启,那么这个Pod就会一直保存running状态,并进行容器重启
  • 对于包含多个容器的Pod,只有它里面的所有容器全部进入异常状态,Pod的状态才会进入Failed状态

其它健康检测的方式

除了上面例子中的执行命令外,还有发起http或者tcp请求的方式来进行健康检查。

...
livenessProbe:
     httpGet:
       path: /healthz
       port: 8080
       httpHeaders:
       - name: X-Custom-Header
         value: Awesome
       initialDelaySeconds: 3
       periodSeconds: 3

上面是http请求,还有下面的tcp:

    ...
    livenessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 20

所以,你的 Pod 其实可以暴露一个健康检查 URL(比如 /healthz),或者直接让健康检查去检测应用的监听端口。这两种配置方法,在 Web 服务类的应用中非常常用。


tags: pod k8s