本文主要介绍docker默认的网络行为。其中,包含创建的默认网络类型和如何创建用户自定义网络。
默认网络:当我们安装docker后,它会自动创建3个网络,我们也可以通过docker network命令来查看(在此就不附图了)
注意:这3个网络是被docker内建的。当我们运行一个容器需要制定的网络的时候,就可以通过--network参数来指定我们的容器连接到某一个被指定的网络。
1,bridge网络:默认连接docker0这个网桥(brctl命令在centos中可以使用,yum install bridge-utils来安装)
启动并且运行一个容器(test1)
从上图我们可以看到test1容器已经获取了一个地址为:172.17.0.2的地址。它和主机的docker0的接口地址是在同一个网络,并且将主机docker0的接口地址设置成为了网关(可以使用route -n来查看)
返回物理主机上查看网桥docker0,这时候我么可以看到已经多了一个接口。可以使用:brctl show docker0来查看
bridge模式的网络特点:1,使用一个Linux bridge,默认为docker0,。
2,使用veth对,一头在容器的网络namespace中,另一头则在docker0上。
3,该模式下docker container不具有一个公有的IP 。因为,宿主机的IP地址与veth pair 的ip地址不在同一个网段内。
4,docker采用NAT的方式,将容器内部的服务监听的端口与宿主机的某一个端口(port)进行“绑定”,使得宿主机以外的世界可以主动将网络报文发送到容器内部。
5,外界访问容器内的服务时,需要访问宿主机的ip和端口。
6,NAT模式由于是在三层网络上实现的手段。所以,它会影响网络的传输效率。
7,容器拥有独立、隔离的网格线,可以让容器和宿主机一位的世界通过NAT建立通信
效果图:
在物理主机上查看iptables的nat表,我们可以看到POSTROUTING链中做了地址伪装。MASQUERADE动作,这样容器就可以通过源地址转换成NAT访问外部网络
使用iptables -t nat -vnl 来查看
显示详细的网卡信息:docker network inspect bridge显示bridge的网络情况
2,none网络模式
none模式它不会为docker容器创建任何网络环境,更不会为容器创建网络接口。docker容器若是采用none网络模式,容器内部只能使用loopback网络设备不会再有其他网络资源。只能使用127.0.0.1的本机网络
例子:启动一个容器并且设置为none网络
docker run -it -d --network none --name test2 cnetos7:new002 /bin/bash
进入容器,并且查看网络情况:docker exec -it test2 /bin/bash
3,host网络模式
host网络模式并没有为容器创建一个隔离的网络环境。此时docke容器会和host宿主机共用一个网络namespace。简单的说,此时docker的ip地址就是宿主机etho的IP地址
特点:容器没有隔离并且和宿主机共用同一个ip地址。应该注意的是,docker容器中的服务端口不可以和宿主机端口冲突。host模式可以和其他任何模式共存
例子:我们在一台10.0网段的机器上用host模式启动一个含有web应用的docker容器,并且监听80端口。当我们在docker容器内执行任何类似于ifconfig命令查看网络环境时,我们看到的全部是宿主机上的信息。反观点说,当外界访问容器中的应用时,可以直接使用10.0网段。不用任何的NAT转换。在容器中,如文件系统和进程列表等它还是和宿主机隔离的
4,container模式
指定一个新创建的容器或者说和一个已经存在的容器共享一个Network Namespace。它并不是和宿主机共享。container模式是一个特别的网络模式,两个容器之间不存在网络隔离,但是却又和其他容器以及宿主机等存在网络隔离。
注意:由于两个容器要共享一个network namespace 。因此,需要注意端口的冲突情况,不然第二个容器将会被无法启动
思考:以上等内容,均可以实现容器内部和外部网络进行通信。那么,如何让外部网络来访问容器呢?
一:外部访问容器
当容器运行一些网络应用时需要被外部网络访问,可以使用-p或者-P来参数来指定端口映射
注意:使用-P时,docker会随机映射一个端口到容器内部。
-p则需要指定映射端口,并且在一个指定端口只可以绑定一个容器。若想绑定多个端口,则可以多次标记-p
例子: docker run -d -p 8000:80 --name web-test2 httpd(主机的8000端口和容器web-test2的80端口做了映射。外部访问时,只需要加宿主机的ip地址和8000端口号。就可以访问到容器内部的80端口)
同理,我们也可以映射到指定地址的指定端口
格式:ip地址:端口:连接容器端口。指定映射使用一个特定地址。
例子:宿主机网卡配置192.168.1.102
docker run -dit -p 192.168.1.102:10112:22 -p 192.168.1.102:80:80 centos:http
映射指定地址的任意端口
格式:IP地址::container 端口
例子:绑定192.168.1.100的任意端口到容器的80端口,本地主机会自动分配一个端口,--name为启动容器指定一个容器名
docker run -d -p 192.168.1.100::80 --name webserver centos:http
注:不仅可以绑定tcp端口,也可以绑定udp端口
例子:docker run -d -p 127.0.0.1:5000:5000/udp --name db4 commit:v1
查看映射端口配置:docker port web-test002(容器名)
docker容器端口映射实际上就是在iptables的nat表中添加DNAT规则
二:用户自定义网络
我们可以使用用户自定义的桥接网络来控制容器之间的通信。同时,依旧可以启用容器名称和IP地址的DNS自动解析。
docker默认提供了用于创建这些网络的默认网络驱动程序。在此,我们可以自动创建的有网络模式有:bridge network 、overlay network、MACVLAN network、 network plugin和remote network
当然了,我们也可以根据自身需要创建尽可能多的网络。并且,可以让其在任何给定的时间将容器连接到0个或者多个网络。甚至,还可以在不重新启动容器的情况下连接或者断开网络中的运行容器。当容器连接到多个网络时,它的外部连接是通过第一个非内部网络提供。bridge network是docker中最常见的网络类型。
例子:创建一个bridge网络
docker network create --driver bridge isolated_nw(网络名字)
查看网络详细情况:docker network inspect isolated——nw(网络名字)
查看网络是否存在:docker network ls
启动一个容器然后将其加入新创建的网络:
docker run -it'd --network isolated_nw(网络名)--那么 web002 httpd
注:加入自己创建的网络容器必须在同一个主机上。网络中的每个容器都可以立即与网络中的其他容器通信。但是网络本身是将容器与外部网络隔离开的
用户自定义的网桥网络中,不支持linking。可以这个网络中公开和发布容器端口,也就是expose and publish。在单一主机上运行一个相对小的网络,使用桥接网络是有效果的。但是,要想创建一个大的网络,则需要通过overlay网络实现