Docker 容器跨主机通信 - Flannel

image-20220909094036787

Author:rab


目录

    • 前言
    • 一、架构及环境
    • 二、服务部署
      • 2.1 Etcd 部署
      • 2.2 Flannel 部署
      • 2.3 Docker 网络配置
    • 三、容器通信验证及路由分析
      • 3.1 通信验证
      • 3.2 路由转发分析
      • 3.3 数据分发分析
    • 总结


前言

今天是中秋佳节,首先在此祝大家“中秋快乐,阖家团圆”。

今天我们要讲的一个内容就是 Docker 容器跨主机的通信方案,我们都知道,在 Docker Swarm、K8s 领域中均涉及到了容器间的通信问题。而 Docker 容器跨主机通信本身就有很多方式,其中就包括了其原生网络 Overlay 和 MacVlan 方案及第三方网络方案,如 Flannel、Calico 和 Weave 等网络通信方案,今天我们就来看看 Flannel 是到底是如何实现通信的(重点是掌握原理)。

一、架构及环境

1、容器通信架构

Etcd-Flannel-Docker

2、实验环境

Hostserverversion备注
192.168.56.120Docker、Flannel23.0.6、0.22.3Docker 服务、Flannel 网络
192.168.56.121Docker、Flannel23.0.6、0.22.3Docker 服务、Flannel 网络
192.168.56.122Etcd3.4.27Etcd 服务

这里为了快速实验,我们的 Etcd 采用单节点的方式部署。

二、服务部署

2.1 Etcd 部署

二进制包下载地址:https://github.com/coreos/etcd/releases

除了二进制方式安装外,还可通过 Docker 方式安装

1、二进制部署

# 复制至shell终端并执行
ETCD_VER=v3.4.27
GOOGLE_URL=https://storage.googleapis.com/etcd
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GOOGLE_URL}
rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
rm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-test
curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download-test --strip-components=1
rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz# 配置环境变量
cp /tmp/etcd-download-test/etcd* /usr/bin/# 版本验证
etcd --version
etcdctl version

image-20230920160207562

2、编写配置文件

mkdir /data/etcd/data && mkdir /etc/etcd && vim /etc/etcd/etcd.conf
#[member]
ETCD_NAME="etcd"
ETCD_DATA_DIR="/data/etcd/data"
ETCD_LISTEN_CLIENT_URLS="http://192.168.56.122:2379,http://127.0.0.1:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.56.122:2379,http://127.0.0.1:2379"

参数说明:

# ETCD_NAME 节点名称
# ETCD_DATA_DIR 数据目录
# ETCD_LISTEN_CLIENT_URLS 客户端访问监听地址
# ETCD_ADVERTISE_CLIENT_URLS 客户端通告地址
# ETCD_ENABLE_V2
# 在 ETCD v3.4 版本中 ETCDCTL_API=3 和 --enable-v2=false 成为了默认配置
# 如要使用 ETCD v2 版本, 需要 ETCD_ENABLE_V2=true,否则会报错“404 page not found”

3、配置 systemd 管理

vim /lib/systemd/system/etcd.service
[Unit]
Description=etcd
Documentation=https://github.com/coreos/etcd
Conflicts=etcd.service[Service]
Type=notify
ExecStart=/usr/bin/etcd
EnvironmentFile=/etc/etcd/etcd.conf
Restart=on-failure
RestartSec=10
LimitNOFILE=65536[Install]
WantedBy=multi-user.target

启动并设置开机自启动

systemctl start etcd.service
systemctl enable etcd.service
systemctl status etcd.service

image-20230920162318703

可正常数据读写!

4、Etcd 添加网段

