问题描述
想要使用Traefik将多个使用docker-compose运行的服务路由到不同的前缀下,例如:10.20.30.40/u10/xyz和10.20.30.40/a10/abc,而不是10.20.30.40:8000/xyz和10.20.30.40:8001/abc。
用户在docker-compose.yml文件中启动了a10、u10、x10、mongo、mosquitto等服务,并且这些服务都在各自的端口上暴露出来。用户现在遇到了Traefik的正确参数配置问题。用户尝试了一些参数和注释掉参数的方法,但仍然无法解决问题。
用户希望这些服务只能通过前缀访问,并且都通过80端口进行负载均衡。例如,使用以下命令进行扩展:docker-compose -f dc.yml --scale u10=3 --scale a10=5
。
用户在本地机器上运行时,如果尝试访问http://127.0.0.1/u10/somepage.html
,会出现网关超时错误;如果不使用–scale参数,则会出现404错误。
这些服务在内部使用指定的端口(REST)进行通信,不需要前缀,内部通信正常工作。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
在Docker Compose中使用Traefik进行端口转发和负载均衡的配置如下:
1. 创建一个docker-compose.yml
文件。
2. 在该文件中定义Traefik服务和其他需要转发的服务。
3. 配置Traefik服务的参数,包括日志级别、API安全性、Docker提供者等。
4. 配置其他服务的参数,包括端口、依赖关系、标签等。
5. 启动docker-compose。
以下是一个示例docker-compose.yml
文件:
version: "3"
services:
reverse-proxy:
image: traefik:v2.9
command:
- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedByDefault=true"
- "--entrypoints.web.address=:80"
- "--accesslog=true"
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
u10:
image: "u10"
depends_on:
- reverse-proxy
restart: always
networks:
- my-internal-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.u10.rule=PathPrefix(`/u10`)"
- "traefik.http.routers.u10.entrypoints=web"
- "traefik.http.routers.u10.middlewares=u10"
- "traefik.http.middlewares.u10.stripprefix.prefixes=/u10"
- "traefik.http.middlewares.u10.stripprefix.forceSlash=false"
- "traefik.http.routers.u10.service=u10"
- "traefik.http.services.u10.loadbalancer.server.port=8540"
networks:
my-internal-network:
driver: bridge
在上面的示例中,我们定义了两个服务:reverse-proxy
和u10
。reverse-proxy
是Traefik服务,用于进行端口转发和负载均衡。u10
是用户的服务,通过Traefik进行转发。
在Traefik服务的配置中,我们指定了日志级别、API安全性、Docker提供者等参数。并将80端口映射到主机的80端口,将8080端口映射到主机的8080端口。
在用户的服务u10
的配置中,我们指定了依赖关系、网络、标签等参数。其中,traefik.enable=true
表示启用Traefik转发,traefik.http.routers.u10.rule=PathPrefix(
/u10)
表示只能通过/u10
前缀访问该服务,traefik.http.services.u10.loadbalancer.server.port=8540
表示该服务的负载均衡端口为8540。
请注意,以上示例中的配置仅供参考,具体配置根据实际情况进行调整。
方案2
另一种方法是使用脚本或工具来控制容器的运行顺序和转发规则。你可以编写脚本或使用一些第三方工具来管理容器的依赖关系和转发规则。
以下是一个示例脚本,可以在容器A启动后启动容器B:
#!/bin/bash
# 启动容器A
docker run -d --name container_a your_image_a
# 等待容器A完全启动
while ! docker exec container_a echo "Container A is ready"; do
sleep 1
done
# 启动容器B
docker run -d --name container_b your_image_b
在这个示例中,我们首先使用docker run
命令启动容器A,并将其命名为container_a
。然后,使用一个循环来等待容器A完全启动(这里是通过在容器内运行echo
命令来测试)。一旦容器A就绪,我们再使用docker run
命令启动容器B,并将其命名为container_b
。
请注意,这只是一个示例脚本,具体的脚本内容需要根据实际情况进行调整。
以上是两种使用Traefik和Docker.Compose进行端口转发规则的解决方案,你可以根据自己的需求选择适合的方法。