【问题标题】:docker-compose --scale X nginx.conf configurationdocker-compose --scale X nginx.conf 配置
【发布时间】:2019-01-28 03:09:18
【问题描述】:

我的 nginx.conf 文件目前有直接定义的路由:

worker_processes auto;

events { worker_connections 1024; }

http {
    upstream wordSearcherApi {
          least_conn;

          server api1:61370 max_fails=3 fail_timeout=30s;
          server api2:61370 max_fails=3 fail_timeout=30s;
          server api3:61370 max_fails=3 fail_timeout=30s;
    }

    server {
          listen 80; 
          server_name server_name 0.0.0.0;

          location / {
              proxy_pass http://wordSearcherApi;
          }
    }
}

有没有办法在docker-compose.yml中只创建一个服务,当docker-compose up --scale api=3时,nginx会做自动负载均衡吗?

【问题讨论】:

    标签: docker nginx load-balancing


    【解决方案1】:

    Nginx

    在 Nginx 中可以实现动态上游(正常,无 Plus),但有技巧和限制。

    1. 你放弃 upstream 指令并使用普通的 proxy_pass

      它提供循环负载平衡和故障转移,但没有the directive 的额外功能,如权重、故障模式、超时等。

    2. 您的上游主机名必须通过变量传递给proxy_pass,并且您必须提供resolver

      它强制 Nginx 重新解析主机名(针对 Docker 网络的 DNS)。

    3. 您失去了与斜杠相关的 location/proxy_pass 行为。

      在问题中反向代理到裸/ 的情况下,没关系。否则,您必须手动 rewrite 路径(请参阅下面的参考资料)。

    让我们看看它是如何工作的。

    docker-compose.yml

    version: '2.2'
    services:
      reverse-proxy:
        image: nginx:1.15-alpine
        volumes:
          - ./nginx.conf:/etc/nginx/nginx.conf
        ports:
          - 8080:8080
      app:
        # A container that exposes an API to show its IP address
        image: containous/whoami
        scale: 4
    

    nginx.conf

    worker_processes  1;
    
    events {
      worker_connections  1024;
    }
    
    http {
      access_log /dev/stdout;
      error_log /dev/stderr;
    
      server {
        listen 8080;
        server_name localhost;
    
        resolver 127.0.0.11 valid=5s;
        set $upstream app;
    
        location / {
          proxy_pass http://$upstream:80;
        }
      }
    }
    

    那么……

    docker-compose up -d
    seq 10 | xargs -I -- curl -s localhost:8080 | grep "IP: 172"
    

    ...产生类似于以下内容的内容,表明请求分布在 4 个app 容器中:

    IP: 172.30.0.2
    IP: 172.30.0.2
    IP: 172.30.0.3
    IP: 172.30.0.3
    IP: 172.30.0.6
    IP: 172.30.0.5
    IP: 172.30.0.3
    IP: 172.30.0.6
    IP: 172.30.0.5
    IP: 172.30.0.5
    

    参考资料:

    1. Nginx with dynamic upstreams
    2. Using Containers to Learn Nginx Reverse Proxy
    3. Dynamic Nginx configuration for Docker with Python

    Traefik

    Traefik 直接依赖 Docker API,可能是一个更简单、更可配置的选项。让我们看看它的实际效果。

    docker-compose.yml

    version: '2.2'
    services:
      reverse-proxy:
        image: traefik  
        # Enables the web UI and tells Traefik to listen to docker
        command: --api --docker  
        ports:
          - 8080:80      
          - 8081:8080  # Traefik's web UI, enabled by --api
        volumes:
          # So that Traefik can listen to the Docker events
          - /var/run/docker.sock:/var/run/docker.sock  
      app:
        image: containous/whoami
        scale: 4
        labels:
          - "traefik.frontend.rule=Host:localhost"
    

    那么……

    docker-compose up -d
    seq 10 | xargs -I -- curl -s localhost:8080 | grep "IP: 172"
    

    ...还会产生一些输出,表明请求分布在 4 个app 容器中:

    IP: 172.31.0.2
    IP: 172.31.0.5
    IP: 172.31.0.6
    IP: 172.31.0.4
    IP: 172.31.0.2
    IP: 172.31.0.5
    IP: 172.31.0.6
    IP: 172.31.0.4
    IP: 172.31.0.2
    IP: 172.31.0.5
    

    在 Traefik UI(示例中为 http://localhost:8081/dashboard/)中,您可以看到它识别出 4 个 app 容器:

    参考资料:

    1. The Traefik Quickstart (Using Docker)

    【讨论】:

      【解决方案2】:

      您当前的配置是不可能的,因为它是静态的。你有两个选择-

      1.使用 docker 引擎集群模式 - 您可以定义副本,集群内部 DNS 将自动平衡这些副本之间的负载。
      参考 - https://docs.docker.com/engine/swarm/

      2。使用著名的 Jwilder nginx 代理 - 此图像侦听 docker 套接字,使用 GO 中的模板在您扩大或缩小容器时动态更改您的 nginx 配置。
      参考 - https://github.com/jwilder/nginx-proxy

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-13
        • 2019-12-04
        • 2017-08-20
        • 1970-01-01
        • 2021-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多