【问题标题】:nginx does not automatically pick up dns changes in swarmnginx 不会自动获取 swarm 中的 dns 更改
【发布时间】:2017-10-10 07:00:28
【问题描述】:

我在 docker swarm 的默认 nginx 配置(根据lets-nginx项目)中通过lets-nginx运行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 是一个烧瓶应用程序,在 swarm 覆盖网络 backend 的 5000 端口上运行。

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

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

为了让 nginx '看到'新 IP,我需要重新启动 nginx 容器或 docker exec 进入它,kill -HUP nginx 进程。

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

【问题讨论】:

  • 您可以尝试将proxy_pass 设置为变量并定义解析器以强制重新解析,如下所示:serverfault.com/questions/240476/…
  • 好的提示 - 但我已经仔细检查过,默认配置包括 proxy_pass http://${UPSTREAM};,它被lets-nginx 替换为配置的主机名
  • 或者此设置带有set ... 子句是否相关?我会试试看。
  • 是的,它与使用 set 设置变量以及定义解析器有关
  • 好的,我已经尝试了建议的配置更改(resolverset ...),但它似乎仍然没有接受服务 ips 的更改。

标签: docker nginx docker-swarm nginx-reverse-proxy


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    请记住,当您使用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$1/api/v1/$2$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 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-10
      • 1970-01-01
      • 1970-01-01
      • 2020-03-05
      • 1970-01-01
      • 2020-02-13
      • 2023-01-23
      • 2021-07-30
      相关资源
      最近更新 更多