Pod 启动时间
本部分介绍了与 Pod 启动时间相关的常见 Cloud Service Mesh 问题及其解决方法。如果您需要其他帮助,请参阅获取支持。
Pod 启动和 Envoy 配置同步
在某些 Cloud Service Mesh 和 Istio 环境中,Pod 启动期间观察到的一个常见问题涉及应用就绪状态与 Envoy 代理配置之间的同步。此问题是由于应用容器和 Envoy 边车同时启动而导致的。应用可能会在 Envoy 代理完成其初始化并从控制平面接收其配置之前发出就绪信号。这会创建一个竞态条件,其中传入的请求会被定向到未配置且尚未准备好接收任何流量的 Envoy 代理。由于没有边车来转发任何流量,这可能会导致在应用启动的初始阶段丢弃请求、将请求错误路由或错误处理请求。
缓解策略
以下部分介绍了可缓解此问题的方法。
全局网格配置:holdApplicationUntilProxyStarts
第一种方法是在 Istio 网格配置中设置 holdApplicationUntilProxyStarts: true
。请注意,该功能默认处于关闭状态。该标志会添加钩子,以延迟应用启动,直到 Pod 的代理准备好接受流量。
添加此配置可消除这种竞态条件,但如果先前未启用此配置,则可能会导致新 Pod 的应用就绪时间延迟。
就绪性探测
另一种解决方案是实现同时包含应用和 Envoy 健康检查的就绪探测器。就绪探测器会在 Pod 准备好接受流量时通知 Kubernetes。关键在于,就绪探测器逻辑不仅应验证应用的就绪状态,还应验证 Envoy 代理的状态。这可以通过查询 Envoy 管理员端口的健康状况来实现。通过结合这两项检查,Kubernetes 可防止流量被定向到 Pod,直到应用和 Envoy 都完全初始化和配置完毕。
这种方法更灵活,允许实现更复杂的启动和就绪逻辑,但代价是复杂性也更高。
使用以下代码创建文件 healthcheck.sh
:
#!/bin/sh
APP_HEALTH=$(curl -s -o /dev/null -w "%{http_code}" \
http://localhost:8080/health)
ENVOY_HEALTH=$(curl -s -o /dev/null -w "%{http_code}" \
http://localhost:9901/ready)
if [[ "$APP_HEALTH" -eq 200 && "$ENVOY_HEALTH" -eq 200 ]]; then
exit 0
else
exit 1
fi
将 IP/端口替换为您的应用容器和 Envoy 的对应值。
以下 YAML 文件定义了一个就绪探测器,该探测器使用您先前创建的脚本:
apiVersion: v1
kind: Pod
metadata:
name: my-app-with-envoy
spec:
containers:
- name: application
<…>
readinessProbe:
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
exec:
command:
- /healthcheck.sh # using the script
- name: envoy
<…>