这篇文章是由软件工程师
Anton Kuliashov
所写,主要讨论了为什么他们选择 Cilium 作为 Kubernetes 网络的解决方案。
感谢 CNI(容器网络接口),Kubernetes 提供了许多选项来满足你的网络需求。在多年依赖简单的解决方案后,我们面临着由客户需求支持的高级功能的日益增长的需求。Cilium 将我们的 K8s 平台的网络提升到了新的水平。
我们为各行业、规模和技术栈的公司构建和维护基础设施。他们的应用程序部署到私有云和公共云以及裸机服务器上。他们对容错、可扩展性、财务开支、安全性等有不同的要求。在提供我们的服务时,我们需要满足所有这些期望,同时还要足够高效地应对新出现的基础设施相关的需求。
几年前,当我们构建早期的基于 Kubernetes 的平台时,我们着手实现基于坚定的开源组件的生产就绪、简单、可靠的解决方案。为了实现这一目标,我们的 CNI 插件的自然选择是 Flannel。当时最受欢迎的选择是 Flannel
和 Weave Net
。Flannel 更成熟,依赖性最小,并且易于安装。我们的基准测试也证明它具有高水平的性能。因此,我们选择了它,并最终对我们的选择感到满意。
随着时间的推移,我们获得了更多的客户,更多的 Kubernetes 集群,以及对平台的更多的要求。现在我们遇到了对更好的安全性、性能和可观察性的日益增长的需求。这些需求适用于各种基础设施元素,网络显然是其中之一。
许多问题促使我们迈向下一个阶段:
最终,我们意识到是时候转向更高级的 CNI 插件了。
现在有很多 CNI 选项可供选择。我们想坚持使用 eBPF,这是一种在可观察性、安全性等方面提供许多好处的强大技术。考虑到这一点,当你想到 CNI 插件时,有两个知名的项目浮现在脑海中:Cilium
和 Calico
。
总的来说,这两个都非常棒。然而,我们只能选择其中一个。Cilium 在社区中似乎更广泛地被使用和讨论:更好的 GitHub 统计数据(如 star、fork 和贡献者)可以被用作证明其价值的某种论据。它也是一个 CNCF 项目。虽然这并不能保证太多,但在所有其他条件相等的情况下,这仍然是一个有效的观点。
以下是我们在考虑是否使用 Cilium 来解决我们之前遇到的问题时喜欢的一些功能:
使用 bpfilter(而不是iptables)进行路由意味着将 filter 任务转移到内核空间,这可以显著提高性能。我们自己的测试证实,与我们之前使用的 Flannel + kube-proxy 相比,在处理流量速度方面有显着的改进。
eBPF 主机路由与使用 iptables 的比较
关于此主题的有用的一些资源:
CiliumNetworkPolicy
CRD 扩展了 Kubernetes NetworkPolicy API。它带来了 L7(而不仅仅是 L3/L4)网络策略支持,支持入口和出口以及端口范围规范。
正如 Cilium 开发人员所指出的:理想情况下,所有的功能都将合并到标准资源格式中,这个 CRD 将不再需要。
你可以通过 CiliumClusterwideNetworkPolicy
控制节点间流量。这些策略适用于整个集群(非命名空间),并为你提供了指定节点作为源和目标的方式,它使得过滤不同节点组之间的流量变得方便。
其易于使用的策略执行模式变得更加轻松。默认模式在大多数情况下都很合适:没有初始限制,但一旦允许了某些内容,所有其他内容都会受到限制。Always
模式 — 当所有端点都启用策略执行时,有助于满足更高安全要求的环境。
Hubble
是一个真正奇妙的网络和服务可观察性工具,以及可视化呈现。具体来说,它监视流量并实时更新服务交互图。你可以轻松地查看正在进行的请求、相关IP、如何应用网络策略等。
有一个更有趣的例子:Hubble 花了大约一分钟的时间来可视化 Prometheus 命名空间与集群的其余部分之间的通信。可以看到 Prometheus 从许多服务中抓取了指标。这是一个很棒的功能!如果你在为项目绘制基础架构图花费几个小时之前知道了这一点,那该多好啊!
这个在线服务提供了一个易于使用的用户界面,用于创建规则并获取相应的 YAML 配置以应用它们。唯一值得注意的是,这里缺少一个机会来制作现有配置的反向可视化。
再次强调,这个列表远非 Cilium 功能的完整集合。这只是基于我们需要和我们最感兴趣的内容所做的选择。
让我们回顾一下我们的客户遇到的具体问题。在第一个案例中,“默认情况下禁止一切”规则是使用上述策略 enforcement
模式实现的。通常,我们会依赖默认模式,通过指定在此特定环境中允许的完整列表并禁止其他所有内容来实现此目的。
以下是一些比较简单的策略示例,可能对其他人有所帮助。
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: all-pods-to-istio-internal-access
spec:
egress:
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: infra-istio
toPorts:
- ports:
- port: "8443"
protocol: TCP
endpointSelector: {}
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-ingress-egress-within-namespace
spec:
egress:
- toEndpoints:
- {}
endpointSelector: {}
ingress:
- fromEndpoints:
- {}
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: vmagent-allow-desired-namespace
spec:
egress:
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: desired-namespace
endpointSelector:
matchLabels:
k8s:io.cilium.k8s.policy.serviceaccount: victoria-metrics-agent-usr
k8s:io.kubernetes.pod.namespace: vmagent-system
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: host-firewall-allow-metrics-server-to-kubelet
spec:
ingress:
- fromEndpoints:
- matchLabels:
k8s:io.cilium.k8s.policy.serviceaccount: metrics-server
k8s:io.kubernetes.pod.namespace: my-metrics-namespace
toPorts:
- ports:
- port: "10250"
protocol: TCP
nodeSelector:
matchLabels: {}
总结这次经验,我们成功解决了与 Kubernetes 网络相关的所有痛点。
关于 Cilium 的未来,我们可以说什么?虽然它目前是一个孵化中的 CNCF 项目,但它在去年底申请了毕业。这需要一些时间,但这个项目的方向非常明确。最近,在2023年2月,宣布 Cilium 通过了两个安全审计,这是其进一步毕业的重要步骤。
我们正在关注该项目的路线图,并等待某些功能和相关工具得到实现或足够成熟。(没错,Tetragon,毫无疑问会很棒!)
例如,虽然我们在高流量的集群中利用 Kubernetes 的 EndpointSlice CRD,但相关的 Cilium 功能目前仍处于beta版,因此,我们正在等待其稳定版本的发布。我们还在等待另一个beta功能变得稳定,即本地重定向策略,它将 Pod 流量在本地重定向到节点内的另一个后端Pod,而不是集群中的随机Pod。
在生产环境中确定了我们的新网络基础设施,并评估了其性能和新功能后,我们对采用 Cilium 的决定感到满意,其好处是显而易见的。也许它不是应对多样化和不断变化的云原生世界的银弹,也绝不是最容易开始使用的技术。然而,如果你有动力和一点冒险精神,那么它绝对值得一试,很可能会得到多倍的回报。
原文链接:https://blog.palark.com/why-cilium-for-kubernetes-networking/