Kubernetes为每个Pod都分配了唯一的IP地址,一个Pod里的多个容器共享PodIp地址。Kubernetes要求底层网络支持集群内任意两个Pod间的TCP/IP直接通信。Kubernetes的跨主机任意Pod访问方式主要是遵循CNI容器网络规范,目前已经有多个开源组件支持CNI,包括Flannel、Open VSwitch、Calico等。本文主要介绍在Calico的ipip模式下,K8s的Pod间访问原理。

Calico容器网络简介

Calico是一个基于BGP的纯三层网络方案,其会为每个容器(pod)分配一个可路由的IP,在通信时不需要解包和拆包,因此网络性能损耗小,易于排查和水平扩展。

Calico标志

标题Calico架构


Calico网络模型主要工作组件:

  1. Felix:Calico Agent,运行在每一台 Host 的 agent 进程,主要负责网络接口管理和监听、路由、ARP 管理、ACL 管理和同步、状态上报等,保证跨主机容器的网络互通。

  2. etcd:Calico的后端存储,主要负责网络元数据一致性,确保Calico网络状态的准确性,可以与kubernetes共用;

  3. BGP Client(BIRD):Calico 为每一台 Host 部署一个 BGP Client,使用 BIRD 实现,BIRD 是一个单独的持续发展的项目,实现了众多动态路由协议比如 BGP、OSPF、RIP 等。负责将Felix 在各Node上的设置通过BGP协议广播到Calico网络,从而实现网络互通。

  4. BGP Route Reflector:在大型网络规模中,如果仅仅使用 BGP client 形成 mesh 全网互联的方案就会导致规模限制,因为所有节点之间俩俩互联,需要 N^2 个连接,为了解决这个规模问题,可以采用 BGP 的 Router Reflector 的方法,使所有 BGP Client 仅与特定 RR 节点互联并做路由同步,从而大大减少连接数。

IPIP模式简介

Calico中的IP Pool可以使用两种模式:BGP或者IPIP。本文使用的是IPIP模式,是一种将各Node的路由之间做一个tunnel,再把网络连接起来的模式:

从字面上说,就是将一个IP数据包套在另一个IP包里,使用到了Linux提供的隧道技术。可以理解为一个基于IP层的网桥,将两个本不通的网络通过点对点连接起来。

K8s-Calico-IPIP网络实战分析

下面我们就进行基于Calico-IPIP模式下的K8s容器互联网络分析。
##实验准备
准备了1master 2slaver的K8s集群,设置为Calico-IPIP网络。每个slaver内(node1,node2)分别部署了一个Pod容器,结构示意图如下:

网络结构解析

pod网络

首先通过指令 kubectl exec -it pod1 /bin/bash</font color=grey> 进入pod1容器中,再使用指令 ip addr</font color=grey> 查看pod1内的网络设备。

ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
4: eth0@if26: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UP group default link/ether ce:83:2b:89:af:9e brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 10.100.15.150/32 scope global eth0valid_lft forever preferred_lft forever

可以看到,pod只有普通的loopback和eth0。

node网络

先查看node网络设备。

ip addr
...省略部分
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 00:16:3e:02:03:5c brd ff:ff:ff:ff:ff:ffinet 172.31.112.2/20 brd 172.31.127.255 scope global dynamic eth0valid_lft 311927346sec preferred_lft 311927346sec
4: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN group default qlen 1000link/ipip 0.0.0.0 brd 0.0.0.0inet 10.100.15.128/32 brd 10.100.15.128 scope global tunl0valid_lft forever preferred_lft forever
26: cali3ef8aad4b4e@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UP group default link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 1

node中除了eth0外,多了tunl0和cali3ef8aad4b4e(下面简称为cali.4e),结合之前的Calico简介,大家肯定可以猜到,tunl0就是Calico在IPIP模式下的隧道名称 ,而cali.4e是啥子类,注意到,该设备的编号为26。让我们回到pod1中,查看pod1内的ip link:

$ip link show eth0
4: eth0@if26: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UP mode DEFAULT group default link/ether ce:83:2b:89:af:9e brd ff:ff:ff:ff:ff:ff link-netnsid 0

eth0@if26,这里eth0连接的设备号也是26!其实这个设备就是veth pair,K8s在创建Pod的时候,会创建一个veth pair设备。设备的一端是pod2的网卡,另一端就是我们在node中看见的cali.4e了。是不是清楚了很多☺node2与之类似。
下面我们将node节点的route规则也贴上,后面会用到。

