一、Docker提供了四种网络模式:
- host模式,使用–net=host指定。
- container模式,使用–net=container:NAME_or_ID指定。
- none模式,使用–net=none指定。
- bridge模式,使用–net=bridge指定,默认设置。
下面分别简单介绍一下各种网络模式。
host模式
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
container模式
Container模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
none模式
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
bridge模式
bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。
桥接网络详解:
当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
桥接网络拓扑结构如下
网络配置过程如下:
1. 在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
2. Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以veth***这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看。
3. 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
容器内部访问外网以及容器和主机之间的端口映射都是通过Iptables实现的,可以查看Iptables表分析。
二、Docker配置自己的网桥
1)、自定义新网桥
root@Docker:~# dpkg -l | grep bridge* #查看是否有安装brctl命令包
root@Docker:~# apt-get install bridge-utils #安装brctl命令包
root@Docker:~# docker -v #docker版本
root@Docker:~# ps -ef | grep docker #正在运行
root 6834 1 0 16:28 ? 00:00:00 /usr/bin/docker -d
root@Docker:~# service docker stop #停止
root@Docker:~# ifconfig | grep docker0 #docker默认网桥
docker0 Link encap:以太网 硬件地址 56:84:7a:fe:97:99
root@Docker:~# ifconfig docker0 down #停止docker默认网桥
root@Docker:~# brctl show #查看物理机上有哪些网桥
root@Docker:~# brctl delbr docker0 #删除docker默认网桥
root@Docker:~# brctl addbr docker_new0 #自定义网桥
root@Docker:~# ifconfig docker_new0 192.168.6.1 netmask 255.255.255.0 #给自定义网桥指定IP和子网
root@Docker:~# ifconfig | grep docker_new0 #查看发现自定义网桥已经启动
docker_new0 Link encap:以太网 硬件地址 0a:5b:26:48:dc:04
inet 地址:192.168.6.1 广播:192.168.6.255 掩码:255.255.255.0
root@Docker:~# echo 'DOCKER_OPTS="-b=docker_new0"' >> /etc/default/docker #指定网桥写入docker配置文件
root@Docker:~# service docker start #启动docker
root@Docker:~# ps -ef | grep docker #成功启动,并且成功加载了docker_new0
root 21345 1 0 18:44 ? 00:00:00 /usr/bin/docker -d -b=docker_new0
root@Docker:~# brctl show #查看当前网桥下是否有容器连接
bridge name bridge id STP enabled interfaces
docker_new0 8000.fa3ce276c3b9 no
root@Docker:~# docker run -itd CentOS:centos6 /bin/bash #创建容器测试
root@Docker:~# docker attach 7f8ff622237f #进入容器
[root@7f8ff622237f /]# ifconfig eth0 | grep addr #容器IP已经和自定义网桥一个网段,该容器IP为DHCP自动分配,不属于指定固定IP
eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:06:02
inet addr:192.168.6.2 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::42:c0ff:fea8:602/64 Scope:Link
root@Docker:~# brctl show #该网桥上已经连接着一个网络设备了
bridge name bridge id STP enabled interfaces
docker_new0 8000.fa3ce276c3b9 no veth17f560a
注:veth设备是成双成对出现的,一端是容器内部命名eth0,一端是加入到网桥并命名的veth17f560a(通常命名为veth*),他们组成了一个数据传输通道,一端进一端出,veth设备连接了两个网络设备 并实现了数据通信。
2)、Pipework 配置Docker固定IP --最新版本的docker是否支持固定IP的配置需测试
我们在自定义网桥的基础上去做固定IP配置
Pipework有个缺点就是给容器指定完固定IP,如果容器重启,那么固定IP会消失,还需要重新指定,容器量大时可写个脚本来完成
root@Docker:~# wget https://github.com/jpetazzo/pipework/archive/master.zip #下载 pipework
root@Docker:~# unzip master.zip #解压
root@Docker:~# cp pipework-master/pipework /usr/bin/ #拷贝pipework到 /usr/bin/下
root@Docker:~# chmod +x /usr/bin/pipework #赋予该命令执行权限
root@Docker:~# docker attach 2966430e2dbe #进入新容器
[root@2966430e2dbe /]# ifconfig #容器内IP为指定的IP 192.168.6.27
eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:06:05
inet addr:192.168.6.7 Bcast:0.0.0.0 Mask:255.255.255.0 #docker_new0网桥创建容器时DHCP分配的IP
eth1 Link encap:Ethernet HWaddr 82:DB:F7:A3:33:92
inet addr:192.168.6.27 Bcast:0.0.0.0 Mask:255.255.255.0 #pipework指定的固定IP,网桥还是docker_new0
[root@2966430e2dbe /]# route -n #查看路由路径
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.6.1 0.0.0.0 UG 0 0 0 eth0
192.168.6.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.6.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
[root@2966430e2dbe /]# ping www.linuxidc.com #测试网络
PING www.linuxidc.com (119.75.218.70) 56(84) bytes of data.
64 bytes from 119.75.218.70: icmp_seq=1 ttl=127 time=3.98 ms
64 bytes from 119.75.218.70: icmp_seq=2 ttl=127 time=2.98 ms
[root@2966430e2dbe /]# netstat -anptu | grep 80 #容器内80端口已经开启
tcp 0 0 :::80 :::* LISTEN -
root@Docker:~# telnet 192.168.6.27 80 #物理机上测试指定的IP是否和映射的端口等通信正常
Trying 192.168.6.27...
Connected to 192.168.6.27.
Escape character is '^]'.
- host模式,使用–net=host指定。
- container模式,使用–net=container:NAME_or_ID指定。
- none模式,使用–net=none指定。
- bridge模式,使用–net=bridge指定,默认设置。
下面分别简单介绍一下各种网络模式。
host模式
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
container模式
Container模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
none模式
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
bridge模式
bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。
桥接网络详解:
当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
桥接网络拓扑结构如下
网络配置过程如下:
1. 在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
2. Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以veth***这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看。
3. 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
容器内部访问外网以及容器和主机之间的端口映射都是通过Iptables实现的,可以查看Iptables表分析。
二、Docker配置自己的网桥
1)、自定义新网桥
root@Docker:~# dpkg -l | grep bridge* #查看是否有安装brctl命令包
root@Docker:~# apt-get install bridge-utils #安装brctl命令包
root@Docker:~# docker -v #docker版本
root@Docker:~# ps -ef | grep docker #正在运行
root 6834 1 0 16:28 ? 00:00:00 /usr/bin/docker -d
root@Docker:~# service docker stop #停止
root@Docker:~# ifconfig | grep docker0 #docker默认网桥
docker0 Link encap:以太网 硬件地址 56:84:7a:fe:97:99
root@Docker:~# ifconfig docker0 down #停止docker默认网桥
root@Docker:~# brctl show #查看物理机上有哪些网桥
root@Docker:~# brctl delbr docker0 #删除docker默认网桥
root@Docker:~# brctl addbr docker_new0 #自定义网桥
root@Docker:~# ifconfig docker_new0 192.168.6.1 netmask 255.255.255.0 #给自定义网桥指定IP和子网
root@Docker:~# ifconfig | grep docker_new0 #查看发现自定义网桥已经启动
docker_new0 Link encap:以太网 硬件地址 0a:5b:26:48:dc:04
inet 地址:192.168.6.1 广播:192.168.6.255 掩码:255.255.255.0
root@Docker:~# echo 'DOCKER_OPTS="-b=docker_new0"' >> /etc/default/docker #指定网桥写入docker配置文件
root@Docker:~# service docker start #启动docker
root@Docker:~# ps -ef | grep docker #成功启动,并且成功加载了docker_new0
root 21345 1 0 18:44 ? 00:00:00 /usr/bin/docker -d -b=docker_new0
root@Docker:~# brctl show #查看当前网桥下是否有容器连接
bridge name bridge id STP enabled interfaces
docker_new0 8000.fa3ce276c3b9 no
root@Docker:~# docker run -itd CentOS:centos6 /bin/bash #创建容器测试
root@Docker:~# docker attach 7f8ff622237f #进入容器
[root@7f8ff622237f /]# ifconfig eth0 | grep addr #容器IP已经和自定义网桥一个网段,该容器IP为DHCP自动分配,不属于指定固定IP
eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:06:02
inet addr:192.168.6.2 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::42:c0ff:fea8:602/64 Scope:Link
root@Docker:~# brctl show #该网桥上已经连接着一个网络设备了
bridge name bridge id STP enabled interfaces
docker_new0 8000.fa3ce276c3b9 no veth17f560a
注:veth设备是成双成对出现的,一端是容器内部命名eth0,一端是加入到网桥并命名的veth17f560a(通常命名为veth*),他们组成了一个数据传输通道,一端进一端出,veth设备连接了两个网络设备 并实现了数据通信。
2)、Pipework 配置Docker固定IP --最新版本的docker是否支持固定IP的配置需测试
我们在自定义网桥的基础上去做固定IP配置
Pipework有个缺点就是给容器指定完固定IP,如果容器重启,那么固定IP会消失,还需要重新指定,容器量大时可写个脚本来完成
root@Docker:~# wget https://github.com/jpetazzo/pipework/archive/master.zip #下载 pipework
root@Docker:~# unzip master.zip #解压
root@Docker:~# cp pipework-master/pipework /usr/bin/ #拷贝pipework到 /usr/bin/下
root@Docker:~# chmod +x /usr/bin/pipework #赋予该命令执行权限
root@Docker:~# pipework docker_new0 -i eth1 $(docker run -itd -p 9197:80 centos:centos6 /bin/bash) 192.168.6.27/24@192.168.6.1 #创建容器,并指定固定IP
格式:pipework 网桥名 -i 指定在那块网卡上配置 <容器名or容器ID> 指定容器内IP/子网@网关 注:容器内网关就是物理机网桥的IProot@Docker:~# docker attach 2966430e2dbe #进入新容器
[root@2966430e2dbe /]# ifconfig #容器内IP为指定的IP 192.168.6.27
eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:06:05
inet addr:192.168.6.7 Bcast:0.0.0.0 Mask:255.255.255.0 #docker_new0网桥创建容器时DHCP分配的IP
eth1 Link encap:Ethernet HWaddr 82:DB:F7:A3:33:92
inet addr:192.168.6.27 Bcast:0.0.0.0 Mask:255.255.255.0 #pipework指定的固定IP,网桥还是docker_new0
[root@2966430e2dbe /]# route -n #查看路由路径
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.6.1 0.0.0.0 UG 0 0 0 eth0
192.168.6.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.6.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
[root@2966430e2dbe /]# ping www.linuxidc.com #测试网络
PING www.linuxidc.com (119.75.218.70) 56(84) bytes of data.
64 bytes from 119.75.218.70: icmp_seq=1 ttl=127 time=3.98 ms
64 bytes from 119.75.218.70: icmp_seq=2 ttl=127 time=2.98 ms
[root@2966430e2dbe /]# netstat -anptu | grep 80 #容器内80端口已经开启
tcp 0 0 :::80 :::* LISTEN -
root@Docker:~# telnet 192.168.6.27 80 #物理机上测试指定的IP是否和映射的端口等通信正常
Trying 192.168.6.27...
Connected to 192.168.6.27.
Escape character is '^]'.