目录

一、前言

二、背景

三、计划赶不上变化

四、为什么是 Cilium?

五、Cilium 的主要功能

5.1、性能

5.2、更好的网络策略

5.3、节点间流量控制

5.4、策略模式

5.5、Hubble & UI

5.6、可视化策略编辑器

六、我们怎么使用的 Cilium?

6.1、允许任何 Pod 访问 Istio 端点

6.2、允许给定命名空间内的所有流量

6.3、允许 VictoriaMetrics 抓取给定命名空间中的所有 Pod

6.4、允许 Metrics Server 访问 kubelet 端口

七、总结


一、前言

突然想写一篇关于 eBPF 相关的文章,简单的写点部署,功能,解决方案不一定是大家要的,不如把我近些年对这块理解和看法写一写。

得益于容器网络接口 (CNI),Kubernetes 提供了大量选项来满足咱们的网络需求。经过多年不同场景下的不断迭代,我们面临着对以客户需求为后盾的,高级功能日益增长的需求。Cilium 将 K8s 平台的网络提升到了一个新的水平。

二、背景

我们处在不同行业、规模和技术栈的公司,构建和维护着越来越沉重的基础设施。大家的应用程序被部署到私有云和公共云以及裸机服务器。它们对容错性、可伸缩性、财务费用、安全性等有不同的要求。在提供服务时,我们需要满足所有这些期望,同时要足够高效,以应对与基础设施相关的新多样性。

几年前,当我们构建基于 Kubernetes 的平台时,我们着手实现基于 开源组件 的生产就绪、简单、可靠的解决方案。为了实现这一点,我们的 CNI 插件的自然选择似乎是 Flannel(以 kube-proxy 作为它的实现)。

当时最受欢迎的选择是 Flannel 和 Weave NetFlannel 更成熟,依赖性最少,并且易于安装。我们的基准测试也证明了它的性能很高。因此,我们做了最后的决定,当然对我们的选择也挺感到满意。

当然,我们也持着怀疑的态度,万一有一天我们的使用会达到它的极限,这个是怎么办?

三、计划赶不上变化

随着时间的流逝,我们获得了更多的客户、更多的 Kubernetes 集群以及对平台的更具体及更高要求。我们遇到了一些场景,需要对安全性、性能和可观测性的各种日益增长的需求。这些需求适用于各种基础设施要素,网络显然是其中之一。最终,我们意识到是时候转向更高级的 CNI 插件了。

主要遇到了哪些问题?

  • 为了等保,我们需要执行更严格的 “默认情况下禁止一切” 的规则。

  • 大量的服务及流量集群,这对 kube-proxy 产生了压倒性的影响。

  • 合规性要求实施灵活而强大的网络策略管理,并在此基础上具有良好的可观察性。

  • 更多的是大量的应用程序在 Flannel 使用的 iptables 和 netfilter 中面临性能问题。

我们不能再被现有的限制所束缚,于是决定,在我们的 Kubernetes 平台中使用另一个 CNI,一个可以应对所有新挑战的 CNI

四、为什么是 Cilium?

大家也都知道,今天有很多 CNI 选项可用。我们希望坚持使用 eBPF,事实证明,eBPF 是一项强大的技术,在可观测性、安全性等方面提供了许多好处。考虑到这一点,当想到 CNI 插件时,会出现两个著名的项目:Cilium 和 Calico

总的来说,他们俩都挺牛逼的。但是,我们仍然需要选择其中之一。Cilium 似乎在社区中得到了更广泛的使用和讨论:更好的 GitHub 统计数据(例如 Star、branch和贡献者)足以证明。这也是一个 CNCF 项目。虽然在国内,Calico 的使用场景远比 Cilium 多。

在阅读了有关 Cilium 的各种文章后,我们决定尝试一下,并在几个不同的 K8s 集群上进行了各种测试。事实证明,它超过了我们预期的更多功能和优势。

五、Cilium 的主要功能

以下几点,当时是我们在考虑是否使用它来解决上述问题时的一些数据:

