kubernetes之容器探针(liveness and readiness probe)

1、为什么需要容器探针

只要将pod调度到某个节点,Kubelet将运行pod的容器,如果该pod的容器有一个或所有的都终止运行(容器的主进程崩溃),Kubelet将重新启动容器,那么即使应用程序本身没有做任何特殊的事,在Kubemetes中运行也能自动获得自我修复的能力。

自动重启容器以保证应用程序的正常运行,这是使用Kubernetes的优势,不过在某些情况下,即使进程没有崩溃,有时应用程序运行也会出错。有时情况下Kubernetes只是检查Pod容器是否正常运行,而容器正常运行并不一定代表应用健康,在以下两种情况下Kubernetes将不会重启容器:

  • 1.访问Web服务器时显示500内部错误

    该报错可能是系统超载,也可能是资源死锁,不过此时httpd进程依旧运行,重启容器可能是最直接有效的办法。

  • 2.具有内存泄漏的Java应用程序将开始引发OutOfMemoryErrors,此时JVM进程会一直运行,Kubernetes也不会重启容器,但此时应用被称为是异常的。

此时可以考虑从外部检查应用程序的运行状况:

  • Kubemetes可以通过存活探针(liveness probe)检查容器是否还在运行。

  • 通过就绪探针(readiness probe)保证只有准备好了请求的Pod才能接收客户端请求。

2、存活探针

Kubemetes可以通过存活探针(liveness probe)检查容器是否还在运行。可以为pod中的每个容器单独指定重复探针。如果检测失败,Kubemetes将定期执行探针并重新启动容器。

Kubernetes支持三种方式来执行探针:

  • exec:在容器中执行一个命令,如果命令退出码返回0则表示探测成功,否则表示失败。

  • httpGet:对指定的容器IP,端口和路径执行一个HTTP Get请求,如果返回的状态码在[200,400)之间则表示探测成功,否则表示失败。

  • tcpSocket:对指定的容错IP和端口执行一个TCP检查,如果端口是开放的则表示探测成功,否则表示失败。

3、exec探针

exec类型的探针通过在目标容器中执行由用户自定义的命令来判断容器的监控状态,若命令状态返回变量0则表示“成功”通过检测,其他值则变为“失败”状态。

3.1创建liveness-exec.yaml

 apiVersion: v1
 kind: Pod
 metadata:
 labels:
   test: liveness-exec
 name: liveness-exec
 spec:
 restartPolicy: OnFailure
 containers:
  -name: liveness-exec
   image: busybox
   args:
    -/bin/sh
    --c
    -touch/tmp/healthy; sleep15; rm-rf/tmp/healthy; sleep600
   livenessProbe:
     exec:
       command: ["test","-e","/tmp/healthy"]
     initialDelaySeconds: 5   #探测延时时长,第一次探测前等待5秒,默认为0
     periodSeconds: 5         #每5秒执行一次liveness探测,默认值10秒,最小1秒 
     timeoutSeconds: 2        #超长时长,默认为1s,最小值也为1s
     failureThreshold: 3      #处于成功状态时,探测操作至少连续多少次的失败才被视为检测不通过,默认为3,最小为1

3.2查看Pod

 [root@yygh-de huqi]# kubectl apply -f liveness-exec.yaml 
 pod/liveness-exec created
 [root@yygh-de huqi]# kubectl get po -o wide
 NAME           READY   STATUS             RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
 liveness-exec   0/1     ContainerCreating   0        9s      yygh-te              
 [root@yygh-de huqi]# kubectl describe po liveness-exec

3.3pod运行正常,10秒内文件/tmp/healthy还存在,probe检测正常。第15秒,probe再次检测,由于文件被删,检测失败,此后容器会进行多次重启操作

 [root@yygh-de huqi]# kubectl get po -o wide
 NAME           READY   STATUS             RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
 liveness-exec   0/1     CrashLoopBackOff   5        7m3s   10.244.66.90   yygh-te              

4、HTTP探针

基于HTTP的探测(HTTPGetAction)向目标容器发起一个HTTP请求,根据其相应码进行结果判定,响应码如2xx或3xx时表示检测通过。

4.1创建liveness-http.yaml

 [root@yygh-de huqi]# vim liveness-http.yaml 
 apiVersion : v1
 kind: Pod
 metadata:
 labels:
   test: liveness
 name: liveness-http
 spec:
 containers:
  -name: liveness-http
   image: nginx
   ports:
    -name: http
     containerPort: 80
   lifecycle:
     postStart:
       exec:
         command: ["/bin/sh","-c","echo liveness-http test > /usr/share/nginx/html/health"]
   livenessProbe:
     httpGet:
       path: /health
       port: http
       scheme: HTTP

