docker常见的网络

使用docker info (Docker version 19.03.6)

可查询有6种网络模式

Network: bridge host ipvlan macvlan null overlay

一: bridge(桥接默认网络)

–net=bridge
Docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。

docker0为虚拟网卡,红色标注部分为容器的网关

二: host  宿主机网络

–net=host
容器不会获得一个独立的network namespace,而是与宿主机共用一个。这就意味着容器不会有自己的网卡信息,而是使用宿主
机的。容器除了网络,其他都是隔离的。
# docker run -it --net=host  busybox   进入容器查看网卡信息与宿主机相同,即网络未隔离

三:none(不常用)

–net=none
获取独立的network namespace,但不为容器进行任何网络配置,需要我们手动配置。
# docker run -it --net=none  busybox   

四、 container(与指定容器共用网络名称空间)

–net=container:Name/ID
与指定的容器使用同一个network namespace,具有同样的网络配置信息,两个容器除了网络,其他都还是隔离的。
# 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      -
访问99端口号,成功访问nginx(99端口是为容器bs的80端口映射,却访问到nginx的80,即nginx共用了bs的网络名称空间)

五、 自定义网络

与默认的bridge原理一样,但自定义网络具备内部DNS发现,可以通过容器名容器之间网络通信。

bs1和bs2没有加入到同一个网络,不可以相互通信

# docker exec -it bs1 sh  
/ # 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

六、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,转发效率更高。

macvlan技术就是在物理网卡下,添加另一张虚拟网卡,其实就是在物理网卡下添加了一个条件分支。我们可以认为报文从物理网卡进入之后,会做一个switch判断,如果该报文mac属于macvlan,则直接发往macvlan后面的网络,否则就发往原host的网络。
                                   +---------------+
                                    | 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

七、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

八、网络访问原理

 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

容器访问外界网络:

外界网络访问容器:


https://www.cnblogs.com/iiiiher/p/8067226.html    macvlan实现双vlan互通

https://www.jianshu.com/p/4ccb5e1c3016  docker 网络-overlay

https://www.cnblogs.com/mushou/p/9656401.html   docker 环境下创建 overlay 网络方案




原文地址:https://www.cnblogs.com/zjz20/p/13699492.html