灰度发布不是docker原生功能,必须依赖swarm、kubernetes或istio等上层编排/服务网格实现流量控制;单机docker run或docker-compose无法支持,因其缺乏服务发现、动态路由和流量拆分能力。

灰度发布本身不是 Docker 原生功能,而是依赖上层编排或服务网格实现的流量控制策略。Docker 单机环境下不支持灰度,必须结合 Swarm、Kubernetes 或 Istio/Envoy 等组件才能完成容器网络层面的灰度发布。
核心前提:选对部署架构
纯 docker run 或 docker-compose up 无法做灰度——它们没有服务发现、动态路由和流量拆分能力。必须升级到以下任一环境:
- Docker Swarm + Traefik(轻量级推荐):Swarm 提供内置 DNS 轮询与服务标签,Traefik 支持基于 Header、Cookie 或权重的路由规则
- Kubernetes + Istio(生产级标准):Istio VirtualService + DestinationRule 可精确控制 5%~100% 流量切到新版本 Pod
-
Kubernetes + Nginx Ingress + Canary 注解(兼容老项目):通过 ingress-nginx 的
nginx.ingress.kubernetes.io/canary系列注解启用灰度
Swarm + Traefik 实现 10% 流量灰度(实操示例)
假设已有旧版服务 web:v1 在运行,要将 10% 请求导给 web:v2:
- 用不同标签启动两个服务:
docker service create --name web-v1 --label traefik.http.routers.web.rule="Host(`app.example.com`)” web:v1docker service create --name web-v2 --label traefik.http.routers.web-v2.rule="Headers(`X-Canary`, `true`)” web:v2 - 配置 Traefik 动态路由,在
traefik.yml中添加加权负载:http:<br> routers:<br> web:<br> service: web-stable<br> services:<br> web-stable:<br> weighted:<br> services:<br> - name: web-v1<br> weight: 90<br> - name: web-v2<br> weight: 10
K8s + Istio 灰度发布关键配置
这是目前最主流、最可控的方式,重点在两份 YAML:
-
DestinationRule:定义子集(subsets),标记 v1/v2 版本标签
subsets:<br> - name: v1<br> labels:<br> version: v1<br> - name: v2<br> labels:<br> version: v2
-
VirtualService:按百分比分流
http:<br> - route:<br> - destination:<br> host: web<br> subset: v1<br> weight: 90<br> - destination:<br> host: web<br> subset: v2<br> weight: 10
网络层注意事项
灰度发布成败常卡在底层网络连通性上,务必确认:
- 新旧版本容器必须处于同一 Kubernetes 命名空间或同一 Swarm 网络,否则 DNS 解析失败
- 若使用 host 网络模式,灰度将失效——所有容器共享宿主机端口,无法隔离实例
- 避免用 bridge 默认网桥(docker0):IP 不固定、无服务发现,应改用自定义 bridge 或 overlay 网络
- Istio 等服务网格要求容器注入 sidecar(如 istio-proxy),否则流量不经过控制面,灰度规则不生效