vim /data/etcd/flannel-config.json
----------------------------------------------
{
"Network": "10.2.0.0/16",
"SubnetLen": 24,
"SubnetMin": "10.2.1.0",
"SubnetMax": "10.2.254.0",
"Backend":{"Type": "vxlan"}
}
----------------------------------------------
# 参数说明:
# Network(字符串):CIDR格式的IPv4网络,用于整个flannel网络。(这是唯一的强制密钥。)
# SubnetLen(整数):分配给每个主机的子网大小,除非Network小于24,否则默认为24(即/24)。
# SubnetMin(字符串):子网分配应从哪个IP范围开始,默认为第一个子网Network。
# SubnetMax(字符串):子网分配应结束的IP范围的结尾,默认为最后一个子网Network。
# Backend(后端):要使用的后端类型和该后端的特定配置。
etcdctl --endpoints http://192.168.56.122:2379 put /docker/network/config < /data/etcd/flannel-config.json# 如果你在Etcd本地,可以不指定endpoints(远程则需指定,与连接MySQL、Redis一个道理)
etcdctl put /docker/network/config < /data/etcd/flannel-config.json

5、数据验证

etcdctl get /docker/network/config

image-20230921103528805

Etcd 部署完成,第4、5步也验证了读写没问题!

2.2 Flannel 部署

分别在 20、21 上分别进行以下 5 步来部署

1、部署

# 下载二进制包,解压并配置环境变量
tar xzf flannel-v0.22.3-linux-amd64.tar.gz# 配置环境变量
cp flanneld mk-docker-opts.sh /usr/bin/

2、配置 systemd 管理

mk-docker-opts.sh:运行后会将 flannel 获取的网络参数写入 /run/flannel/subnet.env 文件

vim /lib/systemd/system/flanneld.service
[Unit]
Description=Flanneld
Documentation=https://github.com/coreos/flannel
After=network.target
Before=docker.service[Service]
User=root
ExecStartPost=/usr/bin/mk-docker-opts.sh
ExecStart=/usr/bin/flanneld \
-etcd-endpoints=http://192.168.56.122:2379 \
-iface=ens33 \
-ip-masq=true \
-etcd-prefix=/docker/network
Restart=on-failure
Type=notify
LimitNOFILE=65536[Install]
WantedBy=multi-user.target

3、启动 flannel

必须先提前保证 etcd 启动正常,才能使 flannel 获取正确地址段,docker 容器才能从 flannel 获取唯一地址。

systemctl daemon-reload
systemctl start flanneld.service
systemctl enable flanneld.service
systemctl status flanneld.service

2.3 Docker 网络配置

120服务器的 Docker 启动参数添加:--bip=10.2.23.1/24 --mtu=1450

121服务器的 Docker 启动参数添加:--bip=10.2.79.1/24 --mtu=1450

注意启动顺序,Etcd => flannel => Docker

注意的是,要先启动 flannel,这样的话才能根据 flannel 分配到的 IP 来修改 Docker 的启动参数。

1、修改 docker 启动参数

vim /lib/systemd/system/docker.service
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --bip=10.2.23.1/24 --mtu=1450
...
...

2、启动 Docker

systemctl daemon-reload
systemctl start docker.service
systemctl enable docker.service
systemctl status docker.service

3、此时看看服务器就多了一个 flannel 的虚拟网卡

其 IP 正是我们 flannel 配置文件中指定的 IP 段,此时 docker0 的 IP 也发生了变化,因为上面我们修改了 docker 服务的启动参数。

image-20230921104106895

三、容器通信验证及路由分析

3.1 通信验证

1、120 服务器运行测试容器

docker run -it --rm --name test120 busybox

image-20230921110641057

2、121 服务器运行测试容器

docker run -it --rm --name test121 busybox

image-20230921110710154

3、互 Ping 连通性验证

