我使用Traefik basic example并提供两项服务:traefik
本身和traefik/whoami
,我将两种服务分别分配给名为web
的网络,后者分配给backend
网络好吧。
但是,Traefik发现了backend
服务的traefik/whoami
IP地址,无法通过web
网络建立联系,并导致“网关超时”
为了强迫Traefik使用网络,我同时添加了--providers.docker.network=web
和traefik.docker.network=web
,但仍然发现了backend
IP地址。
如何让Traefik在正确的网络上发现服务IP地址?
这是我要开始使用的docker-compose.yml
文件。
version: "3.8"
services:
traefik:
image: "traefik:v2.3"
command:
- --log.level=DEBUG
- --api.insecure=true
- --api.dashboard=true
- --api.debug=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --providers.docker.network=web
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
- web
whoami:
image: "traefik/whoami"
labels:
- traefik.enable=true
- traefik.http.routers.whoami.rule=Host(`whoami.localhost`)
- traefik.http.routers.whoami.entrypoints=web
- traefik.docker.network=web
networks:
- web
- backend
networks:
web:
backend:
PS!!当您从服务中删除backend
网络时,它工作正常!
答案 0 :(得分:1)
网络名称有一个小故障。当您在撰写文件中运行并且不引用外部网络时,网络名称将在当前compose project
的范围内创建。启动时,您可能会看到一些消息
Creating network "traefik2-test_web" with the default driver
Creating network "traefik2-test_backend" with the default driver
(假设您正在其中运行的文件夹称为traefik2-test),这意味着创建的docker网络以项目名称作为前缀,例如允许为孤立的实例启动两次撰写文件。
您可能还会在日志中看到一些错误,表明未找到名为web
的已配置网络-因此,它会退回到随机选择一个网络的位置。
traefik_1 | time="2020-10-29T14:24:25Z" level=warning msg="Could not find network named 'web' for container '/traefik2-test_whoami_1'! Maybe you're missing the project's prefix in the label? Defaulting to first available network." providerName=docker container=whoami-traefik2-test-4661d09157cf941b7efd7c8154af5611249866c4bc394c256e225e05db21a784 serviceName=whoami-traefik2-test
因此traefik期望网络使用全局有效的名称,而不关心它是从compose项目内部启动的。您可以通过执行
来验证网络名称docker container inspect XXX_whoami_1
其中XXX是您的docker-compose项目的名称。
您现在可以做什么?
相应地构造网络名称,以使参数与docker-compose创建的网络的全局唯一名称匹配。如果此撰写文件中的所有目标容器都位于web
网络中,则您甚至可以省略目标容器上的特殊标签。
traefik:
image: "traefik:v2.3"
command:
- --log.level=DEBUG
- --api.insecure=true
- --api.dashboard=true
- --api.debug=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --providers.docker.network=${COMPOSE_PROJECT_NAME}_web
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
- web
这要求您为每个命令传递一个docker compose项目名称(或相应地设置env)
COMPOSE_PROJECT_NAME=proj docker-compose up
问题是您确实需要为每个调用指定该变量。您可以通过使用.env
旁边的docker-compose.yml
文件来解决此问题。
COMPOSE_PROJECT_NAME=projfromenv
但是可能会有更好的解决方案。第二种选择是通过引用现有网络来使用全局唯一的网络名称。这需要像这样对网络进行初始设置:
docker network create traefik-net
然后在网络部分中引用它:
networks:
web:
external: true
name: traefik-net
backend:
并以对该网络名称(代码段)的引用开头traefik:
- --providers.docker.network=traefik-net
您的目标容器仍然引用本地网络名称web
,现在它是对该全局名称的引用。您无需为whoami容器指定traefik网络标签,因为您无需覆盖默认值。
此设置还允许使用容器(也应从此traefik实例公开)来启动其他组合项目。所以我会选择第二种选择...