4.2查看Pod

 [root@yygh-de huqi]# kubectl apply -f liveness-http.yaml 
 pod/liveness-http created
 [root@yygh-de huqi]# kubectl get po -o wide
 NAME           READY   STATUS   RESTARTS   AGE     IP             NODE     NOMINATED NODE   READINESS GATES
 liveness-http   1/1     Running   0        12s     10.244.66.91   yygh-te              
 [root@yygh-de huqi]# curl 10.244.66.91/health
 liveness-http test

4.3删除测试页面health

 [root@yygh-de huqi]# kubectl exec -it liveness-http rm /usr/share/nginx/html/health
 [root@yygh-de huqi]# kubectl get pod -o wide
 NAME           READY   STATUS   RESTARTS   AGE     IP             NODE     NOMINATED NODE   READINESS GATES
 liveness-http   1/1     Running   1        4m28s   10.244.66.91   yygh-te              
 [root@yygh-de huqi]# kubectl describe pod liveness-http 
 Events:
 Type     Reason     Age                 From               Message
  ----    ------    ----                ----              -------
 Normal   Scheduled 5m11s               default-scheduler Successfully assigned default/liveness-http to yygh-te
 Normal   Pulling   12s (x3 over 5m10s) kubelet, yygh-te   Pulling image "nginx"
 Warning Unhealthy 12s (x6 over 102s)   kubelet, yygh-te   Liveness probe failed: HTTP probe failed with statuscode: 404
 Normal   Killing   12s (x2 over 82s)   kubelet, yygh-te   Container liveness-http failed liveness probe, will be restarted
 Normal   Pulled     8s (x3 over 5m6s)   kubelet, yygh-te   Successfully pulled image "nginx"
 Normal   Created   8s (x3 over 5m6s)   kubelet, yygh-te   Created container liveness-http
 Normal   Started   7s (x3 over 5m6s)   kubelet, yygh-te   Started container liveness-http
 [root@yygh-de huqi]# curl 10.244.66.91/health
 liveness-http test
 # 探测失败,返回码404,重启容器。

5、TCP探针

基于TCP的存活性探测(TCPSocketAction)用于向容器的特定端口发起TCP请求并尝试建立连接,连接成功即为通过检测。

5.1 创建liveness-tcp.yaml

 [root@yygh-de huqi]# vim liveness-tcp.yaml
 apiVersion: v1
 kind: Pod
 metadata:
 labels:
   test: liveness
 name: liveness-tcp
 spec:
 containers:
  -name: liveness-tcp
   image: nginx
   ports:
    -name: http
     containerPort: 80
   livenessProbe:
     tcpSocket:
       port: http

5.2查看pod

 [root@yygh-de huqi]# kubectl apply -f liveness-tcp.yaml 
 pod/liveness-tcp created
 [root@yygh-de huqi]# kubectl get pod -o wide
 NAME           READY   STATUS   RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
 liveness-tcp    1/1     Running   0        15s   10.244.66.92   yygh-te              
 [root@yygh-de huqi]# kubectl get pod -o wide
 NAME           READY   STATUS   RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
 liveness-tcp   1/1     Running   0        51s   10.244.66.92   yygh-te              
 [root@yygh-de huqi]# curl 10.244.66.92:80

5.3修改默认端口

 [root@yygh-de huqi]# kubectl exec -it liveness-tcp -- sed -i 's/^ *listen       80/   listen       81/g' /etc/nginx/conf.d/default.conf
 [root@yygh-de huqi]# kubectl exec -it liveness-tcp -- nginx -s reload
 2020/06/17 08:54:27 [notice] 34#34: signal process started
 [root@yygh-de huqi]# curl 10.244.66.92:80
 curl: (7) Failed connect to 10.244.66.92:80; 拒绝连接
 [root@yygh-de huqi]# curl 10.244.66.92:81
 # 80是nginx的默认端口,开始发起TCP连接的端口也是80,默认端口改成81后连接报错,容器重启。

6、ReadinessProbe

6.1概念

用于容器的自定义准备状态检查。如果ReadinessProbe检查失败,Kubernetes会将该Pod从服务代理的分发后端去除,不再分发请求给该Pod。

