DEVOPS: K8s集群网络

概述

  • 阿里云 K8S 集群网络目前有两种方案
    • 一种是 flannel 方案
    • 另外一种是基于 calico 和弹性网卡 eni 的 terway 方案
  • Terway 和 flannel 类似,不同的地方在于
  • terway 支持 Pod 弹性网卡,以及 NetworkPolicy 功能
  • 这里,我们以 flannel 为例,分析阿里云 K8S 集群网络的实现方法
  • 我们会从两个角度去分析
    • 一个是网络的搭建过程
    • 另外一个是基于网络的通信
  • 我们的讨论基于当前的 1.12.6 版本
  • 总体上来说,阿里云 K8S 集群网络配置完成之后
  • 如下图,包括集群 CIDR,VPC 路由表,节点网络,节点的 podCIDR,节点上的虚拟网桥 cni0,连接 Pod 和网桥的 veth 等部分
  • 类似的图,大家可能在很多文章中都看过,但是因为其中相关配置过于复杂,比较难理解
  • 这里我们可以把这些配置,分三种情况来理解:集群配置,节点配置以及 Pod 配置
  • 与这三种情况对应的,其实是对集群网络 IP 段的三次划分:
    • 首先是集群 CIDR
    • 接着为每个节点分配 podCIDR(即集群 CIDR 的子网段)
    • 最后在 podCIDR 里为每个 Pod 分配自己的 IP

集群网络搭建

  • 集群的创建,基于云资源 VPC 和 ECS,在创建完 VPC 和 ECS 之后
  • 我们基本上可以得到如下图的资源配置
  • 我们得到一个 VPC,这个 VPC 的网段是 192.168.0.0/16
  • 我们得到若干 ECS,他们从 VPC 网段里分配到 IP 地址
### 集群阶段
  • 在以上出初始资源的基础上,我们利用集群创建控制台得到集群 CIDR
  • 这个值会以参数的形式传给集群节点 provision 脚本,并被脚本传给集群节点配置工具 kubeadm
  • kubeadm 最后把这个参数写入集群控制器静态 Pod 的 yaml 文件 kube-controller-manager.yaml
  • 集群控制器有了这个参数,在节点 kubelet 注册节点到集群的时候
  • 集群控制器会为每个注册节点,划分一个子网出来,即为每个节点分配 podCIDR
  • 如上图,Node B 的子网是 172.16.8.1/25,而 Node A 的子网是 172.16.0.128/25
  • 这个配置会记录到集群 node 的 podCIDR 数据项里

节点阶段

  • 经过以上集群阶段,K8S 有了集群 CIDR,以及为每个节点划分的 podCIDR
  • 在此基础上,集群会下发 flanneld 到每个阶段上,进一步搭建节点上,可以给 Pod 使用的网络框架
  • 这里主要有两个操作,第一个是集群通过 Cloud Controller Manager 给 VPC 配置路由表项
  • 路由表项对每个节点有一条
  • 每一条的意思是,如果 VPC 路由收到目的地址是某一个节点 podCIDR 的 IP 地址
  • 那么路由会把这个网络包转发到对应的 ECS 上
  • 第二个是创建虚拟网桥 cni0,以及与 cni0 相关的路由
  • 这些配置的作用是,从阶段外部进来的网络包,如果目的 IP 是 podCIDR,则会被节点转发到 cni0 虚拟局域网里
  • 注意:实际实现上,cni0 的创建,是在第一个使用 Pod 网络的 Pod 被调度到节点上的时候
  • 由 flannal cni 创建的,但是从逻辑上来说,cni0 属于节点网络,不属于 Pod 网络,所以在此描述

Pod 阶段

  • 在前边的三个阶段,集群实际上已经为 Pod 之间搭建了网络通信的干道
  • 这个时候,如果集群把一个 Pod 调度到节点上,kubelet 会通过 flannel cni 为这个 Pod
    本身创建网络命名空间和 veth 设备
  • 然后,把其中一个 veth 设备加入到 cni0 虚拟网桥里,并为 Pod 内的 veth 设备配置 ip 地址
  • 这样 Pod 就和网络通信的干道连接在了一起
  • 这里需要强调的是,前一节的 flanneld 和这一节的 flannel cni 完全是两个组件
  • flanneld 是一个 daemonset 下发到每个节点的 pod,它的作用是搭建网络(干道)
  • 而 flannel cni 是节点创建的时候,通过 kubernetes-cni 这个 rpm 包安装的 cni 插件,其被 kubelet 调用,用来为具体的 pod 创建网络(分枝)
  • 理解这两者的区别,有助于我们理解 flanneld 和 flannel cni 相关的配置文件的用途
  • 比如 /run/flannel/subnet.env,是 flanneld 创建的,为 flannel cni 提供输入的一个环境变量文件
  • 又比如 /etc/cni/net.d/10-flannel.conf,也是 flanneld pod(准确的说,是 pod 里的脚本 install-cni)从 pod 里拷贝到节点目录,给 flannel cni使用的子网配置文件

通信

  • 以上完成 Pod 网络环境搭建
  • 基于以上的网络环境,Pod 可以完成四种通信:
    • 本地通信,同节点 Pod 通信,跨节点 Pod 通信
    • 以及 Pod 和 Pod 网络之外的实体通信
  • 其中本地通信,说的是 Pod 内部,不同容器之前通信
  • 因为 Pod 内网容器之间共享一个网络协议栈,所以他们之间的通信,可以通过 loopback 设备完成
  • 同节点 Pod 之间的通信,是 cni0 虚拟网桥内部的通信,这相当于一个二层局域网内部设备通信
  • 跨节点 Pod 通信略微复杂一点,但也很直观,发送端数据包,通过 cni0 网桥的网关,流转到节点上,然后经过节点 eth0 发送给 VPC 路由,这里不会经过任何封包操作
  • 当 VPC 路由收到数据包时,它通过查询路由表,确认数据包目的地,并把数据包发送给对应的 ECS 节点
  • 而进去节点之后,因为 flanneld 在节点上创建了真的 cni0 的路由,所以数据包会被发送到目的地的 cni0 局域网,再到目的地 Pod
  • 最后一种情况,Pod 与非 Pod 网络的实体通信,需要经过节点上 iptables 规则 做 snat
  • 而此规则就是 flanneld 依据命令行 --ip-masq 选项做的配置

总结

  • 以上是阿里云 K8S 集群网络的搭建和通信原理
  • 我们主要通过网络搭建和通信两个角度去分析 K8S 集群网络
  • 其中网络搭建包括初始阶段,集群阶段,节点阶段以及 Pod 阶段
  • 这么分类有助于我们理解这些复杂的配置。而理解了各个配置,集群通信原理就比较容易理解了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值