k8s实践(五):容器探针(liveness and readiness probe)

环境说明:html

主机名 操做系统版本 ip docker version kubelet version 配置 备注
master Centos 7.6.1810 172.27.9.131 Docker 18.09.6 V1.14.2 2C2G master主机
node01 Centos 7.6.1810 172.27.9.135 Docker 18.09.6 V1.14.2 2C2G node节点
node02 Centos 7.6.1810 172.27.9.136 Docker 18.09.6 V1.14.2 2C2G node节点

 

k8s集群部署详见:Centos7.6部署k8s(v1.14.2)集群
k8s学习资料详见:基本概念、kubectl命令和资料分享
k8s高可用集群部署详见:Centos7.6部署k8s v1.16.4高可用集群(主备模式)
k8s集群高可用部署详见:lvs+keepalived部署k8s v1.16.4高可用集群  node

1、为何须要容器探针

如何保持Pod健康

  只要将pod调度到某个节点,Kubelet就会运行pod的容器,若是该pod的容器有一个或者全部的都终止运行(容器的主进程崩溃),Kubelet将重启容器,因此即便应用程序自己没有作任何特殊的事,在Kubemetes中运行也能自动得到自我修复的能力。nginx

 

  自动重启容器以保证应用的正常运行,这是使用Kubernetes的优点,不过在某些状况,即便进程没有崩溃,有时应用程序运行也会出错。默认状况下Kubernetes只是检查Pod容器是否正常运行,但容器正常运行并不必定表明应用健康,在如下两种状况下Kubernetes将不会重启容器:git

  • 1.访问Web服务器时显示500内部错误
  • 该报错多是系统超载,也多是资源死锁,不过此时httpd进程依旧运行,重启容器多是最直接有效的办法。
     
  • 2.具备内存泄漏的Java应用程序将开始抛出OutOfMemoryErrors
  • 此时JVM进程会一直运行,Kubernetes也不会重启容器,但此时对应用来说是异常的。

此时能够考虑从外部检查应用程序的运行情况:github

  • Kubemetes能够经过存活探针(liveness probe)检查容器是否还在运行;
  • 经过就绪探针(readiness probe)保证只有准备好了请求的Pod才能接收客户端请求。

2、LivenessProbe

1. 概念

  Kubemetes能够经过存活探针(liveness probe)检查容器是否还在运行。能够为pod中的每一个容器单独指定存活探针。若是探测失败,Kubemetes将按期执行探针并从新启动容器。docker

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

  • exec:在容器中执行一个命令,若是命令退出码返回0则表示探测成功,不然表示失败
  • tcpSocket:对指定的容IP及端口执行一个TCP检查,若是端口是开放的则表示探测成功,不然表示失败
  • httpGet:对指定的容器IP、端口及路径执行一个HTTP Get请求,若是返回的状态码在 [200,400)之间则表示探测成功,不然表示失败

2. exec探针

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

2.1 建立liveness-exec.yaml

[root@master ~]# more 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; sleep 10; rm -rf /tmp/healthy; sleep 600
    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
[root@master ~]# kubectl apply -f liveness-exec.yaml 
pod/liveness-exec created

2.2 查看Pod

[root@master ~]# kubectl get po -o wide
[root@master ~]# kubectl describe po liveness-exec

k8s实践(五):容器探针(liveness and readiness probe)

pod运行正常,10秒内文件/tmp/healthy还存在,probe检测正常。bash

k8s实践(五):容器探针(liveness and readiness probe)

第15秒,probe再次检测,因为文件被删,检测失败,此后容器会进行屡次重启操做。服务器

k8s实践(五):容器探针(liveness and readiness probe)

3. HTTP探针

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

3.1 建立liveness-http.yaml

[root@master ~]# more 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
[root@master ~]# kubectl apply -f liveness-http.yaml       
pod/liveness-http created

3.2 查看Pod

[root@master ~]# kubectl get po -o wide                                
NAME            READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
liveness-http   1/1     Running   0          5s    10.244.2.206   node02   <none>           <none>
[root@master ~]# curl 10.244.2.206/health
liveness-http test

k8s实践(五):容器探针(liveness and readiness probe)

