8

我在 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 覆盖网络的 5000 端口上运行backend

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

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

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

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

4

2 回答 2

10

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

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

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

于 2017-10-10T10:27:06.607 回答
0

请记住,使用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 中。

于 2020-04-09T08:28:43.267 回答