Nginx
Nginx支持动态上游(normal, sans Plus),但需要用一些技巧和有限制。
放弃使用upstream
指令,改为使用普通的proxy_pass
指令。
这样可以实现轮询负载均衡和故障转移,但无法使用该指令的其他功能,如权重、故障模式、超时等。
必须通过变量传递上游主机名到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:
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:
}
}
}
然后...
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
- 使用容器学习Nginx反向代理
- 用Python为Docker动态配置Nginx
Traefik
Traefik直接依赖于Docker API,可能是一种更简单和可配置的选择。让我们看看它的实际应用。
docker-compose.yml
version: '2.2'
services:
reverse-proxy:
image: traefik
command: --api --docker
ports:
- 8080:80
- 8081:8080
volumes:
- /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用户界面中(例如:
http://localhost:8081/dashboard/
),您可以看到它识别出4个
app
容器:
![Backends](https://istack.dev59.com/GlZM7.webp)
参考资料:
- Traefik快速入门(使用Docker)