liveness-probe探针和readness-probe

简介: liveness-probe探针和readness-probe

目录

探针

在我们之前提到过的deploy控制器里面,他是对pod的状态进行管理,只有当pod的状态不是running的时候他才会重构pod,但是如果我们启动了一个nginx的pod,但是这个pod的index文件被删除掉了,此时pod的状态依旧是running,但是用户无法拿到正常的页面,这种情况下控制器是做不了管控的,对于这种情况,我们可以来使用探针

liveness-probe 存活探针

这个探针的作用是保证pod的正常运行,注意,是正常运行而不是运行,这个就是他与deploy控制器最大的区别

我们可以使用这个探针来检测nginx容器的index.html文件是否存在,如果存在的话那么这个容器就是正常在运行的,如果不存在那么就是我们开头就提到过的那种情况,控制器看他的状态是running,但是他没有index文件,探针负责每隔一段时间就检查这个文件是否存在,如果存在就不做操作,如果不存在的话那么kebelet就会干掉这个容器并重新启动一个新的容器

探针的3种方式

探针有3种检测方式,分别是exec,httpGet和tcpSocket,这三种方式的定义方法都大差不差

1. exec

这种方式就是通过事先定义好的命令去检测,如果命令执行的结果为0那么就是正常的,如果命令的结果是非0的任何值,那么说明命令执行失败了,容器没有正常运行,需要重构容器

apiVersion: v1
kind: Pod
metadata:
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
# 存活探针
livenessProbe:
# 执行的操作
exec:
# 使用test -f 命令来检测文件是否存在
command: ["test","-f","/usr/share/nginx/html/index.html" ]
# 在执行第一次检测之前需要等待多少秒,这里是2
initialDelaySeconds: 2
# 每隔多少秒触发一次检测,这里也是2
periodSeconds: 2
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}

我们写好的yaml文件是检测index.html文件是否存在,那么我们现在来将他创建出来,然后删除index.html文件看看他会发生什么

[root@master k8s]# kubectl apply -f liveness-probe.yaml 
pod/nginx created
[root@master k8s]# kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          3s

他现在是正常运行的,并且重启次数是0,那么我们使用命令删除掉他的index.html文件

[root@master k8s]# kubectl exec -it nginx -- rm -f /usr/share/nginx/html/index.html
[root@master k8s]# kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          60s
[root@master k8s]# kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          62s
[root@master k8s]# kubectl get pods
NAME    READY   STATUS    RESTARTS     AGE
nginx   1/1     Running   1 (1s ago)   63s

我们可以看到,在我们执行完删除命令之后,过了几秒这个容器的重启次数就是1了,然后我们再来看看index.html文件是否回来了

[root@master k8s]# kubectl exec -it nginx -- ls -l /usr/share/nginx/html/index.html
-rw-r--r-- 1 root root 615 Oct 24 13:46 /usr/share/nginx/html/index.html

我们可以看到,这个文件确实重新回来了,为什么他会重新回来呢?

我们之前说过,只要存活探针检测到这个文件不存在了,那么他就会直接使用之前的镜像来创建一个新的pod

所以这个文件就又有了

2. httpGet

apiVersion: v1
kind: Pod
metadata:
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
livenessProbe:
# 只改动了这个地方
httpGet:
# http请求的地址,端口
path: /index.html
port: 80
initialDelaySeconds: 2
periodSeconds: 2
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}

通过上面的yaml文件我们可以很清楚的知道,我们需要请求的是这个网站的根目录下的index.html,注意,是网站的根目录,不是linux的根目录,注意区分开

[root@master k8s]# kubectl apply -f liveness-probe.yaml 
pod/nginx created
[root@master k8s]# kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          3s

我们还是去删除掉他的index.html文件

[root@master k8s]# kubectl exec -it nginx -- rm -f /usr/share/nginx/html/index.html
[root@master k8s]# kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          47s
[root@master k8s]# kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          48s
[root@master k8s]# kubectl get pods
NAME    READY   STATUS    RESTARTS     AGE
nginx   1/1     Running   1 (0s ago)   49s

我们可以看到,当我们删除掉这个文件之后,他请求不到index.html文件了,所以这个容器会重启

3. tcpSocket

这个方式就更加简单了,探针会对你定义的端口发起tcp连接,如果可以不能正常进行三次握手,那么就会重启容器

apiVersion: v1
kind: Pod
metadata:
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
livenessProbe:
tcpSocket:
port: 81
initialDelaySeconds: 2
periodSeconds: 2
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}

我们直接将80端口改为81端口,nginx使用的是80端口提供服务,我们现在让他去尝试连接81端口肯定是连接不上的,我们来看看效果

