xiaohanliang
Docker
Docker
  • hi
  • STORAGE DRIVER
    • 1. 什么叫联合挂载
    • 2. 镜像ID是从哪来的
    • 3. 如何组装出一个镜像
    • 4. 为什么有这么多fs@aufs
    • 5. 为什么有这么多fs@overlay
    • 6. 为什么有这么多fs@dm
    • 7. 正确安装devicemapper
  • EXEC DRIVER
    • 1. 资源限制-cgroup
    • 2. 制造小型监狱
    • 3. 切换根目录是什么概念
    • 4. 标准极简容器runC
    • 5. 尝试安装runc工具
  • KUBERNETES NETWORK
    • 0. [WIP]我想串联容器网络的故事
    • 1. 容器网络是什么样的网络
    • 2. cnm认为应该怎样让容器组网
    • 3. 为什么会有一大堆cni插件
    • 4. 为什么要设计出pod
    • 5. 怎样形成一个服务
    • 6. Service就是iptables规则
    • 7. IPVS也能实现Service
    • 8. 从集群外访问服务-nodeport
    • 9. 从集群外访问服务-ingress
    • 10. 想要把域名变成IP
    • 11. DNS是怎么实现的
    • 12. 最常见的方案@flannel
    • 13. 使用tun设备封包@flannel
    • 14. 使用vxlan设备封包@flannel
    • 15. 可不可以不封包@flannel
Powered by GitBook
On this page
  • introduction
  • vxlan里面那些问题是怎么被搞定的

Was this helpful?

  1. KUBERNETES NETWORK

14. 使用vxlan设备封包@flannel

introduction

在我们讨论如何在 flannel 中使用 vxlan 之前, 简单回顾一下 vxlan 网络中有哪些难点: vxlan 是一个多出口的大隧道, 同一个 vxlan 中不同的宿主机通过不同的 vni 鉴别彼此 , 因为没有 tun 所以不会内核态/用户态切换, 所有的包装工作都是 vtep 在内核态中完成的, 因为是 Linux 原生支持的, 所以即使做了相同的工作也不会产生态的切换, 为了使 vxlan 消息发出我们需要知道对方容器的 mac 地址以及宿主机的 ip 地址, 衍生出了arp表以及fdb表用于完成这个任务

# vxlan 模式下的 flannel 会先创建一个 flannel.1 网络设备
# 这个设备就是这台宿主机的 vtep , 其中1代表vni
# 而vtep使用的local-ip就是本宿主机的IP, 因为vtep使用eth0发出
$ ip -d link show flannel.1
5. flannel.1 <BROADCAST> mtu 1450
VXLAN id 1 172.17.130.244 nolearning


# 宿主机上的路由表, 172.17.1/2 是区别的宿主机的包, 通过vtep发出
$ route -n
172.17.0.0   255.255.255.0   cni0
172.17.1.0   255.255.255.0   flannel.1
172.17.2.0   255.255.255.0   flannel.1

# vtep 在proxy模式下会代答arp请求, 这里是我们已经收集到的别的容器的mac
$ arp -n
172.17.1.3 dev flannel.1 lladdr 42:7f:69:c7:cd:37
172.17.2.4 dev flannel.1 lladdr 7a:2c:d0:7f:48:3f

# fdb表用于在已知容器mac的情况下查宿主机的ip, 如果我们已经有两个容器mac了
# 那么相对应的, 我们也应该有两条 fdb 表记录, 用于查这两个mac的宿主机IP
$ bridge fdb show dev flannel.1 
42:7f:69:c7:cd:37 dst 192.168.139.164 self permanent
7a:2c:d0:7f:48:3f dst 192.168.130.140 self permanent

# 看下端口, vxlan模式下的flanneld在内核态中, 监听8472端口
$ netstat -ulnp | grep 8472
udp     0    0.0.0.0:8472    -

一次跨宿主机的通讯过程如下

  • 同udp模式, 这个包会先发送到 cni0 网桥上, 并根据宿主机A的路由表转发到 flannel.1手上

  • Flannel.1是一个 vtep, 开始封包, 首先通过etcd得知容器B属于宿主机B, 然后查出宿主机B的IP地址, 有了IP地址以后我们需要宿主机B - vtep的mac地址(你其实可以通过多播查) , 但实际上我们是查表的, 这个表是通过Watch Api Server得到的, 至此封包完成, 我们都还一直在内核态里

  • flannel.1 经过查表发现这个包应该从 eth0 接口发出. 到达宿主机B的8472端口(flannel.1监听中) , 这个包于是被宿主机B的 flannel.1 (vtep) 拿到

  • flannel.1 拆包后发现内层ip里写着容器B的ip, 经过检查宿主机B的路由表以后, flannel.1 把这个包丢给 cni0 网桥

  • cni0 网桥把这个包给容器B 完成通信

vxlan里面那些问题是怎么被搞定的

无论如何, vxlan里面都存在一些比较棘手的问题, 这些问题在 flannel中是怎么搞定的? flannel 相比于裸的vxlan 网络一个最大的特点在于, 我们能通过watch etcd知道现在有哪些节点加入网络了, 这允许我们主动的去添加arp/fdb 等等所有需要的信息. 而不需要多播等vxlan中比较原始的手 .

另一个比较confusing的问题在于fdb到底是干什么的?

  • 我们在裸 vxlan 中学过, 在fdb这一层里, vtep通过容器mac, 查询对端宿主机ip, 接着通过多播查询对端宿主机mac, 这样我们就有 vtep 封装出来的外层所有必要消息了(ip+mac)

  • 但是在 flannel 中, 我们又有了一种新的做法, 就是fdb表中又存上了对端vtep的mac地址+ip地址, 这里真的很tricky的点在于, 最新版的flannel 这下把宿主机的信息也全都存上了, 这样可以避免一次多播查mac地址

  • 想不明白, 先放这儿吧, 蛋疼

Previous13. 使用tun设备封包@flannelNext15. 可不可以不封包@flannel

Last updated 4 years ago

Was this helpful?