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