白月光与朱砂痣 -Flannel 略糙,Cilium 太美
社交网络有一股神奇的力量,它总是能重新定义一些老的词汇。比如“白月光”和“朱砂痣”早已不是张爱玲小说里说的那个意思了,如今在网上它们会被用来表示人的喜新厌旧。借我们的专业术语来讲,这叫“词汇重载”。我想把 K8s 原生的 Flannel 比作朱砂痣,而本文及接下来几篇要说到的 Cilium 看成白月光。这个系列我老早就想跟大家分享了,因为 Cilium 它太香,太漂亮了。Cilim 读音是 ['siliəm],译作纤毛;睫毛。
Cilium 速览
图 1:Cilium 的生态
Cilium 是什么?它是一个 K8s CNI 插件,但这只是它的起点,它的目标是星辰大海。
上图是 Cilium 及以它作为数据源所形成的一个集 Networking, Observability 和 Security 于一体的生态,这个生态里包含 ES,Redis,Service Mesh 等等。而 Cilium 的核心是 eBPF。
Networking 方面:
首先它是一个 K8s CNI 插件,所以它可以被无缝集成到 K8s 中。
它可以代替 kube-proxy,包括
ClusterIP
,NodePort
,ExternalIPs
和LoadBalancer
,同时提供更好的性能、可靠性以及可调试性,当然,这些都要归功于 eBPF。我们知道 kube-proxy 是 K8s 的组件,它会监控 API server 上面的 pod,service 和 endpoint 的修改,并对宿主机的 iptables 做相应的更新,以便实现 virtual service IP:Port 到多个 Pod IP:Port 的转变。这个过程也是一种 Load Balance。
我忍不住强调一下,每一个 Pod 的创建和删除操作都会使得 kube-proxy 在所有的 node 上更新 iptables。K8s 的问题列表里面曾经记录了一个问题 #44613:在 100 个 Node 的 K8s 集群里,kube-proxy 有时会消耗 70%的 CPU。
还有一个更恐怖的对比数据:当 K8s 里有 5k 个 services(每个 service 平均需要插入 8 条 rule,一共 40k iptables rules)的时候,插入一条新的 rule 需要 11 分钟;而当 services 数量 scale out 4 倍到 20k(160k rules)时,需要花费 5 个小时,而非 44 分钟,才能成功加入一条新的 rule。可以看到时间消耗呈指数增加,而非线性。
K8s 多个 Cluster 间的连接。K8s cluster 的规模会逐渐变大,但我们总归需要把 cluster 控制在合理的大小,而不可能让它无限膨胀,所以在某一个时间点会需要切割 cluster 成若干个规模相对小一点的集群。这种情况下,需要将支持 service 的所有 endpoint(pod)分散编排部署在不同的 cluster 里,也即 K8s 需要跨集群编排,Pod 需要跨集群服务请求。
这个功能开始慢慢变成刚需,但对我们而言,它又有点遥远,暂时略过。
Observability 方面:
Identity-aware(身份感知)的网络可视化。如图 2 所示。传统的基于 IP 和 Port 的网络可视化对 K8s 来说已经不适用,因为 Pod 的创建和销毁非常频繁,这导致 IP 和 Pod 的关系是动态变化的,这一刻 192.168.1.24 是 Pod A 在使用,下一秒可能已经被另做它用。
Cilium 所提供的网络可视化可以识别 service/pod/container 的类似 name 之类的标识,甚至到 Pod Label 的粒度,这无疑比用传统的 IP+Port 的方式更有实际意义。
提供网络流量的 metric,并可以无缝集成到 Prometheus。这些 Metric 里面还会包含 traffic 是被哪些 Network Policy 所允许或禁止的。
可以和普罗米修斯无缝集成则意味着以 Prometheus 为数据源的 Grafana 可以直接将 Cilium 的 metric 显示在它优美的曲线图上。
可以通过 HTTP,gRPC,Kafka 等协议和其它服务集成。
图 2:身份感知的网络可视化示意图
Security 方面:
支持 K8s 的 Network Policy,例如 Label + CIDR 匹配方式。
注意:并不是每个 CNI 插件都实现了 Network Policy,比如 Flannel 就没有。CNI 规范也没有要求插件一定要支持 Network Policy。
基于 DNS-aware 的 Policy,例如只允许查询 *.google.com 的 IP,而不允许查询 *.food.com。
基于 API-aware 的 Policy,例如不允许访问 HTTP DELETE /concern。
支持 Cluster-scope 的 Network Policy,而 K8s 的 Network Policy 是 Namespace scope。
Node-scope 的防火墙。
透明加密。这是一个非常有意思的功能。这等于是将加密功能做成了一个对 Pod 无感的中间件和基础设施。
提供丰富的基于 Identity 的 audit log 供安全取证(security forensics)分析。为什么基于 Identity 的 audit log 这么重要呢?如上文所说,基于 IP 和 Port 的 log 信息对安全取证分析来说已经没有参考价值。下面是基于 Identity 的 audit log 示例,可以看到 IP 已经被替换成了 pod name:
Cilium 架构
每研究一个新的东西或者做一个新的项目时,我总喜欢看它的架构图。架构图的意义如同地图,拿着架构图做项目就像对着地图旅游,进可知细节,退可揽全局。我们来看看 Cilium 的架构。
它分为三大部分:Cilium 本体,和编排系统集成部分,与 Kernel 集成部分。
图 3:Cilium 架构
Cilium 本体部分:
Cilium 自身是一个庞大的系统,包含 daemon(agent),CNI plugin,CLI,Policy repo 等等。其中 CLI 用于 Cilium 的安装和对 Cilium 的配置。
其中 agent 是以 DaemonSet 方式部署的 Pod(container name: cilium-agent),所以在每个 node 上都会有它的身影。一方面它会接收来自通过 K8s 和 API 等方式送过来的配置,另一方面它会尤其关注 K8s 里关于 container 的创建、停止、删除等事件并随之执行与 eBPF Hook 相关的动作。
从架构图中可以看出来,daemon 是整个系统的信息、决策和执行中枢。
和编排系统集成部分:
Cilium 首先是一个 K8s CNI 插件。一个平台要做成一个开放性的生态的话,设计上需要留下空间和接口,让平台里面的某一个功能模块可以被以插件形式任意替换。而一个插件,通常会作为一个工作在一线的使者专门与平台对接、打交道,并把平台安排的具体任务转交至它的背后团队处理。Cilium plugin 作为一个插件,将 K8s 的网络相关的任务接下来并转移至后方的 daemon 进一步处理,我们将会在后文的 IPAM 中看到这个详细过程。
与 Kernel 集成部分:
这个部分满眼望去都是 eBPF。是的,Cilium 是 eBPF 的维护者。前文提到的 Networking,Observability 和 Security 三大方面的各式各样的功能很多都是得益于 eBPF。没有了 eBPF,在众多 CNI 插件中,Cilium 也只能是普通的路人甲。
Cilium 太大,要说的东西太多,但篇幅有限,今天我们只聊到这里。下一篇我们聊 IPAM。祝大家国庆节快乐,祝伟大的祖国繁荣昌盛。
以上就是本文的全部内容。码字不易,更多内容请关注二哥的微信公众号。您的举手之劳是对二哥莫大的鼓励。感谢有你!
版权声明: 本文为 InfoQ 作者【Lance】的原创文章。
原文链接:【http://xie.infoq.cn/article/ea70f3246186b3866d1717255】。文章转载请联系作者。
评论