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

zsohkypk  于 2022-11-03  发布在  Docker
关注(0)|答案(1)|浏览(154)

我希望你能帮助我,提前谢谢!
我有一个包含三个服务traefik, app and service-x的docker-compose文件。app可以有许多示例,我使用traefik实现了一个负载平衡器/反向代理,它工作正常。app在内部调用service-xservice-x也可以有许多示例,但是当app调用http://service-x时,它总是对同一个示例(第一个示例)进行调用,因此我想知道是否有一种方法可以实现负载平衡机制,以便当我调用service-x时,它分布在所有示例中?
这是简化的Docker-Composer文件:

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"
mf98qq94

mf98qq941#

我想知道是否有一种方法可以实现负载平衡机制,这样当我调用service-x时,它就分布在所有示例中了。
这是docker-compose的默认行为。如果您没有看到这种行为,我怀疑是您使用了过时的links参数。当您将container附加到同一用户定义的网络(默认情况下是这样做的)时,它们可以使用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运行的是this image,它运行一个Web服务器,该服务器报告其主机名和一些其他元数据。
app服务的角色由nginx扮演,使用以下配置:

server {
    listen       80;
    server_name  localhost;

    location / {
        proxy_pass          "http://service-x";
        proxy_set_header    Host $http_host;
    }
}

使用上面的配置,对http://127.0.02的请求(具有example.comHost头)将转到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

相关问题