如何使用 docker-compose 对内部服务(具有许多实例)进行负载均衡?



希望你能帮到我,提前谢谢!

我有一个 docker-compose 文件,其中包含三个服务traefik, app and service-x.app可以有很多实例,我使用 traefik 实现了负载均衡器/反向代理,它工作正常。app内部调用service-xservice-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.comhttp://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

最新更新