Docker根据项目名称组成隔离网络



我正试图在部署w/docker compose和traefik时实现零停机,但我遇到了容器与另一个项目交叉通信的问题。

docker-compose.yml(细节省略(

services:
proxy:
networks:
- net
app:
networks:
- net
auth:
networks:
- net
networks:
net:
external:
name: traefik_webgateway # not really important here

我通过以下方式运行我的服务的两个不同实例:

docker-compose --env-file=.env --project-name=green -f docker-compose.yml up
docker-compose --env-file=.env --project-name=blue -f docker-compose.yml up

我在";绿色";工作良好,直到我运行";蓝色";项目当";蓝色";正在被提起时;绿色""代理";集装箱正被路由到";蓝色";容器在";"代理";与";auth";服务:

http://auth/session

我需要在";绿色";留在";绿色";,以及";蓝色";在";蓝色";。。。否则";绿色";将";蓝色";当它没有准备好时,它会导致API失败。一旦所有的容器都准备好了,一切都会正常工作,但这并不是零停机时间。

看起来所有内容都由容器名称绑定。我不想使用container_name,因为我想要使用docker scale

我的解决方法是创建docker-compose.blue.ymldocker-compose.green.yml,并复制所有内容,但在container name后面加上_blue_green。但我想知道是否有更好的解决方案。

提前谢谢。

编辑:提出的解决方案回答了这个问题,但通过将internal网络添加到我的proxy,traefik失去了与我的服务的通信。

默认情况下,docker-compose将为您的项目设置一个独立的网络。当使用自定义网络时,这些网络也将以项目名称命名,从而隔离具有不同名称的项目-请参阅docker-compose网络文档。

但是:在您的示例中,所有容器都连接到一个外部网络,该网络没有名称空间,因此即使对于不同的项目也是相同的。由于容器也共享相同的名称,因此在该网络中解析它们可能会导致绿色蓝色版本。

有几种方法可以解决这个问题。适当的方法取决于您的特定用例。最好也是最安全的方法是将具有相同项目名称的所有容器隔离到其自己的内部网络,并且只将用于外部连接的端口暴露到外部网络:

services:
proxy:
networks:
- net
- internal
app:
networks:
- internal
auth:
networks:
- internal
networks:
internal:
net:
external:
name: traefik_webgateway # not really important here

在这里,所有容器都只连接到项目范围内的内部网络,并且能够相互通信。只有proxy服务也连接到外部net网络,并且可以从那里连接到。

如果你真的需要将所有服务连接到同一个外部网络,你可以将aliases与变量替换一起使用:

services:
proxy:
networks:
net:
aliases:
- proxy_${COLOR}
app:
networks:
net:
aliases:
- app_${COLOR}
auth:
networks:
net:
aliases:
- auth_${COLOR}
networks:
net:
external:
name: traefik_webgateway # not really important here

这基本上是你的解决方法,但有一个docker-compose.yml,你可以这样使用:

COLOR=green docker-compose --env-file=.env --project-name=green -f docker-compose.yml up
COLOR=blue docker-compose --env-file=.env --project-name=blue -f docker-compose.yml up

最新更新