docker的五种网络(六):

bridge:默认网络,Docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中;IP地址段是172.17.0.1/16
在docker安装好以后就会有一个docker默认网络

# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02426d8b7049	no		

启动一个容器
# docker run -itd --name test01 centos
a71988e84605c994374ecc56bb6b2675f9cba65b108a44df403135bae730cec5

创建了一个网卡对
# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02426d8b7049	no		veth84e5035

# ip link
11: veth84e5035@if10:  mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
    link/ether 76:ab:8c:55:08:29 brd ff:ff:ff:ff:ff:ff link-netnsid 0

进入容器自动生成ip地址
# docker attach test01

yum -y install net-tools iproute
[root@a71988e84605 /]# ifconfig
eth0: flags=4163  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 2424  bytes 10800077 (10.2 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2148  bytes 131501 (128.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

网关为172.17.0.1
[root@a71988e84605 /]# ip route
default via 172.17.0.1 dev eth0 

docker访问外网做了snat:
# iptables -L -n -t nat -v
Chain POSTROUTING (policy ACCEPT 302 packets, 22293 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  105  6525 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           

host:与主机的网络完全一致

启动一个容器:
# docker run -itd --name test02 --net=host centos:self
4c3e8c76c9793c8e87181e6bc90b634f80acde1fd1cc52bc18cbc50cba3ebd6c


与主机的网络一致:
# ifconfig
docker0: flags=4163  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:6dff:fe8b:7049  prefixlen 64  scopeid 0x20
        ether 02:42:6d:8b:70:49  txqueuelen 0  (Ethernet)
        RX packets 5874  bytes 3829100 (3.6 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7274  bytes 13690008 (13.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33: flags=4163  mtu 1500
        inet 10.0.0.5  netmask 255.255.255.0  broadcast 10.0.0.255
        inet6 fe80::20c:29ff:fe33:ffd2  prefixlen 64  scopeid 0x20
        ether 00:0c:29:33:ff:d2  txqueuelen 1000  (Ethernet)
        RX packets 89266  bytes 113049099 (107.8 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 25124  bytes 7176772 (6.8 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 32  bytes 13560 (13.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 32  bytes 13560 (13.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth84e5035: flags=4163  mtu 1500
        inet6 fe80::74ab:8cff:fe55:829  prefixlen 64  scopeid 0x20
        ether 76:ab:8c:55:08:29  txqueuelen 0  (Ethernet)
        RX packets 2652  bytes 172322 (168.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2915  bytes 12197820 (11.6 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

none:获取独立的network namespace,但不为容器进行任何网络配置

启动一个容器
# docker run -itd --name test03 --net=none centos:self
9c7cd0dea4a288b214325b75a16b827c1ac7bdad4717d638b0d52a27cf1f560c

查看网络模式
# docker inspect -f '{{.HostConfig.NetworkMode}}' test03
none

查看pid
# C_PID=$(docker inspect -f '{{.State.Pid}}' test03)
# echo $C_PID
12263

# 创建network namespace目录并将容器的network namespace软连接到此目录,以便ip netns命令读取
mkdir -p /var/run/netns
ln -s /proc/$C_PID/ns/net /var/run/netns/$C_PID
# 添加虚拟网卡veth+容器PID,类型是veth pair,名称是vp+容器PID
ip link add veth$C_PID type veth peer name vp$C_PID

检查是否已经成功添加:
# ip link
12: vp12263@veth12263:  mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether f2:6f:17:b8:e5:57 brd ff:ff:ff:ff:ff:ff
13: veth12263@vp12263:  mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 26:a9:fe:6b:d9:37 brd ff:ff:ff:ff:ff:ff

# 添加虚拟网卡到br0网桥
# brctl addif docker0 veth$C_PID
# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02426d8b7049	no		veth12263
							veth84e5035


# 激活虚拟网卡
ip link set veth$C_PID up
# ifconfig
veth12263: flags=4099  mtu 1500
        ether 26:a9:fe:6b:d9:37  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




# 给进程配置一个network namespace
ip link set vp$C_PID netns $C_PID
# ip netns exec $C_PID ip link
1: lo:  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
12: vp12263@if13:  mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether f2:6f:17:b8:e5:57 brd ff:ff:ff:ff:ff:ff link-netnsid 0


# docker attach test03
[root@9c7cd0dea4a2 /]# ifconfig
lo: flags=73  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        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


# 在容器进程里面设置网卡信息
ip netns exec $C_PID ip link set dev vp$C_PID name eth0
ip netns exec $C_PID ip link set eth0 up
# docker attach test03
[root@9c7cd0dea4a2 /]# ifconfig
eth0: flags=4163  mtu 1500
        ether f2:6f:17:b8:e5:57  txqueuelen 1000  (Ethernet)
        RX packets 7  bytes 586 (586.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

lo: flags=73  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        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


# 设置容器网络信息
IP='172.17.0.4/24'
GW='172.17.0.1'
ip netns exec $C_PID ip addr add $IP dev eth0
ip netns exec $C_PID ip route add default via $GW
ip netns exec $C_PID ip addr add 172.17.0.4/24 dev eth0
ip netns exec $C_PID ip route add default via 172.17.0.1

# docker attach test03
[root@9c7cd0dea4a2 /]# ifconfig
eth0: flags=4163  mtu 1500
        inet 172.17.0.4  netmask 255.255.255.0  broadcast 0.0.0.0
        ether f2:6f:17:b8:e5:57  txqueuelen 1000  (Ethernet)
        RX packets 8  bytes 656 (656.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

lo: flags=73  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        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

[root@9c7cd0dea4a2 /]# ping www.163.com
PING www.163.com.lxdns.com (182.136.72.133) 56(84) bytes of data.
64 bytes from 182.136.72.133 (182.136.72.133): icmp_seq=1 ttl=55 time=13.7 ms
64 bytes from 182.136.72.133 (182.136.72.133): icmp_seq=2 ttl=55 time=12.8 ms
64 bytes from 182.136.72.133 (182.136.72.133): icmp_seq=3 ttl=55 time=11.5 ms

container:两个容器公用一个网卡
在理解了host模式后,这个模式也就好理解了。
这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。
新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。
同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。
两个容器的进程可以通过lo网卡设备通信。

# docker run -itd --name test04 --net=container:test03 centos:self
2bacf77aecc40fadb88f76b4bc7b28ef2e05b34cfeebdfa687ae1c9e3fd3edaa

两个容器网卡配置是一样的:

# docker attach test04
[root@9c7cd0dea4a2 /]# ifconfig
eth0: flags=4163  mtu 1500
        inet 172.17.0.4  netmask 255.255.255.0  broadcast 0.0.0.0
        ether f2:6f:17:b8:e5:57  txqueuelen 1000  (Ethernet)
        RX packets 15  bytes 1294 (1.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7  bytes 536 (536.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        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

# docker attach test03
[root@9c7cd0dea4a2 /]# ifconfig
eth0: flags=4163  mtu 1500
        inet 172.17.0.4  netmask 255.255.255.0  broadcast 0.0.0.0
        ether f2:6f:17:b8:e5:57  txqueuelen 1000  (Ethernet)
        RX packets 15  bytes 1294 (1.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7  bytes 536 (536.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        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

自定义:自定义网桥,默认与bridge网络一样。

安装网桥命令:
# yum -y install bridge-utils

创建一个新的网桥:
# brctl  addbr br0
# brctl show
bridge name	bridge id		STP enabled	interfaces
br0		8000.000000000000	no		
docker0		8000.02426d8b7049	no		veth12263
							veth84e5035
							
配置网桥地址:
# cat > /etc/sysconfig/network-scripts/ifcfg-br0 << EOF
DEVICE="br0"
BOOTPROTO="static"
NM_CONTROLLED="no"
IPADDR=192.168.102.10
NETMASK=255.255.255.0
GATEWAY=192.168.102.1
DNS1=10.0.0.1
ONBOOT="yes"
TYPE="Bridge"
DELAY=0
EOF

将eth0的配置文件/etc/sysconfig/network-scripts/ifcfg-ens37的内容修改为:
# cat > /etc/sysconfig/network-scripts/ifcfg-ens37 << EOF
DEVICE="ens37"
BOOTPROTO="static"
NM_CONTROLLED="no"
ONBOOT="yes"
TYPE="Ethernet"
BRIDGE="br0"
EOF

# systemctl restart network
							
启动一个none类型的容器:
# docker run -itd --name test05 --net=none centos:self
7868a13e4b8e844ed52a968b2009db1498573efb62a504b85c344cd46af9b746

查看网络类型
# docker inspect -f '{{.HostConfig.NetworkMode}}' test05
none

查看pid
# C_PID=$( docker inspect -f '{{.State.Pid}}' test05)
# echo $C_PID
12856

创建network namespace目录并将容器的network namespace软连接到此目录,以便ip netns命令读取
# ln -sv /proc/12856/ns/net /var/run/netns/$C_PID
‘/var/run/netns/12856’ -> ‘/proc/12856/ns/net’
# ll /var/run/netns/
total 0
lrwxrwxrwx 1 root root 18 Apr 15 12:41 12263 -> /proc/12263/ns/net
lrwxrwxrwx 1 root root 18 Apr 15 13:56 12856 -> /proc/12856/ns/net

# 添加虚拟网卡veth+容器PID,类型是veth peer,名称是vp+容器PID
# ip link add veth$C_PID type veth peer name pv$C_PID
# ip link
15: pv12856@veth12856:  mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 62:65:26:6f:71:5d brd ff:ff:ff:ff:ff:ff
16: veth12856@pv12856:  mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 9e:86:2a:67:b3:56 brd ff:ff:ff:ff:ff:ff

# 添加虚拟网卡到br0网桥并激活
# brctl addif br0 veth$C_PID
# brctl show
bridge name	bridge id		STP enabled	interfaces
br0		8000.9e862a67b356	no		veth12856
docker0		8000.02426d8b7049	no		veth12263
							veth84e503
# ip link set veth$C_PID up

#把虚拟网卡加入名称空间
# ip link set pv$C_PID netns $C_PID

设置docker里网卡名称,并激活网卡
# ip netns exec $C_PID ip link set pv$C_PID name eth0
# ip netns exec $C_PID ip link set eth0 up

配置docker网卡ip地址
IP='192.168.102.11/24'
GW='192.168.102.1'

ip netns exec $C_PID ip addr add $IP dev eth0
ip netns exec $C_PID ip route add default via $GW

你可能感兴趣的:(docker的五种网络(六):)