Docker:在網路級別隔離組合堆棧,同時允許 Traefik 反向代理單個服務
我正在嘗試保護我的家庭實驗室中的容器。
主要目標是:
- 隔離nginxA和nginxB,因此它們無法通過彼此交談
172.17.0.1
(例如,阻止nginxA通過到達nginxB172.17.0.1:5001
)- 將nginxA和nginxB與 localhost隔離,使它們可以通過 traefik 獨占訪問
- 允許nginxA與位於同一堆棧中的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"
使這些服務只能通過localhost (172.17.0.1) 或traefik 訪問,
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
一個想法是
/24
用 traefik 連接同一網路中的所有容器,而不通過 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: ...
感謝您閱讀到這裡!你有什麼想法可以做到這一點嗎?
你在正確的軌道上。與上一個範例一樣,您希望為兩個容器之間的每個通信路徑創建一個單獨的網路。只要子網不同,這些都可以是
/31
’s 或s 或任何您想要的。/29
例子:
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
),它會照顧其餘的!