Docker Swarm 之 网络(Overlay)
摘要
-
本文介绍 Docker Swarm 的 网络(Overlay)
Overlay 简介
-
在 Docker Swarm 中,overlay 网络 是一种分布式网络驱动,用于将集群中不同主机上的容器连接到同一个逻辑网络中,就像它们在同一台主机上一样。
-
当你使用 Docker Swarm 部署服务时,Swarm 会自动使用 overlay 网络来连接不同节点上的容器,实现服务发现和负载均衡,保证容器间的通信安全(通过加密)。
-
overlay 网络特点
- 跨主机通信:容器无论在哪个节点上,都可以使用 overlay 网络进行通信。
- 内置服务发现:容器之间可以通过服务名称直接通信。
- 支持加密:Swarm 的 overlay 网络支持数据加密,提高安全性。
- 自动配置:Swarm 会自动为 overlay 网络分配子网、管理 IP 等。
Swarm 中的 overlay 网络
-
当我们初始化Swarm 时,Swarm 会自动创建两个network,一个是 bridge network:
docker_gwbridge
,一个是 overlay network:ingress
。
1 | docker network ls |
docker_gwbridge
-
查看
docker_gwbridge
详情,其网段为172.18.0.0/16
,网关为172.18.0.1
,内部有一个容器ingress-sbox
1 | docker inspect docker_gwbridge |
-
先来看这个网段
172.18.0.0/16
,我们查看主机的网络和路由表,可以看到261: docker_gwbridge
,其IP地址为172.18.0.1
,所以这里我们就可以知道docker_gwbridge
就是连接到261: docker_gwbridge
这块网卡上的,另外当前还有一个263: veth3176100@if262
虚拟网络接口也连接到261: docker_gwbridge
上,通过路由表我们得知其最终连接到2: enp0s5
上,也就是这台主机的网卡。
1 | ip a |
-
按理说
263: veth3176100@if262
虚拟网络接口应该对应到一个容器上,那么接下来我们就看一看这个容器ingress-sbox
,当前docker中并没有这个容器,那么这个容器在哪里呢?docker创建的容器都会有一个网络命名空间,其保存在宿主机的/var/run/docker/netns/
下
1 | cd /var/run/docker/netns/ |
-
进入这个网络,我们就找到与宿主机上的虚拟网络接口对应的容器网络接口了:
262: eth1@if263
1 | nsenter --net=ingress_sbox ip a |
-
这里还有一个网络接口
259: eth0@if260
,它又是与谁对接的呢?别着急,我们接着往下看。
ingress
-
查看
ingress
详情,其网段为10.0.0.0/24
,网关为10.0.0.1
,内部有一个容器ingress-sbox
,另外其有一个Peers
属性,内部包含了集群中所有的节点IP,所以从这里也能大概猜出这个网络是负责节点间通信的。
1 | docker network inspect ingress |
-
我们还是先来看这个网关
10.0.0.1
,在哪呢?宿主机的网络设备中并没有,所以它应该是docker创建的,我们还是要从/var/run/docker/netns
中查看一下,这里还有一个名称为1-idx465x3jg
的网络命名空间,我们进去看看
1 | nsenter --net=/var/run/docker/netns/1-idx465x3jg ip a |
-
在这里我们找到了
2: br0
,其IP地址为10.0.0.1
,所以它就是我们要找的网关。其上面还挂载了两个网络设备,一个是260: veth0@if259
,这个就是与ingress_sbox
中259: eth0@if260
对应的网络接口 ,另一个是258: vxlan0@if258
,其基于vxlan
协议,负责集群跨主机通信。
overlay总结
-
docker_gwbridge
中的容器ingress-sbox
,其有两块网卡,一块对接宿主机上的261: docker_gwbridge
,另一块对接/var/run/docker/netns/1-idx465x3jg
中的2: br0
。 -
实际上Swarm中的所有容器都有两个网卡,一块对接宿主机上的
261: docker_gwbridge
,另一块对接/var/run/docker/netns/1-idx465x3jg
中的2: br0
。 -
当请求到达宿主机时,会通过
enp0s5
转发到docker_gwbridge
,然后先被转到ingress-sbox
容器,然后再经过其转发到br0
网关,再由它负责查找目标容器。如果目标容器不在本节点,则通过vxlan0
网络接口转发到其它节点进行查找,中间经过一系列的网络地址转换。
-
当你通过
docker network create --driver overlay my-network
创建一个overlay网络时,Docker会创建一个类似“ingress”的网络结构(新的br0
),如果不指定ip段,其ip段会从10.0.1.0/24
开始,依次递增一个网段。但会共用docker_gwbridge
。
查看overlay网络中的负载均衡
-
启动一个service
1 | docker service create --name my-nginx --replicas 5 --publish 80:80 nginx |
-
查看
ingress_sbox
的iptables
数据链中的 mangle 表
1 | nsenter --net=/var/run/docker/netns/ingress_sbox iptables -nvL -t mangle |
-
通过
ipvsadm
查看负载均衡信息
ipvsadm 是 Linux 下管理 IPVS(IP Virtual Server)负载均衡器的命令之一
1 | # 如果没有ipvsadm,则安装 |
VXLAN是什么?
-
VXLAN(Virtual Extensible LAN)是 Cisco 公司开发的一种虚拟局域网(VLAN)技术,它可以将多个 VLAN 逻辑分组,并使用单个物理网络进行管理。VXLAN 的主要作用是提高网络性能和扩展性。
-
它本质上是一种 网络封装协议(overlay protocol),用来在已有的 IP 网络之上,构建二层(L2)虚拟网络。
为什么需要 VXLAN?
-
在传统数据中心或云计算中,经常有这样的需求:
- 跨不同物理网络或子网,部署在不同服务器上的虚拟机或容器,要能像在同一个二层网络里一样直接通信。
- VLAN(802.1Q)提供的二层隔离能力只有 12 bit VLAN ID(最多 4096 个 VLAN),在大型数据中心远远不够用。
-
数据中心想要更好的弹性、跨区域部署、容器编排、大规模租户隔离。
VXLAN 核心原理
-
VXLAN 通过封装的方式,把二层以太网帧包在 UDP 数据报里,在三层 IP 网络中传递。
-
封装格式大致是:
1 | +-------------------------+ |
-
外层 IP/UDP 用于三层传输
-
内层保留原本的二层以太网帧(如 MAC 地址)
-
VXLAN 头部里面包含了一个 VNI (VXLAN Network Identifier):24 bit,可支持 1600万个虚拟网络
-
简单示意图
1 | VM1 (10.1.1.1) ——> VTEP1 ——> Underlay IP网络 ——> VTEP2 ——> VM2 (10.1.1.2) |