AWS CNI Proposal

查看原文

AWS VPS CNI K8S

本文是 aws-cni 的设计文档。AWS Kubernetes CNI 插件可用于在 EKS 中提供类似 Flannel, Calico 这类网络软件的功能 - 为 Pod 配置必要的网络。

更具体的,它的设计目标: * 为成为 kubernetes 节点的每个 ec2 实例创建多个 Elastic network interface(ENI),分配二级 IP 地址 * 为每个 Pod 挑选一个可用的二级 IP 地址,把主机跟 Pod 的网络连起来,允许 Pod-Pod, Pod-PodInAnotherHost, Pod-AWSService, Pod-DC, Pod-Internet 多个级别的通信。

它的需求是: * Pod 网络必须有高吞吐,高可用,低延迟,Jitter * 用户可以在不同的粒度控制网络 Policy * 网络操作简单,能够将 VPC routing policies,security groups 等等粘合起来。 * Pod 网络能够秒级启动。 * 至多管理 2000 台机器。

VPC 中的 EC2 每台机器都可以有多个 ENI,每个 ENI都可以用多个 IP 地址。主 ENI IP 地址是实例创建时自动分配的,所有的二级地址由 host owner 自己管理,在这个工具中,就是由 aws-cni 插件来完成的。

能创建的 IP 上线取决于你的 VPC 的 CIDR block,例如 10.0.0.0/16. 假设,每台实例有 N 个ENI,每个 ENI 可以有 M 个地址,那最多可分配的 IP 要么是子网的可用 IP 数量,要么是 N * M - N.

架构:

  • Pod 内部 eth0 inet 是由 ENI 分配的二级地址,例如 10.0.97.30
  • Pod 内部的路由表默认路由到 169.254.1.1, 一个写死的 IP
  • 宿主机这边每块路由表里面也会有相应的 Pod IP 对应的规则
  • Pod 到 Pod 通信需要如下配置
    • 配置 veth pair:host namespace veth & pod namespace veth。
    • 在 pod namespace 里写入 Pod 的二级地址
    • 在宿主机的路由表里加上一个 route 规则,让Pod二级地址的数据包可以路由到 veth 对应的 namespace 去。

Local IP Address Manager (L-IPAM) 是用来管理可用二级IP地址池子的工具。当 kubelet 接收到添加 Pod 的请求时,L-IPAM 会马上从池子里分配一个二级IP给 Pod。当可用 IP 低于阈值了,L-IPAM 会自动创建 ENI 分配给实例,然后当其可用时再分配二级 IP。当可用 IP 超过上限时,就销掉回收 ENI。CNI Plugin 本身是通过 gPRC 与 L-IPAM 通信的。

一些使用上的 Caveats: * 遇到过 Kubernetes 无论如何也无法成功创建 Pod,Pod 一直处于 ContainerCreating 的状态。当时的原因是同时遇到了 aws-cni 自己的 bug,以及二级 IP 不够用了。 * 在 EKS 的 kube-system namespace 里面有一些叫做 aws-node 的 Pod,它们就是 aws-cni 的 daemonset 创建出来的。