linux Virtual Network - Network namespace and veth

Posted by shinyo on Mon, 17 Jan 2022 01:08:31 +0100

Network namespace

Network namespace is the function of network isolation provided by linux kernel. Each namespace has its own independent network protocol stack and its own independent routing table. The implementation and isolation of Docker container network is realized through network namespace.

Operational network namespace

# add to
[root@localhost ~]# ip netns add ns1

# see
[root@localhost ~]# ip netns list
ns1

[root@localhost ~]# ip netns show
ns1

# Execute commands within a namespace
[root@localhost ~]# ip netns exec ns1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

# Enter namespace
[root@localhost ~]# ip netns exec ns1 bash

# Execute the command to view the network card information of the namespace
[root@localhost ~]# ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

# Exit namespace
[root@localhost ~]# exit
exit

# delete
[root@localhost ~]# ip netns delete ns1

FAQ

How to view the network namespace of Docker container?

The entry file provided by the default network namespace is in the / var/run/netns / directory, and the ip netns command also reads the entry file in this directory by default. Docker reassigns the directory to / var/run/docker/netns /, so if you want to use the default ip netns command to manage the network namespace of docker, you only need to make a soft link to / var/run/netns /

# The test environment uses to soft link the network namespace of the docker container to / var/run/netns / and display the container name
test -d /var/run/netns || mkdir /var/run/netns
for container in $(docker ps -a| awk '{print $NF}'| grep -v 'NAMES'); \
do \
ln -s $(docker inspect $container| grep SandboxKey| awk -F '"' '{print $4}') /var/run/netns/$container; \
done
ip netns list

veth

Virtual ethernet interface is a Virtual ethernet interface. In linux, veth is treated the same as an ordinary network card. veth always appears in pairs, which is called veth pair. We can simply understand the network cable in our real world. A network cable has two crystal heads, which is mainly used for interconnection between devices.

Operation veth

# add to
ip link add veth1 type veth peer name veth2

# see
ip add
ip link show type veth

# The default veth is down, so it needs to be up
ip link set veth1 up

# Configure ip
ip addr add 1.1.1.1/32 dev veth1

# Modify mac address
ip link set veth1 addr ee:ee:ee:ee:ee:ee

# Move veth to a different network namespace
ip netns add ns1
ip link set dev veth1 netns ns1 

# Delete: as long as either end is deleted, the entire veth pair will be deleted
ip link del veth2

Simulate the communication between two hosts and the network segment

# Topology
# The two terminals are interconnected through a network cable
# The terminal uses the network namespace to simulate

# Create two new namespaces
ip netns add ns1
ip netns add ns2

# Create a new veth pair
ip link add veth1 type veth peer name veth2

# Insert both ends of veth pair into the terminal respectively
ip link set dev veth1 netns ns1
ip link set dev veth2 netns ns2

# Configure the network card information in the terminal
ip netns exec ns1 ip addr add 10.0.12.1/24 dev veth1
ip netns exec ns1 ip link set veth1 up
ip netns exec ns2 ip addr add 10.0.12.2/24 dev veth2
ip netns exec ns2 ip link set veth2 up

# Test the interworking of two terminals
ip netns exec ns1 ping 10.0.12.2 -c 4

# View terminal network configuration
[root@localhost ~]# ip netns exec ns1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
4: veth1@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 52:6e:c4:c9:6b:75 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet 10.0.12.1/24 scope global veth1
       valid_lft forever preferred_lft forever
    inet6 fe80::506e:c4ff:fec9:6b75/64 scope link
       valid_lft forever preferred_lft forever
[root@localhost ~]# ip netns exec ns2 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3: veth2@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether d2:2c:22:bb:e4:99 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.12.2/24 scope global veth2
       valid_lft forever preferred_lft forever
    inet6 fe80::d02c:22ff:febb:e499/64 scope link
       valid_lft forever preferred_lft forever

# Communication packet capture information
[root@localhost ~]# ip netns exec ns2 tcpdump -i veth2 -ne
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth2, link-type EN10MB (Ethernet), capture size 262144 bytes
11:02:16.500486 52:6e:c4:c9:6b:75 > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 10.0.12.2 tell 10.0.12.1, length 28
11:02:16.500511 d2:2c:22:bb:e4:99 > 52:6e:c4:c9:6b:75, ethertype ARP (0x0806), length 42: Reply 10.0.12.2 is-at d2:2c:22:bb:e4:99, length 28
11:02:16.500515 52:6e:c4:c9:6b:75 > d2:2c:22:bb:e4:99, ethertype IPv4 (0x0800), length 98: 10.0.12.1 > 10.0.12.2: ICMP echo request, id 1201, seq 1, length 64
11:02:16.500538 d2:2c:22:bb:e4:99 > 52:6e:c4:c9:6b:75, ethertype IPv4 (0x0800), length 98: 10.0.12.2 > 10.0.12.1: ICMP echo reply, id 1201, seq 1, length 64
11:02:17.524159 52:6e:c4:c9:6b:75 > d2:2c:22:bb:e4:99, ethertype IPv4 (0x0800), length 98: 10.0.12.1 > 10.0.12.2: ICMP echo request, id 1201, seq 2, length 64
11:02:17.524190 d2:2c:22:bb:e4:99 > 52:6e:c4:c9:6b:75, ethertype IPv4 (0x0800), length 98: 10.0.12.2 > 10.0.12.1: ICMP echo reply, id 1201, seq 2, length 64
11:02:18.549011 52:6e:c4:c9:6b:75 > d2:2c:22:bb:e4:99, ethertype IPv4 (0x0800), length 98: 10.0.12.1 > 10.0.12.2: ICMP echo request, id 1201, seq 3, length 64
11:02:18.549041 d2:2c:22:bb:e4:99 > 52:6e:c4:c9:6b:75, ethertype IPv4 (0x0800), length 98: 10.0.12.2 > 10.0.12.1: ICMP echo reply, id 1201, seq 3, length 64
11:02:19.572310 52:6e:c4:c9:6b:75 > d2:2c:22:bb:e4:99, ethertype IPv4 (0x0800), length 98: 10.0.12.1 > 10.0.12.2: ICMP echo request, id 1201, seq 4, length 64
11:02:19.572336 d2:2c:22:bb:e4:99 > 52:6e:c4:c9:6b:75, ethertype IPv4 (0x0800), length 98: 10.0.12.2 > 10.0.12.1: ICMP echo reply, id 1201, seq 4, length 64
11:02:21.749109 d2:2c:22:bb:e4:99 > 52:6e:c4:c9:6b:75, ethertype ARP (0x0806), length 42: Request who-has 10.0.12.1 tell 10.0.12.2, length 28
11:02:21.749178 52:6e:c4:c9:6b:75 > d2:2c:22:bb:e4:99, ethertype ARP (0x0806), length 42: Reply 10.0.12.1 is-at 52:6e:c4:c9:6b:75, length 28

FAQ

There are many Veth pairs on the machine. How to determine which network namespace the other end is in

When viewing the network card configuration information by using the ip a command, you can see that there is a number at the front of the network card, which is the unique index of the network card, and then look at the network card name veth2@if4 , if4 means that the index number of the opposite end is 4.

Idea: the index number of the network card is unique in the same namespace. What does it mean? That is, if you create veth in other network namespaces and move it to another or default network namespace, it will be very confusing. Therefore, we usually create veth in the default namespace and then move it to other namespaces, which is easier to identify.

Topics: Linux