Farklı bir fiziksel ağ arabirimi ve varsayılan ağ geçidi kullanarak docker kapsayıcılarından yönlendirme


13

Arkaplan bilgisi

Docker çalıştıran iki ağ arabirimine sahip bir sunucum var. Docker, bazı sanallaştırma araçları gibi, adlı bir Linux köprü arayüzü oluşturur docker0. Bu arabirim varsayılan olarak bir IP'si ile yapılandırılır 172.17.42.1ve tüm Docker kapsayıcıları bu arabirimle ağ geçidi olarak iletişim kurar ve aynı /16aralıkta IP adresleri atanır . Anladığım kadarıyla, kapsayıcılara / kapsayıcılardan gelen tüm ağ trafiği bir NAT'dan geçer, bu yüzden giden 172.17.42.1ve gelen gönderilir 172.17.42.1.

Kurulumum şöyle görünür:

                                          +------------+        /
                                          |            |       |
                            +-------------+ Gateway 1  +-------
                            |             | 10.1.1.1   |     /
                     +------+-------+     +------------+    |
                     |     eth0     |                      /
                     |   10.1.1.2   |                      |
                     |              |                      |
                     | DOCKER HOST  |                      |
                     |              |                      | Internet
                     |   docker0    |                      |
                     |   (bridge)   |                      |
                     |  172.17.42.1 |                      |
                     |              |                      |
                     |     eth1     |                      |
                     |  192.168.1.2 |                      \
                     +------+-------+     +------------+    |
                            |             |            |     \
                            +-------------+ Gateway 2  +-------
                                          | 192.168.1.1|       |
                                          +------------+            

Sorun

Ben yönlendirmek için / den ikinci dışına herhangi Docker kaplara tüm trafiği istiyorum eth1 192.168.1.2varsayılan ağ geçidine arayüzüne 192.168.1.1dışarı çıkmak konak makineye / den tüm trafiği yerken, eth0 10.1.1.2varsayılan ağ geçidi için arayüzü 10.1.1.1. Şimdiye kadar boşuna çeşitli şeyler denedim ama düzeltmek için en yakın olduğunu düşünüyorum tek şey iproute2 böyle kullanmaktır:

# Create a new routing table just for docker
echo "1 docker" >> /etc/iproute2/rt_tables

# Add a rule stating any traffic from the docker0 bridge interface should use 
# the newly added docker routing table
ip rule add from 172.17.42.1 table docker

# Add a route to the newly added docker routing table that dictates all traffic
# go out the 192.168.1.2 interface on eth1
ip route add default via 192.168.1.2 dev eth1 table docker

# Flush the route cache
ip route flush cache

# Restart the Docker daemon so it uses the correct network settings
# Note, I do this as I found Docker containers often won't be able
# to connect out if any changes to the network are made while it's     
# running
/etc/init.d/docker restart

Bir konteyneri kaldırdığımda, bunu yaptıktan sonra hiç ping alamıyorum. Köprü arabirimlerinin bu tür bir yönlendirme için fiziksel arabirimlerle aynı şekilde ele alınıp alınmadığından emin değilim ve sadece akıl sağlığı kontrolünün yanı sıra bu basit görünen görevi nasıl gerçekleştirebileceğime dair ipuçları istiyorum.


NAT hakkındaki yorumunuz doğru değil. Çıktı arabiriminin docker0 olmadığı 172.17.0.0/16 kaynak adresinde maskelenecek şekilde ayarlanmıştır. yani -BİR SONRAKİ -s 172.17.0.0/16! -o docker0 -j MASQUERADE. Bu, bir docker konteynerinden kaynaklanan paket eth0 veya eth1 yoluyla çıkarsa, 172.17.xx IP'sini değil, bu arabirimlerin IP adresini alır.
Matt

Yorumun için teşekkürler. Böylece bu, belirli bir arayüzden yönlendirme yaklaşımımı değiştirir, değil mi? Bunu nasıl başarabileceğimi biliyor musun? Docker, ana bilgisayar sisteminin varsayılan ağ geçidini kullanıyor gibi görünüyor ve bu istenen davranış değil. Docker'ın belirli bir arayüzden çıkmasını istiyorum.

Önerdiğim şeyin neden işe yaramadığından emin değilim. Ancak başka bir seçenek boru tesisatı kullanmak olabilir. github.com/jpetazzo/pipework Docker yardımının gelişmiş ağ bölümünü okumak da yararlı olabilir. docs.docker.com/articles/networking
Matt

@Matt Bu konudaki önerileriniz için teşekkür ederim. Okuduğumdan, bir kapsayıcı bir güvenlik açığı gibi görünen doğru ağ geçidine erişmek için başlatıldıktan sonra ek komutlar gerektirir. Başlangıçta kapsayıcıları birden çok ana bilgisayara bağlamak için yaratılmıştı, bu da benim amacım değil. Docker gelişmiş ağ dokümanlarına gelince, tekrar bakacağım, ancak şu ana kadar bu durumda yardımcı olmadı (burada göndermeden önce okumuştum). Docker Github Sorunları sayfasında bu yazının bağlantısını göndereceğim ve oradan nasıl gittiğini göreceğim.

İşte Github Sorununun bir bağlantısı: github.com/docker/docker/issues/13762

Yanıtlar:


1

