容器探针(liveness and readiness probe)
一、为什么需要容器探针
如何保持Pod健康
只要将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才能接收客户端请求。
二、LivenessProbe
1. 概念
Kubemetes可以通过存活探针(liveness probe)检查容器是否还在运行。可以为pod中的每个容器单独指定存活探针。如果探测失败,Kubemetes将定期执行探针并重新启动容器。
Kubernetes 支持三种方式来执行探针:
- exec:在容器中执行一个命令,如果命令退出码返回0则表示探测成功,否则表示失败
- tcpSocket:对指定的容IP及端口执行一个TCP检查,如果端口是开放的则表示探测成功,否则表示失败
- httpGet:对指定的容器IP、端口及路径执行一个HTTP Get请求,如果返回的状态码在 [200,400)之间则表示探测成功,否则表示失败
2. exec探针
exec类型的探针通过在目标容器中执行由用户自定义的命令来判断容器的监控状态,若命令状态返回值为0则表示“成功”通过检测,其他值则均为“失败”状态。
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
pod运行正常,10秒内文件/tmp/healthy还存在,probe检测正常。
第15秒,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
3.3 删除测试页面health
[root@master ~]# kubectl exec -it liveness-http rm /usr/share/nginx/html/health
探测失败,返回码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
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
4.3 查看Pod
[root@master ~]# kubectl describe po liveness-tcp
80是nginx的默认端口,开始发起TCP连接的端口也是80,默认端口改成81后连接报错,容器重启。
三、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
刚开始处于'预热'阶段,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将在没有接收到任何流量的情况下启动,并且只有在探针探测成功后才开始接收流量。
- 两种探测的配置方法完全一样,支持的配置参数也一样,既可单独探测又可结合者一起执行。
容器探针(liveness and readiness probe)的更多相关文章
- Kubernetes Pod中容器的Liveness、Readiness和Startup探针
我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 探针的作用 在Kubernetes的容器生命周期管理中,有三种探针,首先要知道,这探针是属于容器的,而不是Pod: 存 ...
- pod健康检查(liveness probe存活探针&&readiness probe 可读性探针)
在Kubernetes集群当中,我们可以通过配置liveness probe(存活探针)和readiness probe(可读性探针)来影响容器的生存周期.参考文档:https://kubernete ...
- 详解k8s中的liveness和readiness的原理和区别
liveness与readiness的探针工作方式源码解析 liveness和readiness作为k8s的探针,可以对应用进行健康探测. 二者支持的探测方式相同.主要的探测方式支持http探测,执行 ...
- 第11 章 : 可观测性:你的应用健康吗?(liveness和readiness)
课时 11:可观测性:你的应用健康吗?(莫源) 本次课程的分享主要围绕以下五个部分: 介绍一些整体需求的来源: 介绍在 K8s 中 Liveness 和 Readiness 的使用方式: 介绍在 K8 ...
- 应用健康: Liveness 与 Readiness
文章转载自:https://www.kuboard.cn/learning/k8s-intermediate/workload/pod-health.html 介绍 Liveness 指针是存活指针, ...
- Readiness probe failed:connection refused
我的K8S集群在启动一个POD的时候说死起不来,然后就报下面的错误 Events: Type Reason Age From Message ---- ------ ---- ---- ------- ...
- K8S容器探针
容器探针 探针是由 kubelet对容器执行的定期诊断.要执行诊断, kubelet 调用由容器实现的 Handler .有三种类型的处理程序: ExecAction :在容器内执行指定命令 ...
- 掌握SpringBoot-2.3的容器探针:基础篇
欢迎访问我的GitHub 地址:https://github.com/zq2599/blog_demos 内容:原创文章分类汇总,及配套源码,涉及Java.Docker.K8S.DevOPS等 关于& ...
- 掌握SpringBoot-2.3的容器探针:深入篇
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:原创分类汇总及配套源码,涉及Java.Docker.K8S.DevOPS等 关于<Spr ...
随机推荐
- 在.NET中使用DiagnosticSource
前言 DiagnosticSource是一个非常有意思的且非常有用的API,对于这些API它们允许不同的库发送命名事件,并且它们也允许应用程序订阅这些事件并处理它们,它使我们的消费者可以在运行时动态发 ...
- 014 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 08 “字符型”字面值
014 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 08 "字符型"字面值 字符型 字面值如何表示? 两个关键:单引号(必须是英文单引号). ...
- 轻轻松松学CSS:Grid布局
网页布局总的来说经历了以下四个阶段: 1.古老的table表格布局,现在基本已被淘汰. 2.float浮动布局(或者position定位布局),借助float.position 等属性等进行布局,这种 ...
- python之线程了解部分
一.死锁(了解) 死锁产生的4个必要条件: 互斥:一个资源同一时刻只允许一个线程进行访问 占有未释放:一个线程占有资源,且没有释放资源 不可抢占:一个已经占有资源的线程无法抢占到其他线程拥有的资源 循 ...
- Python的逻辑控制true/false和循环
逻辑判断 简单的几个尝试,看下和java的一点不同之处 1 > 2 # False 1 < 2 <3 # True 42 != '42' # True 'Name' == 'name ...
- HTML常用标签(下)
HTML常用标签(下) 1. 表格标签 1.1 语法 <table> <!--table定义表格--> <tr> <!--tr定义表格中的行--> &l ...
- 什么是C和C++标准——小白必看
本文简要介绍编写C/C ++应用程序的领域,标准库的作用以及它是如何在各种操作系统中实现的. 我已经接触C++一段时间了,一开始就让我感到疑惑的是其内部结构:我所使用的内核函数和类从何而来? 谁发明了 ...
- 扫描仪扫描文件处理-imagemagick常用参数
-resize 宽x高(缩放,不变形) -extent 宽x高(放大,不变形)之前设置:-gravity center(重心居中) -brightness-contrast 亮度x对比度(设置亮度对比 ...
- go panic
panic 抛出异常 通过recover捕获 类似 php python等语言的try catch package mainimport ( "fmt" "errors& ...
- git reset 与 git revert的区别?
一,git reset的功能: 该命令修改HEAD的位置,即将HEAD指向的位置改变为之前存在的某个版本, 说明: 修改后,push到远程仓库时需要使用"git push -f"提 ...