一、Docker 网络模式
- host 模式
容器和宿主机共享 network namespace - container 模式
容器和另外一个容器共享 Network namespace - none 模式:
该模式关闭了容器的网络功能 - bridge 模式
默认模式,该模式会为每一个容器分配IP,并将容器连接到一个docker 0的虚拟网桥上
1.1 bridge 模式
介绍
当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥。
此主机上启动Docker容器会连接到这个虚拟网桥上,所以有默认地址172.17.0.0/16*的地址。
从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0,另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。
bridge 示意图

实例
[root@docker01 ~]# docker run -it --network=bridge busybox
/ # hostname
5b49bbaecb7e
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:7 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:586 (586.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
1.2 host 模式
介绍
使用host网络模式, 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
host 模式不需要做网络地址转换(NAT),并且不会为每个端口创建"userlad-proxy",所以它的性能是最高的。
Host 模式示意图

实例
公用宿主机,主机名与IP地址都与宿主机公用
[root@docker01 ~]# docker run -it --network=host busybox
/ # hostname
docker01
/ # ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:0C:29:3A:CC:0A
inet addr:10.0.0.11 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe3a:cc0a/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:523747 errors:0 dropped:0 overruns:0 frame:0
TX packets:147805 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:746408332 (711.8 MiB) TX bytes:18872001 (17.9 MiB)
1.3 container 模式
介绍
该模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。
新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。
同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。
container 模式示意图

)
实例
[root@docker01 ~]# docker run -it --network container:5b49bbaecb7e busybox
/ # hostname
5b49bbaecb7e
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:656 (656.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
1.4 node 模式
介绍
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。 也就是说,这个Docker容器没有网卡、IP、路由等信息,只有lo 网络接口。
none 示意图

)
实例
[root@docker01 ~]# docker run -it --network none busybox
/ # ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
1.5 Docker 网络相关命令
| docker 命令 | 说明 |
|---|---|
| docker network connect | 将容器连接到网络 |
| docker network create | 创建一个网络 |
| docker network disconnect | 将容器从网络断开 |
| docker network inspect | 查看网络的详细信息 |
| docker network ls | 查看网络列表 |
| docker network prune | 删除所有未使用的网络 |
| docker network rm | 删除网络 |
二、Docker 跨主机容器之间的通讯macvlan
2.1 macvlan 介绍
macvlan 本身是 linux kernel 模块,其功能是允许在同一个物理网卡上配置多个 MAC 地址,即多个 interface,每个 interface 可以配置自己的 IP。
macvlan 本质上是一种网卡虚拟化技术。
2.2 macvlan网络 创建
[root@docker01 ~]# docker network create --driver macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.254 -o parent=eth0 macvlan_1
参数说明
--driver 使用的网络类型
--subnet 使用的网段/子网范围
--gateway 网段地址
-o parent=eth0 基于eth0进行的桥接/流量将在docker主机上的实际通过的接口
macvlan_1 创建网络的名称
查看创建网络
[root@docker01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
b8aa27b430c9 bridge bridge local
418c982a7562 host host local
b1627a2e64ff macvlan_1 macvlan local ##创建的macvlan网络
7adeb86e280f none null local
2.3 macvlan网络 测试
环境说明
使用镜像 centos:6.9
docker01 主机:10.0.0.11
docker02 主机:10.0.0.12
1) 开启网卡的混杂模式
ip link set eth0 promisc on
2) 创建网络
docker01 与docker02 同时操作
docker network create --driver macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.254 -o parent=eth0 macvlan_1
3) 创建容器
[root@docker01 ~]# docker run -it --network macvlan_1 --ip=10.0.0.100 busybox
[root@docker02 ~]# docker run -it --network macvlan_1 --ip=10.0.0.200 busybox
4) 访问测试
docker01 主机
-- 连接docker02 主机上的容器
/ # ping 10.0.0.200
PING 10.0.0.200 (10.0.0.200): 56 data bytes
64 bytes from 10.0.0.200: seq=0 ttl=64 time=0.324 ms
64 bytes from 10.0.0.200: seq=1 ttl=64 time=0.437 ms
-- 连接 docker02 主机
/ # ping -w 3 10.0.0.11
PING 10.0.0.11 (10.0.0.11): 56 data bytes
--- 10.0.0.11 ping statistics ---
4 packets transmitted, 0 packets received, 100% packet loss
-- 连接docker01 主机
/ # ping 10.0.0.12
PING 10.0.0.12 (10.0.0.12): 56 data bytes
64 bytes from 10.0.0.12: seq=1 ttl=64 time=0.662 ms
5) DHCP 模式
问题:每个容器都会从
1开始分配
[root@docker01 ~]# docker run -it --network macvlan_1 centos:6.9
[root@b0031b3570ba /]# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:0A:00:00:01
inet addr:10.0.0.1 Bcast:10.0.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
[root@docker02 ~]# docker run -it --network macvlan_1 centos:6.9
[root@648805d9dea4 /]# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:0A:00:00:01
inet addr:10.0.0.1 Bcast:10.0.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
2.4 macvlan 网络的缺点
- 要手动指令IP地址,容易出现IP地址冲突问题
- 使用macvlan网络的容器无法连接宿主机
三、Dcoker跨主机容器通信之overlay
3.1 overlay 介绍
overlay模式是多个Docker主机之间的分布式网络解决方案。
该网络位于特定于主机的网络之上,允许连接到它的容器(包括群集服务容器)安全地进行通信。
Docker透明地处理每个数据包与Docker守护程序主机和正确的目标容器之间正确的的路由。
[图片上传失败...(image-999d5a-1573369958207)]
3.2 overlay 网络使用条件
- 正常工作的key-value 存储服务,比如 consul、etcd、zookeeper 等
- 可以访问到 key-value 服务的主机集群
- 集群中的每台机器的hostname都是唯一的
3.3 overlay 网络模拟
环境说明
主机
docker-network 10.0.0.10
docker01 10.0.0.11
docker02 10.0.0.12
docker 版本: Docker version 19.03.4
启动consul
这里直接使用最简单的
docker方式启动
[root@consul ~]# docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -bootstrap
[root@consul ~]# netstat -lntup|grep 8500
tcp6 0 0 :::8500 :::* LISTEN 9628/docker-proxy
容器创建成功后,会启动一个8500端口,我们通过此端口可以访问consul的web管理界面
[图片上传失败...(image-a83e2c-1573369958207)]
修改docker 配置文件
--cluster-store 指定 consul 的地址。
--cluster-advertise 告知 consul 自己的连接地址。
docker01
[root@docker01 ~]# vim /etc/docker/daemon.json
{
"hosts":["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"],
"cluster-store": "consul://10.0.0.10:8500",
"cluster-advertise": "10.0.0.11:2376"
}
[root@docker01 ~]# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock
[root@docker01 ~]# systemctl daemon-reload
[root@docker01 ~]# systemctl restart docker
docker02
[root@docker02 ~]# vim /etc/docker/daemon.json
{
"hosts":["tcp://0.0.0.0:2376","unix:///var/run/docker.sock"],
"cluster-store": "consul://10.0.0.10:8500",
"cluster-advertise": "10.0.0.12:2376"
}
[root@docker02 ~]# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock
[root@docker02 ~]# systemctl daemon-reload
[root@docker02 ~]# systemctl restart docker
此时 docker01 与docker02 将自动注册到consul 数据库中
[图片上传失败...(image-bc33a3-1573369958207)]
创建 overlay 网络
docker01
[root@docker01 ~]# docker network create -d overlay --subnet 172.16.2.0/24 --gateway 172.16.2.254 ol1
[root@docker01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
7cf8a5332f43 ol1 overlay global
测试网络
创建容器查看网络
[root@docker01 ~]# docker run -it --network ol1 --name test01 busybox:latest
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:10:02:01
inet addr:172.16.2.1 Bcast:172.16.2.255 Mask:255.255.255.0
eth1 Link encap:Ethernet HWaddr 02:42:AC:12:00:02
inet addr:172.18.0.2 Bcast:172.18.255.255 Mask:255.255.0.0
[root@docker02 ~]# docker run -it --network ol1 --name test02 busybox:latest
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:10:02:02
inet addr:172.16.2.2 Bcast:172.16.2.255 Mask:255.255.255.0
eth1 Link encap:Ethernet HWaddr 02:42:AC:12:00:02
inet addr:172.18.0.2 Bcast:172.18.255.255 Mask:255.255.0.0
连接测试
[root@docker02 ~]# docker run -it --network ol1 --name test02 busybox:latest
/ # ping 172.16.2.1
PING 172.16.2.1 (172.16.2.1): 56 data bytes
64 bytes from 172.16.2.1: seq=0 ttl=64 time=0.399 ms
64 bytes from 172.16.2.1: seq=1 ttl=64 time=0.373 ms
/ # ping test01
PING test01 (172.16.2.1): 56 data bytes
64 bytes from 172.16.2.1: seq=0 ttl=64 time=0.317 ms
64 bytes from 172.16.2.1: seq=1 ttl=64 time=0.478 ms
/ # ping 223.5.5.5
PING 223.5.5.5 (223.5.5.5): 56 data bytes
64 bytes from 223.5.5.5: seq=0 ttl=127 time=6.389 ms
64 bytes from 223.5.5.5: seq=1 ttl=127 time=11.280 ms
/ # ping 10.0.0.11
PING 10.0.0.11 (10.0.0.11): 56 data bytes
64 bytes from 10.0.0.11: seq=0 ttl=63 time=0.455 ms
/ # ping 10.0.0.10
PING 10.0.0.10 (10.0.0.10): 56 data bytes
64 bytes from 10.0.0.10: seq=0 ttl=63 time=0.342 ms