希望你能帮到我,提前谢谢!
我有一个 docker-compose 文件,其中包含三个服务traefik, app and service-x
.app
可以有很多实例,我使用 traefik 实现了负载均衡器/反向代理,它工作正常。app
内部调用service-x
和service-x
也可以有很多实例,但是当app
调用http://service-x
它总是对同一个实例(第一个)进行调用时,所以我想知道是否有办法实现负载平衡机制,所以当我调用service-x
时,它会分布在所有实例中?
这是简化的 docker 撰写文件:
services:
traefik:
image: "traefik"
restart: always
command:
- "--api=true"
...
ports:
- "80:80"
- "443:443"
app:
image: app:latest
labels:
- "traefik.enable=true"
...
ports:
- "3000"
restart: on-failure
links:
- service-x
service-x:
image: service-x:latest
ports:
- "8001"
我想知道是否有办法实现负载平衡机制,所以当我调用 service-x 时,它会分布在所有实例中?
这就是docker-compose默认的行为方式。如果您没有看到该行为,我怀疑这是您对已弃用的links
参数的使用。你已经很多年不需要它了;当您将容器附加到同一用户定义的网络(默认情况下,docker-compose 会这样做)时,它们可以使用 Docker 自动维护的 DNS 服务按名称相互引用。
另外 - 这与你的问题没有直接关系 - 你不需要ports
仅在内部使用的服务的条目。
有关实际示例,请看此docker-compose.yaml
:
version: "3"
services:
proxy:
image: traefik:latest
command:
- --api.insecure=true
- --providers.docker
- --accesslog=true
- --accesslog.filepath=/dev/stderr
ports:
- "127.0.0.2:80:80"
- "127.0.0.2:443:443"
- "127.0.0.2:8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
app:
image: docker.io/nginx:mainline
volumes:
- "./default.conf:/etc/nginx/conf.d/default.conf"
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`example.com`)"
service-x:
image: docker.io/containous/whoami:latest
在上面,service-x
正在运行此映像,该映像运行一个报告其主机名和其他一些元数据的Web服务器。
您的app
服务的角色由nginx扮演,使用以下配置:
server {
listen 80;
server_name localhost;
location / {
proxy_pass "http://service-x";
proxy_set_header Host $http_host;
}
}
使用上述配置,对Host
标头为example.com
的http://127.0.02
的请求将转到app
服务,然后该服务会将请求代理给service-x
服务。
如果我们提出service-x
的多个实例,像这样:
docker-compose up --scale service-x=3
这样我们就有了:
$ docker ps -f label=com.docker.compose.project=proxy-example
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e2cbcb3e4e36 containous/whoami:latest "/whoami" 6 minutes ago Up 5 minutes 80/tcp proxy2_service-x_2
48655b9f0dd3 containous/whoami:latest "/whoami" 6 minutes ago Up 5 minutes 80/tcp proxy2_service-x_3
f6cdd1cfe908 nginx:mainline "/docker-entrypoint.…" 10 minutes ago Up 5 minutes 80/tcp proxy2_app_1
d65f996e7113 containous/whoami:latest "/whoami" 22 minutes ago Up 5 minutes 80/tcp proxy2_service-x_1
af1310113b6a traefik:latest "/entrypoint.sh --ap…" 22 minutes ago Up 5 minutes 127.0.0.2:80->80/tcp, 127.0.0.2:443->443/tcp, 127.0.0.2:8080->8080/tcp proxy2_proxy_1
然后通过 Traefik 发出多个请求:
for x in {1..10}; do
curl -sf --resolve example.com:80:127.0.0.2 http://example.com/ | grep Hostname
done
我们看到请求在service-x
容器之间轮换:
Hostname: e2cbcb3e4e36
Hostname: 48655b9f0dd3
Hostname: d65f996e7113
Hostname: e2cbcb3e4e36
Hostname: 48655b9f0dd3
Hostname: d65f996e7113
Hostname: e2cbcb3e4e36
Hostname: 48655b9f0dd3
Hostname: d65f996e7113
Hostname: e2cbcb3e4e36
<小时 />注释:
- 为什么
127.0.0.2
?因为我已经有一个服务在端口 80 上侦听127.0.0.1
。