欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

docker 网络实现原理及网络模式

程序员文章站 2022-06-05 18:48:11
...

docker的网络隔离底层技术为linux提供的网络命名空间。
基本上可以通过ip命令复现docker的网络隔离。

linux 网络命名空间管理:ip命令

ip netns help 查看命令

ip link 挪网络设备

创建命名空间

ip netns add r1
ip netns add r2
ip netns exec r1 ifconfig -a  
ip netns exec r2 ifconfig -a

命名空间默认没有网卡,只有一个lo设备。sit0是ipv6的适配设备。

[email protected]:~$ sudo ip netns exec r1 ifconfig -a
lo: flags=8<LOOPBACK>  mtu 65536
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

sit0: flags=128<NOARP>  mtu 1480
        sit  txqueuelen 1000  (IPv6-in-IPv4)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ip link add 创建虚拟网卡

ip link add name veth1.1 type veth peer name veth1.2
两个网卡在默认空间。
执行ifconfig 会发现并没网卡。默认创建的网卡是down状态。

执行:ifconfig -a,列表如下。

...

veth1.1: flags=4098<BROADCAST,MULTICAST>  mtu 1500
        ether 8a:53:6c:29:09:b6  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth1.2: flags=4098<BROADCAST,MULTICAST>  mtu 1500
        ether 76:bd:2d:4d:f2:a4  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

可以通过ip命令查看当前的网卡:ip link sh
其中包括了所有的网卡。

...
6: [email protected]: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 76:bd:2d:4d:f2:a4 brd ff:ff:ff:ff:ff:ff
7: [email protected]: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 8a:53:6c:29:09:b6 brd ff:ff:ff:ff:ff:ff

新创建的网卡在r1和r2命名空间不可见。

执行下面命令,看不到网卡veth1.1和veth1.2

ip netns exec r1 ifconfig -a
ip netns exec r2 ifconfig -a

网卡在命名空间迁移

将网卡放到 r1中

ip link set dev veth1.1 netns r1

在默认的命名空间,查看网卡,发现已经看不到网卡veth1.1:

[email protected]:~$ sudo ip link sh
...
6: [email protected]: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 76:bd:2d:4d:f2:a4 brd ff:ff:ff:ff:ff:ff link-netns r1

在r1中查看网卡,发现虚拟网卡已经在r1中。

[email protected]:~$ sudo ip netns exec r1 ifconfig -a
lo: flags=8<LOOPBACK>  mtu 65536
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

sit0: flags=128<NOARP>  mtu 1480
        sit  txqueuelen 1000  (IPv6-in-IPv4)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth1.1: flags=4098<BROADCAST,MULTICAST>  mtu 1500
        ether 8a:53:6c:29:09:b6  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

网络连通性

目前的网络拓扑:r1和默认空间通过veth1.1—veth1.2关联。
分别启动r1中的veth1.1 和默认空间的veth1.2 。

sudo ip netns exec r1 ifconfig veth1.1 10.1.0.1/24 up
sudo ifconfig veth1.2 10.1.0.2/24 up

在r1测试连通性:

[email protected]:~$ sudo ip netns exec r1 ping 10.1.0.2
PING 10.1.0.2 (10.1.0.2) 56(84) bytes of data.
64 bytes from 10.1.0.2: icmp_seq=1 ttl=64 time=0.281 ms
64 bytes from 10.1.0.2: icmp_seq=2 ttl=64 time=0.029 ms
64 bytes from 10.1.0.2: icmp_seq=3 ttl=64 time=0.044 ms
64 bytes from 10.1.0.2: icmp_seq=4 ttl=64 time=0.039 ms

将veth1.2迁移到r2中:

sudo ip link set dev veth1.2 netns r2
sudo ip netns exec r2 ifconfig veth1.2 10.1.0.2/24 up

[email protected]:~$ sudo ip netns exec r2 ifconfig
veth1.2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.1.0.2  netmask 255.255.255.0  broadcast 10.1.0.255
        inet6 fe80::74bd:2dff:fe4d:f2a4  prefixlen 64  scopeid 0x20<link>
        ether 76:bd:2d:4d:f2:a4  txqueuelen 1000  (Ethernet)
        RX packets 19  bytes 1522 (1.5 KB)
        RX errors 0  dropped 2  overruns 0  frame 0
        TX packets 25  bytes 1998 (1.9 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

测试r1和r2的连通性:

[email protected]:~$ sudo ip netns exec r1 ping 10.1.0.2
PING 10.1.0.2 (10.1.0.2) 56(84) bytes of data.
64 bytes from 10.1.0.2: icmp_seq=1 ttl=64 time=0.050 ms
64 bytes from 10.1.0.2: icmp_seq=2 ttl=64 time=0.070 ms
64 bytes from 10.1.0.2: icmp_seq=3 ttl=64 time=0.104 ms

[email protected]:~$ sudo ip netns exec r2 ping 10.1.0.1
PING 10.1.0.1 (10.1.0.1) 56(84) bytes of data.
64 bytes from 10.1.0.1: icmp_seq=1 ttl=64 time=0.048 ms
64 bytes from 10.1.0.1: icmp_seq=2 ttl=64 time=0.075 ms

设置网卡信息

ip netns exec r1 ip link set dev veth1.2 name eth0
ip netns exec r1 ifconfig -a

docker网络模型

封闭容器 只有lo设备

docker run --name t1 -it --network none --rm busybox:1.31.1
ifconfig 一个网卡 lo

[email protected]:~$ docker run --name t1 -it --network none --rm busybox:1.33.1
/ # ifconfig
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ #

桥接容器

docker run --name t1 -it --rm busybox:1.31.1

ifconfig 两个网卡 lo, eth0

[email protected]:~$ docker run --name t1 -it --rm busybox:1.33.1
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:11 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:962 (962.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
docker run --name t1 -it --network bridge --rm busybox:1.31.1

ifconfig 两个网卡 lo, eth0,和默认的情况一样。

hostname为容器的id

/ # hostname
92b72be55875

设置主机名:

docker run --name t1 -it --network bridge -h t1.com --rm busybox:1.31.1

hostname 显示:t1.com

[email protected]:~$ docker run --name t1 -it --network bridge -h t1.com --rm busybox:1.33.1
/ # hostname
t1.com
/ #

域名解析:

查看hosts可以看到,容器自己的ip和主机名做了映射:

cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      t1.com t1

resolv.conf中使用宿主机作为dns

cat /etc/resolv.conf
# DNS requests are forwarded to the host. DHCP DNS options are ignored.
nameserver 192.168.65.5
 nslookup  -type=A www.baidu.com
Server:         192.168.65.5
Address:        192.168.65.5:53

Non-authoritative answer:
www.baidu.com   canonical name = www.a.shifen.com
Name:   www.a.shifen.com
Address: 110.242.68.4
Name:   www.a.shifen.com
Address: 110.242.68.3

自定义dns主机:

docker run --name t1 -it --network bridge -h t1.com --dns 114.114.114.114 --rm busybox:1.31.1
cat /etc/resolv.conf 包含114

添加hosts:

docker run --name t1 -it --network bridge -h t1.com --add-host www.baidu.com:1.1.1.1 --rm busybox:1.31.1
cat /etc/hosts

joined容器 容器间共享网络

docker run --name b1 -it --rm busybox
ifconfig

docker run --name b2 -it --network container:b1 --rm busybox
ifconfig   结果和b1的相同

宿主机模式 容器直接使用主机网络

docker run --name b1 --network host -it --rm busybox

ifconfig  同主机

注意:wsl2不支持宿主机模式。