docker官网学习–docker网络之bridge
本节介绍docker基础网络概念.以便能认识和利用各种不同的网络类型功能.
docker的网络支持插件化,驱动化定制.有一些网络驱动已经默认集成到docker中.docker网络主要有以下类型
- bridge
- host
- overlay
- macvlan
- none
- 其他网络插件
bridge
bridge是docker默认的网络驱动.如果在docker run
启动一个容器时没有指定任何网络驱动.那么默认就是bridge桥接网络.桥接网络通常适用于应用进程部署在多个独立的容器中,并且容器之间需要互相通信的场景中.
在docker环境中.bridge使用软件桥接允许容器之间通过同一个bridge互联.隔离没有连到这个bridge网络的其他容器网络.docker网络自动创建iptables规则阻止其他网络的容器访问.
当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。
在Linux中.可以使用brctl命令查看和管理网桥(需要先安装bridge-utils软件包).例如查看本机上的网桥及其端口
1 | [work@docker conf.d]$sudo brctl show |
docker 0网桥下关联了很多vethxxxxx规范命名的interfaces.每一个vethxxxx接口对应一个docker容器.在docker容器中一般是eth0的网卡
1 | [work@docker conf.d]$docker exec -it nginx ifconfig |
bridge网桥就是这样通信的,docker服务端通过vethxxxx端口和容器的eth0虚拟网卡进行通信.docker容器将宿主机的docker 0虚拟网卡的IP作为它的网关:
1 | [work@docker conf.d]$docker exec -it nginx route -n |
bridge模式是docker的默认网络模式,不写–net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。
bridge网络模式如下所示:
bridge网桥是docker的默认网络驱动.如果用户在创建容器时自定义了Bridge网络.那么自定义Bridge要优于docker默认的Bridge
用户定义的bridge和默认bridge的区别
用户定义的bridge在多个容器之间提供更好的隔离性和协调性.
连到同一个自定义的bridge的容器之间的所有端口互通.而无需通过-p参数暴露到宿主机.这让容器之间的通信更简单,而且提供更好的安全性.例如:
连到同一个自定义的bridge网络的Nginx容器和mysql容器.及时mysql容器没有暴露任何端口.nginx也可以访问mysql容器的3306端口.
而默认的Bridge网络,则需要将mysql容器通过
-p
参数暴露3306端口给宿主机.自定义bridge网络提供容器的主机名DNS解析
默认的bridge网络下的容器间不能通过主机名互相访问,只能通过IP地址.(除非使用—link参数,但是这个参数已经废弃).而用户自定义的bridge网络则可以直接访问对方的主机名.
- 自定义bridge网络配置更方便
配置一个默认bridge网络,会影响到全局所有容器.而且需要重启docker服务.使用docker network create
可以创建一个自定义bridge网络.,而且可以分别配置
创建和管理自定义bridge网络
创建命令:
1 | #创建自定义网络名称为my-net |
删除自定义网络:
1 | #如果有容器正在使用该网络,需要先断开容器 |
管理自定义网络下的容器
创建一个自定义网络下的容器
1 | #在创建容器的时候指定自定义网络名 |
将一个正在运行的容器关联(移除)自定义网络
1 | #关联容器和自定义网络命令格式: |
实验:
- 默认的bridge网络,容器之间无法互相访问对方的主机名.只能通过iP地址通信
1 | [root@localhost ~]$docker run -itd --rm --name=busybox busybox |
- 自定义的Bridge网络,可以在容器之间互相访问主机名
1 | #创建一个自定义网络 |
- 连接到不同的bridge网络下的容器互相之间网络隔离
1 | docker network create bridge |
由于博客不能识别go模板语法,所以省去了go模板,直接用docker inspect busybox1命令来代替.实际场景中该命令无法直接获取容器IP
将容器从自定义bridge网络中移除
1 | #将jesse从jesse网络移除 |
将一个正在运行的容器加入到自定义bridge网络
1 | #将jesse加回到jesse网络 |
宿主机转发容器端口
默认情况下,bridge网络不会转发外部的请求到容器.开启转发需要更改2个设置:
1.修改内容,开启转发
1 | sysctl net.ipv4.conf.all.forwarding=1 |
2.更改iptables的转发的默认规则
1 | sudo iptables -P FORWARD ACCEPT |
更改默认Bridge网络配置
docker0网桥是在docker daemon启动时自动创建的.IP默认为172.17.0.1/16.所有连到docker 0网桥的docker容器都会在这个IP范围内选取一个未占用的IP使用.并连接到docker 0网桥上
docker提供了一些参数帮助用户自定义docker0网桥的设置
- —bip=CIDR: 设置Docker0的IP地址和子网范围.使用CIDR格式.例如192.168.0.1/24.需要注意的是这个参数仅仅是配置docker0的,对其他自定义的网桥无效.
- —fixed-cidr=CIDR:限制docker容器获取iP的范围.默认情况下docker容器获取的IP范围为整个docker0网桥的IP地址段,也就是—bip指定的地址范围.此参数可以将docker容器缩小到某个子网范围.
- —mtu=BYTES: 指定docker0的最大传输单元(MTU)
1 | #更改daemon.json配置文件.下面这个例子修改了docker0网络的网段地址 |