Docker 容器跨主机通信 - Flannel

news2024/11/25 22:44:18

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.coloradmin.cn/o/1050501.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java mongodb 并表 group 查询 Bson

对mongodb的使用中&#xff0c;需要将发生额表occr期初表open表&#xff0c;进行union的并表操作后&#xff0c;再进行group&#xff0c;sum&#xff0c;排序&#xff0c;分页操作。 查询了一番后&#xff0c;mongodb4.4版本后&#xff0c;新增了一个管道符&#xff0c;$union…

什么是 DNS 泛洪攻击(DNS 泛洪)

什么是 DNS 泛洪攻击&#xff08;DNS 泛洪&#xff09;&#xff1f; 域名系统 &#xff08;DNS&#xff09; 是用于在网站的机器可读地址&#xff08;例如 191.168.0.1&#xff1a;80&#xff09;和人类可读名称&#xff08;例如 radware.com&#xff09;之间进行解析的目录DN…

【HUAWEI】单臂路由

目录 ​ &#x1f96e;写在前面 &#x1f96e;2.1、拓扑图 &#x1f96e;2.2、操作思路 &#x1f96e;2.3、配置操作 &#x1f363;2.3.1、LSW4配置 &#x1f363;2.3.2、R2配置 &#x1f363;2.3.3、测试网络 &#x1f990;博客主页&#xff1a;大虾好吃吗的博客 &…

​面试官:谈谈 Go 泛型编程

大家好&#xff0c;我是木川 泛型编程是一种编程范式&#xff0c;它允许编写具有参数化类型的代码&#xff0c;从而增加代码的复用性和灵活性。在泛型编程中&#xff0c;你可以编写一段代码&#xff0c;使其适用于不同类型的参数&#xff0c;而不需要为每种类型编写不同的实现。…

js 时差计算 根据时间戳获取相差时间 几时几分几秒

上代码 // 如下&#xff1a;封装方法直接调用console.log("根据时间戳差值计算相差几小时几分几秒"); console.log("时间相差", timestampDifference(1695522383442 ,1695521518845)); 根据测试代码段 可以在浏览器控制台打印&#xff1a; 可以看到 &…

No148.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

No150.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

MacBook Pro 电池电量限制充电怎么设置AlDente Pro for Mac最大充电限制工具

通过充电电量限制工具可以更好的保护MacBook Pro的电池&#xff0c;通过 AlDente Pro 您可以设置电池的最大充电百分比设置为 20&#xff05; 至 100&#xff05;&#xff0c;然后&#xff0c;它将保持在所需的电池百分比&#xff0c;然后再次使用电源适配器进行充电。 AlDent…

led灯什么牌子的质量好?Led护眼台灯排行榜

现在我们很多家长对自己孩子的视力十分关心&#xff0c;生怕自己的孩子是近视、远视、弱视等等。对于父母而言&#xff0c;在孩子读书压力大课业重的关键时期&#xff0c;为孩子选择合适的桌椅&#xff0c;保护灯具从而保护孩子的眼睛是非常重要的事情!那么买给孩子读书做功课的…

如何改变讨好型人格,做回真正的自己

讨好型人格虽然说不上疾病那么严重&#xff0c;但是又切实的影响了正常的生活&#xff0c;阻碍了个人的事业发展&#xff0c;在人际关系方面也同样面临诸多不良影响。 根据我这段时间的阅读&#xff0c;尤其是知乎上关于讨好型人格的话题实在太多太多。那么如何才能摆脱讨好型…

Java实现使用多线程,实现复制文件到另一个目录,起不一样的名字,创建100万个数据

目录 1 需求2 实现 1 需求 我现在有一个300MB 的文件&#xff0c;想要根据这个文件&#xff0c;创建100万个大小一样的&#xff0c;名称不一样&#xff0c;如何实现&#xff0c;如何比较快点实现 2 实现 1 先准备好这个文件 2 准备好目录 3 写代码 private static void crea…

大数据分布式处理框架Hadoop

大数据是什么 大数据容量常以TB、PB、甚至EB为单位&#xff0c;远超传统数据库的承载能力&#xff0c;无论入库还是查询都出现性能瓶颈。 Hadoop是什么 Hadoop是开源的分布式计算技术框架&#xff0c;用于处理大规模数据和实现分布式存储。 Hadoop核心组件 HDFS&#xff08;…

PHP8的数据封装(数据隐藏)-PHP8知识详解

面向对象的特点之一就是封装性&#xff0c;也就是数据封装&#xff0c;也被称为数据隐藏。 php8通过限制访问权限来实现数据的封装性&#xff0c;这里用到了public、private、protected、static和final几个关键字。下面来介绍前3个。 1.、public&#xff08;公共成员&#xf…

JavaSE学习之--继承和多态

&#x1f495;"越是不思考的人&#xff0c;越不愿倾听别人说话。"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;JavaSE学习之--继承和多态 目录 一.继承(inheritance) 1.为什么要有继承 2.继承的概念 3.继承的语法及代码实现 4.在子类中访…

【1++的Linux】之进程(四)

&#x1f44d;作者主页&#xff1a;进击的1 &#x1f929; 专栏链接&#xff1a;【1的Linux】 文章目录 一&#xff0c;进程创建二&#xff0c;进程等待三&#xff0c;进程终止 一&#xff0c;进程创建 在Linux中我们通过fork来创建一个新的进程。新创建的进程叫做子进程&…

No149.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

No147.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

logback.xml springboot 项目通用logback配置,粘贴即用,按日期生成

<configuration scan"false" scanPeriod"10 seconds"><!-- 定义日志存放的根目录 --><property name"log.dir" value"./logs" /><!-- 彩色日志依赖的渲染类 --><conversionRule conversionWord"clr&q…

求职面试,如何赢得面试官的满意赞许?

在面试的时候&#xff0c;我们会遇到很多突发事件&#xff0c;这些事件让我们不能很好地将面试进行下去。那么&#xff0c;在出现事情的时候&#xff0c;我们应该如何让面试官满意&#xff1f; 1、选择得体的服装 在面试的时候&#xff0c;想要面试官更好地选择自己&#x…

后端基础php

虚拟机安装网络方面名词介绍快速自建web环境&#xff08;phpstudy&#xff09;前端基础mysql语法前端【展示】----后端【功能实现】标准php 【ASP / ASPX / PHP / JSP】0基础 --->php入门编程--->代码 对逻辑要求高变量--->会改变的量 php---->$aHello…