Wie richte ich eine Linux Bridge in einem Container ein?

Wie richte ich eine Linux Bridge in einem Container ein?

Ich arbeite in einem Container und versuche, eine Linux-Bridge und eine Layer-2-Verbindung zu demonstrieren.

Ich habe einen neuen Container gestartet:

host$ docker run -it --rm --name c1 --privileged networking sh

Auf dem Container habe ich Folgendes verwendet, um die Bridge-Schnittstelle und die Tap-Schnittstelle zu erstellen

c1$ ip link add br0 type bridge
c1$ ip link set eth0 master br0
c1$ ip tuntap add tap0 mode tap
c1$ ip link set tap0 master br0
c1$ ip link set tap0 up
c1$ ip link set br0 up
c1$ ping -I tap0 172.17.0.2

Der letzte Ping-Befehl funktioniert nicht. Was mache ich falsch? Ist die Tap-Schnittstelle die richtige? Wie kann ich eine Layer-2-Verbindung auf einem Container mit Linux Bridge anzeigen?

Nach der Antwort von @grawity habe ich Folgendes versucht:

ip link add dev veth1 type veth peer name veth2
ip link set dev veth1 up
ip link add br0 type bridge
ip link set veth1 master br0
ip link set eth0 master br0
ip link set br0 up
ip link set veth1 up
ip link set veth2 up
ip addr add 10.0.0.3/24 dev veth1
ip addr add 10.0.0.4/24 dev veth2
ip addr add 10.0.0.2/24 dev br0


/ # brctl show
bridge name bridge id       STP enabled interfaces
br0     8000.0242ac110002   no      veth1
                                    eth0

Ping an alle Schnittstellen funktioniert

/ # ping -c1 10.0.0.2
PING 10.0.0.2 (10.0.0.2): 56 data bytes
64 bytes from 10.0.0.2: seq=0 ttl=64 time=0.068 ms

--- 10.0.0.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.068/0.068/0.068 ms
/ # ping -c1 10.0.0.3
PING 10.0.0.3 (10.0.0.3): 56 data bytes
64 bytes from 10.0.0.3: seq=0 ttl=64 time=0.072 ms

--- 10.0.0.3 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.072/0.072/0.072 ms
/ # ping -c1 10.0.0.4
PING 10.0.0.4 (10.0.0.4): 56 data bytes
64 bytes from 10.0.0.4: seq=0 ttl=64 time=0.095 ms

--- 10.0.0.4 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.095/0.095/0.095 ms

Sowohl Ping als auch Arping funktionieren nicht von veth2 zu eth0.

ping -I veth2 -c1 172.17.0.2

IP-Link-Ausgabe

10: veth2@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000\    link/ether f2:8e:e4:f7:fc:7c brd ff:ff:ff:ff:ff:ff
11: veth1@veth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000\    link/ether 1a:3a:26:02:8a:a1 brd ff:ff:ff:ff:ff:ff
12: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000\    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
21: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default \    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0

und ip eine Ausgabe

/ # ip -o a
1: lo    inet 127.0.0.1/8 scope host lo\       valid_lft forever preferred_lft forever
1: lo    inet6 ::1/128 scope host \       valid_lft forever preferred_lft forever
10: veth2    inet 10.0.0.4/24 scope global veth2\       valid_lft forever preferred_lft forever
10: veth2    inet6 fe80::f08e:e4ff:fef7:fc7c/64 scope link \       valid_lft forever preferred_lft forever
11: veth1    inet 10.0.0.3/24 scope global veth1\       valid_lft forever preferred_lft forever
11: veth1    inet6 fe80::183a:26ff:fe02:8aa1/64 scope link \       valid_lft forever preferred_lft forever
12: br0    inet 10.0.0.2/24 scope global br0\       valid_lft forever preferred_lft forever
12: br0    inet6 fe80::42:acff:fe11:2/64 scope link \       valid_lft forever preferred_lft forever
21: eth0    inet 172.17.0.2/16 scope global eth0\       valid_lft forever preferred_lft forever
21: eth0    inet6 fe80::42:acff:fe11:2/64 scope link \       valid_lft forever preferred_lft forever

tcpdump hat folgendes

