docker 6 种网络类型+网络插件

使用docker info (Docker version 19.03.6)

可查询有6种网络模式

1
2
#docker info   |  grep  Network
  Network: bridge host ipvlan macvlan  null overlay

docker使用网桥来实现容器与主机,容器与容器之间的网络链接。网桥可以理解为一个交换机,一个网桥对应一个网络。

查看网络:

1
docker network ls

查看连接到某个网络上的容器有哪些

1
docker network inspect bridge

把容器从网络断开

1
docker network disconnect bridge nginx

创建网络

1
docker network create -d bridge my-new-network

把容器增加到网络中

1
docker run -d --net=my-new-network -name db training/postgres

查看容器所在的网络

1
docker inspect --format='{{json .NetworkSettings.Networks}}' web

官网介绍Networking overview | Docker Documentation

一: bridge(桥接默认网络)

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

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

自定义网络 --net  bs-test(自定义的名字,也属于桥接网络)

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

自定义网络的优点:可以指定ip地址

1
2
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没有加入到同一个网络,不可以相互通信

# docker exec -it bs1 sh  
1
2
3
4
/ # hostname
0eb59ec71d44
/ # ping bs2
ping: bad address 'bs2'

# docker exec -it bs2 sh

1
2
3
4
/ # hostname
a51dcef1803d
/ # ping bs1
ping: bad address 'bs1'

# docker run -it --name bs4 --net  bs-test  busybox  (自定义属于桥接网络)

1
$ docker network ls  列出所有正在使用的网络

bs3和bs4加入到同一个网络,相互可以通信

# docker run -it --name bs=4  --net bs-test  busybox

1
2
3
4
/ # 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

1
2
3
4
/ # 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和端口。容器除了网络,其他都是隔离的。

1
# docker run -it --net=host  busybox   进入容器查看网卡信息与宿主机相同,即网络未隔离
1
2
3
4
5
6
7
docker  inspect   cassandra   |grep "NetworkMode"
            "NetworkMode": "host",
 
docker  inspect   cassandra   |grep  -i  IPAddres
            "SecondaryIPAddresses": null,
            "IPAddress": "",
                    "IPAddress": "",

三:null(不常用)

–net=none
需要使用 --network=none 参数指定,不分配局域网的IP。
1
# docker run -it --net=none  busybox  

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

–net=container:Name/ID
与指定的容器使用同一个network namespace,具有同样的网络配置信息,两个容器除了网络,其他都还是隔离的。
1
2
3
4
5
6
7
8
9
10
11
# 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的网络名称空间)

五、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的网络。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
                                   +---------------+
                                    | network stack |
                                    +---------------+
                                        |  |  |  |
                              +---------+  |  |  +------------------+
                              |            |  +------------------+  |
                              |            +------------------+  |  |
                              |                               |  |  |
                              |            aa  +----------+   |  |  |
                              | eth0     +-----| macvlan0 |---+  |  |
                              |         /      +----------+      |  |
 Wire   +------+       +---------------+   bb  +----------+      |  |
--------| eth0 |------/ if dst mac is /--------| macvlan1 |------+  |
        +------+     +---------------+ \       +----------+         |
                                        \  cc  +----------+         |
                                         +-----| macvlan2 |---------+
                                               +----------+

use macvlan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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网络:

1
2
3
4
5
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:

1
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:

1
2
3
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通:

1
2
3
4
5
6
7
8
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。

 配置与上面类似,只是用的是子接口:

1
2
3
4
5
6
7
8
9
10
11
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

1
2
3
4
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一次,完全没问题:

1
2
3
4
5
6
~ 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)

什么?网卡也能虚拟化? (qq.com)

六、overlay网络

overlay网络用于连接不同机器上的docker容器,允许不同机器上的容器相互通信,同时支持对消息进行加密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#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

1
2
3
4
5
6
# 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

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




 

posted @   凡人半睁眼  阅读(1313)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示