一些收藏

《k8s权威指南》读书笔记-Pod生命周期&健康检查

2021-11-16  本文已影响0人  乙腾

4.Pod的生命周期和重启策略

image.png

5.Pod健康检查和服务可用性检查

5.1 Kubernetes 对 Pod 的健康状态可以通过探针来检查

  Kubernetes 对 Pod 的健康状态可以通过探针来检查,kubelet定期执行探针来诊断容器的健康状况。

5.2 LivenessProbe和ReadinessProbe均可配置以下三种实现方式

(1)定义存活命令

ExecAction:在容器内部执行一个命令,如果该命令的返回码为0,则表明容器健康。

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy             # kubelet 在容器内执行命令 `cat /tmp/healthy` 来进行探测
      initialDelaySeconds: 5       # `initialDelaySeconds` 字段告诉 kubelet 在执行第一次探测前应该等待 5 秒
      periodSeconds: 5             # `periodSeconds` 字段指定了 kubelet 应该每 5 秒执行一次存活探测

  在这个配置文件中,可以看到 Pod 中只有一个容器。 periodSeconds 字段指定了 kubelet 应该每 5 秒执行一次存活探测。 initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 5 秒。 kubelet 在容器内执行命令 cat /tmp/healthy 来进行探测。 如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的。 如果这个命令返回非 0 值,kubelet 会杀死这个容器并重新启动它。

例子:

下面例子中,通过删除/tmp/healthy,展示pod通过探针检查健康状态和重启的过程。

当容器启动时,执行如下的命令:


/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"

这个容器生命的前 30 秒, /tmp/healthy 文件是存在的。 所以在这最开始的 30 秒内,执行命令 cat /tmp/healthy 会返回成功代码。 30 秒之后,执行命令 cat /tmp/healthy 就会返回失败错误码。

创建 Pod:


kubectl apply -f exec-liveness.yaml

在 30 秒内,查看 Pod 的事件:


kubectl describe pod liveness-exec

输出结果表明还没有存活探测器失败:


FirstSeen    LastSeen    Count   From            SubobjectPath           Type        Reason      Message

--------- --------    -----   ----            -------------           --------    ------      -------

24s       24s     1   {default-scheduler }                    Normal      Scheduled   Successfully assigned liveness-exec to worker0

23s       23s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Pulling     pulling image "k8s.gcr.io/busybox"

23s       23s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Pulled      Successfully pulled image "k8s.gcr.io/busybox"

23s       23s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Created     Created container with docker id 86849c15382e; Security:[seccomp=unconfined]

23s       23s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Started     Started container with docker id 86849c15382e

35 秒之后,再来看 Pod 的事件:


#kubectl describe pod liveness-exec

//在输出结果的最下面,有信息显示存活探测器失败了,这个容器被杀死并且被重建了。

FirstSeen LastSeen    Count   From            SubobjectPath           Type        Reason      Message

--------- --------    -----   ----            -------------           --------    ------      -------

37s       37s     1   {default-scheduler }                    Normal      Scheduled   Successfully assigned liveness-exec to worker0

36s       36s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Pulling     pulling image "k8s.gcr.io/busybox"

36s       36s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Pulled      Successfully pulled image "k8s.gcr.io/busybox"

36s       36s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Created     Created container with docker id 86849c15382e; Security:[seccomp=unconfined]

36s       36s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Started     Started container with docker id 86849c15382e

2s        2s      1   {kubelet worker0}   spec.containers{liveness}   Warning     Unhealthy   Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory

再等另外 30 秒,检查看这个容器被重启了:


#kubectl get pod liveness-exec

//输出结果显示 RESTARTS 的值增加了 1。

NAME            READY     STATUS    RESTARTS   AGE

liveness-exec   1/1       Running   1          1m

(2)定义TCP的存活探测

  TCPSocketAction:通过容器的IP地址和端口号执行TCP检查,如果能够建立TCP连接,则表明容器健康。

apiVersion: v1
kind: Pod
metadata:
  name: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    image: k8s.gcr.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:        # 就绪探针
      tcpSocket:   #tcp
        port: 8080
      initialDelaySeconds: 5  
      periodSeconds: 10
    livenessProbe:        #存活探针
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 20

就绪探针:kubelet 会在容器启动 5 秒后发送第一个就绪探测。 这会尝试连接 goproxy 容器的 8080 端口。 如果探测成功,这个 Pod 会被标记为就绪状态,kubelet 将继续每隔 10 秒运行一次检测。

存活探针:kubelet 会在容器启动 15 秒后进行第一次存活探测。 与就绪探测类似,会尝试连接 goproxy 容器的 8080 端口。 如果存活探测失败,这个容器会被重新启动。

(3)定义一个存活态HTTP请求接口

  HTTPGetAction:通过容器的IP地址、端口号及路径调用HTTP Get方法,如果响应的状态码大于等于200且小于400,则认为容器健康。

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3   #启动容器后进行首次健康检查的等待时间,单位为s。
      periodSeconds: 3         #每隔3s检查一次  
      timeoutSeconds:1         #健康检查发送请求后等待响应的超时时间,单位为s。当超时发生时,kubelet会认为容器已经无法提供服务,将会重启该容器。

  在这个配置文件中,可以看到 Pod 也只有一个容器。 periodSeconds 字段指定了 kubelet 每隔 3 秒执行一次存活探测。 initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 3 秒。 kubelet 会向容器内运行的服务(服务会监听 8080 端口)发送一个 HTTP GET 请求来执行探测。 如果服务器上 /healthz 路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。 如果处理程序返回失败代码,则 kubelet 会杀死这个容器并且重新启动它。

  任何大于或等于 200 并且小于 400 的返回代码标示成功,其它返回代码都标示失败。

上一篇 下一篇

猜你喜欢

热点阅读