09:29:31.253321 ARP, Request who-has 6e2b9b27d81b (Broadcast) tell 10.0.0.4, length 28
09:29:31.253509 ARP, Request who-has 172.17.0.1 tell 6e2b9b27d81b, length 28
09:29:31.253541 ARP, Reply 172.17.0.1 is-at 02:42:be:d6:a7:81 (oui Unknown), length 28
09:29:31.253541 ARP, Reply 172.17.0.1 is-at 02:42:be:d6:a7:81 (oui Unknown), length 28
09:29:36.263281 ARP, Request who-has 172.17.0.1 tell 6e2b9b27d81b, length 28
09:29:36.263313 ARP, Reply 172.17.0.1 is-at 02:42:be:d6:a7:81 (oui Unknown), length 28
09:29:36.263313 ARP, Reply 172.17.0.1 is-at 02:42:be:d6:a7:81 (oui Unknown), length 28
09:29:36.268142 ARP, Request who-has 6e2b9b27d81b (Broadcast) tell 10.0.0.4, length 28
09:29:41.284187 ARP, Request who-has 6e2b9b27d81b (Broadcast) tell 10.0.0.4, length 28
09:29:41.284196 ARP, Request who-has 6e2b9b27d81b (Broadcast) tell 10.0.0.4, length 28

Was übersehe ich? Was ist 6e2b9b27d81b?

Antwort1

Erstens: Für Ihre Schnittstelle ist keine IP-Adresse konfiguriert. Sie können daher ohne Adresse keine IP-Pakete senden und empfangen. ( pingverwendet ICMP, ein IP-Protokoll.)

Zweitens: So funktionieren Tap-Schnittstellen nicht – sie „reflektieren“ die pingPakete nicht zurück in die Brücke; stattdessen erwarten sie eine Verbindung zu einemProgramm, zB OpenVPN oder andere VPN-Software.

Ihr Ansatz würde also funktionieren, wenn Sie beispielsweise versuchen würden, OpenVPN einzurichten, das mit dem Host-Netzwerk verbunden ist (und ein einzelnes Subnetz gemeinsam nutzt). Wenn Sie jedoch nur sehen möchten, wie Linux-Brücken funktionieren, haben Sie mit vethSchnittstellen mehr Erfolg.

Und wenn Sie nur eine L2-Verbindung zum externen LAN wünschen, dann erstellen Sie die Brücke an der falschen Stelle – solche Dinge werden normalerweise auf derGastgeber, nicht in einem Behälter.


Stellen Sie sich eine Netzwerkschnittstelle so vor, als hätte sie zwei Enden: Das „Host“-Ende wird im Betriebssystem angezeigt und von der gesamten Software verwendet; das andere Ende ist mit dem eigentlichen Netzwerk verbunden (z. B. ein physischer Ethernet-Port). Wenn Pakete über ein Ende eingehen, gehen sie durch dasandereEnde. (Brücken können natürlich mehrere Ports haben, nicht nur zwei, aber es gilt das gleiche allgemeine Prinzip.)

Wenn Sie eine Schnittstelle überbrücken, übernimmt die Brücke dieGastgeberSeite dieser Schnittstelle, so dass es nur Pakete sieht, die kamenausdas Netzwerk. Wenn Sie jedoch ping -I eth0oder verwenden ping -I tap0, umgehen Sie die Brücke und senden alles an das eigentliche Netzwerk.

ping ──› [eth0 ──› NIC] ──› network

ping ──› [tap0 ──› VPN software] ──› ???

               ┌─› [eth0 ──› NIC] ──› network
ping ──› br0 ──┤
               └─› [tap0 ──› VPN software] ──› ???
     ping -I tap0 ───┘

In Ihrer Situation ist die Tap-Schnittstelle also nutzlos – alle Pakete, die Sie darüber senden möchten, werden einfach verworfen, da am anderen Ende kein Programm angeschlossen ist. (Wenn Sie nachsehen, ip linkwerden Sie es wahrscheinlich mit der Flagge sehen NO-CARRIER.)

Stattdessen könnten Sie beispielsweise eine vethSchnittstelle verwenden (die gleiche Art, die Container häufig verwenden) – sie werden immer paarweise erstellt und miteinander verbunden. Wenn Sie also pingPakete über senden veth0, werden sie zurückgeschleift und kommen über die Hostseite von veth1, wo die Brücke sie empfangen und bei Bedarf über eth0 weiterleiten kann.

      ┌── [eth0 ──› NIC] ──› network
br0 ──┤
      └── [veth1 ‹───› veth0] ‹── ping -I veth0

verwandte Informationen