Envoy Sidecar 启动失败主因是 bootstrap.yaml 路径错误或 YAML 格式不合规(如 tab 缩进、BOM 头);Go 服务需显式配置 HTTP/gRPC 客户端代理至 localhost:15001;须对齐 Envoy 与 Go 生命周期,避免孤儿进程;本地 curl 不通常因 iptables 或 Istio CNI 干扰回环流量。

Envoy Sidecar 启动失败:找不到 bootstrap.yaml 或配置解析报错
Go 服务本身不直接“配置”Envoy——Envoy 是独立进程,Go 程序只负责启动它、传入配置路径、与之通信。常见错误是启动后立刻退出,日志里出现 error initializing configuration: unable to read bootstrap config。
根本原因通常是路径没对上,或 YAML 格式有隐藏问题(比如 tab 缩进、BOM 头)。Envoy 对 YAML 严格,不接受制表符,且必须用空格缩进。
-
bootstrap.yaml必须放在容器或进程能访问的路径下,推荐绝对路径,比如/etc/envoy/bootstrap.yaml - 启动命令里
--config-path参数值要和实际路径完全一致,别信相对路径在容器里能自动 resolve - 用
yq或envoy --mode validate --config-path bootstrap.yaml预检配置,比等 Envoy 启动失败再查快得多 - Go 中用
exec.Command启动时,记得设置Cmd.Dir或显式传入完整路径,避免工作目录干扰
Go 服务如何把流量发给 Envoy:HTTP/GRPC 客户端默认行为陷阱
Go 服务默认直连下游,想走 Envoy Sidecar,得改请求目标地址——不是“加个代理配置”就行,而是让所有出向请求指向本地 Envoy 的监听端口(如 localhost:15001 for HTTP)。
关键点在于:Envoy 的 inbound/outbound 监听器端口是固定的,但 Go 代码里写死 http://localhost:15001 很危险。Kubernetes 下 Pod IP 变化不影响 localhost,但本地开发或非 K8s 环境容易误配。
立即学习“go语言免费学习笔记(深入)”;
- HTTP 客户端必须显式设置
http.DefaultTransport的Proxy字段为http.ProxyURL(&url.URL{Scheme: "http", Host: "localhost:15001"}) - gRPC 客户端需用
grpc.WithTransportCredentials(insecure.NewCredentials())+grpc.WithContextDialer自定义 dialer,把地址替换成localhost:15001 - 别依赖
HTTP_PROXY环境变量——Go 的http.ProxyFromEnvironment默认会读,但 gRPC 不认,造成协议不一致 - 如果用了 OpenTelemetry SDK,它的 HTTP exporter 也得单独配置 proxy,否则 trace 上报绕过 Envoy
Envoy 和 Go 进程生命周期怎么对齐:崩溃、重启、信号处理
Sidecar 模式下,Envoy 和 Go 主进程必须共存亡。一个挂了另一个还跑着,会导致流量黑洞或连接堆积。Go 不能只简单 exec.Run 就完事。
Envoy 默认不响应 SIGTERM 做优雅退出(除非配置了 runtime: shutdown_grace_period),而 Go 的 os.Interrupt 信号捕获后若没同步 kill Envoy,就会残留孤儿进程。
- 启动 Envoy 时加
--service-cluster和--service-node,方便后续通过 Admin API 触发热重启或统计 - Go 主程序用
exec.CommandContext,把 context 传进去;收到中断信号后先调envoyCmd.Process.Signal(syscall.SIGTERM),再wait,别直接os.Exit - 检查 Envoy 日志里是否有
hot restart epoch X exited with code 0,没有就说明没正常退出 - 在 Kubernetes 中,建议用
initContainer预检 Envoy 配置,而不是靠主容器里 Go 程序重试启动
调试时 curl 不通 localhost:15001:iptables 或 Istio CNI 干扰了本地回环
本地开发或裸机部署时,curl -v http://localhost:15001 返回空响应或 connection refused,但 Envoy 进程明明在跑——大概率是 iptables 规则把 loopback 流量劫持走了,或者 Istio CNI 插件覆盖了本机路由。
Envoy 的 admin 接口(默认 127.0.0.1:19000)通常不受影响,但出向监听器(如 0.0.0.0:15001)可能被规则屏蔽。
- 用
sudo ss -tlnp | grep :15001确认 Envoy 是否真在监听*:15001,而不是只监听127.0.0.1:15001 - 临时清空 iptables:
sudo iptables -t nat -F(仅测试!勿在生产执行)看是否恢复,确认是不是规则冲突 - 检查 Envoy 配置中
address字段是否用了0.0.0.0而非127.0.0.1,Sidecar 场景必须绑定全接口 - 若用 Istio,
istioctl analyze可发现常见的 CNI 冲突提示,比如PodMissingNetworkPolicy类告警
Sidecar 的本质是进程协作,不是配置拼接。Envoy 的配置粒度、Go 的网络栈控制、宿主机网络策略,三者稍有错位,流量就静默丢弃。最常被跳过的其实是验证环节:在 Go 启动前,先手动 curl -v http://localhost:15001/healthz 看通不通,比看日志快十倍。