5.1、性能

它是使用 bpfilter(而不是 iptables)进行路由,意味着将过滤任务转移到内核空间,从而在性能上产生显著的提升。这正是项目设计、大量文章及第三方基准测试所承诺的。我们自己的测试证实,与我们之前使用的 Flannel + kube-proxy 相比,处理流量速度有了显着提高。

图片

 

如下文章大家也可以看下:

eBPF 主机路由与使用 iptables 的比较。

5.2、更好的网络策略

CiliumNetworkPolicy CRD 扩展了 Kubernetes NetworkPolicy API。它带来了诸如 L7(而不仅仅是 L3 / L4)网络策略,支持网络策略中的入口和出口以及端口范围规范等功能。

正如 Cilium 开发人员所指出的:“理想情况下,所有功能都将合并到标准资源格式中,不再需要此 CRD

5.3、节点间流量控制

借助 CiliumClusterwideNetworkPolicy,可以控制节点间流量。这些策略适用于整个集群(非命名空间),并提供了将节点指定为源和目标的方法。它使过滤不同节点组之间的流量变得方便。

5.4、策略模式

在大多数情况下:

默认模式:是很合适的,没有初始限制,但一旦允许某些东西,其余的都会受到限制。

策略模式(当所有端点都启用策略时)对于具有较高安全要求的环境是很有帮助。

5.5、Hubble & UI

Hubble 是一个真正出色的网络和服务可观测性以及视觉渲染工具。具体来说,它监控流量并实时更新服务交互图。我们可以轻松查看正在处理的请求、相关 IP、网络策略的应用等。

举个例子来说明,如何在 Kubernetes 沙盒中使用 Hubble

首先,我们通过  Ingress-NGINX 控制器的命名空间。我们可以看到,外部用户在获得 Dex 授权后进入了 Hubble UI 的整条链路。

图片

 

另外,关于可观察性,这里有个很棒的功功能:Hubble 花了大约一分钟的时间,可视化 Prometheus 命名空间如何与集群的其余部分通信。

可以看到 Prometheus 已经从众多服务中抓取了指标。特别好的功能!在你花几个小时为你的项目绘制所有这些基础设施图之前,你已经可以自动的得到它了!

图片

 

5.6、可视化策略编辑器

此服务提供了一个易于使用友好的 UI,用于创建规则并获取相应的 YAML 配置以应用它们。不过也有个缺点,缺乏对现有配置进行反向可视化。

六、我们怎么使用的 Cilium?

先来回顾下,客户遇到的具体问题,这些问题也激发了我们开始在 Kubernetes 平台中使用 Cilium 的兴趣。

第一种情况下的 "默认情况下禁止一切" 规则是使用上述策略实现的。通常,我们将通过指定此特定环境中允许 APP 完整列表并禁止其他所有 APP 来作为默认模式。

以下是一些相当简单的政策示例,这些策略可能对其大家有所帮助。当然如果深度使用,可能会有几十个或几百个。

6.1、允许任何 Pod 访问 Istio 端点
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: {}
6.2、允许给定命名空间内的所有流量
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-ingress-egress-within-namespace
spec:
  egress:
  - toEndpoints:
    - {}
  endpointSelector: {}
  ingress:
  - fromEndpoints:
    - {}
6.3、允许 VictoriaMetrics 抓取给定命名空间中的所有 Pod
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
6.4、允许 Metrics Server 访问 kubelet 端口
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-10-13 13:30:00 CNCF 宣布 Cilium 正式毕业,这个项目正朝着一个非常明确的方向前进。

我们也在关注项目的发展规划,并等待一些功能和相关工具的实现或变得足够成熟。

例如,虽然我们在高流量集群中使用 Kubernetes EndpointSlice CRD,但相关的 Cilium 功能目前处于测试阶段。我们也在等待它的稳定版本。另一个挺好的功能:本地重定向策略,它将 Pod 流量本地重定向到节点内的另一个后端 Pod,而不是整个集群中的随机 Pod

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