docker 6 种网络类型+网络插件
使用docker info (Docker version 19.03.6)
可查询有6种网络模式
#docker info | grep Network Network: bridge host ipvlan macvlan null overlay
docker使用网桥来实现容器与主机,容器与容器之间的网络链接。网桥可以理解为一个交换机,一个网桥对应一个网络。
查看网络:
docker network ls
查看连接到某个网络上的容器有哪些
docker network inspect bridge
把容器从网络断开
docker network disconnect bridge nginx
创建网络
docker network create -d bridge my-new-network
把容器增加到网络中
docker run -d --net=my-new-network -name db training/postgres
查看容器所在的网络
docker inspect --format='{{json .NetworkSettings.Networks}}' web
官网介绍Networking overview | Docker Documentation
一: bridge(桥接默认网络)
![](https://img2020.cnblogs.com/blog/1656853/202009/1656853-20200920121634766-1816610045.png)
docker0为虚拟网卡,红色标注部分为容器的网关
自定义网络 --net bs-test(自定义的名字,也属于桥接网络)
自定义网络的优点:可以指定ip地址
docker network create --subnet=192.168.250.1/24 mybridge docker run --name eureka -itd --net mybridge --ip 192.168.250.3 scot-eureka:latest /bin/bash
bs1和bs2没有加入到同一个网络,不可以相互通信
/ # hostname 0eb59ec71d44 / # ping bs2 ping: bad address 'bs2'
# docker exec -it bs2 sh
/ # hostname a51dcef1803d / # ping bs1 ping: bad address 'bs1'
# docker run -it --name bs4 --net bs-test busybox (自定义属于桥接网络)
$ docker network ls 列出所有正在使用的网络
bs3和bs4加入到同一个网络,相互可以通信
# docker run -it --name bs=4 --net bs-test busybox
/ # ping bs3 PING bs3 (172.18.0.3): 56 data bytes 64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.151 ms 64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.115 ms
# docker run -it --name bs3 --net bs-test busybox
/ # ping bs4 PING bs4 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.126 ms 64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.286 ms
二: host 宿主机网络
–net=host
容器不会获得一个独立的network namespace,而是与宿主机共用一个。这就意味着容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。容器除了网络,其他都是隔离的。
# docker run -it --net=host busybox 进入容器查看网卡信息与宿主机相同,即网络未隔离
![](https://img2020.cnblogs.com/blog/1656853/202009/1656853-20200920122500761-1225961436.png)
docker inspect cassandra |grep "NetworkMode" "NetworkMode": "host", docker inspect cassandra |grep -i IPAddres "SecondaryIPAddresses": null, "IPAddress": "", "IPAddress": "",
三:null(不常用)
# docker run -it --net=none busybox
四、 container(与指定容器共用网络名称空间)
# docker run -itd -p 99:80 --name bs busybox 新开窗口,创建容器指定网络为container:bs # docker run -d --name nginx01 --net=container:bs nginx # docker exec -it bs sh (注意busybox使用bash进不去,用sh可以) / # netstat -anpt (nginx容器未开启时,没用建立监听) Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN - tcp 0 0 :::80 :::* LISTEN -
![](https://img2020.cnblogs.com/blog/1656853/202009/1656853-20200920125722083-438411124.png)
五、macvlan(硬件地址vlan)
Macvlan和overlay都属于bridge网络,目的是跨主机节点,实现容器通信
macvlan的原理是在宿主机物理网卡上虚拟出多个子网卡,通过不同的MAC地址在数据链路层(Data Link Layer)进行网络数据转发的,它是比较新的网络虚拟化技术,需要较新的内核支持(Linux kernel v3.9–3.19 and 4.0+)。
需要把container的ip暴露给外面,使用macvlan或者overlay技术来实现。同时macvlan的配置更简单,并且没有使用docker的bridge,转发效率更高。
+---------------+ | network stack | +---------------+ | | | | +---------+ | | +------------------+ | | +------------------+ | | +------------------+ | | | | | | | aa +----------+ | | | | eth0 +-----| macvlan0 |---+ | | | / +----------+ | | Wire +------+ +---------------+ bb +----------+ | | --------| eth0 |------/ if dst mac is /--------| macvlan1 |------+ | +------+ +---------------+ \ +----------+ | \ cc +----------+ | +-----| macvlan2 |---------+ +----------+
use macvlan
docker network create -d macvlan \ --subnet=192.168.1.0/24 \ --gateway=192.168.1.1 \ -o parent=enp4s0 mcv # 解释: # 1.创建macvlan网络,使用macvlan网络驱动 # 2.指定要桥接的网络地址 # 3.指定网关 # 4.设置要在宿主机上那块网卡上建立虚拟子网卡 # 测试 docker run --net=mcv --ip=192.168.1.99 -itd alpine /bin/sh # 运行容器,指定刚建好的macvlan网络,并制定IP地址。 # 如果不指定IP,会通过IPAM分配IP,默认是从192.168.1.2开始分配。 # 注意,分配时并不会判断地址冲突,可以通过docker的network命令去指定分配方式,这里不做赘述。 docker run --net=mcv -it --rm alpine /bin/sh # 运行另外一个容器,进行连通性测试 ping 192.168.1.99 ping 192.168.1.1
实验ping host
创建一个macvlan docker网络:
docker network create -d macvlan \ --subnet=192.168.1.0/24 \ --ip-range=192.168.1.0/24 \ -o macvlan_mode=bridge \ -o parent=enp0s3 macvlan
然后我们起一个container,ip为192.168.1.11
:
docker run -d --net=macvlan --ip=192.168.1.11 --name ngix ngix
container确实没法ping通host,但是它是能够ping通外接的switch。
container能够ping通host
利用linux创建一个macvlan类型的link,同时赋予一个与container同网段的ip:
sudo ip link add mymacvlan link enp0s3 type macvlan mode bridge sudo ip addr add 192.168.1.10/24 dev mymacvlan sudo ifconfig mymacvlan up
ping通:
ping 192.168.1.11 PING 192.168.1.11 (192.168.1.11) 56(84) bytes of data. 64 bytes from 192.168.1.11: icmp_seq=1 ttl=64 time=0.142 ms 64 bytes from 192.168.1.11: icmp_seq=2 ttl=64 time=0.069 ms 64 bytes from 192.168.1.11: icmp_seq=3 ttl=64 time=0.050 ms 64 bytes from 192.168.1.11: icmp_seq=4 ttl=64 time=0.066 ms 64 bytes from 192.168.1.11: icmp_seq=5 ttl=64 time=0.062 ms 64 bytes from 192.168.1.11: icmp_seq=6 ttl=64 time=0.064 ms
带vlan的macvlan
我理解的带vlan的macvlan其实并不是macvlan实现的,实际上是linux的子接口本身就是利用vlan来区别不同的子接口,而macvlan依附在子接口上,为子接口上加了一个mac,因此从子接口macvlan出来的报文都会带有vlan tag。
配置与上面类似,只是用的是子接口:
docker network create -d macvlan \ --subnet=192.168.2.0/24 \ --ip-range=192.168.2.0/24 \ -o macvlan_mode=bridge \ -o parent=enp0s3.20 macvlan20 docker run -d --net=macvlan20 --ip=192.168.2.11 --name ngix ngix sudo ip link add mymacvlan20 link enp0s3.20 type macvlan mode bridge sudo ip addr add 192.168.2.10/24 dev mymacvlan20 sudo ifconfig mymacvlan20 up
看一看interface
ip -d link 34: enp0s3.20@enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default link/ether 08:00:27:0a:7c:d0 brd ff:ff:ff:ff:ff:ff promiscuity 1 vlan protocol 802.1Q id 20 <REORDER_HDR> addrgenmode eui64
可以看到我们添加了一个子接口,同时这个子接口有带vlan id 20
,使用的802.1q协议。
再来ping一次,完全没问题:
~ ping 192.168.2.11 PING 192.168.2.11 (192.168.2.11) 56(84) bytes of data. 64 bytes from 192.168.2.11: icmp_seq=1 ttl=64 time=0.175 ms 64 bytes from 192.168.2.11: icmp_seq=2 ttl=64 time=0.046 ms 64 bytes from 192.168.2.11: icmp_seq=3 ttl=64 time=0.126 ms 64 bytes from 192.168.2.11: icmp_seq=4 ttl=64 time=0.061 ms
Docker 网络模型之 macvlan 详解,图解,实验完整 - 云+社区 - 腾讯云 (tencent.com)
六、overlay网络
overlay网络用于连接不同机器上的docker容器,允许不同机器上的容器相互通信,同时支持对消息进行加密
#1、创建docker swarm 集群(前提条件) docker-machine create --driver virtualbox m docker-machine create --driver virtualbox s ssh docker@192.168.99.106 -i ~/.docker/machine/machines/m/id_rsa ssh docker@192.168.99.107 -i ~/.docker/machine/machines/s/id_rsa # on m # master service on 2377 port , tcp 2377 port for cluster #management communications m is manager docker swarm init --advertise-addr 192.168.99.106 # 2、 # docker_gwbridge 172.18.0.0/16 # ingress: 10.255.0.0/16 # bridge - docker0 172.17.0.0/16 docker network ls # on s # join swarm as a work node docker swarm join --token xx 192.168.99.106:2377 # on m docker network create -d overlay --attachable my-overlay-attach # on s 不能看见my-overlay-attach docker network ls # on s 使用my-overlay-attach 创建容器后 , 使用docker network ls #可以看见my-overlay-attach docker run -itd --name s-c1 --net my-overlay-attach hub.c.163.com/library/busybox sh #on m docker run -itd --name m-c1 --net my-overlay-attach hub.c.163.com/library/busybox sh # on m docker exec -it m-c1 ping s-c1 # on s docker exec -it s-c1 ping m-c1
七、IPVLAN
Ipvlan与macvlan非常相似,但又存在显著不同。Ipvlan的子接口上并不拥有独立的MAC地址,所有共享父接口MAC地址的子接口拥有各自独立的IP。
八、网络访问原理
Veth设备的作用主要用来连接两个网络命名空间,如同一对网卡中间连着一条网线。既然是一对网卡,那么其中一块网卡称作另一块的peer。在Veth设备的一端发送数据会直接发送到另一端。
docker就是这样使用veth pair设备连接宿主机网络与容器网络。理解veth设备的工作原理对于理解bridge网络起到至关重要的作用。
# yum install -y bridge-utils-1.5-9.el7.x86_64
# brctl show bridge name bridge id STP enabled interfaces br-f8764a88ccd2 8000.02422f5f8a4c no docker0 8000.0242b035e79f no veth1884649 veth8c1abb8 vethd30a157
容器访问外界网络:
外界网络访问容器:
Macvlan与IPvlan_bob62856的博客-CSDN博客_ipvlan macvlan区别
https://www.cnblogs.com/iiiiher/p/8067226.html macvlan实现双vlan互通
https://www.jianshu.com/p/4ccb5e1c3016 docker 网络-overlay