3.3 删除测试页面health

[root@master ~]# kubectl exec -it liveness-http rm  /usr/share/nginx/html/health

k8s实践(五):容器探针(liveness and readiness probe)

探测失败,返回码404,重启容器。

4. TCP探针

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

4.1 建立liveness-tcp.yaml

```bash
[root@master ~]# more 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
[root@master ~]# kubectl apply -f liveness-tcp.yaml 
pod/liveness-tcp created
[root@master ~]# kubectl get po -o wide             
NAME           READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
liveness-tcp   1/1     Running   0          4s    10.244.2.217   node02   <none>           <none>
[root@master ~]# curl 10.244.2.217:80

k8s实践(五):容器探针(liveness and readiness probe)

4.2 修改默认端口

[root@master ~]# kubectl exec -it liveness-tcp -- sed -i  's/^ *listen       80/    listen       81/g' /etc/nginx/conf.d/default.conf

若是kubectl exec在容器内执行命令时若是带参数则需加上'--'

加载nginx

[root@master ~]# kubectl exec -it liveness-tcp -- nginx -s reload

k8s实践(五):容器探针(liveness and readiness probe)

4.3 查看Pod

[root@master ~]# kubectl describe po liveness-tcp

k8s实践(五):容器探针(liveness and readiness probe)

80是nginx的默认端口,开始发起TCP链接的端口也是80,默认端口改为81后链接报错,容器重启。

3、ReadinessProbe

1. 概念

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

2. readinessprobe使用场景

   Pod对象启动后,容器应用一般须要一段时间才能完成其初始化过程,例如加载配置或数据,甚至有些程序须要运行某类的预热过程,若在此阶段完成以前接入客户端的请求,势必会由于等待过久而影响用户体验,这时就须要就绪探针。

 

   若是没有将就绪探针添加到pod中,它们几乎会当即成为服务端点。若是应用程序须要很长时间才能开始监听传入链接,则在服务启动但还没有准备好接收传入链接时,客户端请求将被转发到该pod。所以,客户端会看到"链接被拒绝"类型的错误。

3. 机制

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

4. 建立readiness-exec.yaml

本文以exec方式为例实践

[root@master ~]# more 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; sleep 10; rm -rf /tmp/healthy; sleep 600
    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
[root@master ~]# kubectl apply -f readiness-exec.yaml 
pod/readiness-exec created

5. 查看Pod

[root@master ~]# kubectl get po readiness-exec -w     
NAME             READY   STATUS              RESTARTS   AGE
readiness-exec   0/1     ContainerCreating   0          2s
readiness-exec   0/1     Running             0          3s
readiness-exec   1/1     Running             0          9s
readiness-exec   0/1     Running             0          24s

'-w'选项能够监视pod资源变更,刚开始尽管pod处于Running状态,但知道就绪探测命令执行成功后pod资源才ready

k8s实践(五):容器探针(liveness and readiness probe)

刚开始处于'预热'阶段,pod为running状态但不可用;当10秒后(initialDelaySeconds + periodSeconds),readinessprobe开始第一次探测,成功后pod处于ready状态,45秒后(sleep30 + periodSeconds * failureThreshold)探测失败,pod再次为running但not ready状态。

6. 与livenessprobe区别

  • 若是容器中的进程可以在遇到问题或不健康的状况下自行崩溃,则不必定须要存活探针; kubelet 将根据Pod的restartPolicy自动执行正确的操做。
  • 若是您但愿容器在探测失败时被杀死并从新启动,那么请指定一个存活探针,并指定restartPolicy为Always或OnFailure。
  • 若是要仅在探测成功时才开始向 Pod 发送流量,请指定就绪探针。在这种状况下,就绪探针可能与存活探针相同,可是spec中的就绪探针的存在乎味着Pod将在没有接收到任何流量的状况下启动,而且只有在探针探测成功后才开始接收流量。
  • 两种探测的配置方法彻底同样,支持的配置参数也同样,既可单独探测又可结合者一块儿执行。

 
 

本文全部脚本和配置文件已上传github:https://github.com/loong576/k8s-liveness-and-readiness-probe.git

相关文章
相关标签/搜索