Nginx
在 Nginx 中可以实现动态上游(正常,无 Plus),但有技巧和限制。
-
你放弃 upstream 指令并使用普通的 proxy_pass。
它提供循环负载平衡和故障转移,但没有the directive 的额外功能,如权重、故障模式、超时等。
-
您的上游主机名必须通过变量传递给proxy_pass,并且您必须提供resolver。
它强制 Nginx 重新解析主机名(针对 Docker 网络的 DNS)。
-
您失去了与斜杠相关的 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
参考资料:
- Nginx with dynamic upstreams
- Using Containers to Learn Nginx Reverse Proxy
- 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 容器:
参考资料:
- The Traefik Quickstart (Using Docker)