docker的四种网络模式以及在none网络模式下为容器分配固定 ip - Go语言中文社区

docker的四种网络模式以及在none网络模式下为容器分配固定 ip


docker网络介绍

Docker 在启动时会创建一个虚拟网桥 docker0,默认地址为 172.17.0.1/16,容器启动后都会被桥接到 docker0 上,并自动分配到一个 IP 地址 (IP地址都会在172.17.0.1基础上递增 ==,第一个容器它获取到的IP为172.17.0.2)。

docker0默认地址
在这里插入图片描述
网桥
在这里插入图片描述
容器桥接docker0后,自动分配ip地址。
在这里插入图片描述

容器桥接docker0后,再次查看docker0的网桥,会发现docker0增加了相应的接口。
在这里插入图片描述

容器的四种网络模式

1.bridge模式,使用–net=bridge指定,默认设置。
2.none模式,使用–net=none指定。
3.host模式,使用–net=host指定。
4.container模式,使用–net=container:容器名称或ID指定

Bridge 桥接模式部署

[root@server1 ~]# docker run -it --name vm1 ubuntu

在这里插入图片描述
在这里插入图片描述

2、Host 模式部署

[root@server1 ~]# docker run -it --name vm2 --net host ubuntu

在这里插入图片描述

用host网络模式启动的容器vm2,拥有与宿主机server1完全相同的结构。

3、Container 模式部署

[root@server1 ~]# docker run -it --name vm3 --net container:vm1 ubuntu

在这里插入图片描述

[root@server1 ~]# brctl show   #docker0的桥接接口只有一个;新创建的vm3容器,使用的是vm1的namespace
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02426b0d90ce	no		veth8aa2220

4、None 模式部署

[root@server1 ~]# docker run -it --name vm4 --net none ubuntu

在这里插入图片描述

网络虚拟化部署(在 none 网络模式下为容器分配固定 ip)

在为容器分配固定ip之前,我们需要先建立/var/run/netns目录

#生成/var/run/netns目录的方法一:用mkdir建一个该目录即可#
[root@server1 ~]# mkdir /var/run/netns
 
#生成/var/run/netns目录的方法二:利用ip netns命令先增加一个虚拟命名空间,然后再删除该虚拟命名空间即可。#
[root@server1 ~]# ip netns add test   #增加虚拟命名空间test。该命令会在/var/run/netns目录下创建test网络命名空间名(其中/var/run/netns目录是自动生成的)
[root@server1 ~]# ip netns list   #显示所有的虚拟网络命名空间,也可通过查看/var/run/netns目录下的文件来列出,结果一样。([root@server1 ~]# ls /var/run/netns/) 
[root@server1 ~]# ip netns del test   #删除虚拟命令空间。该命令会在/var/run/netns目录下删除test网络命名空间名
[root@server1 ~]# ip netns list   #此时再次查看虚拟命名空间,发现test已经不存在了。也可以通过查看/var/run/netns目录下的文件来列出,结果一样。([root@server1 ~]# ls /var/run/netns/)

1、在本地主机查找容器vm3的进程 id,并为它创建网络命名空间。

[root@server1 ~]# docker inspect vm4 | grep Pid   #查看vm4容器的Pid号,用其来生成一个虚拟网络命名空间
            "Pid": 24341,
            "PidMode": "",
            "PidsLimit": 0,
[root@server1 ~]# ln -s /proc/24341/ns/net /var/run/netns/24341   #增加虚拟网络命名空间24341。值的注意的是这里不能通过"ip netns add 24341"来增加虚拟网络命名空间,这是因为用软链接的方式是有vm3的数据的;而用"ip netns add 24341是没有vm3的数据的"。
[root@server1 ~]# ip netns list   #显示所有的虚拟网络命名空间(或者使用命令"ls /var/run/netns/"),以查看24341这个虚拟网络命名空间是否添加成功

2、创建一对 “veth pair” 接口 veth0 和 veth1,激活veth0和vrth1,绑定 veth0 到网桥 docker0,

[root@server1 ~]# ip link add name veth0 type veth peer name veth1   #增加一对veth虚拟网卡(网卡的名字分别是veth0,veth1)。以便将一块网卡连接docker0,一块网卡连接需要增加ip的容器vm4
[root@server1 ~]# ip addr   #查看虚拟网卡veth0和veth1是否已经生成。我们可以看到这两个虚拟网卡没有被激活
260: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 2a:6a:45:96:69:da brd ff:ff:ff:ff:ff:ff
261: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether d6:dd:99:81:ed:c2 brd ff:ff:ff:ff:ff:ff
[root@server1 ~]# ip link set up veth0   #激活虚拟网卡veth0
[root@server1 ~]# ip link set up veth1   #激活虚拟网卡veth1
[root@server1 ~]# ip addr   #再次查看虚拟网卡veth0和veth1是否已经被激活。我们可以看到两块虚拟网卡已经被激活
260: veth1@veth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 2a:6a:45:96:69:da brd ff:ff:ff:ff:ff:ff
    inet6 fe80::286a:45ff:fe96:69da/64 scope link 
       valid_lft forever preferred_lft forever
