增强 Kubernetes 网络扩展性和性能 - 阿里
2020-04-26 tech network troubleshooting 5 mins 18 图 1994 字
https://mp.weixin.qq.com/s/e4Ph3scexAZKGHA8Yds3rQ
1. Kubernetes Service 性能和扩展性问题
默认的 Kubernetes 的 Service 实现 kube-proxy,它是使用了 iptables 去配置 Service IP 和负载均衡:
如上图所示:
- 负载均衡过程的 iptables 链路长,导致网络延时显著增加,就算是 ipvs 模式也是绕不开 iptables 的调用;
- 扩展性差。iptables 规则同步是全量刷的,Service 和 Pod 数量多了,一次规则同步都得接近 1s;Service 和 Pod 数量多了之后,数据链路性能大幅降低。
NetworkPolicy 性能和扩展性问题
NetworkPolicy 是 Kubernetes 控制 Pod 和 Pod 间是否允许通信的规则。目前主流的 NetworkPolicy 实现基于 iptables 实现,同样有 iptables 的扩展性问题:
- iptables 线性匹配,性能不高, Scale 能力差
- iptables 线性更新,更新速度慢
使用 eBPF 加速 Service 和 NetworkPolicy 扩展性
关于 eBPF 的介绍如下:
- Linux 在最近版本提供的可编程接口
- 通过 tc-ebpf 将 ebpf 程序注入到网卡中
- 用于大幅降低网络链路的长度和复杂度
如上图所示,使用 tc 工具注入 eBPF 程序到 Pod 的网卡上,可以直接将 Service 和 NetworkPolicy 在网卡中解决,然后直接转发到弹性网卡,大幅降低网络复杂度:
- 每个节点上运行 eBPF Agent,监听 Service 和 NetworkPolicy,配置容器网卡的 Ingress 和 Egress 规则;
- 在 Egress 的 eBPF 程序中,判断访问 k8s Service IP 的请求直接负载均衡到后端 Endpoint;
- 在 Ingress 的 eBPF 程序中,根据 NetworkPolicy 规则计算源 IP 决定是否放行。
PS:我们使用 Cilium 作为节点上的 BPF-agent 去配置容器网卡的 BPF 规则,已贡献 Terway 相关适配:https://github.com/cilium/cilium/pull/10251
性能对比
- 通过 eBPF 对链路的简化,性能有明显提升,相对 iptables 提升 32%, 相对 ipvs 提升 62%;
- 通过编程的 eBPF 的形式,让 Service 数量增加到 5000 时也几乎没有性能损耗,而 iptables 在 Service 增加到 5000 时性能损失了 61%。
2. Kubernetes Coredns 性能和扩展性问题
Kubernetes Pod 解析 DNS 域名会 search 很多次,例如上图 Pod 中 DNS 配置,当它请求 aliyun.com,会依次解析:
- aliyun.com.kube-system.svc.cluster.local -> NXDOMAIN
- aliyun.com.svc.cluster.local -> NXDOMAIN
- aliyun.com.cluster.local -> NXDOMAIN
- aliyun.com -> 1.1.1.1
Coredns 是中心化部署在某一个节点上的,Pod 访问 Coredns 解析经过链路过长,又是 UDP 协议,导致失败率高。
使用 AutoPath 大幅降低 Pod DNS 的查询量
由客户端 Search 变成服务端 Search:
当 Pod 请求 Coredns 时解析域名:
- Coredns 会通过源 IP 地址查询到 Pod 的信息
- 然后根据 Pod 的 Namespace 信息,匹配到它真正想访问的是哪个服务直接返回
- 客户端请求从 4 个直接减少到 1 个,降低了 75% 的 Coredns 请求,从而让失败率降低
在每个节点上使用 node-local-dns
- 拦截 Pod 的 DNS 查询的请求
- 将外部域名分流,外部域名请求不再请求中心 Coredns
- 中间链路使用更稳定的 TCP 解析
- 节点级别缓存 DNS 解析结果,较少请求中信 Coredns
ExternalDNS 直接使用阿里云的域名解析服务
- 云原生的 DNS 解析,Pod 直接请求云服务 PrivateZone 中的自定义 DNS 能力;
- 由 ExternalDNS 监听到服务和 Pod 创建后配置 PrivateZone 中的域名解析;
- 和原生的 ECS 解析同样的 DNS 解析性能。