docker swarm 服务前端的 nginx

docker swarm 服务前端的 nginx

我已经思考了好几个星期该如何严肃地完成这件事,但还没有得出结论。也许我想错了。

假设您有 100 个来来去去的 Web 应用。您需要一个类似这样的 nginx 配置,以 gitlab 为例:

location / {
  proxy_pass http://gitlab;
}

由于 gitlab 是使用创建的docker service create,因此 nginx 将能够通过您的入口网络内的 swarm-vip 虚假 DNS 名称解析 gitlab。

但:仅当服务容器正在运行时才有效。否则,nginx 将无法启动,原因是 [emerg] 1#1: host not found in upstream "gitlab"

当你必须运行高可用性 nginx 时,这是一件非常困难的事情,而确保 proxy_passed 应用程序正在运行并不是你的事。

每次你更新 nginx 服务时,如果其他一百个 swarm 服务中只有一个没有运行,即使在同一秒钟,它也不会启动。这是怎么回事?

如果这不管用,我们为什么需要在 Swarm 中进行名称解析?您如何解决这个问题?

我考虑过 consul 和动态生成 nginx 虚拟主机模板(别想 docker-nginx-proxy!),但应用程序非常不同,可以说每个应用程序都有自己的单独配置。所有这些工作不是出于特殊原因,只是为了解决 nginx 的解析问题?

答案1

我建议将静态定义的 nginx 反向代理换成 traefik,它具有 Swarm 感知功能,可以在服务部署和销毁时动态地重新配置自身。

以下是一个示例实现:

  1. 为 traefik 创建一个与容器通信的网络:docker network create proxy

  2. 创建一个traefik.toml,下面是示例:

traefik.toml

accessLogsFile = "/proc/1/fd/1"
defaultEntryPoints = ["http"]
[entryPoints]
  [entryPoints.http]
  address = ":80"
[web]
address = ":8080"
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "localhost"
watch = true
swarmmode = true
constraints = ["tag==frontend"]
  1. traefik 的示例撰写文件:

docker-compose.traefik.yml

version: '3'

networks:
  proxy:
    external:
      name: proxy

services:
  traefik:
    image: traefik:latest
    volumes:
    - ./traefik.toml:/etc/traefik/traefik.toml:ro
    - /var/run/docker.sock:/var/run/docker.sock
    ports:
    - 80:80
    - 8080:8080
    networks:
    - proxy
    restart: unless-stopped
  1. 使用标签并在同一网络上配置您的应用。

docker-compose.app.yml

version: '3'

networks:
  proxy:
    external: true

services:
  webtest:
    image: nginx:latest
    networks:
    - default
    - proxy
    labels:
    - traefik.frontend.rule=PathPrefixStrip:/webtest
    - traefik.port=80
    - traefik.docker.network=proxy
    - traefik.tags=frontend
    restart: unless-stopped

为了简单起见,上述规则使用容器的路径前缀,但您可以使用任何您喜欢的规则来代理您的应用程序。

相关内容