浅析flannel与docker结合的机制和原理
flannel
flannel可以为容器提供网络服务。
其模型为全部的容器使用一个network,然后在每个host上从network中划分一个子网subnet。
为host上的容器创建网络时,从subnet中划分一个ip给容器。
其采用目前比较流行的no server的方式,即不存在所谓的控制节点,而是每个host上的flanneld从一个etcd中获取相关数据,然后声明自己的子网网段,并记录在etcd中。
其他的host对数据转发时,从etcd中查询到该子网所在的host的ip,然后将数据发往对应host上的flanneld,交由其进行转发。
根据kubernetes的模型,即为每个pod提供一个ip。flannel的模型正好与之契合。因此flannel是最简单易用的kubernetes集群网络方案。
flannel与docker的结合
flannel的工作原理这里不重复赘述。网上有很多资料。本文主要讲一下flannel是怎么与docker结合起来的。
flannel服务启动
flannel服务需要先于docker启动。flannel服务启动时主要做了以下几步的工作:
- 从etcd中获取network的配置信息
- 划分subnet,并在etcd中进行注册
- 将子网信息记录到
/run/flannel/subnet.env中
[root@localhost run]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=4.0.0.0/16
FLANNEL_SUBNET=4.0.34.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
- 之后将会有一个脚本将subnet.env转写成一个docker的环境变量文件
/run/flannel/docker
[root@localhost run]# cat /run/flannel/docker
DOCKER_OPT_BIP="--bip=4.0.34.1/24"
DOCKER_OPT_IPMASQ="--ip-masq=true"
DOCKER_OPT_MTU="--mtu=1472"
DOCKER_NETWORK_OPTIONS=" --bip=4.0.34.1/24 --ip-masq=true --mtu=1472 "
docker服务启动
接下来,docker daemon启动,使用/run/flannel/docker中的变量,作为启动参数,启动后的进程如下
[root@localhost ~]# ps -fe|grep docker
root 4538 4536 0 Jul20 ? 00:08:04 /usr/bin/docker-current daemon --exec-opt native.cgroupdriver=systemd --selinux-enabled --log-driver=journald --bip=4.0.100.1/24 --ip-masq=true --mtu=1472
容器启动
容器之后的启动,就是由docker daemon负责了。因为配置了bip,因此创建出来的容器会使用该网段的ip,并赋给容器。即容器其实还是按照bridge的模式,进行创建的。
flannel与docker结合原理
现在问题来了,容器之间是怎么互通的呢?这里先要说道flanneld,他会在宿主机host上创建一个flannel0的设备。
[root@localhost ~]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:b7:7e:f3 brd ff:ff:ff:ff:ff:ff
inet 10.8.65.66/24 brd 10.8.65.255 scope global dynamic enp0s3
valid_lft 67134sec preferred_lft 67134sec
inet6 fe80::a00:27ff:feb7:7ef3/64 scope link
valid_lft forever preferred_lft forever
5: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state UNKNOWN qlen 500
link/none
inet 4.0.100.0/16 scope global flannel0
valid_lft forever preferred_lft forever
6: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1472 qdisc noqueue state UP
link/ether 02:42:2e:5e:cd:90 brd ff:ff:ff:ff:ff:ff
inet 4.0.100.1/24 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:2eff:fe5e:cd90/64 scope link
valid_lft forever preferred_lft forever
接下来我们在看宿主机host上的路由信息。
[root@localhost ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.8.65.1 0.0.0.0 UG 100 0 0 enp0s3
4.0.0.0 0.0.0.0 255.255.0.0 U 0 0 0 flannel0
4.0.100.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0
10.8.64.10 10.8.65.1 255.255.255.255 UGH 100 0 0 enp0s3
10.8.65.0 0.0.0.0 255.255.255.0 U 100 0 0 enp0s3
现在有三个容器分别是A/B/C
| 容器 | ip |
|---|---|
| A | 4.0.100.3 |
| B | 4.0.100.5 |
| C | 4.0.32.3 |
当容器A发送到同一个subnet的容器B时,因为二者处于同一个子网,所以容器A/B位于同一个宿主机host上,而容器A/B也均桥接在docker0上。
[root@localhost ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.02422e5ecd90 no veth2d1c803
veth916067e
借助于网桥docker0,容器A/B即可实现通信。
那么位于不同宿主机的容器A和C如何通信呢?这个时候就要用到了flannel0这个设备了。
容器A想要发送给容器C,查路由表,可以知道需要使用flannel0接口,因此将数据发送到flannel0。
flanneld进程接收到flannel0接收的数据,然后从etcd中查询出4.0.32.0/24的子网的宿主机host的ip10.8.65.53。
[root@localhost calico]# etcdctl get /coreos.com/network/subnets/4.0.32.0-24
{"PublicIP":"10.8.65.53"}
然后将数据封包,发送到10.8.65.53的对应端口,由10.8.65.53的flanneld接收,解包,并转发到对应的容器中。
浅析flannel与docker结合的机制和原理的更多相关文章
- 深入理解docker的link机制
https://yq.aliyun.com/articles/55912 摘要: 什么是docker的link机制 同一个宿主机上的多个docker容器之间如果想进行通信,可以通过使用容器的ip地址来 ...
- 一次Flannel和Docker网络不通定位问题
一次Flannel和Docker网络不通定位问题 查看路由表的配置 路由表情况 [root@k8s-master ~]# route -n Kernel IP routing table Des ...
- Docker垃圾回收机制
由Docker垃圾回收机制引发的一场血案 AlstonWilliams 关注 2017.04.01 19:00* 字数 1398 阅读 253评论 0喜欢 0 今天早晨,在我还没睡醒的时候,我们团队中 ...
- etcd和flannel实现docker跨物理机通信
实验目标 跨物理机的容器之间能直接访问docker通过Flannel可以实现各容器间的相互通信,即宿主机和容器,容器和容器之间都能相互通信 实验环境 192.168.3.50 //etcd.flann ...
- docker 垃圾回收机制
docker垃圾回收机制 作者: 张首富 时间: 2019-04-10 个人博客: www.zhangshoufu.com QQ群: 895291458 说明 对于Docker来说,存在镜像/容器/存 ...
- [转帖]Docker五种存储驱动原理及应用场景和性能测试对比
Docker五种存储驱动原理及应用场景和性能测试对比 来源:http://dockone.io/article/1513 作者: 陈爱珍 布道师@七牛云 Docker最开始采用AUFS作为文件系统 ...
- 浅析 Linux 中的时间编程和实现原理一—— Linux 应用层的时间编程【转】
本文转载自:http://www.cnblogs.com/qingchen1984/p/7007631.html 本篇文章主要介绍了"浅析 Linux 中的时间编程和实现原理一—— Linu ...
- Docker Compose 部署 Redis 及原理讲解 | 懒人屋
原文:Docker Compose 部署 Redis 及原理讲解 | 懒人屋 Docker Compose 部署 Redis 及原理讲解 4.4k 字 16 分钟 2019-10-1 ...
- logrotate机制与原理[转载]
http://blog.lightxue.com/how-logrotate-works/ 日志实在是太有用了,它记录了程序运行时各种信息.通过日志可以分析用户行为,记录运行轨迹,查找程序问题.可惜磁 ...
随机推荐
- 一个意想不到的CDO.Message 错误
原文:一个意想不到的CDO.Message 错误 几个月之前,写了一个服务从MSMQ取消息发群发邮件的程序,一直也没时间测试,今日一试,出现发送邮件时报错,异常情况如下: "Syst ...
- 思维方式--SMART原则
假设你的项目管理.系统架构的兴趣,请加微信订阅号"softjg",收藏此PM.建筑师的家 万事开头于你目标的设定,假设開始走错了,那么后面的路将会更加的错误.甚至于更加的努力犯错就 ...
- ANDROID定义自己的观点——模仿瀑布布局(源代码)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 简单介绍: 在自己定义view的时候,事实上非常easy,仅仅须要知道3步骤: 1.測量- ...
- TreeView的绑定
近期遇到了TreeView的数据库绑定问题,确实是弄了我好几天,特别是多级节点的分步绑定,最開始不分步,发现所有载入页面都卡爆了,真心让人头疼.所以放出来,给须要的朋友看看,以免大家走冤枉路. 1.仅 ...
- 系统预定义委托与Lambda表达式
NET中那些所谓的新语法之三:系统预定义委托与Lambda表达式 开篇:在上一篇中,我们了解了匿名类.匿名方法与扩展方法等所谓的新语法,这一篇我们继续征程,看看系统预定义委托(Action/Fun ...
- Hbuilder常用快捷键功能.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- SSMS2008插件开发(4)--自定义菜单
原文:SSMS2008插件开发(4)--自定义菜单 打开上次的项目MySSMSAddin中的Connect类,发现该类继于了两个接口:IDTExtensibility2和IDTCommandTarge ...
- Web服务器性能/压力测试工具http_load、webbench、ab、Siege使用教程
一.http_load 程序非常小,解压后也不到100K http_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载.但是它不同于大多数压力测试工 具,它可以以一个单一的进程运行,一般 ...
- Strongly connected(hdu4635(强连通分量))
/* http://acm.hdu.edu.cn/showproblem.php?pid=4635 Strongly connected Time Limit: 2000/1000 MS (Java/ ...
- bash下几个替换运算符的区分
bash下几个替换运算符的区分 2012-03-21 22:20:54 分类: Python/Ruby 一直对四个替换运算符比较的迷惑,分布太清楚,记下来避免再次遗忘: ${name:-word} ...