261: veth0@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether d6:dd:99:81:ed:c2 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::d4dd:99ff:fe81:edc2/64 scope link 
       valid_lft forever preferred_lft forever
[root@server1 ~]# brctl addif docker0 veth0   #将一块虚拟网卡veth0(当然也可以是veth1)连接docker0。即将veth0添加为docker0的网络接口
[root@server1 ~]# brctl show docker0   #查看docker0的桥接情况,以确保veth0已经成功连接docker0
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02426b0d90ce	no		veth0
							veth8aa2220

3、将veth1放到容器的网络命名空间,命名为 eth0,启动它。

[root@server1 ~]# ip link set veth1 netns 24341   #将另一块虚拟网卡veth1添加到24341虚拟网络环境中
[root@server1 ~]# docker attach vm4   #连接容器vm4,我们发现多了一个网卡veth1,但是该网卡的状态是DOWN,所以需要激活该网卡
root@dd42b8e24eeb:/# ip a
       valid_lft forever preferred_lft forever
262: veth1@if263: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 76:6f:e2:d8:cf:03 brd ff:ff:ff:ff:ff:ff
root@dd42b8e24eeb:/# ip link set up veth1   #在容器内激活veth1网卡,发现操作不允许
RTNETLINK answers: Operation not permitted
[root@server1 ~]# ip netns exec 24341 ip link set veth1 name eth0   #连接虚拟网络命名空间24341,将容器内的网卡veth1改名为eth0(这步可做,也可不做)
[root@server1 ~]# ip netns exec 24341 ip link set up eth0   #连接虚拟网络命名空间24341,激活网卡eth0

4、为eth0配置一个可用 IP(桥接网段)和默认网关。

[root@server1 ~]# docker attach vm4   #连接容器vm4,查看网卡名字是否修改成功,网卡是否激活成功。但是又会发现一个问题(网卡eth0没有ip地址)
root@dd42b8e24eeb:/# 
root@dd42b8e24eeb:/# ip a   
262: eth0@if263: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 76:6f:e2:d8:cf:03 brd ff:ff:ff:ff:ff:f
[root@server1 ~]# ip netns exec 24341 ip addr add 172.17.0.100/24 dev eth0   #连接24341虚拟网络命名空间,给容器内的eth0网卡添加ip地址
[root@server1 ~]# docker attach vm4   #连接容器vm4,我们可以看到eth0网卡上已经有设定的ip地址了
root@dd42b8e24eeb:/# ip a
262: eth0@if263: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 76:6f:e2:d8:cf:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.100/24 scope global eth0
       valid_lft forever preferred_lft forever
root@dd42b8e24eeb:/# ping 172.17.0.2   #ping容器vm1的ip地址(能pin通,这是因为vm1桥接在docker0,而连接容器vm3的虚拟网络命名空间24341的一个网卡veth0也桥接在docker0上)
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.100 ms
root@dd42b8e24eeb:/# ping 172.17.0.1   #能ping通docker0的地址
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.076 ms
root@dd42b8e24eeb:/# ping 172.25.83.1   #能ping通虚拟机server1的地址(docker0可以跟虚拟机server1进行通信,容器vm3可以和docker0进行通信,所以容器vm3可以和虚拟机server1通信)
PING 172.25.83.1 (172.25.83.1) 56(84) bytes of data.
64 bytes from 172.25.83.1: icmp_seq=1 ttl=64 time=0.055 ms
root@dd42b8e24eeb:/# ping www.baidu.com   #ping www,baidu.com。报错,这是因为没有解析
ping: unknown host www.baidu.com
[root@server1 ~]# ip netns exec 24341 ip route add default via 172.17.0.1   #ip netns exec 24341 ip route add default gw 172.17.0.1或连接虚拟网络命名空间24341,为位于该虚拟网络命名空间的容器添加网关。
root@dd42b8e24eeb:/# route -n   #查看网关
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.17.0.1      0.0.0.0         UG    0      0        0 eth0
172.17.0.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0
root@dd42b8e24eeb:/# cat /etc/resolv.conf   #查看dns

    nameserver 114.114.114.114
    root@dd42b8e24eeb:/# ping www.baidu.com   #能ping通www.baidu.com,这是因为虚拟机server1能够上网
    PING www.a.shifen.com (220.181.111.37) 56(84) bytes of data.
    64 bytes from 220.181.111.37: icmp_seq=1 ttl=50 time=28.8 ms
    64 bytes from 220.181.111.37: icmp_seq=2 ttl=50 time=52.4 ms

当容器vm4结束后,Docker 会清空容器,容器内的 eth0 会随网络命名空间一起被清除,veth0 接口也被自动从 docker0 卸载。

此外,用户也可以使用 ip netns exec 命令来在指定网络命名空间中进行配置,从而配置容器内的网络。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_44299264/article/details/98846037
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