美文网首页
Docker网络命名空间

Docker网络命名空间

作者: 云师兄 | 来源:发表于2018-06-07 22:58 被阅读26次

首先运行一个基于busybox镜像的busybox容器,名字为test1:

docker run -d --name test1 hub.c.163.com/library/busybox:latest /bin/sh -c "while true;do sleep 3600;done"

启动容器后进入容器:

docker exec -it aec1c356e72c /bin/sh

我们在容器中首先输入命令ip a来查看当前容器的网络接口:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
58: eth0@if59: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

第一个网络接口为本地的Lookback,即回还口。当我们创建一个容器时,也会相应创建一个网络namespace。我们退出容器后,在本地宿主机上执行 ip a命令时,打印如下:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:5f:94:78 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
       valid_lft 57642sec preferred_lft 57642sec
    inet6 fe80::5054:ff:fe5f:9478/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:08:96:2b:f9 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:8ff:fe96:2bf9/64 scope link
       valid_lft forever preferred_lft forever
59: vetha65affd@if58: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether 5a:31:ef:f0:fb:64 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::5831:efff:fef0:fb64/64 scope link
       valid_lft forever preferred_lft forever

由此可见主机的网络接口信息和容器的网络接口信息不同,这是由于宿主机也有自己的网络命名空间,和容器的网络命名空间相互隔离。
当我们再启动另外一个容器,并执行docker exec -it hub.c.163.com/library/busybox:latest ip a来查看网络的接口信息如下:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
60: eth0@if61: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

由此发现,创建的这两个容器的网络是相通的,因为172.17.0.2和172.17.0.3位于同一网段,所以可以ping通。
接下来来了解下两个容器能够网络相通的原理。

原理

sudo ip netns list命令:在宿主机上可以通过来查看当前已有的network namespace。
sudo ip netns delete test1命令:删除名称为test1的network namespace。
sudo ip netns add test1命令:新增名为test1的network namespace。
了解上面几个命令后,我们新增test1和test2两个network namespace,并执行命令:
sudo ip netns exec test1 ip a来查看test1这个network namespace,如下:

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

由上可知test1这个network namespace的lo回还口的状态为Down。再介绍一个命名:
ip link,它也可以查看network namespace信息,另外可以使用这个 命令将状态为down的网络接口启动起来,使之状态为up。为此我们想将test1这个network namespace的lo端口up起来:

sudo ip netns exec test1 ip link set dev lo up

然后使用sudo ip netns exec test1 ip link来查看test1的网络接口信息,如下:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

状态并没有从down变成up,而是变成了unknown状态。这是因为在Linux里面端口是成对出现才会变成up状态。

下面我们来了解下两个命名空间之间通信的原理:


image.png

由上图可知,两个命名空间内部都有一个通信的接口,中间通过类似于网线的Veth pair进行通信,下面我们通过命令来模拟这个实现的过程:
首先我们执行命令如下:

sudo ip link add veth-test1 type veth peer name veth-test2

通过这个命令,我们创建了两个网络端口veth-test1和veth-test2,查看结果:

[vagrant@localhost ~]$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 52:54:00:5f:94:78 brd ff:ff:ff:ff:ff:ff
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether 02:42:08:96:2b:f9 brd ff:ff:ff:ff:ff:ff
59: vetha65affd@if58: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
    link/ether 5a:31:ef:f0:fb:64 brd ff:ff:ff:ff:ff:ff link-netnsid 1
61: veth7dcab2c@if60: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
    link/ether 32:87:13:6c:b5:39 brd ff:ff:ff:ff:ff:ff link-netnsid 0
62: veth-test2@veth-test1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether da:3f:b3:ab:f7:0b brd ff:ff:ff:ff:ff:ff
63: veth-test1@veth-test2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether e2:5a:43:9f:c0:a8 brd ff:ff:ff:ff:ff:ff

可以看到现在在最下面多了两个网络端口。
接着我们将创建的这两个网络端口分别添加到两个命名空间中:

sudo ip link set veto-test1 netns test1
sudo ip link set veto-test2 netns test2

添加完后查看命名空间test1和test2的网络接口信息:

[vagrant@localhost ~]$ sudo ip netns exec test1 ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
63: veth-test1@if62: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether e2:5a:43:9f:c0:a8 brd ff:ff:ff:ff:ff:ff link-netnsid 1
[vagrant@localhost ~]$ sudo ip netns exec test2 ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
62: veth-test2@if63: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether da:3f:b3:ab:f7:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0

可以看出,两个命名空间中已经多了网络端口veth-test1和veth-test2。
但是这两个网络端口状态都是down,并且没有IP地址,为此下面我们给这两个网络端口分配IP地址:

sudo ip netns exec test1 ip addr add 192.168.1.1/24 dev veth-test1
sudo ip netns exec test2 ip addr add 192.168.1.2/24 dev veth-test2

然后我们将这两个网络端口都up起来:

sudo ip netns exec test1 ip link set dev veth-test1 up
sudo ip netns exec test2 ip link set dev veth-test2 up

由于192.168.1.1和192.168.1.2这两个地址位于同一网段,为此两个命名空间之间就可以互相ping通了:

[vagrant@localhost ~]$ sudo ip netns exec test1 ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.062 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.052 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.070 ms
64 bytes from 192.168.1.2: icmp_seq=4 ttl=64 time=0.058 ms
^C
--- 192.168.1.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3007ms
rtt min/avg/max/mdev = 0.052/0.060/0.070/0.010 ms

这就是两个容器也能ping通的原理。

相关文章

  • 十三、docker网络的命名空间

    查看当前电脑的全名空间 查看docker容器中的网络命名空间 查看本机有的网络命名空间 删除网络命名空间 添加网络...

  • 十三、docker命名空间二

    创建一个docker网络 查看docker 的网络空间 查看命名空间连接情况 启动一个新的容器连接新的命名空间--...

  • Docker网络命名空间

    首先运行一个基于busybox镜像的busybox容器,名字为test1: 启动容器后进入容器: 我们在容器中首先...

  • docker网络之bridge详解

    上一篇文章docker网络之Linux网络命名空间(namespace)中我们了解了一些关于网络命名空间的知识,以...

  • Docker网络实现

    众所周知,docker网络是它薄弱的地方! Docker的网络实现: 利用linux的网络命名空间和虚拟网络设备(...

  • K8S 网络详解 1 DOCKER 网络基础

    DOCKER 网络基础 网络命名空间(linux net namespace) linux 内核支持(net na...

  • 四十、Docker网络-网络命名空间

    网络命名空间 Linux的Namespace(命名空间)技术是一种隔离技术,常用的Namespace有 user ...

  • 如何在主机上直接操作容器

    一、进入容器网络命名空间进程操作 step1、docker inspect -f ‘{{.State.Pid}} ...

  • iptables和netfilter

    前段时间学习了docker容器网络中bridge模式,linux下端口转发(iptables)和网络命名空间ip ...

  • docker命名空间

    1、 docker命名空间 linux namespace 资源隔离如果要自己实现一个资源隔离的容器,应该从哪些方...

网友评论

      本文标题:Docker网络命名空间

      本文链接:https://www.haomeiwen.com/subject/gsvnsftx.html