nginx 不会自动获取 swarm 中的 dns 变化

nginx does not automatically pick up dns changes in swarm

我是 运行 nginx 通过 lets-nginx 在 docker 群中的默认 nginx 配置(根据 lets-nginx 项目):

服务:

  ssl:
    image: smashwilson/lets-nginx
    networks:
      - backend
    environment:
      - EMAIL=sas@finestructure.co
      - DOMAIN=api.finestructure.co
      - UPSTREAM=api:5000
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - letsencrypt:/etc/letsencrypt
      - dhparam_cache:/cache

  api:
    image: registry.gitlab.com/project_name/image_name:0.1
    networks:
      - backend
    environment:
      - APP_SETTINGS=/api.cfg
    configs:
      - source: api_config
        target: /api.cfg
    command:
      - run
      - -w
      - tornado
      - -p
      - "5000"

api 是一个 flask 应用程序,它在 swarm 覆盖网络 backend.

的端口 5000 上运行

最初启动服务时一切正常。但是,每当我以一种使 api 容器在三节点群中的节点之间移动的方式更新 api 时,nginx 无法将流量路由到新容器。

我可以在 nginx 日志中看到它坚持使用旧的内部 IP,例如 10.0.0.2,而新容器现在位于 10.0.0.4。

为了使 nginx 'see' 成为新的 IP,我需要重新启动 nginx 容器或 docker exec 进入它并 kill -HUP nginx 进程。

有没有更好的自动方式让nginx容器刷新名字解析?

感谢@Moema 的指点,我想出了一个解决方案。 lets-nginx 的默认配置需要进行如下调整,以使 nginx 获取 IP 更改:

  resolver 127.0.0.11 ipv6=off valid=10s;
  set $upstream http://${UPSTREAM};
  proxy_pass $upstream;

这使用 docker 带 TTL 的 swarm 解析器并设置一个变量,强制 nginx 刷新 swarm 中的名称查找。

请记住,当您使用 set 时,您需要自己生成整个 URL。

我在 compose 中使用 nginx 来代理 zuul 网关:

        location /api/v1/ {
           proxy_set_header X-Forwarded-Host $host:$server_port;
           proxy_pass http://rs-gateway:9030/api/v1/;
        }

        location /zuul/api/v1/ {
           proxy_set_header X-Forwarded-Host $host:$server_port;
           proxy_pass http://rs-gateway:9030/zuul/api/v1/;
        }

现在有了 Swarm,它看起来像这样:

        location ~ ^(/zuul)?/api/v1/(.*)$ {
            set $upstream http://rs-gateway:9030/api/v1/$is_args$args;
            proxy_pass $upstream;
            # Set headers
            proxy_set_header X-Forwarded-Host $host:$server_port;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $http_connection;
        }

正则表达式很好,但不要忘记自己将 GET 参数插入到生成的 URL 中。