只要将pod调度到某个节点,Kubelet就会运行pod的容器,若是该pod的容器有一个或者全部的都终止运行(容器的主进程崩溃),Kubelet将重启容器,因此即便应用程序自己没有作任何特殊的事,在Kubemetes中运行也能自动得到自我修复的能力。html
自动重启容器以保证应用的正常运行,这是使用Kubernetes的优点,不过在某些状况,即便进程没有崩溃,有时应用程序运行也会出错。默认状况下Kubernetes只是检查Pod容器是否正常运行,但容器正常运行并不必定表明应用健康,在如下两种状况下Kubernetes将不会重启容器:node
- 1.访问Web服务器时显示500内部错误
- 该报错多是系统超载,也多是资源死锁,不过此时httpd进程依旧运行,重启容器多是最直接有效的办法。
- 2.具备内存泄漏的Java应用程序将开始抛出OutOfMemoryErrors
- 此时JVM进程会一直运行,Kubernetes也不会重启容器,但此时对应用来说是异常的。
此时能够考虑从外部检查应用程序的运行情况:nginx
Kubemetes能够经过存活探针(liveness probe)检查容器是否还在运行。能够为pod中的每一个容器单独指定存活探针。若是探测失败,Kubemetes将按期执行探针并从新启动容器。后端
Kubernetes 支持三种方式来执行探针:api
exec类型的探针经过在目标容器中执行由用户自定义的命令来判断容器的监控状态,若命令状态返回值为0则表示“成功”经过检测,其余值则均为“失败”状态。bash
[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
[root@master ~]# kubectl get po -o wide [root@master ~]# kubectl describe po liveness-exec

pod运行正常,10秒内文件/tmp/healthy还存在,probe检测正常。服务器
第15秒,probe再次检测,因为文件被删,检测失败,此后容器会进行屡次重启操做。app
基于HTTP的探测(HTTPGetAction)向目标容器发起一个HTTP请求,根据其相应码进行结果断定,响应码如2xx或3xx时表示检测经过。curl
[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
[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
[root@master ~]# kubectl exec -it liveness-http rm /usr/share/nginx/html/health
探测失败,返回码404,重启容器。tcp
基于TCP的存活性探测(TCPSocketAction)用于向容器的特定端口发起TCP请求并尝试创建链接,链接成功即为经过检测。
```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
[root@master ~]# kubectl exec -it liveness-tcp -- sed -i 's/^ *listen 80/ listen 81/g' /etc/nginx/conf.d/default.conf
若是kubectl exec在容器内执行命令时若是带参数则需加上'--'
[root@master ~]# kubectl exec -it liveness-tcp -- nginx -s reload
[root@master ~]# kubectl describe po liveness-tcp
80是nginx的默认端口,开始发起TCP链接的端口也是80,默认端口改为81后链接报错,容器重启。
用于容器的自定义准备状态检查。若是ReadinessProbe检查失败,Kubernetes会将该Pod从服务代理的分发后端去除,再也不分发请求给该Pod。
Pod对象启动后,容器应用一般须要一段时间才能完成其初始化过程,例如加载配置或数据,甚至有些程序须要运行某类的预热过程,若在此阶段完成以前接入客户端的请求,势必会由于等待过久而影响用户体验,这时就须要就绪探针。
若是没有将就绪探针添加到pod中,它们几乎会当即成为服务端点。若是应用程序须要很长时间才能开始监听传入链接,则在服务启动但还没有准备好接收传入链接时,客户端请求将被转发到该pod。所以,客户端会看到"链接被拒绝"类型的错误。
与存活探针机制相同,就绪探针也支持Exec、HTTP GET和TCP Socket三种探测方式,且各自的定义机制相同,将容器定义中的livenessProbe字段名替换为readinessProbe便可定义出就绪探测的配置,这里再也不赘述。
本文以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
[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
刚开始处于'预热'阶段,pod为running状态但不可用;当10秒后(initialDelaySeconds + periodSeconds),readinessprobe开始第一次探测,成功后pod处于ready状态,45秒后(sleep30 + periodSeconds * failureThreshold)探测失败,pod再次为running但not ready状态。