6.2readinessprobe使用场景

Pod对象启动后,容器应用通常需要一段时间才能完成其初始化过程,例如加载配置或数据,甚至有些程序需要运行某类的预热过程,若在此阶段完成之前接入客户端的请求,势必会因为等待太久而影响用户体验,这时就需要就绪探针。   如果没有将就绪探针添加到pod中,它们几乎会立即成为服务端点。如果应用程序需要很长时间才能开始监听传入连接,则在服务启动但尚未准备好接收传入连接时,客户端请求将被转发到该pod。因此,客户端会看到"连接被拒绝"类型的错误。

6.3机制

与存活探针机制相同,就绪探针也支持Exec、HTTP GET和TCP Socket三种探测方式,且各自的定义机制相同,将容器定义中的livenessProbe字段名替换为readinessProbe即可定义出就绪探测的配置,这里不再赘述。

6.4创建

 [root@yygh-de huqi]# vim readiness-exec.yaml
 apiVersion: apps/v1
 kind: Deployment
 metadata:
 name: nginx
 spec:
 replicas: 3
 selector:
   matchLabels:
     app: nginx
 template:
   metadata:
     labels:
       app: nginx
   spec:
     containers:
      -image: nginx:latest
       name: container-0
       resources:
         limits:
           cpu: 500m
           memory: 1024Mi
         requests:
           cpu: 500m
           memory: 1024Mi
       readinessProbe:           # readinessProbe
         httpGet:                # HTTP GET定义
           path: /read
           port: 80
     imagePullSecrets:
      -name: imagepull-secret
 # Readiness Probe的配置与存活探针(livness probe)一样,都是在 Pod Template 的 containers 里面,如下所示,这个Readiness Probe向Pod发送HTTP请求,当Probe收到2xx或3xx返回时,说明Pod已经就绪。

6.5Readiness Probe高级配置(创建时默认设置,也可以手动配置)

 readinessProbe:      # Readiness Probe
 exec:              # 定义 ls /readiness/ready 命令
   command:
    -ls
    -/readiness/ready
 initialDelaySeconds: 10   # 容器启动后多久开始探测
 timeoutSeconds: 2         # 表示容器必须在2s内做出相应反馈给probe,否则视为探
 测失败
 periodSeconds: 30         # 探测周期,每30s探测一次
 successThreshold: 1       # 连续探测1次成功表示成功
 failureThreshold: 3       # 连续探测3次失败表示失败

7、ReadinessProbe与livenessprobe区别

  • 如果容器中的进程能够在遇到问题或不健康的情况下自行崩溃,则不一定需要存活探针; kubelet 将根据Pod的restartPolicy自动执行正确的操作。

  • 如果您希望容器在探测失败时被杀死并重新启动,那么请指定一个存活探针,并指定restartPolicy为Always或OnFailure。

  • 如果要仅在探测成功时才开始向 Pod 发送流量,请指定就绪探针。在这种情况下,就绪探针可能与存活探针相同,但是spec中的就绪探针的存在意味着Pod将在没有接收到任何流量的情况下启动,并且只有在探针探测成功后才开始接收流量。

  • 两种探测的配置方法完全一样,支持的配置参数也一样,既可单独探测又可结合者一起执行。

如果文章有任何错误欢迎不吝赐教,其次大家有任何关于运维的疑难杂问,也欢迎和大家一起交流讨论。关于运维学习、分享、交流,笔者开通了微信公众号【运维猫】,感兴趣的朋友可以关注下,欢迎加入,建立属于我们自己的小圈子,一起学运维知识。群主还经营一家Orchis饰品店,喜欢的小伙伴欢迎????前来下单。

扫描二维码

获取更多精彩

运维猫公众号

有需要技术交流的小伙伴可以加我微信,期待与大家共同成长,本人微信:

扫描二维码

添加私人微信

运维猫博主

扫码加微信

最近有一些星友咨询我知识星球的事,我也想继续在星球上发布更优质的内容供大家学习和探讨。运维猫公众号平台致力于为大家提供免费的学习资源,知识星球主要致力于即将入坑或者已经入坑的运维行业的小伙伴。

点击阅读原文  查看更多精彩内容!!!

参考文献:https://cloud.tencent.com/developer/article/1501403

https://support.huaweicloud.com/devg-cci/cci_05_0026.html

你可能感兴趣的:(kubernetes之容器探针(liveness and readiness probe))