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
    <>

后续步骤