[root@master k8s]# kubectl apply -f liveness-probe.yaml 
pod/nginx created
[root@master k8s]# kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          8s
[root@master k8s]# kubectl get pods
NAME    READY   STATUS    RESTARTS     AGE
nginx   1/1     Running   1 (1s ago)   9s

这种方式比较简单,就是直接对你指定的端口发起tcp连接,能连上就代表正常,连不上那就重启

这就是探针的3种检测方式了,接下来看就绪探针

readness-probe 就绪探针

这种探针跟liveness探针的区别就是,liveness会重启容器,这个探针不会,这个探针就是说,如果你的deployment的副本数为3,我这个探针依旧是检测你的index.html文件,如果这个文件不存在的话,那么我就不会将流量转发到这个pod上了,并不会重启容器,我们来看看

这个探针依旧是那3种方式

1. exec

我们这里使用deployment的方式来操作,看的更加直观一点

apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: deploy1
name: deploy1
spec:
replicas: 3
selector:
matchLabels:
app: deploy1
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: deploy1
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
readinessProbe:
exec:
command: ["test", "-f", "/usr/share/nginx/html/index.html"]
initialDelaySeconds: 2
periodSeconds: 2
status: {}

我们接下来的操作就是,创建这个控制器,然后进入到每个容器里面修改他的index.html文件的内容,最后再去删除某个容器的index.html文件,尝试访问

# 我们先将这个控制器创建出来
[root@master k8s]# kubectl apply -f deploy1.yaml 
deployment.apps/deploy1 created
[root@master k8s]# kubectl get pods -owide
NAME                       READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
deploy1-869c888fcd-nkqcr   1/1     Running   0          7s    10.244.104.9     node2   <none>           <none>
deploy1-869c888fcd-qpcj6   1/1     Running   0          7s    10.244.104.12    node2   <none>           <none>
deploy1-869c888fcd-s9gjk   1/1     Running   0          7s    10.244.166.149   node1   <none>           <none>
# 然后我们将服务暴露出去
[root@master k8s]# kubectl expose deployment deploy1 --port=80 --target-port=80 --type=NodePort
service/deploy1 exposed
[root@master k8s]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
deploy1      NodePort    10.106.239.238   <none>        80:31268/TCP   33s
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        30d
# 我们将每个容器的index文件改掉
[root@master k8s]# kubectl exec -it deploy1-869c888fcd-nkqcr -- bash
root@deploy1-869c888fcd-nkqcr:/# echo host01 > /usr/share/nginx/html/index.html
[root@master k8s]# kubectl exec -it deploy1-869c888fcd-qpcj6 -- bash
root@deploy1-869c888fcd-qpcj6:/# echo host02 > /usr/share/nginx/html/index.html
[root@master k8s]# kubectl exec -it deploy1-869c888fcd-s9gjk -- bash
root@deploy1-869c888fcd-s9gjk:/# echo host03 > /usr/share/nginx/html/index.html 
root@deploy1-869c888fcd-s9gjk:/# exit
# 然后我们通过svc暴露出来的端口来访问
[root@master k8s]# curl localhost:31268
host03
[root@master k8s]# curl localhost:31268
host02
[root@master k8s]# curl localhost:31268
host01
# 我们可以发现他会将流量转发到每一个pod上,此时我们来删除第一个容器的index.html文件
[root@master k8s]# kubectl exec -it deploy1-869c888fcd-nkqcr -- rm -f /usr/share/nginx/html/index.html
[root@master k8s]# kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
deploy1-869c888fcd-nkqcr   0/1     Running   0          9m42s
deploy1-869c888fcd-qpcj6   1/1     Running   0          9m42s
deploy1-869c888fcd-s9gjk   1/1     Running   0          9m42s

这个时候我们看到第一个pod的read状态是0/1了,我们再来尝试访问

[root@master k8s]# curl localhost:31268
host02
[root@master k8s]# curl localhost:31268
host02
[root@master k8s]# curl localhost:31268
host02
[root@master k8s]# curl localhost:31268
host03

可以看到我们现在无论怎么访问他都不会将流量转发到这个pod上了

2. httpGet

这种方式的定义跟之前的定义方式一样

apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: deploy1
name: deploy1
spec:
replicas: 3
selector:
matchLabels:
app: deploy1
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: deploy1
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
readinessProbe:
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 2
periodSeconds: 2
status: {}
[root@master k8s]# kubectl apply -f deploy1.yaml 
deployment.apps/deploy1 created
[root@master k8s]# kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
deploy1-6757fdb6d9-dl7fc   1/1     Running   0          3s
deploy1-6757fdb6d9-mrttl   1/1     Running   0          3s
deploy1-6757fdb6d9-zkj5b   1/1     Running   0          3s

