Nem megy a routing úgy ahogy szeretném, és nem jövök rá, hogy miért.
Az alap felállás a következő:
* van egy test01 szerver (docker host), amin létrehoztam egy docker internal network-öt, 10.241.32.0/24
* van egy test02 szerver (docker host), amin létrehoztam egy másik docker internal network-öt, 10.241.33.0/24
* mindkét szerveren elindítottam egy-egy konténert "gateway" néven, amin beállítottam wireguard-ot. ezeknek a címei az internal hálózatokon 10.241.32.11 és 10.241.33.11, plusz ezek a bridge hálózatban is benne vannak (elérik az internetet)
* ezen felül a test01 szerveren elindítottam egy busybox01-et is, 10.241.32.12 címmel, illetve a test02 szerver is, ott 10.241.33.12 címmel. Ők csak az internal hálózatokon vannak rajta.
* Elvileg mindenhol beállítottam a route-okat, de a két busybox nem látja egymást, illetve a busybox-ok nem érik a távoli gatweway-eket se.
Móricka rajz:
busybox01 <--> 10.241.32.0/24 <--> gateway01 <--> wireguard <--> gateway02 <--> busybox02
A végső cél az lenne, hogy a test01 és test02 gépeken indítsak különféle konténereket az internal hálózatokon, és ez a konténerek elérjék egymást a gateway-eken keresztül.
A gateway01 és gateway02 ezekkel a beállításokkal van indítva:
-v /lib/modules:/lib/modules \
--sysctl="net.ipv4.conf.all.src_valid_mark=1" \
--sysctl="net.ipv4.ip_forward=1" \
--cap-add=NET_ADMIN
Amennyire én tudom, ennek elégnek kellene lennie ahhoz, hogy gateway-ként működjön.
Ami már működik: a gateway01 és a gateway02 -őn működik a wireguard kapcsolat, és ők látják egymást.
0ba58a4b5cfc:/config# ip a | grep 10.241
inet 10.241.32.11/24 brd 10.241.32.255 scope global eth0
0ba58a4b5cfc:/config# ping -c 1 10.241.33.11
PING 10.241.33.11 (10.241.33.11) 56(84) bytes of data.
64 bytes from 10.241.33.11: icmp_seq=1 ttl=64 time=22.2 ms
--- 10.241.33.11 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 22.161/22.161/22.161/0.000 ms
0ba58a4b5cfc:/config#
2bc76d2071c6:/config# ip a | grep 10.241
inet 10.241.33.11/24 brd 10.241.33.255 scope global eth0
2bc76d2071c6:/config# ping -c 1 10.241.32.11
PING 10.241.32.11 (10.241.32.11) 56(84) bytes of data.
64 bytes from 10.241.32.11: icmp_seq=1 ttl=64 time=22.3 ms
--- 10.241.32.11 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 22.337/22.337/22.337/0.000 ms
2bc76d2071c6:/config#
A wireguard így néz ki rajtuk (a nyilvános címeket lecseréltem x.y.z.w -re):
0ba58a4b5cfc:/config# wg show
interface: grimdam
public key: aICWm8W3nJfE7Y/y3ghGHp1GEkBEoCuc0ymodNUh6EA=
private key: (hidden)
listening port: 51820
peer: z9XEpgLuNPOfP+0VmubixYd3sqiadpZwfa9ui1Gf8Vk=
endpoint: x.y.z.w:51820
allowed ips: 10.241.33.0/24
latest handshake: 1 minute, 30 seconds ago
transfer: 4.63 KiB received, 4.38 KiB sent
persistent keepalive: every 5 seconds
0ba58a4b5cfc:/config#
2bc76d2071c6:/config# wg show
interface: grimdam
public key: z9XEpgLuNPOfP+0VmubixYd3sqiadpZwfa9ui1Gf8Vk=
private key: (hidden)
listening port: 51820
peer: aICWm8W3nJfE7Y/y3ghGHp1GEkBEoCuc0ymodNUh6EA=
endpoint: x.y.z.w:51820
allowed ips: 10.241.32.0/24
latest handshake: 1 minute, 33 seconds ago
transfer: 4.26 KiB received, 4.66 KiB sent
persistent keepalive: every 5 seconds
2bc76d2071c6:/config#
Hogy kizárjam a tűzfal beállítási hibalehetőségeket, egy forward accept all rule-t adtam hozzá mindkét oldalon. Alább látható a két konténer iptables-save kimenetei. A nat részt nem én adtam hozzá, hanem a docker magától, amit én adtam hozzá az a -A FORWARD -j ACCEPT.
# Generated by iptables-save v1.8.10 (nf_tables) on Sun Feb 25 19:26:57 2024
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A FORWARD -p icmp -j ACCEPT
-A FORWARD -j ACCEPT
COMMIT
# Completed on Sun Feb 25 19:26:57 2024
# Generated by iptables-save v1.8.10 (nf_tables) on Sun Feb 25 19:26:57 2024
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:DOCKER_OUTPUT - [0:0]
:DOCKER_POSTROUTING - [0:0]
-A OUTPUT -d 127.0.0.11/32 -j DOCKER_OUTPUT
-A POSTROUTING -d 127.0.0.11/32 -j DOCKER_POSTROUTING
-A DOCKER_OUTPUT -d 127.0.0.11/32 -p tcp -m tcp --dport 53 -j DNAT --to-destination 127.0.0.11:43875
-A DOCKER_OUTPUT -d 127.0.0.11/32 -p udp -m udp --dport 53 -j DNAT --to-destination 127.0.0.11:44004
-A DOCKER_POSTROUTING -s 127.0.0.11/32 -p tcp -m tcp --sport 43875 -j SNAT --to-source :53
-A DOCKER_POSTROUTING -s 127.0.0.11/32 -p udp -m udp --sport 44004 -j SNAT --to-source :53
COMMIT
# Completed on Sun Feb 25 19:26:57 2024
# Generated by iptables-save v1.8.10 (nf_tables) on Sun Feb 25 19:27:02 2024
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A FORWARD -p icmp -j ACCEPT
-A FORWARD -j ACCEPT
COMMIT
# Completed on Sun Feb 25 19:27:02 2024
# Generated by iptables-save v1.8.10 (nf_tables) on Sun Feb 25 19:27:02 2024
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:DOCKER_OUTPUT - [0:0]
:DOCKER_POSTROUTING - [0:0]
-A OUTPUT -d 127.0.0.11/32 -j DOCKER_OUTPUT
-A POSTROUTING -d 127.0.0.11/32 -j DOCKER_POSTROUTING
-A DOCKER_OUTPUT -d 127.0.0.11/32 -p tcp -m tcp --dport 53 -j DNAT --to-destination 127.0.0.11:36441
-A DOCKER_OUTPUT -d 127.0.0.11/32 -p udp -m udp --dport 53 -j DNAT --to-destination 127.0.0.11:42835
-A DOCKER_POSTROUTING -s 127.0.0.11/32 -p tcp -m tcp --sport 36441 -j SNAT --to-source :53
-A DOCKER_POSTROUTING -s 127.0.0.11/32 -p udp -m udp --sport 42835 -j SNAT --to-source :53
COMMIT
# Completed on Sun Feb 25 19:27:02 2024
A route-ok a következők:
0ba58a4b5cfc:/config# ip route
default via 172.17.0.1 dev eth1
10.241.32.0/24 dev eth0 proto kernel scope link src 10.241.32.11
10.241.33.0/24 dev grimdam scope link src 10.241.32.11
172.17.0.0/16 dev eth1 proto kernel scope link src 172.17.0.2
2bc76d2071c6:/config# ip route
default via 172.17.0.1 dev eth1
10.241.32.0/24 dev grimdam scope link src 10.241.33.11
10.241.33.0/24 dev eth0 proto kernel scope link src 10.241.33.11
172.17.0.0/16 dev eth1 proto kernel scope link src 172.17.0.2
A wireguard interface neve mindkét oldalon "grimdam", és a két gateway erre route-olja a másol oldal privát hálózatát.
Eddig minden szép és jó. Ezek után elindítok egy busybox-ot a test01 (docker host) gépen úgy, hogy a címe 10.241.32.12, és a gateway01-el azonos internal docker hálózaton van, és hozzáadom a következő static route-ot:
ip route add 10.241.32.0/20 via 10.241.32.11
Ezután próbálom elérni a vele azonos gépen levő gateway-t (10.241.32.11) és a távoli oldalon levőt is (10.241.33.11), és a következőt látom:
/ # ip route
10.241.32.0/24 dev eth0 scope link src 10.241.32.12
10.241.32.0/20 via 10.241.32.11 dev eth0
/ # ping -c 1 10.241.32.11
PING 10.241.32.11 (10.241.32.11): 56 data bytes
64 bytes from 10.241.32.11: seq=0 ttl=64 time=0.182 ms
--- 10.241.32.11 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.182/0.182/0.182 ms
/ # ping -c 1 10.241.33.11
PING 10.241.33.11 (10.241.33.11): 56 data bytes
^C
--- 10.241.33.11 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
/ #
Tehát a "közeli" gateway01-el van kapcsolat, és a gateway01-nek is van kapcsolata a gateway02-vel. Viszont a busybox01-nek nincs kapcsolata a gateway02-vel.
Ha traceroute-ot próbálok, akkor a gateway01 nem küld vissza ICMP-t:
/ # traceroute 10.241.33.11
traceroute to 10.241.33.11 (10.241.33.11), 30 hops max, 46 byte packets
1 * * *
2 * * *
Mivel a gateway01 nem jelenik meg a traceroute-ban, ezért azt sejtem, hogy a gateway-nél rontottam el valamit, de nem jövök rá, hogy mit.
Mit rontottam el? A route-ok a rosszak, vagy a tűzfal szabályok, vagy valamilyen sysctl-t felejtettem el?
Köszönöm!
Hozzászólások
válaszdzsípítí:
Az általad leírt konfiguráció alapján a hálózati beállítások rendben vannak, és valószínűleg a tűzfal szabályok okozhatják a problémát. Az iptables konfiguráció alapján mindkét gateway-en elvileg megengedted az összes forgalmat a FORWARD chain-ben.
Azonban az látszik, hogy a Docker által generált szabályok futnak a nat table-ben, ami átírja a csomagokat, mielőtt azok elérnék az iptables által definiált saját szabályokat. Ez a DOCKER_POSTROUTING chain-ben történik.
A probléma megoldása érdekében próbáld meg hozzáadni a következő szabályokat az iptables-re, hogy megakadályozd a Docker által generált nat szabályok futtatását a specific IP címekre:
Ezek a szabályok megakadályozzák, hogy a Docker nat-olja az IP címeket a saját hálózatok között. Próbáld meg ezeket a szabályokat hozzáadni mindkét gateway-en, majd próbáld újra a kapcsolatot a busybox-ok között. Ez segíthet megoldani a problémát.
Szia!
Ebből ilyen lett:
Ez így sajnos nem működik.
Észrevételek:
* Ahogy így írtad, nem a DOCKER_POSTROUTING chain-be szúrja be, hanem a POSTROUTING-ba. Ezt így gondoltad?
* A grimdam nevű wireguard interface-nek nincsen IP címe. A MASQUERADE honnan venné a címet?
* Végül de nem utolsó sorban, én **nem akarok** masquerade-et használni az internal network-ök között. Bár ezt így külön nem írtam le a fórum indító bejegyzésben, de az ellenkezőjét se.
Azt szeretném, hogy a két oldal között a csomagok "simán" lennének route-olva, és minden csomagnál az eredeti forrás és célcím jelenne meg. A MASQUERADE azért nem jó, mert az internal hálózatokon olyan szolgáltatások lesznek, amiknél jogot is kell szabályozni IP cím alapján, plusz a napló file-okban is szeretném ha megjelennének a távoli oldal IP címei. Ezért nem jó lenne, ha egy NAT szabály átírná őket.
Szóval az eredeti "gyári" iptables-ben volt ez a sor:
Ha a célcím nem a 127.0.0.11/32 -ben van, hanem a 10.241.32.0/20-ban akkor nem is megy át a DOCKER_POSTROUTING -ba, és akkor nincs SNAT.
Ezen felül DNAT sincs, a másik szabály miatt:
Ezek alapján nincsen se DNAT se SNAT az "alap", módosítás nélküli szabályokkal, így is mennie kellene. Nem értem. :-(
Az a /20 a 32-t és a 33-at is fedi. Eleve nem tudom, honnan jön a 20, mikor végig 24-es hálózatokkal dolgoztál, de az biztos, hogy itt csak a túl oldalnak kéne lenni. Nem vagyok benne biztos, hogy ez s baj, mert a hibás bejegyzés ellenére, lehet, hogy a connected hálózat miatt nem kavarja el a routeot (specifikusabb mask), de gyanúsan nem ezt akartad irni.
Igen, fedi. Onnan jön a /20, hogy a további célok között szerepel további wireguard peer-ek hozzákapcsolása. A távoli internal network-ök mind ebben a /20-ban vannak; és nem egyesével akarom őket route-olgatni, hanem egyben (prefix based routing). A helyi internal hálózat route-ja pedig valóban specifikusabb, ezért abba nem kavarhat bele (és nem is kavar, az a része jól megy).
Illetve ez fejből nincs meg, de szerintem a forwardot a konténer network namespaceben (magyarán odabent iptablessal) kellene engedni. Vagy legalábbis ott is. Bár tippre accept a default.
Erről szólt az első kódblokk az első post-omban...
Nem egészen. Az első blokk bekapcsolja a forwardingot, meg megengedi neki, hogy piszkálja a network beállításokat. Külön írtad, hogy " amit én adtam hozzá az a -A FORWARD -j ACCEPT."
Na, ennek szerintem a konténer network namespaceében kellene lenni, nem (vagy nem csak) a hostéban. Más kérdés, hogy a default valószínűleg ACCEPT, tehát valójában jó eséllyel nem kell.
De ezt NEM a host-hoz adtam hozzá, hanem a konténerhez.
Ah, akkor félreértettem. Úgy emlékeztem, hogy azt a sok dockeres chaint kintre teszi csak a docker, ezért azt hittem, az iptables-save kintről van.
Debugolásnál elfelejteném a wireguardot. Amire neked kell itt, arra felhúznék egy sima UDP tunnelt socat-al, ha azzal megy akkor lehet haladni a wireguard debugolásával.
A másik amit kipróbálnék, hogy Docker helyett veth-ekkel és net namespacekkel reprodukálnám az egészet. Így tuti nincs semmi NAT meg tűzfal szabály ami félreviheti a dolgot.
Amit hiányolok még, az bármiféle packet capture. ICMP-s pingelős debugolás helyett TCP vagy UDP forgalommal (netcat pl.) próbálkoznék és figyelném wiresharkba meddig jut el. Ennél a setupnál nem valószínű, de nekem nagyon sokszor volt hogy vswitch-ek rosszul konfigurált hálókártyák elrontották az UDP checksumot és a cél gép (esetedben gw2) dobta el a csomagot, a routinggal meg minden rendben volt.
Az gondolom, hogy ha gw2 dobná el, akkor a traceroute kimenetében a gw1-nek meg kellett volna jelennie.
Jól gondolom, hogy wireshark csak akkor fog menni, ha wireguard helyett sima UDP-t próbálok?
Akkor ez munkás lesz. :-(
Ja nem, wireshark ICMP-vel is menni fog, protokolltól független. Annyi, hogy ha WG vagy más tunnel interfészen tap-elsz, akkor látod majd az ICMP-t, ha meg a docker interfészeken vagy bridge-n tap-elsz, akkor valami tunnelezett csomagok látszanak majd rajta (szerintem UDP-t használ a WG is)
Nem. Nyilván attól függően, hogy hol futtatod, fog látszani, hogy "hol veszik el", és a host interfacen már a tunnel packeteket kell lásd, de az kb mindegy, úgyis arra vagy kíváncsi első körben, hogy hol akad meg.
(És a wireshark elég ott, ahol nézegeted, capturera a jó öreg tcpdump elég, szóval nem ügy a konténerben futtatni.)
Annyit fűzék hozzá, hogy tcpdumpban az alap buffer túl nagy kis ICMP csomagoknál 100+ kell hogy azokat kiírja képernyőre interaktív módban (ha eleve file az output, akkor mindegy).
Valamint akkor is ha egyébként megy a DNS lookup a konténerben, érdemes -n kapcsolót használni, name lookup ha nem megy annak nagy a timeoutja és megfoghatja az outputot.
én csuklóból kb a "-penni any -s 0"-t szoktam írni (bár asszem az -s 0 már nem azt csinálja, amit gondoltam :) )
A két "világ" között nem a vpn tunnel a wireguard lenne az átjáró? Nem kellene azt is megadni mint routing?
A gateway01-en meg van adva:
A gateway02-őn is:
A busybox01-en meg nem, mert ott nincs is olyan interface. Ott a gateway01 címe van megadva gateway-nek:
Na beállítgattam a tcpdump-okat. A busybox01 -en ha a közeli gateway01-re küldök ping-et, akkor jön válasz.
Ezzel párhuzamosan a gateway01-en ezt látom:
Minden stimmel.
Ha a busybox01-ről a gateway02-re küldök ping-et, akkor pedig ezt látom a busybox01-en:
és ezt a gateway01-en:
Az ARP-nak valószínűleg semmi köze nincs ehhez, a gateway01-en ICMP csomag egyáltalán nem látszódik.
A tcpdump kapcsolói a kroozo által javasolt "tcpdump -penni any -s 0 -w dumpfile" volt, tehát minden interface-en figyelt.
Namost nem igazán értem, hogy ha a busybox01 -en látszódik, hogy kiment az ICMP request, akkor hogy lehet az, hogy a gateway01-re nem érkezett be? A busybox01-nek összesen két interface-je van, az egyik a loopback, a másik az, amin keresztül direkt módon eléri a gateway01-et:
szóval, ha a wireshark szerint kiment az ICMP request, akkor a gateway01 gépen meg be kellett volna, hogy jöjjön. De nem jött.
Az igazából mindegy is, hogy a gateway01 gépen be van-e kapcsolva a forwarding, mert ha nincs, akkor is be kellene érkeznie a csomagnak, de egyéként:
További segítséget szeretnék kérni. Úgy látszik hogy hiába a tcpdump meg a debugolás, így se jutok előre. :-(
Megmutatod azt a teljes icmp packetet packetet mac címekkel, hogy hova próbálja küldeni?
Illetve egy "ip a" -t a gateway01ről (és esetleg a hostról, amin futnak) is.
Tényleg elég fura. Mivel a pcap befele az első, kifele meg az utolsó, ezért én arra tippelnék, ezért itt lesz még valami namespace mágia, ami megfogja azt a packetet (ha kiment, akkor a busybox01-en már átment a filtereken, és ha megjött volna a csomag, akkor látszana a gw01-en, akkor is, ha utána dobódik), vagy rossz fele routeolódik.
Csak triviáliák lecsapkodása miatt megnézed, hogy mit mondd az ip r get 10.241.33.11 ?
ICMP request:
Ebben nem látszik a MAC cím, szerintem a "-i any" miatt.
busybox gépen:
gateway01 gépen:
Ha -i eth0 -van csinálom akkor:
és a 20:0b végű mac cím megfelel annak, ami a gatway01 -en van eth01-en:
viszont a gateway01 -en továbbra se jelenik meg semmi.
Szóval L2 szinten a busybox01-en kimegy az ethernet frame, gateway01-en meg nem jön be.
Ezt mégis hogy???
Milyen típusú hálózattal vannak a konténerek bekötve a 10.241.32.0/24 subnetre?
Nekem az a gyanúm, hogy a host (mint implicit router) csak az egyes konténerek saját IP-jére menő forgalmat forwardolja oda.
Régóta vágyok én, az androidok mezonkincsére már!
Ez volt az első két dolog amit írtam a fórum tetején. :-)
* van egy test01 szerver (docker host), amin létrehoztam egy docker internal network-öt, 10.241.32.0/24
* van egy test02 szerver (docker host), amin létrehoztam egy másik docker internal network-öt, 10.241.33.0/24
Ha a pici részletek is érdekelnek, akkor test01 host gépen:
test02 host gépen:
A gateway01 és 02 így van létrehozva:
ahol a LOCAL_OPTS -ban ez található a test01 gépen:
és ez a test02 gépen:
illetve nagyon hasonló módon a busybox01 és 02 gépekre:
> Nekem az a gyanúm, hogy a host (mint implicit router) csak az egyes konténerek saját IP-jére menő forgalmat forwardolja oda.
Ez szerintem egy tévedés. A docker internal network level2 és nem level3. Nem csinál semmiféle routing-ot. A tcpdump kimenetében is látszódik, hogy a busybox01 egy ethernet frame-et ír ki az eth0 eszközre.
"Ez volt az első két dolog amit írtam a fórum tetején"
Nem teljesen, annyit írtál, hogy internal, tegnap direkt próbáltam keresni a topicban, hogy valahol szerepel-e bármelyik network driver neve említve, akkor még nem volt. Tudom, hogy a bridge lenne a default, de ilyen problémás debuggolásnál nagy "luxus" a default-okat csak úgy feltételezni, és nem leellenőrizni.
"Ez szerintem egy tévedés. ... Nem csinál semmiféle routing-ot"
Ez még bridge esetén sem teljesen biztos. Nem ismétlem el, lentebb írták, hogy hogyan: https://hup.hu/comment/3032195#comment-3032195
Létezik még egy olyan sysctl paraméter is, hogy net.bridge.bridge-nf-call-iptables ami a bridge-en átmenő L2 forgalmat átküldi iptables-en is. Ez szintén bezavarhat, érdemes leellenőrizni.
Régóta vágyok én, az androidok mezonkincsére már!
Én is így értelmezem, furcsa.
Most csak ötletelek, mert rohadtul kéne dolgozni, de rohadtul gyanús, hogy itt valami docker networking csinál mégis valami, mert mi más lenne. Ami kicsit gyanús:
Egyrészt a --internal kapcsoló leírása ezt mondja:
Amiből egy kicsit gyanús, hogy lehet, hogy ilyenkor mégsem bridge network készül?
Másrészt a bridge aszongya, hogy van egy ilyen paraméter, ami alapból true
Nem tartom teljesen lehetetlennek, hogy mivel a célcím valahova kintre esik, ezért valami mégiscsak elmasqolja a host felé azt a csomagot ilyenkor. Nem jelenik meg az a ping valamelyik host interfacen?
Driver: bridge
> Nem tartom teljesen lehetetlennek, hogy mivel a célcím valahova kintre esik, ezért valami mégiscsak elmasqolja a host felé azt a csomagot ilyenkor. Nem jelenik meg az a ping valamelyik host interfacen?
Jó ezt megnézem. De az azért mégiscsak furcsa lenne, mert a konténeren belül látszódik hogy becsomagolja egy ethernet frame-be, és úgy küldi ki az eth0-ra. Akkor ez azt jelentené, hogy a docker kiszedi az ethernet frame-ből, átírja az ip header-t, aztán visszacsomagoja egy másik ethernet frame-be. Ilyet azért csak nem csinál? :-D
> Ilyet azért csak nem csinál? :-D
Mármint érted, egy "bridge" driver-es network-be beleküldesz egy ethernet frame-et, és a docker meg kiszedi belőle, akkor ez nem is bridge. :-D
A docker biztosan nem, de hogy valójában ott ilyenkor milyen bridge interface készül, és arra nincs-e valami ostoba szabály, ami elviszi másfele... Mert ugye a docker itt valójában a rendes network stackot maszatolja csak, és lehet, hogy rosszul. Én se látom, abból, amit írtál, de most vagy ez van, vagy a tcpdump hazudik.
topicban harmadszor irom le: allowedips :) tobbszor nem fogom, majd a kollega utana nez :D
mivel allitasa szerint a WG mukodik, a wg es a masik kontenerek meg localban kommunikalnak egymassal, vajon mi lehet a hiba :)
Az, hogy nem direktben cimezve egymást láthatóan mégse tudnak kommunikálni egymással. Kicsit nézd már meg megegyszer.
meg nem tudom hogy észrevetted-e, hogy csináltam egy példa minimal working example-t ami demonstrálja a hibát, wireguard-tól teljesen függetlenül. Bárki számára elérhető néhány sor beírásával. Ha tényleg segíteni akarsz, akkor fektess bele annyi energiát, hogy begépeled azt a 8 sor kódot, és utána legyél nagyon okos, és írd meg hogy hogyan lehet javítani. Ha csak annyira vagy képes, hogy ismételgeted ugyan azokat a szavakat, akkor az nem segítség. Az valami más.
bocs, nem vagyok idoutazo :)
a tanacsom tovabbra is all, hogy ne kontenerbol probalj meg routert csinalni. vagy megfogadod, vagy nem.
Megfogadtam. Így legalább nem kell cap NET_ADMIN, és lehet konténeren belül bármilyen userrel futtatni dolgokat, nem csak root-ként.
Konkrétan a host-ra raktam wireguard-ot, és így működik minden. Ja és 5 swarm leader lett, nem kettő. De az adatbázisból továbbra se tudok több mint kettő node-ot, mert nincs rá pénz, és egy ideig nem is lesz.
Mindezektől függetlenül még mindig nem értem, hogy miért nem megy, de lehet hogy elengedem.
Default docker bridge működés az következőképp néz ki nagyvonalakban:
1. Csinál egy bridge-t, pl. docker0 néven
2. Erre rárak egy címet (igen, a bridge-re) pl. 172.17.0.1/16. Ez lesz default gateway minden konténernek + kapnak egy címet az ehhez tartozó subnetből
3. Szintén rákerül NAT szabály docker0-ra, hogy a konténerek egymáson kívül mást IP-ket is láthassanak
Innentől megoldott konténerek egymás közti kommunikációja, mindenki egy ütközési tartományban van. Ha nem az alhálózaton belüli IP a cél cím, abban az esetben is a bridge-hez kerül a csomag, de (ha systcl ip_forward be van kapcsolva) felkerül az IP protocol handlerjének (hiszen van címe) ahol routeolva majd NAT-olva lesz. Innen a POSTROUTING chain, ahol nem a veth lesz a feladó interfész már, hanem a docker0. Magyarán de, pont ez történik, új ethernet frame generálódik, a docker0 IP címével (source IP). Destination cím marad az eredeti, akinek a konténer küldi a csomagot.
+ port expose eseten ezt hasznalja (by default iptables NAT szabalyokkal, amit redeploy/stb-kor ujra is kreal szepen) https://docs.docker.com/engine/reference/run/#exposed-ports
https://docs.docker.com/network/network-tutorial-standalone/#use-the-de…
illetve megnézed azt az iptablest nftablessal is? az iptables-save kimenetéből látszik, hogy valójában az van, lehet, hogy a docker is azt buzizza direktben (nem tudom, tart-e már itt a tudomány), és simán lehet, hogy valami nem látszik a legacy wrapperben
A teljesség kedvéért a busybox01-en ez a teljes routing tábla:
Ez pedig az iptables:
Az egyetlen OUTPUT és POSTROUTING szabályban -d 127.0.0.11/32 szerepel, tehát a 10.241.32.0/20 felé menő csomagokra nincs külön rule, az alapértelmezett OUTPUT ACCEPT és INPUT ACCEPT érvényesül.
wireguard allowedips? verd bele a tavoli oldal routeolando /24-eit is a peer reszbe.
A tcpdump alapján bátran állíthatjuk, hogy a csomag el se jut a gatway gépig. Innentől kezdve mindegy is, hogy jól van-e a wireguard beállítva (vagy hogy van-e egyáltalán).
attol meg kelleni fog az bele, az, hogy kontener nem kontener, mas teszta.
Ezt irod:
A busybox01 -en ha a közeli gateway01-re küldök ping-et, akkor jön válasz.
innentol wireguard. mondom rakd bele az allowedIPs-be a halozatot...
Kicsit bővebben kifejtenéd, hogy melyik konténerbe melyik hálózatot? :-) Ilyen szavakkal, hogy gateway01, gateway02, busybox01, busybox02 és a hálózati címet is légyszi. Ez van annyira összetett, hogy a a "rakd bele a hálózatot" kifejezést félre lehessen érteni.
nezd meg a linken a "rajzot", teljesen egyertelmu mit hova kell beletenned. te pont ezt akarod elerni (site2site vpn routeolva, csak kontenerekkel, de ez addig irrelevans, mig a WG-ban nem engeded a forgalmat)...
elso korben ertsd meg a halozati topologiat es a WG site2site-ot hogyan kell felepiteni.
en pl. nem raknam kontenerbe a WG-ot, mert minek, teljesen jo helyen van a hoston is. sot, normalis esetben a hostodon csak belso halo van, a routing/NAT-ot meg elotte lako eszkozon intezed (tisztabb, szarazabb, biztonsagosabb erzes).
a pub ip-ket igyis ugyis bele kell verned, innentol meg az, hogy kontener konfigba vered bele vagy a hoston, tokmindegy. cserebe nem szivat meg a containerd a sajat tuzfal mokolasaval es a WG-t se konfigolja felre kesobbiekben a csodalatos kontenert letrehozo "magic" ha tobb peer-t szeretnel. (lasd tobb peer/allowedips vs. konteneres WG).
es ilyen mokolasok sem kellenek pl, mint localhost egyik portjat NATolgatni egy masik portjara :D
Azért az függ attól, hogy milyen a provisioning infrastruktúrád :)
aki kezzel mokol kontenerben WG site2site-ot, annak nincs provisioningje. :D normal esetben ezt a SDN intezi, nem rakosgatod bele kontenerekbe :) ahogy normal esetben a docker hostnak sincs pub. ip-je.
Ne viccelj már, attól, hogy valaki nem tett oda egy full blown SDNt, meg nem kell neki k8s cluster, és inkább reszel valamit, mert nem akar behúzni egy bazi nagy stacket valamiért, aminek csak egy kis darabja kell, attól még simán lehetnek eszközei. És simán lehet, hogy arra pont van, hogy konfigostol terítsen konténert, arra meg, hogy dinamikusan basztatott konfig függjön ezektől, arra meg nincs.
nem viccelek. probalj meg ertelmesen ACL-ezni source IP/networkre egy pub ip-re expose-olt portot dokker eseten iptables-szel. csak elotte keszitsd elo a hanyos vedret :D
Mi köze ennek a provisioning meglétéhez? Mindegy, engedjük el ezt a szálat, kivételesen van egy topic, amiben nagyrészt szakma van :)
ha nem erdekel, ne kerdezz :) (az a koze, hogy nincs network provisioning es ezert kontenerben megy a hakkimakki :))
BTW itt pontosan erről van szó. Minimális HA -t kell csinálnom a projekt végére, és az is elvárás, hogy a HA lábai különböző szolgáltatóknál legyenek. Tehát lesz egy bérelt szerver X szolgáltatónál, egy másik az Y szolgáltatónál, és egy backup szerver meg a cégnél on premise. Ezek között lesznek szétosztva a szoftver komponensek konténerekben. Egyrészt a szolgáltató függetlenség, és a (részben) on premise telepítés miatt nem hiszem, hogy tudnék kész SDN megoldást használni. (De ha valaki tud ilyet, akkor írjátok meg.)
Másrészt itt nem lehet túl sok jogot állítani hálózati szinten, mert erre alig van igény. Arra van igény, hogy a szoftver komponensek VPN mögött legyenek, és hogy aminek nem muszáj, az ne lássa az internetet. Meg arra is van igény, hogy több különböző datacenter-ben is lehessen őket futtatni, amik lehetőleg különböző szolgáltatónál vannak. De arra **szinte** semmi szükség nincsen, hogy az egyik komponens ne lássa a másikat valamilyen business logic alapján.
> És simán lehet, hogy arra pont van, hogy konfigostol terítsen konténert, arra meg, hogy dinamikusan basztatott konfig függjön ezektől, arra meg nincs.
Ez pontosan így van. Azért kell a szolgáltató függetlenség, meg a több datacenter-ben való működés, hogy magasabb legyen a rendelkezésre állás. Meg ha valami elromlik (vagy mondjuk az egyik szolgáltatóval jogi vita támad), akkor ne álljon le minden.
es ennek mi koze ahhoz, hogy a docker hoston konfigolsz fel egy vpn-t vagy egy kontenerbe erolteted be? mi valtozik meg attol, hogy docker inditja a daemont (azon kivul, hogy a docker szepen meg*ja a halozatot meg ez melle)? mitol lesz nagyobb a rendelkezesedre allasod? hogyan zarja/nem zarja ki, hogy valakivel jogvitaba kerulsz? hogyan viszed at masik bergepre a pub ip-t/kulcsparokat amit beleversz a kontenerbe, stb stb stb... :D
ertem en, hogy kalapacsod van, ezert mindent azzal akarsz megoldani :)
"aminek nem muszáj, az ne lássa az internetet" > akkor ne expose-old a portot pub ip-s docker hoston :) nem mintha nem pont ezt irtam volna picit feljebb.
meg most van lehetoseged elengedni a hakkolast es a docker hostok ele tenni egy minimal VPN/routert (1-5 EUR/ho kb?), a docker hostnak nem adni pub ip-t es rendesen megtervezni/felepiteni a halozatot. :)
es a ket host-os HA-t most felejtsd el, ha jot akarsz magadnak. (min. 3, mindig paratlan, stb...), mert az nem HA lesz, hanem HAHA, amikor majd kezzel babusgatod a split brainedet.
Hát ez nagyon konstruktív volt, köszi! :-D
Mondjuk ebben azért akad igazság erősen.
Viszont tulajdonképp miért nem futsz egy kört a docker swarmmal? az overlay network megcsinálja neked az encryptelt tunnelt, nem kell semmi varázslat.
Használtam már swarm-ot, és lehet hogy most is kipróbálom.
De ennek a routing problémának már akkor is utána akarok járni, ha nem fogom használni semmire. Nem akarom feladni, szeretném tudni, hogy hol a hiba.
Az engem is érdekel, biztos, hogy nem megoldhatatlan, mert csináltunk mi már ilyet anno. :)
De ha tényleg csak az overlay kell, akkor annak simán lehet létjogosultsága. Élesben sose láttam, de egész jó lightweightnek tűnt nem annyira bonyás dolgokra, csak hát a k8s lett a defakto. Mondjuk annak is lehet értelme, hogy megnézz mondjuk egy k3s-t.
ja, és a két nodeos HAt tényleg ne erőltesd, ha nem muszáj. Én kénytelen voltam mostanában olvasni, bármi, ami slightly is modern, az mind valamilyen consensus algoritmusra épít, szóval min 3 láb. Ha tényleg két node kell, akkor lehet menni vissza
a balettba ugrálniszopni a cronosync, pacemaker, heartbeat, keepalived földére.PostgreSQL streaming replication + manual failover a terv. Ez éppen csak annyira HA, hogy ha a primary postgres tönkremegy, akkor néhány percen belül egy parancs kiadásával (manuálisan) helyre lehet hozni. Annyira nagy HA-ra nincsen szükség, mint egy banknál. Néhány 10 perc leállás belefér. Talán még egy óra is. Fél napos viszont nem. Ebben a konkrét felállásban nem létezik olyan hogy "split brain", és az sem számít, ha páros számú node van. Nem mellesleg ezzel van személyes tapasztalatom, pontosan tudom hogy milyen hibák lehetnek, és hogy melyiket hogyan kell kezelni.
Egyébként meg nem erőltetem a két node-os HA-t. Lehet három vagy négy is, mindenesetre indulásnak kettő lesz. Ebben a döntésben nem csak technikai szempontokat kellett figyelembe venni, hanem pénzügyi kockázatot és más dolgokat.
Egyébként én is gondoltam arra (is), hogy bérelt VPN mögé teszem a docker host -okat, és hogy azokon csak belső privát háló van. Csak hát ez ugye nem valósítható meg úgy, hogy összesen két szerver (docker host) van, amiknek ráadásul különböző szolgáltatónál kell lenniük. Ez nem opció. Ez a sok elvárás eléggé bekorlátozza a lehetőségeket.
Ja és most jöhetnek újra azok a hozzászólások amik leszólják az egész elképzelést, meg a szándékaimat, meg mindent amit csak lehet. De ez a fórum téma nem ezekről akart szólni, hanem routing-ról. :-)
szivesen, lejjebb kb. mindennel egyetertettetek, amit leirtam :)
HA-rol beszelsz, de nem azt csinalsz. a manual failover nem HA, az annyia "A", amennyire available vagy (vagy akit ezzel megsziva...ize..biztal) attol a minutumtol szamitva, hogy at kell konfigolni a rendszert a replica DB-re...
A db átkonfigolás az egyetlen parancs (repmgr standby switchover), az alkalmazás többi részét meg megyáltalán nem kell átkonfigurálni, de még újraindítani se. Ezt persze te nem tudhatod (honnan is tudhatnád?), de mégis úgy tűnik, mintha mindent is tudnál, és mindenkinél jobban.
mar vartam a szemelyeskedest :) nem az egy parancs a kerdes, hanem az availabiliy, mikor nyaralni vagy es fekszel az aszonyon mikozben bejott a mail/hivas, hogy megallt a pg, ki kellene adni :)
-- jó ez a spamszűrő, valami fura helyre vitt, nem láttam a hozzászólásom, visszamentem, hogy beküldjem még egyszer, szólt, hogy várjak, ráfrissítek a másik tabon a topicra, rohadtul nincs ott, újraküldöm, dupla --
Húú, ez most nagyon kusza :D
Ami eddig tiszta:
Van 2db szerver (test01, test02) és azokon futtatod docker-ben a VM-et (gateway01,gateway02),
azt akarod hogy a 2db szerveren futó dockerek lássák egymást majd a (gateway01, gateway02) keresztűl.
Itt kezdődik pár kérdés ami a fenti leírásból nem derül ki:
"gateway01,gateway02" -ben hogy van/lesz összekötve a többi "lokális" docker VM?
pl.:
br0 - (L2 mode: bridge, ipvlan interface)
Mutatok egy példát, akkor megérted szerintem, hol rontod el.
> Itt kezdődik pár kérdés ami a fenti leírásból nem derül ki: "gateway01,gateway02" -ben hogy van/lesz összekötve a többi "lokális" docker VM?
Szerintem meg kiderül. A legelső dolog amit leírtam a post tetején az volt, hogy
Tehát úgy vannak összekötve, hogy minden konténer azonos --network -öt használ.
Én nem ipvlan driver-t használtam, hanem a defaultot, ami a bridge. Azért nem írtam ki a driver típusát, mert ez a default. A bridge driver-nek is jónak kellene lennie. Az ipvlan -ra akkor lenne szükség, ha vlan-okat is szeretnék rajta használni, de azt nem akarok. Milyen más előnye van az ipvlan-nak ebben a konkrét esetben?
De ha úgy gondolod hogy ez segíthet, akkor ki fogom próbálni ipvlan -nal is. De ezen felül meg is szeretném érteni, hogy miért. :-)
Nem szeretném, ha ez lenne a default route, de ez mondjuk részletkérdés.
> Mutatok egy példát, akkor megérted szerintem, hol rontod el.
Sajnos a példából nem értettem meg. :-( Kifejtenéd?
Összekötést ne a docker-féle fogalmakkal akard értelmezni, hanem az OSI-féle modellben gondolkodj.
HOST = server1, server2
Tehát, OSI féle modllben, hogy akarod összekötni a docker féle VM-ket (internal-network)?
1., HOST-on keresztűl OSI L3 mód ( iptables segítségével )
2., HOST-on keresztűl OSI L2 mód ( iptables nélkül )
Másodszor, OSI féle modllben, hogy akarod összekötni a docker féle VM-ket( gateway1, gateway2) a "külső hálózattal (internet)"?
1., HOST-on keresztűl OSI L3 mód ( iptables segítségével )
2., HOST-on keresztűl OSI L2 mód ( iptables nélkül )
A fentiek leírása alapján ez nem derül ki sehonnan, addig nem fog tudni segíteni itt senki.
Ezt a részt elírtam, MACVLAN kell ( IPVLAN az más probléma megoldásához való).
Egyiknek sincs köze a VLAN-hoz, MACVLAN a "valódi" bridge, ez egy későbbi fejlesztés a LINUX-nál ( korábban csak a VETH párokkal és a HOST-n lévő iptables szabályok használatával együtt lehetett megoldani docker-VM összekötését a "külső hálózattal").
MACVLAN lehetővé teszi, hogy a HOST-gép iptables használata nélkül kösd össze a "külső hálózattal" ( OSI L2 szint ).
Itt van egy leírás (ezt folyamatosan frissítik):
https://developers.redhat.com/blog/2018/10/22/introduction-to-linux-int…
> Tehát, OSI féle modllben, hogy akarod összekötni a docker féle VM-ket (internal-network)?
> 1., HOST-on keresztűl OSI L3 mód ( iptables segítségével )
> 2., HOST-on keresztűl OSI L2 mód ( iptables nélkül )
> Másodszor, OSI féle modllben, hogy akarod összekötni a docker féle VM-ket( gateway1, gateway2) a "külső hálózattal (internet)"?
> A fentiek leírása alapján ez nem derül ki sehonnan, addig nem fog tudni segíteni itt senki.
De ezek egzakt módon kiderülnek, mivel csináltam egy minimal working example-t, amiben nincsen wireguard, nincsen internet se. Összesen csak 3 konténer van benne, és egyetlen internal network. A kérdés le lett redukálva, és a "hogyan akarod" kérdésre az a válasz, hogy "git clone https://github.com/nagylzs/docker_routing_test.git" - és ebben benne van minden a hálózat típusától, a konkrét IP címektől kezdve, a routing táblán és az összes konténer beállításon keresztül minden.
Ehhez képest azt írod, hogy "nem derül ki sehonnan". Összesen 8 sor begépelésével bárki tudja a saját gépén tesztelni és demonstrálni pontosan azt a problémát, amivel szembesültem. Mégis mit tudnék még hozzá tenni?
Mégis mit tudnék még hozzá tenni? > mondjuk azt, hogy nem erted a docker/linux networkinget es az osi modellt.
Elkezdtem redukálni az egészet egy minimal working example-re. Úgy gondolom ez sokat fog segíteni a hiba megtalálásában, mert a sok gépelés helyett bárki kipróbálhatja magánál a tesztet. Egyelőre kihagytam belőle a wireguard-ot is, és egy 3 node-ból álló példát raktam össze.
Két internal network van benne:
És ez a három node:
* node01 10.241.32.12 az nw_01_02 hálózaton
* node02 10.241.32.11 és 10.241.33.11 az nw_01_02 és nw_02_03 hálózatokon
* node01 10.241.33.12 az nw_02_03 hálózaton
Az lenne az első lépés, hogy össze lehessen rakni egy olyant, hogy a node02 végzi a route-ingot a node01 és a node03 között.
Feltöltöttem ide: https://github.com/nagylzs/docker_routing_test
A teszteléshez:
Így bárki kipróbálhatja, néhány sor begépelésével.
Viszont elakadtam, mert a node02 nem indul el. Ezt adom meg neki:
és ezt kapom hibának:
amit nem értek, mivel az nw_02_03 az 10.241.33.0/24, és ebben benne van a 10.241.33.11; nem világos, hogy miért gondolja azt, hogy ez az ip cím az nw_01_02 -höz tartozik. Vagy talán az is lehet, hogy nem így kell megadni a statikus címeit, de akkor hogy? A docker dokumentációban semmit nem találtam arról, hogy hogyan lehetne azt megadni, hogy a --ip kapcsoló melyik hálózatra vonatkozik.
hint:
a "docker network connect" nem használható "docker run" -nal, csak "docker create"-tel.
hmm végülis de, ha már fut a run. Csak ez olyan izé, így nem lehet egy parancssorba beletenni :-(
Így, hogy csak a futó docker run közben lehet connect-elni a network-höz, egy nagyon minimálisan bonyolultabb:
Amit én tapasztalok az az, hogy nem megy forward, a node01 nem éri el 10.241.33.0/24-ből egyik címet se, a node03 nem éri el 10.241.32.0/24 -ből egyik címet se. A node02 -őn be van kapcsolva a forwarding, és a FORWARD chain-ben default accept van, és nincsen semmiféle forward szabály.
Minden node bridge driver-es network-kel van összekötve, és minden node bind mount-olja a saját könyvtárát a /node alá, és van rajtuk tcpdump.
Én továbbra se látom hogy hol a hiba. Ha valaki szeretne segíteni, akkor a fenti néhány sor begépelésével tudja tesztelni.
Köszönöm!