Docker-按项目名称组成隔离网络
Docker-compose isolate networks by project name
我正在尝试使用 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
在我 运行 “蓝色”项目之前,我在“绿色”中的服务工作正常。当“蓝色”被启动时,“绿色”“代理”容器中的一些请求被路由到“蓝色”容器。在“proxy”中进行与“auth”服务对话的示例调用:
http://auth/session
我需要“绿色”网络保持“绿色”,“蓝色”网络保持“蓝色”...否则“绿色”中的一些请求会在“绿色”状态下变为“蓝色”未准备好它导致 API 失败。一旦所有容器准备就绪,一切正常,但这不是零停机时间。
看起来一切都被容器名称绑定了。我不想使用 container_name
因为我想使用 docker scale
.
我的解决方法是创建 docker-compose.blue.yml
和 docker-compose.green.yml
并复制除 container name
后缀 _blue
和 _green
之外的所有内容。但是我想知道有没有更好的解决办法
提前致谢。
编辑:建议的解决方案回答了这个问题,但是通过将 internal
网络添加到我的 proxy
,traefik 失去了与我的服务的通信。
默认情况下,docker-compose
将为您的项目设置一个独立的网络。使用自定义网络时,这些网络也将使用项目名称命名空间,隔离具有不同名称的项目 - 请参阅 docker-compose
networking docs.
但是:在您的示例中,所有容器都连接到未命名空间的外部网络,因此即使对于不同的项目也是相同的。
由于容器也共享相同的名称,因此在该网络中解析它们可能会导致 green 或 blue 版本。
有几种方法可以解决这个问题。适当的方法取决于您的特定用例。最好也是最安全的方法是将所有具有相同项目名称的容器隔离到它们自己的内部网络,并且只将用于外部连接的端口暴露到外部网络:
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
together with variable substitution:
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
我正在尝试使用 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
在我 运行 “蓝色”项目之前,我在“绿色”中的服务工作正常。当“蓝色”被启动时,“绿色”“代理”容器中的一些请求被路由到“蓝色”容器。在“proxy”中进行与“auth”服务对话的示例调用:
http://auth/session
我需要“绿色”网络保持“绿色”,“蓝色”网络保持“蓝色”...否则“绿色”中的一些请求会在“绿色”状态下变为“蓝色”未准备好它导致 API 失败。一旦所有容器准备就绪,一切正常,但这不是零停机时间。
看起来一切都被容器名称绑定了。我不想使用 container_name
因为我想使用 docker scale
.
我的解决方法是创建 docker-compose.blue.yml
和 docker-compose.green.yml
并复制除 container name
后缀 _blue
和 _green
之外的所有内容。但是我想知道有没有更好的解决办法
提前致谢。
编辑:建议的解决方案回答了这个问题,但是通过将 internal
网络添加到我的 proxy
,traefik 失去了与我的服务的通信。
默认情况下,docker-compose
将为您的项目设置一个独立的网络。使用自定义网络时,这些网络也将使用项目名称命名空间,隔离具有不同名称的项目 - 请参阅 docker-compose
networking docs.
但是:在您的示例中,所有容器都连接到未命名空间的外部网络,因此即使对于不同的项目也是相同的。 由于容器也共享相同的名称,因此在该网络中解析它们可能会导致 green 或 blue 版本。
有几种方法可以解决这个问题。适当的方法取决于您的特定用例。最好也是最安全的方法是将所有具有相同项目名称的容器隔离到它们自己的内部网络,并且只将用于外部连接的端口暴露到外部网络:
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
together with variable substitution:
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