Kubernetes网络方案Cilium
Cilium是第一个通过eBPF实现了kube-proxy所有功能的Kubernetes网络方案,让我们一起来实践下吧~
Cilium简介
- 官方网站:https://cilium.io/
- Github仓库:https://github.com/cilium/cilium
当前趋势
现代数据中心的应用系统已经逐渐转向基于微服务架构的开发体系,一个微服务架构的应用系统是由多个小的独立的服务组成,它们之间通过轻量通信协议如 HTTP、gRPC、Kafka 等进行通信。微服务架构下的服务天然具有动态变化的特点,结合容器化部署,时常会引起大规模的容器实例启动或重启。要确保这种向高度动态化的微服务应用之间的安全可达,既是挑战,也是机遇。
现有问题
传统的 Linux 网络访问安全控制机制(如 iptables)是基于静态环境的IP地址和端口配置网络转发、过滤等规则,但是 IP 地址在微服务架构下是不断变化的,非固定的;出于安全目的,协议端口(例如 HTTP 传输的 TCP 端口 80)也不再固定用来区分应用系统。为了匹配大规模容器实例快速变化的生命周期,传统网络技术需要维护成千上万的负载均衡规则和访问控制规则,并且需要以不断增长的频率更新这些规则,而如果没有准确的可视化功能,要维护这些规则也是十分困难,这些对传统网络技术的可用性和性能都是极大的挑战。比如经常会有人对 kube-proxy 基于 iptables 的服务负载均衡功能在大规模容器场景下具有严重的性能瓶颈,同时由于容器的创建和销毁非常频繁,基于 IP 做身份关联的故障排除和安全审计等也很难实现。
解决方案
Cilium 作为一款 Kubernetes CNI 插件,从一开始就是为大规模和高度动态的容器环境而设计,并且带来了 API 级别感知的网络安全管理功能,通过使用基于 Linux 内核特性的新技术——BPF,提供了基于 service/pod/container 作为标识,而非传统的 IP 地址,来定义和加强容器和 Pod 之间网络层、应用层的安全策略。因此,Cilium 不仅将安全控制与寻址解耦来简化在高度动态环境中应用安全性策略,而且提供传统网络第 3 层、4 层隔离功能,以及基于 http 层上隔离控制,来提供更强的安全性隔离。
另外,由于 BPF 可以动态地插入控制 Linux 系统的程序,实现了强大的安全可视化功能,而且这些变化是不需要更新应用代码或重启应用服务本身就可以生效,因为 BPF 是运行在系统内核中的。
以上这些特性,使 Cilium 能够在大规模容器环境中也具有高度可伸缩性、可视化以及安全性。

环境要求
- CentOS >= 7.0 or RedHat Enterprise Linux >= 8.0
- Linux Kernel >= 4.9.17
- Create a Kubernetes cluster without install cni
- Mounted eBPF filesystem mounted on all worker nodes
- Kubernetes must be configured to use CNI
- Helm3
升级Linux Kernel
http://elrepo.org/tiki/tiki-index.php
Cilium使用了一种名为eBPF的新Linux内核技术,它支持在各种集成点(例如网络IO、应用Sockets)将eBPF字节码动态插入Linux内核,以实现安全性、网络和可见性逻辑。此技术需在新版本内核中才支持,因此我们需要先升级所有节点的内核到官方建议版本(Linux Kernel >= 4.9.17),可执行uname -r查看当前系统内核版本是否满足条件。
安装ELRepo
1 | rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org |
列出可以使用的kernel版本。lt是longterm的缩写,指长期维护版;ml是mainline的缩写,指最新稳定版
1 | yum --disablerepo="*" --enablerepo="elrepo-kernel" list available |
安装需要的Kernel,建议选择长期维护版
1 | yum --enablerepo=elrepo-kernel install kernel-lt -y |
设置以新版本内核启动
1 | # 查看新版本内核的menuentry名称 |
重启机器,若机器上已运行有Kubernetes集群建议逐台重启
1 | reboot |
挂载BPF文件系统
在所有节点挂载BPF文件系统
1 | mount bpffs /sys/fs/bpf -t bpf |
验证是否挂载成功
1 | # mount |grep bpf |
使用Helm3安装Cilium
说明
请使用Helm3,Helm2不再支持
添加Cilium Helm仓库
1 | helm repo add cilium https://helm.cilium.io/ |
拉取Cilium Helm Chart
1 | # 查询可安装的Cilium版本 |
修改cilium/values.yaml
1 | ... |
- 更多配置参数可参考https://docs.cilium.io/en/stable/helm-reference/
- 当集群规模超过250个节点,5000个Pod建议使用外部KVStore,例如etcd。可参考https://docs.cilium.io/en/stable/gettingstarted/k8s-install-external-etcd/
安装Cilium
1 | helm install cilium -f values.yaml . --namespace kube-system |
以下是Cilium的整体部署组件列表