node1
route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.31.127.253  0.0.0.0         UG    0      0        0 eth0
10.100.6.128    172.31.112.1    255.255.255.192 UG    0      0        0 tunl0
10.100.9.192    172.31.127.252  255.255.255.192 UG    0      0        0 tunl0
10.100.15.128   0.0.0.0         255.255.255.192 U     0      0        0 *
10.100.15.129   0.0.0.0         255.255.255.255 UH    0      0        0 cali386c6dca3ac
10.100.15.150   0.0.0.0         255.255.255.255 UH    0      0        0 cali3ef8aad4b4e
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.31.112.0    0.0.0.0         255.255.240.0   U     0      0        0 eth0
node2
route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.31.127.253  0.0.0.0         UG    0      0        0 eth0
10.100.6.128    172.31.112.1    255.255.255.192 UG    0      0        0 tunl0
10.100.9.192    0.0.0.0         255.255.255.192 U     0      0        0 *
10.100.9.193    0.0.0.0         255.255.255.255 UH    0      0        0 cali4360a48538f
10.100.9.206    0.0.0.0         255.255.255.255 UH    0      0        0 cali2d771657bc2
10.100.9.207    0.0.0.0         255.255.255.255 UH    0      0        0 cali7116f2b12fa
10.100.15.128   172.31.112.2    255.255.255.192 UG    0      0        0 tunl0
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.31.112.0    0.0.0.0         255.255.240.0   U     0      0        0 eth0

网络结构小结

根据上节的信息,绘出当前实验网络的主要设备图。后面将进行网络连接实战。

网络连接实战

node间连接

很容易的,我们先猜测一个从pod2发往pod1的ip数据流向。

下面让我们一起来验证我们的猜测吧!使用的工具就是tcpdump啦~
分别在两个node的Cali.c2、tunl0、eth0出进行抓包分析,结果如下图所示,其中Cali.c2与tunl0的ip完全一致,因此合并输出。

按照标志的①、②、③、④来依次分析:
①:上节已经说了,pod2中的eth0(即图中的vthe0)与Cali.c2是一对veth pair,因此,Cali.c2接收到的ip流向一定与vthe0相同,为 10.100.9.206->10.100.15.150</font color=grey>。查看之前的node2 route表,发现有一条 :

 Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.100.15.128   172.31.112.2    255.255.255.192 UG    0      0        0 tunl0

所有发往10.100.15.128/255.255.255.192的ip报都需要通过tunl0,经过172.31.112.2作为gateway发送。因此,cali.c2的ip报会发往tunl0。
②:经过tunl0的ip报会被再封上一层ip。通过node2 的route规则,会发往eth0,因此我们在eth0处的抓包结果为 172.31.127.252 > 172.31.112.2: IP 10.100.9.206 > 10.100.15.150</font color=grey>

 Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.31.112.0    0.0.0.0         255.255.240.0   U     0      0        0 eth0

③、④:三和四其实就是①、②的逆过程,检查node1的route表即可知道流向。etho0将ipip拆封后,将流量发给tunl0,tunl0再转发给cali.4e。

 Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.100.15.150   0.0.0.0         255.255.255.255 UH    0      0        0 cali3ef8aad4b4e

node内连接

如果是同一个node内的两个pod进行访问,那么还会走tunl0进行ipip封装吗?
其实很容易回答这个问题,通过上节的route规则就可以知道,Calico会为每一个node分配一小段网络,同时会Wie每个pod创建一个“入”的ip route规则。如下图所示,当从pod2访问pod3时,Cali.c2是直接发出10.100.9.206-> 10.100.9.207</font color=grey>流量的,在node2的ip route中,发往10.100.9.207的ip报直接会被转发到cali.fa,不会用到tunl0,只有在node间访问的时候才会使用tunl0进行ipip封装!

 Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.100.9.207    0.0.0.0         255.255.255.255 UH    0      0        0 cali7116f2b12fa

总结

通过上节的实战与分析,相信大家一定对Calico-ipip网络有了比较清晰的印象,文章最后做个小结:

  1. IPIP模式下,node间的Pod访问会使用IPIP技术对出node的ip报进行隧道封装
  2. node内的Pod访问不会用到ipip隧道封装。
  3. Pod的ip都是由calico-node设置的IP地址池进行分配的,docker0对kubernetes设置的Pod的IP地址将不再起作用。
    下一篇我会基于本文的实战基础,对kubernetes service的网络调用进行实战分析。

