veth 쌍의 경우 ping이 인터페이스 이름을 인식하지 못하고 tc qdisc netem이 작동하지 않습니다.

veth 쌍의 경우 ping이 인터페이스 이름을 인식하지 못하고 tc qdisc netem이 작동하지 않습니다.

Ubuntu 16.04 LTS와 hwe 커널 4.13.0-39-generic이 있습니다. 다음과 같이 기본 네트워크 네임스페이스에 veth 쌍을 구성합니다.

$ sudo ip link add h1-eth0 type veth peer name h2-eth0

$ sudo ip link set dev h1-eth0 up
$ sudo ip link set dev h2-eth0 up

$ sudo ip addr add 10.0.0.1/24 dev h1-eth0
$ sudo ip addr add 10.0.0.2/24 dev h2-eth0

위 구성 후에 얻은 설정은 다음과 같습니다.

$ ifconfig
...
h1-eth0   Link encap:Ethernet  HWaddr ea:ee:1e:bb:66:55  
          inet addr:10.0.0.1  Bcast:0.0.0.0  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          ...

h2-eth0   Link encap:Ethernet  HWaddr ba:aa:99:77:ff:78  
          inet addr:10.0.0.2  Bcast:0.0.0.0  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          ...
$ ip route show
10.0.0.0/24 dev h1-eth0  proto kernel  scope link  src 10.0.0.1 
10.0.0.0/24 dev h2-eth0  proto kernel  scope link  src 10.0.0.2 
...

이제 다음과 같이 한 인터페이스에서 다른 인터페이스로 핑을 보낼 수 있습니다.

$ ping -I 10.0.0.1 -c1 10.0.0.2
PING 10.0.0.2 (10.0.0.2) from 10.0.0.1 : 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.046 ms

--- 10.0.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.046/0.046/0.046/0.000 ms

그러나 첫 번째 문제는 IP 주소 대신 인터페이스 이름을 사용하여 ping을 시도하면 ping이 실패한다는 것입니다.

$ ping -I h1-eth0 -c1 10.0.0.2
PING 10.0.0.2 (10.0.0.2) from 10.0.0.1 h1-eth0: 56(84) bytes of data.
From 10.0.0.1 icmp_seq=1 Destination Host Unreachable

--- 10.0.0.2 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

h1-eth0의 IP 주소가 10.0.0.1인 경우 이것이 어떻게 문제가 될 수 있습니까?

두 번째 질문도 관련이 있다고 생각합니다. 인터페이스를 다음과 같이 구성했습니다.

$ sudo tc qdisc add dev h1-eth0 root netem delay 60ms
$ sudo tc qdisc add dev h2-eth0 root netem delay 60ms
$ tc qdisc show 
qdisc netem 8006: dev h2-eth0 root refcnt 2 limit 1000 delay 60.0ms
qdisc netem 8005: dev h1-eth0 root refcnt 2 limit 1000 delay 60.0ms

이제 지연된 상태로 다시 핑을 보냅니다.

$ ping -I 10.0.0.1 -c4 10.0.0.2
PING 10.0.0.2 (10.0.0.2) from 10.0.0.1 : 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.033 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.034 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.059 ms
64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=0.027 ms

--- 10.0.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3063ms
rtt min/avg/max/mdev = 0.027/0.038/0.059/0.013 ms

그리고 rtt가 예상된 60ms*2=120ms가 아님을 알 수 있습니다. 그래서 tc qdisc netem이 내 인터페이스에서 작동하지 않는 것 같습니다.

전반적으로 내 구성이 어떤 방식으로든 손상되었음을 발견했습니다.

답변1

나는 아래에 내 자신의 질문에 대답합니다.

가장 간단한 해결 방법(내 방법):veth 쌍 중 하나를 다른 네트워크 네임스페이스에 넣습니다. 그냥 그렇게 부르자 test.

$ sudo ip netns add test
$ sudo ip link add h1-eth0 type veth peer name h2-eth0 netns test

$ sudo ip link set dev h1-eth0 up
$ sudo ip netns exec test ip link set dev h2-eth0 up

$ sudo ip addr add 10.0.0.1/24 dev h1-eth0
$ sudo ip netns exec test ip addr add 10.0.0.2/24 dev h2-eth0

$ sudo tc qdisc add dev h1-eth0 root netem delay 60ms
$ sudo ip netns exec test tc qdisc add dev h2-eth0 root netem delay 60ms

이제 다음을 확인합니다.

$ ping -I h1-eth0 -c1 10.0.0.2
PING 10.0.0.2 (10.0.0.2) from 10.0.0.1 h1-eth0: 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=120 ms

--- 10.0.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 120.056/120.056/120.056/0.000 ms
$ sudo ip netns exec test ping -I h2-eth0 -c1 10.0.0.1
PING 10.0.0.1 (10.0.0.1) from 10.0.0.2 h2-eth0: 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=120 ms

--- 10.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 120.146/120.146/120.146/0.000 ms

다른 방법

내 질문이 요청되었지만 아직 답변되지 않은 것을 확인했습니다.https://serverfault.com/questions/585246/network-level-of-veth-doesnt-respond-to-arp. 거기에서 문제가 ARP에 있음을 알 수 있습니다.

ARP 문제와 관련된 질문은 여기에서 확인하세요.요청된 IP 주소가 다른(비활성화된) 인터페이스와 연결된 경우 Linux는 ARP 요청 메시지에 응답하지 않습니다.스레드 시작기에 대한 설명이 있지만 문제는 해결되지 않은 상태로 남아 있습니다.

문제는 주소 10.0.0.1과 10.0.0.2가 메인 라우팅 테이블뿐만 아니라 로컬 라우팅 테이블에도 나타나며, 로컬 라우팅 테이블이 메인 라우팅 테이블보다 우선순위가 높다는 점입니다. 내 질문의 초기 설정 표는 다음과 같습니다. 즉, veth 쌍의 한쪽 끝을 다른 네트워크 네임스페이스에 넣지 않는 것입니다 test.

$ ip route show table local
broadcast 10.0.0.0 dev h1-eth0  proto kernel  scope link  src 10.0.0.1 
broadcast 10.0.0.0 dev h2-eth0  proto kernel  scope link  src 10.0.0.2 
local 10.0.0.1 dev h1-eth0  proto kernel  scope host  src 10.0.0.1 
local 10.0.0.2 dev h2-eth0  proto kernel  scope host  src 10.0.0.2 
broadcast 10.0.0.255 dev h1-eth0  proto kernel  scope link  src 10.0.0.1 
broadcast 10.0.0.255 dev h2-eth0  proto kernel  scope link  src 10.0.0.2 
...
$ ip route show table main
10.0.0.0/24 dev h1-eth0  proto kernel  scope link  src 10.0.0.1 
10.0.0.0/24 dev h2-eth0  proto kernel  scope link  src 10.0.0.2 
...

veth 쌍의 한쪽 끝이 다른 네트워크 네임스페이스에 있는 경우 두 주소를 동시에 로컬 라우팅 테이블에 넣을 수는 없습니다. 그래서 아마도 우리에게는 그런 문제가 없는 것 같습니다. 로컬 라우팅 테이블에서 주소를 제거하려고 시도했지만(하나 또는 둘 다 - 다른 조합으로) 도움이 되지 않았습니다. 전반적으로 상황을 완전히 이해하지 못하므로 veth 쌍의 끝을 다른 네트워크 네임스페이스로 설정하는 방법을 고수하겠습니다. 게다가 내가 아는 한, 이것이 veth 쌍이 사용되는 주요 방식입니다.

관련 정보