如何在 Nginx 上游使用 Docker swarm DNS/Service 名称

How to use Docker swarm DNS/Service names in Nginx upstream

我有一个服务 运行 跨 4 个 swarm 节点 (ServiceA) 和一个 Nginx 服务 运行 跨同一个 Swarm 的 4 个节点。 Nginx 服务 exposes/publishes 端口 80 和 443。所有服务都连接到同一个用户定义的覆盖网络,最重要的是我可以 curl/ping 从容器中获取服务名称 (ServiceA),因此一切正常到目前为止。

我的问题是如何让 Nginx 上游使用服务名称?我读了很多书并尝试将其添加到 nginx.conf resolver 127.0.0.11 ipv6=off; 但它没有帮助,Nginx 服务将无法启动。有关如何获取 Nginx 的任何想法,请参阅 Docker 网络 DNS 名称?

这是我的nginx.conf

events { 
    worker_connections 4096; 
}

http {
    include /etc/nginx/conf/*.conf;
    include /etc/nginx/mime.types;
    proxy_intercept_errors off;
    proxy_send_timeout 120;
    proxy_read_timeout 300;

    upstream serviceA {
        ip_hash;
        server serviceA:8081;
    }

    server {
        listen 80 default_server;
        resolver 127.0.0.11 ipv6=off;
        keepalive_timeout  5 5;
        proxy_buffering    off;
        underscores_in_headers on;

        location ~ ^/serviceA(?<section>.*) {
            access_log /var/log/nginx/access.log nginx_proxy_upstream;
            proxy_pass http://serviceA/$section$is_args$query_string;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

    server {
        listen 443 ssl;
        resolver 127.0.0.11 ipv6=off;
        keepalive_timeout  5 5;
        proxy_buffering    off;
        underscores_in_headers on;

        # allow large uploads
        client_max_body_size 10G;

        ssl_certificate /etc/nginx/ssl/myKey.crt;
        ssl_certificate_key /etc/nginx/ssl/myKey.key;

        location ~ ^/serviceA(?<section>.*) {
            access_log /var/log/nginx/access.log nginx_proxy_upstream;
            proxy_pass http://serviceA/$section$is_args$query_string;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

    }
}

如果已经部署了上游容器(已创建 DNS 条目),删除 resolver 应该可行。但是,这意味着除非上游容器已经 运行.

,否则您无法启动 nginx

对于通过 resolver 动态 方法,您需要使 docker 引擎主机的 DNS 可从容器 (不是通过 127.0.0.11 ...容器本身 更新:在自定义网络上可以查询 127.0.0.0/8 地址).

https://docs.docker.com/engine/userguide/networking/configure-dns/ :

Note: If you need access to a host’s localhost resolver, you must modify your DNS service on the host to listen on a non-localhost address that is reachable from within the container.

更新: 我设法在 docker swarm 中的自定义覆盖网络上做到这一点:

  location / {
    resolver 127.0.0.11 ipv6=off;
    set $upstream_addr <swarm_stack_name>:<port>;
    proxy_pass https://$upstream_addr;
    ...
  }

我没有让它与 upstream {} nginx 指令一起工作......这似乎无法处理动态解析或者我忽略了一些东西。