在纯 Docker 环境(无 K8s)下如何手动注入 Envoy sidecar

解读

国内很多金融、政企项目因合规或历史包袱仍停留在“裸 Docker + 自建脚本”阶段,面试官想确认两点:

  1. 你是否真正理解 sidecar 的本质——与主容器共享网络命名空间
  2. 能否用最朴素的 Linux 能力(docker run、ip netns、iptables)把 Envoy 塞进去,而不是只会写 YAML。
    答不出“共享网络”四字,直接挂;答不出“流量劫持”细节,只能给及格。

知识点

  1. --network container:<name|id>:让两个容器共享同一个网络栈,是手动注入的核心。
  2. Init 容器顺序:先起 Envoy,再起业务容器,保证 iptables 规则先就位。
  3. iptables 透明劫持:在 Envoy 容器内用 istio-iptables 或手写规则,把 0.0.0.0/0 的入站、出站流量重定向到 15001/15006。
  4. PID 空间隔离:业务容器 crash 后 Envoy 仍能继续上报指标,需加 --restart unless-stopped
  5. 国内镜像源:envoyproxy/envoy-alpine 在阿里云 ACR 有同步,避免 docker.io 拉取超时。
  6. 合规小镜像:用 distroless 或 alpine 版 Envoy,<30 MB,满足等保“最小化”要求。
  7. 日志落盘:把 /dev/stdout 挂到宿主机 /var/log/envoy/<app>.log,方便审计系统采集。
  8. Secrets 管理:把 SDS 的 token 挂只读 volume,权限 0400,符合国密条例。

答案

步骤一:准备 Envoy 配置
把 bootstrap.yaml 放在 /etc/envoy/bootstrap.yaml,关键字段:

  • node.id 与业务容器 hostname 保持一致,方便灰度。
  • admin 地址 127.0.0.1:15000,仅本地回环,防止暴露。

步骤二:启动 Envoy sidecar 容器

docker run -d --name app1-envoy \
  --network none \                                    # 先不给网络
  -v /etc/envoy:/etc/envoy:ro \
  -v /var/log/envoy:/var/log \
  --cap-add NET_ADMIN --cap-add NET_RAW \             # 必需,改 iptables
  --restart unless-stopped \
  registry.cn-hangzhou.aliyuncs.com/acs/envoy-alpine:v1.28 \
  envoy -c /etc/envoy/bootstrap.yaml

步骤三:把 Envoy 挂到业务网络命名空间

docker run -d --name app1 \
  --network container:app1-envoy \                    # **共享网络栈**
  -e ENVOY_ADMIN_URL=http://127.0.0.1:15000 \
  your-registry/app:1.2.3

步骤四:在 Envoy 容器内注入 iptables

docker exec app1-envoy sh -c "
  iptables -t nat -A PREROUTING -p tcp -j REDIRECT --to-port 15006
  iptables -t nat -A OUTPUT -p tcp -j REDIRECT --to-port 15001
"

规则立即生效,业务容器无感。

步骤五:验证

docker exec app1-envoy curl -s 127.0.0.1:15000/stats | grep downstream_rq_total
docker exec app1 curl -s http://localhost:8080/health # 业务端口仍可用

若 stats 计数随业务请求上涨,则注入成功。

拓展思考

  1. 多副本场景:用 docker-compose v2 network_mode: service:envoy 一键共享,避免手写脚本。
  2. 热升级:把 Envoy 做成双容器冷备,通过 docker rename 切换,实现零中断。
  3. 出口限流:在 bootstrap 里加 local_rate_limit filter,应对国内运营商突发带宽计费。
  4. 安全加固:给 Envoy 容器加 --security-opt=no-new-privileges 与只读根文件系统,通过国内等保 2.0 三级测评。
  5. 监控对接:用阿里云日志服务的 docker-log-driver 直接把 Envoy access log 打到 SLS,省去自建 ELK。