验证安装
到https://github.com/cilium/cilium-cli/releases下载对应版本和架构的Cilium CLI。Cilium CLI可用于安装Cilium、检查Cilium安装状态以及启用/禁用各种功能(例如clustermesh、Hubble)。
1 | tar zxf cilium-linux-amd64.tar.gz -C /usr/local/bin/ |
验证Cilium是否已正确安装
1 | # cilium status |
查看当前Cilium的kube-proxy替换模式
1 | kubectl exec -it -n kube-system cilium-xxxxx -- cilium status | grep KubeProxyReplacement |
官方提供了一个connectivity检查工具,以检测部署好的Cilium是否工作正常。可到此页面查询Cilium对应版本的检查工具配置清单(connectivity-check.yaml),并确保至少有两个可用的Node节点;若仅有一个Node节点,可在此页面查询Cilium对应版本的单节点检查工具配置清单(connectivity-check-single-node.yaml)。
1 | # 为检测工具创建单独的命名空间 |
connectivity会部署一系列的Deployment并且会使用各种连接路径相互连接。包括有无经过Service负载均衡和各种网络策略组合。通过Pod名称可以方便的看出对应的测试场景,并通过就绪探针和存活探针来表示测试成功还是失败。

如果所有的deployment都能成功运行起来,说明Cilium已经成功部署并工作正常。
开启网络可视化Hubbel
Cilium在1.7版本后推出并开源了Hubble,它是专门为网络可视化设计,能够利用Cilium提供的eBPF数据路径,获得对Kubernetes应用和服务的网络流量的深度可见性。这些网络流量信息可以对接Hubble CLI、UI工具,可以通过交互式的方式快速诊断如与DNS相关的问题。除了Hubble自身的监控工具,还可以对接主流的云原生监控体系——Prometheus和Grafana,实现可扩展的监控策略。

上面已经通过Helm安装了Cilium,则直接使用以下命令开启Hubble和UI
1 | helm upgrade cilium cilium/cilium --version 1.10.3 \ |
默认Hubble通过ClusterIP类型的Service进行暴露,为了方便从外部访问Hubble UI,将Service修改为NodePort类型。
1 | # kubectl edit svc hubble-ui -n kube-system |
验证Hubble是否开启
1 | # 查看hubble的pod是否Running |
浏览器访问http://<NodeIP>:<nodeport>即可打开Hubble UI。

在左上角选择或者直接单击首页上的命名空间名称即可切换到对应命名空间下。以cilium-test命名空间为例,页面上半部分就是之前部署的一整套connectivity-check组件的数据流量图,官方叫做Service Map,默认情况下可以自动发现基于网络3层和4层的访问依赖路径,看上去十分酷炫,有点类似分布式链路追踪图。
页面下半部分显示的是每条数据流路径的详细信息,包括发起请求的pod名称、发起请求的IP、发起请求的service名称、请求的目标pod名称、请求的目标IP、请求的目标service名称、请求的目标端口、执行动作(转发或丢弃)、TCP flags、最后一次查看时间等.(单击”Columns”可自定义显示的字段)

单击某个服务还能看到更为详细的关系图,单击任意一条flow,也可以查看到更多详细信息。

删除Cilium
1 | helm delete cilium --namespace kube-system |