docker安装后会自动创建3种网络:bridge、host、none
bridge网络
docker安装时会创建一个名为 docker0 的Linux bridge,新建的容器会自动桥接到这个接口。
[root@server1 ns]# docker run -it --name vm1 ubuntu
使用默认方式添加容器时使用的就是bridge网络。
[root@server1 docker]# ip a
bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是,不可见的,但容器通过宿主机的NAT规则后可以访问外网。
host网络模式
host网络模式需要在容器创建时指定–network=host,host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。
[root@server1 ns]# docker run -it --name vm2 --network=host ubuntu
设定网络模式为host模式
none模式
none模式是指禁用网络功能,只有lo接口,在容器创建时使用–network=none指定
[root@server1 ns]# docker run -it --name vm3 --network=none ubuntu
设置网络模式为none。
Container 网络模式
Container 网络模式是 Docker 中一种较为特别的网络的模式。在容器创建时使用–network=container:vm1指定。(vm1指定的是运行的容器名)
[root@server1 ~]# docker run -it --name vm4 --network=container:vm1 ubuntu
设置网络模式为Container,处于这个模式下的 Docker 容器会共享一个网络栈,这样两个
容器之间可以使用localhost高效快速通信,此时vm4和vm1的网络是一样的。
除此之外,可以用–link参数将两个容器连接,使得源容器(被链接的容器)和接收容器(主动去链接的容器)之间可以互相通信,并且接收容器可以获取源容器的一些数据,如源容器的环境变量。
[root@server1 ~]# docker run -it --name vm5 --link vm1:db1 ubuntu
此时,容器vm5可以和vm1通信,这里的解析是自动生成的,可以直接ping通vm1.
自定义网络模式
docker提供了三种自定义网络驱动,bridge,overlay,macvlan,bridge驱动类似默认的bridge网络模式,但增加了一些新的功能,overlay和macvlan是用于创建跨主机网络。
[root@server1 ~]# docker network ls
[root@server1 ~]# docker network create my_net1
创建自定义网桥my_net1,这里没有选择网络模式,默认使用bridge。
创建两个容器都使用my_net1网络,发现这两个容器可以相互通信。
[root@server1 ~]# docker network create --subnet=172.10.0.0/24 \
--gateway=172.10.0.1 my_net2
创建网络时使用–subnet选项指定网段,使用–gateway指定网关。
[root@server1 ~]# docker run -it --name vm3 --network=my_net2 --ip=172.10.0.11 ubuntu
使用my_net2网络创建容器可以用–ip选项指定ip,不过必须在my_net2指定的网络内。
此时,在my_net2网络内的vm3是不可以和在my_net1网络内的vm1和vm2通信的。
[root@server1 ~]# docker network connect my_net1 vm3
连接my_net1网络和vm3容器,这样,vm3就可以和my_net1网络内的容器通信了。
容器是如何访问外网,以及外网如何访问容器
当容器访问外网时,实际上是物理机做了一个SNAT。
所有容器访问外网都是通过物理机的网络卡,出去的ip地址是物理机的地址。
而外网访问容器时则是通过和物理机的端口映射。
[root@server1 ~]# docker run -d --name nginx -p 80:80 nginx
如,创建一个搭建nginx服务的容器,映射端口为80,也就是物理机的80端口映射容器的80端口,当访问物理机的80端口时,访问的实际是容器的80端口。
访问本机ip,发现访问到容器内的nginx发布页。
上面的网络模式基本都只能使本机容器进行通信,如果是不同主机上的容器需要通信就不行了。
macvlan网络是LInux kernel提供的一种网卡虚拟化技术,无需Linux bridge,直接使用物理接口,性能极好。
做。因为要实现不同主机间容器的通信,所以至少要有两台主机,这里我在开一台server2主机,并且给这两台主机都添加一快网卡。
1.添加网卡
2.添加好一块网卡之后打开网卡混杂模式
[root@server1 ~]# cd /etc/sysconfig/network-scripts/
[root@server1 network-scripts]# cp ifcfg-ens3 ifcfg-eth1
[root@server1 network-scripts]# vim ifcfg-eth1
BOOTPROTO=none
DEVICE=eth1
ONBOOT=yes
首先编辑新网卡eth1的配置文件,不要给ip。
[root@server1 network-scripts]# ip link set eth1 promisc on
打开网卡混杂模式,两台主机都要进行同样的操作,这里不再重复。
3.在两台docker主机上各创建macvlan网络
首先,在server1上创建网络。
[root@server1 ~]# docker network create -d macvlan --subnet=192.168.0.0/24 \
--gateway=192.168.0.1 -o parent=eth1 macvlan1
创建macvlan网络,指定网段和网关
使用该网络创建两个容器vm1和vm2,指定ip为192.168.0.11和192.168.0.12。
我们发现在这个网络下的两个容器可以相互通信。
接下来在server2上也创建网络,网段和网关指定和server1一样。
[root@server2 ~]# docker network create -d macvlan --subnet=192.168.0.0/24 --gateway=192.168.0.1 -o parent=eth1 macvlan1
此时在server2上创建的vm3容器可以和server1中的的vm1容器和vm2容器进行通信,因为在同一网络下。
通信时使用的是容器的ip地址。
macvlan网络结构分析
使用mancvlan网络时没有新建linux bridge,容器的接口直接与主机网卡连接,无需NAT或端口映射,macvlan会独占主机网卡,但可以使用vlan子接口实现多。
macvlan网络在二层上是隔离的,所以不同macvlan网络的容器是不能通信的。
[root@server1 ~]# docker network create -d macvlan --subnet=192.168.1.0/24 \
--gateway=192.168.1.1 -o parent=eth1.1 macvlan2
新建一个网络macvlan2和上面创建的macvlan1属于不同网段。
[root@server1 ~]# docker run -it --name vm3 --network=macvlan2 --ip=192.168.1.33 ubuntu
新建一个容器。
[root@server1 ~]# docker network connect macvlan1 vm3