我们还是同样删除一个容器里的index.html,其他效果就不演示了,只看他的状态就知道了

[root@master k8s]# kubectl exec -it deploy1-6757fdb6d9-dl7fc -- rm -f /usr/share/nginx/html/index.html
[root@master k8s]# kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
deploy1-6757fdb6d9-dl7fc   1/1     Running   0          78s
deploy1-6757fdb6d9-mrttl   1/1     Running   0          78s
deploy1-6757fdb6d9-zkj5b   1/1     Running   0          78s
[root@master k8s]# kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
deploy1-6757fdb6d9-dl7fc   0/1     Running   0          79s
deploy1-6757fdb6d9-mrttl   1/1     Running   0          79s
deploy1-6757fdb6d9-zkj5b   1/1     Running   0          79s

可以看得到,ready那里已经变成0/1了也就是他不会在有流量转发到他这里了

3. tcpSocket

apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: deploy1
name: deploy1
spec:
replicas: 3
selector:
matchLabels:
app: deploy1
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: deploy1
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 2
periodSeconds: 2
status: {}

也是这样定义的,这个我就不演示了,效果跟前俩是一样的,tcp连接不上的话ready就会变成0

综述:虽然我这里全部都是使用nginx镜像,但是我们一般会使用exec来检测配置文件是否存在,使用httpGet来检测一些网站类的容器,使用tcpSocket来对开放了端口的容器进行检测

本文来自博客园,作者:FuShudi,转载请注明原文链接:https://www.cnblogs.com/fsdstudy/p/18010183

分类: CKA

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
消息中间件 存储 Kafka
实时计算 Flink版产品使用问题之通过flink同步kafka数据进到doris,decimal数值类型的在kafka是正常显示数值,但是同步到doris表之后数据就变成了整数,该如何处理
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
8月前
|
人工智能 监控 安全
让Agent系统更聪明之前,先让它能被信任
当我们将所有希望寄托于大模型的「智能」时,却忘记了智能的不确定性必须以工程的确定性为支撑。一个无法复现、无法调试、无法观测的智能,更像是一场精彩但失控的魔法,而非我们真正需要的、可靠的生产力。本文尝试从系统工程的视角剖析 Agent 系统在可运行、可复现与可进化三个层次上不断升级的问题以及复杂度。进一步认识到:框架/平台让 Agent 「好搭」但没有让它「好用」,真正的复杂性,从未被消除,只是被推迟。
1194 33
让Agent系统更聪明之前,先让它能被信任
|
6月前
|
存储 人工智能 安全
构建AI智能体:四十八、从单体智能到群体智能:A2A协议如何重塑人机协作新范式
本文介绍了基于A2A(Agent-to-Agent)协议的智能代理系统在篮球赛安排中的应用。该系统通过多代理协作(天气、场地、日历、通知代理)实现自动化决策,相比传统API具有动态发现、语义化描述和自主决策优势。文章详细阐述了单代理(天气查询)到多代理系统的演进过程,展示了A2A协议在服务发现、任务标准化和安全通信方面的核心技术特性。该系统采用分级决策机制,优先检查天气安全条件,再验证场地和参与者可用性,最后触发通知流程,体现了分布式智能的协同效应和业务敏捷性。
392 2
|
缓存 NoSQL Redis
【Azure Redis 缓存】Redission客户端连接Azure:客户端出现 Unable to send PING command over channel
【Azure Redis 缓存】Redission客户端连接Azure:客户端出现 Unable to send PING command over channel
1369 3
|
11月前
|
监控 数据可视化 安全
进程管理工具是用于监控、控制和管理计算机系统中进程运行状态的软件工具
进程管理工具用于监控和管理系统中进程的运行状态,帮助用户了解资源使用情况、排查性能问题及管理后台程序。内容涵盖常用工具分类、核心功能场景、选择建议及注意事项,助力高效系统管理。
647 0
|
Kubernetes 调度 异构计算
生产环境 K8S + Deepseek 实现大模型部署 和 容器调度(图解+史上最全)
生产环境 K8S + Deepseek 实现大模型部署 和 容器调度(图解+史上最全)
生产环境 K8S + Deepseek 实现大模型部署 和 容器调度(图解+史上最全)
|
容器
容器内的镜像源地址修改
【8月更文挑战第22天】容器内的镜像源地址修改
858 65
|
Kubernetes 网络协议 调度
kubernetes核心技术之探针知识总结
kubernetes核心技术之探针知识总结
639 0