livenessProbe
在我的部署中,定义如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-deployment
labels:
name: backend-deployment
app: fc-test
spec:
replicas: 1
selector:
matchLabels:
name: fc-backend-pod
app: fc-test
template:
metadata:
name: fc-backend-pod
labels:
name: fc-backend-pod
app: fc-test
spec:
containers:
- name: fc-backend
image: localhost:5000/backend:1.3
ports:
- containerPort: 4042
env:
- name: NODE_ENV
value: "int"
livenessProbe:
exec:
command:
- RESULT=$(curl -X GET $BACKEND_SERVICE_HOST:$BACKEND_SERVICE_PORT/api/v2/makes | wc | awk '{print $3}');
- if [[ $RESULT -lt 150 ]]; then exit 1; else exit 0; fi
initialDelaySeconds: 20
failureThreshold: 8
periodSeconds: 10
由于 API 连接有时会出现一些问题,我决定设置一个操作来检查是否从 API 中获取了整个请求数据集。如果是,则整个数据集的大小约为 400 KB。如果没有,则只会返回一条短消息,响应的大小低于 120 B。此时探测器的第二个命令进入:它检查环境变量是否RESULT
较低:如果是,则意味着响应不包含所有所需数据并以错误代码退出。
这两个命令都是通过从正在运行的容器内部调用来测试的,因此涵盖两种情况:a)获取正确的数据 - 退出 0,b)仅获取错误消息 - 退出 1。
在没有探测器的情况下运行的应用程序至少已经正常工作了 3-4 个小时,然后出现了连接问题,虽然最终可以自行解决,但却使应用程序有点卡住,这是非常不理想的。
探测实施后,第一个不稳定问题在部署几分钟后开始出现。每隔几分钟,pod 就会重新启动,并且重新启动次数有规律地增加。
我发现有关部署的描述如下:
Pod Template:
Labels: app=fc-test
name=fc-backend-pod
Containers:
nsc-backend:
Image: localhost:5000/backend:1.3
Port: 4042/TCP
Host Port: 0/TCP
Liveness: exec [RESULT=$(curl -X GET $BACKEND_SERVICE_HOST:$BACKEND_SERVICE_PORT/api/v2/makes | wc | awk '{print $3}'); if [[ $RESULT -lt 150 ]]; then exit 1; else exit 0; fi] delay=20s timeout=1s period=10s #success=1 #failure=8
它看起来很合理,但是当使用命令进入正在运行的容器时exec
,我发现echo $RESULT
没有输出(只有一行空行)。
这是否意味着只有探测器的第一次调用以某种方式成功处理,而所有后续调用均未成功处理?如何进行探测器配置以使其按预期工作?
答案1
测试了该问题的两种解决方案:第一种是稍微改变一下方法(感谢 @moonkotte 关于日志记录的提示:它给了我在应用程序目录中保存一些证据的想法)。我决定将 的输出转储curl
到文件中,而不是使用环境变量。然后我开始寻找当远程端点发生问题时(Response is empty
在本例中)预计会发送回的特定消息。如果消息存在,则grep
找出它,但与正常模式不同,由于存在-v
参数(反转),它会返回退出代码 1。如果找不到指定的消息,端点似乎一切正常,并返回退出代码 0,导致 pod 继续正常运行。
整个命令如下所示:
livenessProbe:
exec:
command:
- sh
- -c
- >-
curl -X GET $BACKEND_SERVICE_HOST:$BACKEND_SERVICE_PORT/api/v2/makes |
head -c 30 > /app/output.log &&
grep -v 'Response is empty' /app/output.log
第二种解决方案是将curl
命令放入 bash 脚本中,并将其与整个镜像一起发送。脚本本身如下所示:
#!/bin/bash
msg=$(curl -X GET $BACKEND_SERVICE_HOST:$BACKEND_SERVICE_PORT/api/v2/makes | head -c 30)
if [[ $msg == *"Response is empty"* ]]; then
exit 1
else
exit 0
fi
该脚本通过命令调用:
livenessProbe:
exec:
command:
- sh
- ./liveness_check.sh
结果是一样的。第二种方法可用于逻辑更复杂的情况下或作为一种解决方法。