# 120 Ping 121
ping 10.2.79.2
PING 10.2.79.2 (10.2.79.2): 56 data bytes
64 bytes from 10.2.79.2: seq=0 ttl=62 time=1.021 ms
64 bytes from 10.2.79.2: seq=1 ttl=62 time=1.897 ms
64 bytes from 10.2.79.2: seq=2 ttl=62 time=2.176 ms
64 bytes from 10.2.79.2: seq=3 ttl=62 time=1.082 ms# 121 Ping 120
ping 10.2.23.3
PING 10.2.23.3 (10.2.23.3): 56 data bytes
64 bytes from 10.2.23.3: seq=0 ttl=62 time=2.494 ms
64 bytes from 10.2.23.3: seq=1 ttl=62 time=1.734 ms
64 bytes from 10.2.23.3: seq=2 ttl=62 time=2.074 ms
64 bytes from 10.2.23.3: seq=3 ttl=62 time=1.913 ms

当然也能正常访问外网(如百度、京东等)!

3.2 路由转发分析

我们以 120 上的路由规则来讲解。

image-20230921115939498

  1. default via 192.168.56.2 dev ens33 proto static metric 100

    默认路由,将所有不在本地子网范围内的数据包发送到网关 192.168.56.2,通过 ens33 网卡进行传输,路由优先级为 100。

  2. 10.2.23.0/24 dev docker0 proto kernel scope link src 10.2.23.1

    将目标网段 10.2.23.0/24 的数据包通过 docker0 网卡传输,源IP地址为10.2.23.1

  3. 10.2.79.0/24 via 10.2.79.0 dev flannel.1 onlink

    将目标网段 10.2.79.0/24 的数据包通过 flannel.1 网卡传输,网关为 10.2.79.0onlink 表示网关是直接可达的,也就是在同一子网内。

  4. 192.168.56.0/24 dev ens33 proto kernel scope link src 192.168.56.120 metric 100

    将目标网段 192.168.56.0/24 的数据包通过 ens33 网卡传输,源IP地址为 192.168.56.120,路由优先级为100。

字段解释:

  • proto:表示路由协议;
  • dev:表示出接口;
  • src:表示源IP地址;
  • metric:表示路由优先级(值越小优先级越高);
  • onlink:表示网关直接可达;
  • scope link:表示本地链路,即在同一子网内。

3.3 数据分发分析

  1. 容器直接使用目标容器的 ip 访问,默认通过容器内部的eth0发送出去。
  2. 报文通过 veth pair 被发送到 vethXXX。
  3. vethXXX 直接连接到虚拟交换机 docker0 的,报文通过虚拟 bridge docker0 发送出去。
  4. 查找路由表,外部容器 ip 的报文都会转发到 flannel0 虚拟网卡,这是一个 P2P 的虚拟网卡,然后报文就被转发到监听在另一端的 flanneld。
  5. flanneld 通过 etcd 维护了各个节点之间的路由表,把原来的报文 UDP 封装一层,通过配置的 iface 发送出去。
  6. 报文通过主机之间的网络找到目标主机。
  7. 报文继续往上,到传输层,交给监听在 8285 端口的 flanneld 程序处理。
  8. 数据被解包,然后发送给 flannel0 虚拟网卡。
  9. 查找路由表,发现对应容器的报文要交给 docker0。
  10. docker0 找到连到自己的容器,把报文发送过去。

总结

过程其实很简单,重点是掌握理论,如路由转发、数据分发的过程,Flannel 依赖三层 IP 转发,但不会对数据包进行封装,属于 underlay 网络。还有就是实验过程中注意 Docker、Flannel 的启动顺序。

—END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/120644.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式文件系统FastDFS实战

1. 分布式文件系统应用场景 互联网海量非结构化数据的存储需求&#xff1a; 电商网站&#xff1a;海量商品图片视频网站&#xff1a;海量视频文件网盘&#xff1a;海量文件社交网站&#xff1a;海量图片 2.FastDFS介绍 https://github.com/happyfish100/fastdfs 2.1简介 …

MySQL学习笔记17