K8s网络实战分析之Calico-ipip模式相关推荐

  1. 总结 Underlay 和 Overlay 网络,在k8s集群实现underlay网络,网络组件flannel vxlan/ calico IPIP模式的网络通信流程,基于二进制实现高可用的K8S集群

    1.总结Underlay和Overlay网络的的区别及优缺点 Overlay网络:  Overlay 叫叠加网络也叫覆盖网络,指的是在物理网络的 基础之上叠加实现新的虚拟网络,即可使网络的中的容器可 ...

  2. K8s网络插件Flannel,Calico

    文章目录 一.K8s网络插件flannel与calico 1. k8s网络解决方案 容器虚拟化网络方案 基于隧道 基于路由 2. CNI(容器网络接口) flannel与calico 选型比较 3. ...

  3. K8S Calico网络插件之IPIP模式

    注:本文基于Calico v3.20.1版本编写 1 关于Calico flannel是overlay网络, 主要工作在L2(VXLAN),calico主要是L3,通过BGP路由协议在机器之间传送报文 ...

  4. k8s网络之Calico网络

    Calico 是一种容器之间互通的网络方案.在虚拟化平台中,比如 OpenStack.Docker 等都需要实现 workloads 之间互连,但同时也需要对容器做隔离控制,就像在 Internet ...

  5. 【Kubernetes】k8s网络概念和实操详细说明【calico网络】【含docker不同容器网络互通配置,k8s网络互通配置】【1】

    文章目录 calico网络之间通信配置[docker容器互通流程配置] calico网络原理分析 一.Calico基本介绍 二.Calico结构组成 三.Calico 工作原理 四.Calico网络方 ...

  6. cni k8s 插件安装_第一次,如此清晰脱俗的直解K8S网络

    图片出自:<你女儿也能看懂的插画版 Kubernetes 指南> K8S 网络设计原则 K8S 网络设计原则如下: 每个 Pod 都拥有一个独立 IP 地址,Pod 内所有容器共享该 IP ...

  7. k8s网络基础学习-Calico网络插件

    第十课 k8s网络基础学习-Calico网络插件 tags: k8s网络 calico proxy arp bgp full mesh bgp RR 文章目录 第十课 k8s网络基础学习-Calico ...

  8. calico网络原理分析

    最近在搭建k8s生产环境的时候,采用了calico作为网络插件.于是写篇博客记录一下. 一.Calico基本介绍 Calico是一个纯三层的协议,为OpenStack虚机和Docker容器提供多主机间 ...

  9. k8s 网络之Calico

    目录 一.calico 概述 1.1  calico 介绍 1.2.calico 的优点 1.3.calico的缺点 1.4.calico 优势 二.Calico结构组成 2.1  架构​编辑 2.2 ...

最新文章

  1. 2017年7月十三日正式开始记录
  2. Echart的angularjs封装
  3. SeetaFace2 测试
  4. qt 实现的电视遥控系统,如何让qt响应来自遥控器的按键信息?
  5. mysql 主键自增_mysql自增主键在大量删除后如何重新设置避免断层
  6. 从Windows 2012标准版升级到数据中心版
  7. windows10 python2.7 opencv3
  8. 自动关机脚本2007-10-28 10:04@ECHO off
  9. Hbase二级索引+CDH+Lily
  10. 如何手动实现C语言中的字符串操作
  11. Confluence 6 修改日志文件的大小数量和级别
  12. Python-进阶-装饰器小结
  13. 【Postgresql-9.6.8】触发器实例(记录增、删、改)
  14. 解决vue2+vue-cli3项目ie兼容问题
  15. Dialog对话框全解
  16. 编程之美 裴波那楔数列
  17. 图书管理系统软件测试说明,图书管理系统软件测试报告
  18. 三菱plc传送文件到服务器,三菱Q系列PLC通过FTP文件传输案例介绍
  19. docker中mysql忘记密码怎么办?
  20. 从0开始教你三天完成毕业设计-项目设计

热门文章

  1. MYSQL主流版本简述
  2. 运输SaaS平台oTMS宣布完成2500万美元B轮融资
  3. 开源物联网系统 ThingsBoard 上手
  4. 可乐学习NVMe之四:粗茶淡饭NameSpace
  5. 安装ubuntu系统操作系统详细流程、ubuntu管理包命令apt和dpkg命令详细说明、一键部署openstack环境、DBeaver下载驱动报错和登录提示RSA public key.. 解决方法
  6. 关于大型机与X86服务器的性能和成本对比:答网友
  7. 探索职场真我---“DISC测评”
  8. python猜谜语小游戏代码_树莓派趣学实战100例--网络应用+Python编程+传感器+服务器搭建...
  9. React Native小菜鸡的踩坑排雷记录(1)
  10. 思科Webex定义协作的未来