在 docker swarm 中实现 nginx 动态发现服务,核心做法是使用 docker-gen 监听 docker socket 的事件变化,自动生成或重载 nginx 配置文件。具体操作是启动一个挂载了 docker socket 的 docker-gen 容器,配合一个模板文件(如 nginx.tmpl),当 swarm 中的服务状态改变时,docker-gen 会重新渲染模板并触发 nginx 重载,从而实现后端节点的自动更新。

如何配置 docker-gen 与 Nginx 的联动
要实现联动,需要确保 docker-gen 能够读取到 Swarm 服务的标签信息,并将这些信息传递给 Nginx。通常的做法是将 docker-gen 和 Nginx 放在同一个网络中,并通过环境变量或卷挂载共享生成的配置文件。docker-gen 负责解析服务元数据,Nginx 负责根据生成的 conf 文件进行反向代理。

version: '3.8'
services:
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- /var/run/docker.sock:/tmp/docker.sock:ro
networks:
- proxy
depends_on:
- docker-gen
docker-gen:
image: teekay/docker-gen
command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./templates:/etc/docker-gen/templates
- ./nginx.conf:/etc/nginx/conf.d/nginx.conf:ro
networks:
- proxy
networks:
proxy:
driver: overlay
上述配置展示了基本的堆栈结构。docker-gen 监听 /tmp/docker.sock,一旦检测到变化,就会执行 -notify-sighup nginx 信号通知 Nginx 重载配置。Nginx 容器必须挂载相同的 Socket 以便 docker-gen 访问,同时挂载模板目录和输出目录。在实际 Swarm 部署中,需确保所有节点都能访问该 Socket 且权限正确。
如何处理 Swarm 服务标签以生成正确的 upstream
Swarm 服务通过标签(Labels)来标识哪些服务需要被 Nginx 代理。常见的做法是为需要代理的服务添加特定的标签,例如 traefik.frontend.rule=Host:example.com 或自定义的 proxy.enable=true。docker-gen 使用 Go 模板语法遍历这些标签,提取 IP 地址和端口,构建 Nginx 的 upstream 块。
Docker Hub (hub.docker.com)。此技能适用于所有 Docker Hub 操作,包括读取、创建、更新和删除数据。只要任务涉及 Docker Hub,就使用此技能。

upstream backend_service {
# dynamic content generated by docker-gen
server 10.0.0.5:8080;
server 10.0.0.6:8080;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
这个示例展示了生成的 Nginx 配置片段。docker-gen 会根据带有特定标签的服务实例,动态插入 server 指令。每个服务实例的 IP 和端口都会被写入 upstream 块。当 Swarm 扩展或收缩服务时,这些行会自动增减。开发者需要注意,Swarm 模式下服务 IP 是虚拟 IP(VIP),但 docker-gen 通常能获取到具体的任务 IP(Task IP),这取决于 Docker 版本和配置。确保模板中正确引用了 .Address 或 .NetworkSettings.Networks 字段。
当 Swarm 服务重启时 Nginx 配置如何保持同步
在 Swarm 环境中,服务重启会导致容器 IP 地址发生变化。docker-gen 通过持续监控 Docker Daemon 的事件流来捕捉这些变化。当服务重启后,新的任务会被分配新的 IP,docker-gen 检测到旧任务停止和新任务启动,随即重新渲染模板并发送 SIGHUP 信号给 Nginx。Nginx 接收到信号后,会平滑地重新加载配置,断开旧连接并建立与新 IP 的连接,从而保证服务不中断。