MySQL权限管理grant&#xff1a; 权限说明&#xff1a; Table 6.2 Permissible Privileges for GRANT and REVOKE PrivilegeGrant Table ColumnContextALL [PRIVILEGES]Synonym for “all privileges”Server administrationALTERAlter_privTablesALTER ROUTINEAlter_routin…

记录一次SQL注入src挖掘过程

记录一次小白SQL注入src挖掘过程&#xff0c;其中碰到了很多问题&#xff0c;报错和解决 先是使用谷歌语法找到一个可以注入的网站 谷歌语法&#xff1a; 公司inurl:php?id 然后该公司的URL为 URL:XXXXXXXXXX/xxx.php?id1 输入测试有无注入&#xff0c;有没有waf 发现…

传统遗产与技术相遇,古彝文的数字化与保护

古彝文是中国彝族的传统文字&#xff0c;具有悠久的历史和文化价值。然而&#xff0c;由于古彝文的形状复杂且没有标准化的字符集&#xff0c;对其进行文字识别一直是一项具有挑战性的任务。本文介绍了古彝文合合信息的文字识别技术&#xff0c;旨在提高古彝文的自动识别准确性…

队列的使用以及模拟实现(C++版本)

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;强烈推荐优质专栏: &#x1f354;&#x1f35f;&#x1f32f;C的世界(持续更新中) &#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;…

数据安全态势管理:什么是事实,什么是虚构?

考虑到组织存储大量数据的日益复杂的云环境&#xff0c;数据安全态势管理 ( DSPM )的兴起并不令人意外。使组织能够全面了解云数据资产和敏感数据的安全状况的流程对于当今的安全团队来说非常有价值。 尽管 DSPM 的重要性日益凸显&#xff0c;但人们对于它能为企业做什么和不能…

端口被占用怎么解决

第一步&#xff1a;WinR 打开命令提示符&#xff0c;输入netstat -ano|findstr 端口号 找到占用端口的进程 第二步&#xff1a; 杀死使用该端口的进程&#xff0c;输入taskkill /t /f /im 进程号&#xff08; &#xff01;&#xff01;&#xff01;注意是进程号&#xff0c;不…

ssm+vue的OA办公管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的OA办公管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&am…

Event Loop——事件循环

JS 是单线程的&#xff0c;也就是同一个时刻只能做一件事情。 那么思考&#xff1a;为什么浏览器可以同时执行异步任务呢&#xff1f;因为浏览器是多线程的。 当 JS 需要执行异步任务时&#xff0c;浏览器会另外启动一个线程去执行该任务。 也就是说&#xff0c;“JS 是单线程…

【python】基础语法

文章目录 元组列表字典集合推导式函数错误和异常处理文件和操作系统 元组 元组是一个固定长度&#xff0c;不可改变的Python序列对象。创建元组的最简单方式&#xff0c;是用逗号分隔一列值。 创建 2. 元组不可修改的解释 对于元组对象不可变的说明&#xff0c;通俗一点就是…

yolov5-6.0使用改进

代码版本V6.0 源码 YOLOv5 v6.0 release 改动速览 推出了新的 P5 和 P6 ‘Nano’ 模型&#xff1a; YOLOV5n和YOLOV5n6。 Nano 将 YOLOv5s 的深度倍数保持为 0.33&#xff0c;但将 YOLOv5 的宽度倍数从 0.50 降低到 0.25&#xff0c;从而将参数从 7.5M 降低到 1.9M&#xff0…

C2. Powering the Hero (hard version)

题目&#xff1a;样例&#xff1a; 输入 5 5 3 3 3 0 0 6 0 3 3 0 0 3 7 1 2 3 0 4 5 0 7 1 2 5 0 4 3 0 5 3 1 0 0 4输出 6 6 8 9 4 思路&#xff1a; 贪心思维题&#xff0c;这道题要求的是一张一张的凑卡牌&#xff0c;凑到的是力量赋值卡就存储好&#xff0c;抽到 0 就是英…