我正在尝试保护我家庭实验室的容器。
主要目标是:
- 隔离nginx 教程和nginxB,因此他们无法通过
172.17.0.1
(例如阻止nginx 教程从达到nginxB通过172.17.0.1:5001
) - 隔离nginx 教程和nginxB来自 localhost,使其仅通过 traefik 访问
- 允许nginx 教程交谈nginxA_DB,它们位于同一堆栈中,但不允许其他容器或 traefik 与之通信nginxA_DB
每个 docker 堆栈都有一个 nginx/apache 服务,其端口在 docker-compose 中公开方式如下:
docker-compose-nginxA.yml:
networks:
internal:
ipam:
config:
- subnet: 10.0.0.0/29
...SNIP...
nginxA:
networks:
internal:
ipv4_address: 10.0.0.2
ports:
- "172.17.0.1:5000:80"
docker-compose-nginxB.yml:
networks:
internal:
ipam:
config:
- subnet: 10.0.0.8/29
...SNIP...
nginxB:
networks:
internal:
ipv4_address: 10.0.0.10
ports:
- "172.17.0.1:5001:80"
使这些服务只能通过以下方式访问本地主机(172.17.0.1)或特雷菲克,
Traefik 也位于同一台机器上,配置如下:
http:
routers:
nginxA:
entryPoints:
- web
service: nginxA
nginxB:
entryPoints:
- web
service: nginxB
...SNIP...
services:
nginxA:
loadBalancer:
servers:
- url: http://172.17.0.1:5000
nginxB:
loadBalancer:
servers:
- url: http://172.17.0.1:5001
一个想法是使用 traefik 将同一网络中的所有容器连接起来/24
,而不通过 compose 公开任何端口,但是单个 traefik 网络不会将容器彼此隔离,只会与外部隔离。
另一个想法是为每个容器创建一个/31
网络并合并所有网络 traefik,但我不确定这是否会按预期进行隔离。例如。
nginxA:
networks:
internal:
ipv4_address: 10.0.0.2 # /29
nginxA-traefik:
ipv4_address: 10.50.0.1 # /31
traefik:
networks:
nginxA-traefik:
nginxB-traefik:
...
感谢您阅读到这里!您知道如何实现这一点吗?
答案1
您说得对。正如上一个示例所示,您需要为两个容器之间的每条通信路径创建一个单独的网络。这些网络可以是/31
's 或/29
s 或任何您想要的,只要子网不同即可。
例子:
nginxA-traefik
连接nginxA
和traefik
nginxB-traefik
连接nginxB
和traefik
nginxA-nginxA_DB
连接nginxA
和nginxA_DB
您不应该对nginx
容器进行任何端口映射,因为traefik
将通过 docker 网络直接与它们通信。这将允许每个nginx
容器进行通信traefik
(反之亦然),但它们无法相互通信。
但是!这种方法的扩展性不是很好,因为您必须为连接到 traefik 的每项服务创建/管理一个网络,这很快就会变得难以处理。更好的方法是为所有与 traefik 关联的服务(例如traefik_public
)创建一个网络,将所有服务容器(即 和其他任何容器)连接nginx_A
到此nginx_B
网络,并添加一些规则以iptables
仅允许往返 的流量traefik
。
iptables
我编写了一个非常简单的容器防火墙,它可以自动为您处理规则:https://github.com/kaysond/trafficjam
您只需指定要保护的网络(traefik_public
)和允许通信的容器(例如ancestor=traefik:latest
),它会处理剩下的事情!