컨테이너 내부에 Linux 브리지를 설정하는 방법은 무엇입니까?

컨테이너 내부에 Linux 브리지를 설정하는 방법은 무엇입니까?

저는 Linux 브리지와 레이어 2 연결을 시연하려고 컨테이너 내부에서 작업하고 있습니다.

새 컨테이너를 시작했습니다.

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

컨테이너에서 다음을 사용하여 브리지 인터페이스와 탭 인터페이스를 만들었습니다.

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

마지막 ping 명령이 작동하지 않습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까 ? 탭 인터페이스가 올바른 인터페이스입니까? Linux 브리지가 있는 컨테이너에 레이어 2 연결을 어떻게 표시할 수 있나요?

@grawity 답변에 따라 다음을 시도했습니다.

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이 작동합니다.

/ # 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

ping과 arping이 모두 veth2에서 eth0까지 작동하지 않습니다.

ping -I veth2 -c1 172.17.0.2

IP 링크 출력

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

그리고 IP 출력

/ # 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에는 다음이 있습니다

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

내가 무엇을 놓치고 있나요? 무엇인가요 6e2b9b27d81b?

답변1

첫째: 인터페이스에 IP 주소가 구성되어 있지 않으므로 주소가 없으면 인터페이스를 통해 실제로 IP 패킷을 보내고 받을 수 없습니다. ( pingIP 프로토콜인 ICMP를 사용합니다.)

둘째: 그것은 탭 인터페이스가 작동하는 방식이 아닙니다. 그들은 ping패킷을 브리지로 다시 "반사"하지 않습니다. 대신 그들은 다음과 연결되기를 기대합니다.프로그램, 예: OpenVPN 또는 기타 VPN 소프트웨어.

따라서 예를 들어 호스트 네트워크에 브리지되는(단일 서브넷 공유) OpenVPN을 설정하려고 시도한 경우 접근 방식이 작동할 것입니다. 그러나 Linux 브리지가 어떻게 작동하는지 보고 싶다면 veth인터페이스를 사용하는 것이 더 나을 것입니다.

그리고 원하는 것이 외부 LAN에 대한 L2 연결뿐이라면 잘못된 위치에 브리지를 생성하는 것입니다. 이러한 작업은 일반적으로 LAN에서 수행됩니다.주인, 컨테이너에는 없습니다.


네트워크 인터페이스에는 두 개의 끝이 있다고 생각하십시오. '호스트' 끝은 OS에 표시되고 모든 소프트웨어에서 사용됩니다. 다른 쪽 끝은 실제 네트워크(예: 물리적 이더넷 포트)에 연결됩니다. 패킷이 한쪽 끝을 통해 들어오면 다음 끝을 통과합니다.다른끝. (물론 브리지에는 두 개가 아닌 여러 포트가 있을 수 있지만 동일한 일반 원칙이 적용됩니다.)

인터페이스를 브리지하면 브리지가 인터페이스를 대신합니다.주인해당 인터페이스의 측면에서 전송된 패킷만 볼 수 있습니다.~에서네트워크. 그러나 ping -I eth0또는 을 사용하면 ping -I tap0브리지를 우회하고 모든 것을 실제 네트워크로 보내는 것입니다.

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

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

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

따라서 귀하의 상황에서 탭 인터페이스는 쓸모가 없습니다. 이를 통해 보내려고 하는 모든 패킷은 다른 쪽 끝에 연결된 프로그램이 없기 때문에 폐기됩니다. (확인해 보면 ip link아마 깃발과 함께 보일 것입니다 NO-CARRIER.)

대신 예를 들어 veth인터페이스(컨테이너가 자주 사용하는 것과 동일한 종류)를 사용할 수 있습니다. 인터페이스는 항상 서로 연결된 쌍으로 생성됩니다. 따라서 ping을 통해 패킷을 보내도록 지시하면 veth0루프백되어 의 호스트 측을 통해 들어오며 veth1, 여기서 브리지는 패킷을 수신하고 필요한 경우 eth0을 통해 전달할 수 있습니다.

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

관련 정보