Ayrıca iptables kurulumunda daha fazla bakmak zorunda kalabilirsiniz. Docker, konteyner alt ağından kaynaklanan tüm trafiği (ör. 172.17.0.0/16) 0.0.0.0'a maskeler. Çalıştırırsanız iptables -L -n -t nat, bunu yapan nat tablosunun altında POSTROUTING zincirini görebilirsiniz.

Zincir POSTROUTING (politika KABUL)
hedef koruma tercih kaynak hedef
MASQUERADE tümü - 172.17.0.0/16 0.0.0.0/0

Şimdi, bu kuralı kaldırabilir ve kapsayıcıların alt ağından ikinci arabiriminizin IP'sine (192.168.1.2) gelen tüm trafiği maskeleyen bir kuralla değiştirebilirsiniz, böylece istediğiniz gibi. Silme kuralı, POSTROUTING zinciri altındaki ilk kural olduğunu varsayarsak -

iptables -t nat -D POSTROUTING 1

Ardından bu özel kuralı eklersiniz -

iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -j SNAT - kaynağa 192.168.1.2

Aslında bunu çıkış arayüzüne maskeliyor. Bu hedef kısım, kaynak alt ağdan herhangi bir hedefe giden trafiğin maskeleneceğini söylüyor.
Matt

Ne yazık ki bu işe yaramadı. Benim tam süreç çalıştırmak oldu: ip rule add from 172.17.0.0/16 table docker ip route add default via 192.168.1.2 dev eth1 table docker ip route flush cache iptables -t nat -D POSTROUTING 1 iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -j SNAT --to-source 192.168.1.2 /etc/init.d/docker restart. Sonra bir konteynerden ping out ve traceroute çalıştırmaya çalıştım ve hiçbir şeye ulaşamadım.

Benzer bir gereksinimim vardı, ana bilgisayar genel bir IP'ye ulaşmak için ikincil ip kurulumuna sahip. Docker konteynerinin de aynısını takip etmesini istedim. Bu, bu durumda çalıştı: "iptables -t nat -I POSTROUTING 1 -s 172.17.0.0/16 -d PUBIP / 32 -j SNAT - kaynağa SECONDARYIP"
Ram

1

Bir arkadaşım ve ben, docker'ın birden fazla ağ arayüzüne servis taleplerini desteklemesini istediğimiz bu problemle karşılaştık. Ek arayüzleri de taktığımız / yapılandırdığımız / getirdiğimiz AWS EC2 hizmeti ile özel olarak çalışıyorduk. Bu projede , ihtiyacınız olandan daha fazlası var, bu yüzden sadece burada ihtiyacınız olanı dahil etmeye çalışacağım.

İlk olarak, yaptığımız şey için ayrı bir rota tablosu oluşturmaktı eth1:

ip route add default via 192.168.1.2 dev eth1 table 1001

Ardından, mangle tablosunu, gelen bazı bağlantı işaretlerini ayarlayacak şekilde yapılandırdık eth1:

iptables -t mangle -A PREROUTING -i eth1 -j MARK --set-xmark 0x1001/0xffffffff
iptables -t mangle -A PREROUTING -i eth1 -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff

Son olarak, bu kuralı, fwmarkoluşturduğumuz yeni tabloyu kullanmak üzere tüm kullanıcılara ekliyoruz .

ip rule add from all fwmark 0x1001 lookup 1001

Aşağıdaki iptableskomut bağlantı işaretini geri yükler ve ardından yönlendirme kuralının doğru yönlendirme tablosunu kullanmasına izin verir.

iptables -w -t mangle -A PREROUTING -i docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff

(Daha önce de söylediğim gibi) projemizin eth1önyükleme sırasında arayüzü eklediği / yapılandırdığı / gündeme getirdiği daha karmaşık örneğimizden bunun gerekli olduğuna inanıyorum .

Şimdi bu örnek bağlantı eth0isteklerine kadar hizmet durdurmak için olmaz docker0ama ben bunu önlemek için bir yönlendirme kuralı ekleyebilirsiniz inanıyorum.


@stuntmachine bunu denemek için bir şansınız olup olmadığını merak ediyor musunuz? Zaten kendi başınıza bir şey bulduysanız, çözümünüzü paylaşır mısınız?
williamsbdev

Merhaba @williamsbdev - eski yazı ve uzun bir atış, ama bu çözüm SO benim sorunum için de işe yarayacağını düşünüyor musunuz? stackoverflow.com/questions/51312310/…
Jolly Roger

2
Jolly Roger - Bunun sorununuzu çözeceğine inanıyorum. Geçenlerde başka bir ekibin bana bu blog yazısı hakkında sormasını sağladım (aslında burada olduğu gibi aynı çözüm) ve harika çalıştığını söylediler. williamsbdev.com/posts/docker-connection-marking
williamsbdev

0

Maskeli balo 172.17.42.1'den ziyade

 -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

Bu, bu kuralın düzgün çalışmayacağı anlamına gelir.

ip rule add from 172.17.42.1 table docker

Bunun yerine dene

ip rule add from 172.17.0.0/16 table docker

Ne yazık ki bu işe yaramadı. Kaplarım hala ana bilgisayarla aynı varsayılan ağ geçidine yönlendiriliyordu. İşte koştuğum şey: ip rule add from 172.17.0.0/16 table docker ip route add default via 192.168.1.2 dev eth1 table docker ip route flush cache /etc/init.d/docker restart Konteynerden bir traceroute koştum ve ilk atlama 192.168.1.1 olması gerektiğinde 10.1.1.1 idi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.