赞
踩
Cilium
作为近两年最火的云原生网络方案,可谓是风头无两。作为第一个通过 ebpf 实现了 kube-proxy 所有功能的网络插件,它的神秘面纱究竟是怎样的呢?本文主要介绍Cilium
的发展演进,功能介绍以及具体使用示例。
随着云原生的普及率越来越高,各大厂商基本上或多或少都实现了业务的 K8s 容器化,头部云计算厂商更是不用说。
而且随着 K8s 的 普及,当前集群逐渐呈现出以下两个特点:
随着容器密度的增大,以及生命周期的变短,对原生容器网络带来的挑战也越来越大。
在 Cilium 出现之前, Service 由 kube-proxy 来实现,实现方式有 userspace
,iptables
,ipvs
三种模式。
当前模式下,kube-proxy 作为反向代理,监听随机端口,通过 iptables 规则将流量重定向到代理端口,再由 kube-proxy 将流量转发到 后端 pod。Service 的请求会先从用户空间进入内核 iptables,然后再回到用户空间,代价较大,性能较差。
存在的问题:
service
数据达到数千个,其控制面和数据面的性能都会急剧下降。原因在于 iptables 控制面的接口设计中,每添加一条规则,需要遍历和修改所有的规则,其控制面性能是O(n²)
。在数据面,规则是用链表组织的,其性能是O(n)
。IPVS 是专门为 LB 设计的。它用 hash table 管理 service,对 service 的增删查找都是 O(1)的时间复杂度。不过 IPVS 内核模块没有 SNAT 功能,因此借用了 iptables 的 SNAT 功能。
IPVS 针对报文做 DNAT 后,将连接信息保存在 nf_conntrack 中,iptables 据此接力做 SNAT。该模式是目前 Kubernetes 网络性能最好的选择。但是由于 nf_conntrack 的复杂性,带来了很大的性能损耗。
Cilium
是基于 eBpf
的一种开源网络实现,通过在 Linux 内核动态插入强大的安全性、可见性和网络控制逻辑,提供网络互通,服务负载均衡,安全和可观测性等解决方案。简单来说可以理解为 Kube-proxy + CNI 网络实现。
Cilium
位于容器编排系统和 Linux Kernel 之间,向上可以通过编排平台为容器进行网络以及相应的安全配置,向下可以通过在 Linux 内核挂载 eBPF 程序,来控制容器网络的转发行为以及安全策略执行。
简单了解下 Cilium
的发展历程:
查看官网,可以看到 Cilium
的功能主要包含 三个方面,如上图:
网络
高度可扩展的 kubernetes CNI 插件,支持大规模,高动态的 k8s 集群环境。支持多种租网模式:
Overlay
模式,支持 Vxlan 及 Geneve
Unerlay
模式,通过 Direct Routing (直接路由)的方式,通过 Linux 宿主机的路由表进行转发
kube-proxy 替代品,实现了 四层负载均衡功能。LB 基于 eBPF 实现,使用高效的、可无限扩容的哈希表来存储信息。对于南北向负载均衡,Cilium 做了最大化性能的优化。支持 XDP、DSR(Direct Server Return,LB 仅仅修改转发封包的目标 MAC 地址)
多集群的连通性,Cilium Cluster Mesh 支持多集群间的负载,可观测性以及安全管控
可观测性
安全
不仅支持 k8s Network Policy,还支持 DNS 级别、API 级别、以及跨集群级别的 Network Policy
支持 ip 端口 的 安全审计日志
传输加密
总结,Cilium 不仅包括了 kube-proxy + CNI 网络实现,还包含了众多可观测性和安全方面的特性。
linux 内核要求
4.19
及以上
可以采用 helm
或者 cilium cli
,此处笔者使用的是 cilium cli
(版本为 1.10.3
)
cilium cli
- wget https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz
- tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
cilium
- wget https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz
- tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
cilium install --kube-proxy-replacement=strict # 此处选择的是完全替换,默认情况下是 probe,(该选项下 pod hostport 特性不支持)
cilium hubble enable --ui
- ~# cilium status
- /¯¯\
- /¯¯\__/¯¯\ Cilium: OK
- \__/¯¯\__/ Operator: OK
- /¯¯\__/¯¯\ Hubble: OK
- \__/¯¯\__/ ClusterMesh: disabled
- \__/
-
- DaemonSet cilium Desired: 1, Ready: 1/1, Available: 1/1
- Deployment cilium-operator Desired: 1, Ready: 1/1, Available: 1/1
- Deployment hubble-relay Desired: 1, Ready: 1/1, Available: 1/1
- Containers: hubble-relay Running: 1
- cilium Running: 1
- cilium-operator Running: 1
- Image versions cilium quay.io/cilium/cilium:v1.10.3: 1
- cilium-operator quay.io/cilium/operator-generic:v1.10.3: 1
- hubble-relay quay.io/cilium/hubble-relay:v1.10.3: 1
cilium cli
还支持 集群可用性检查(可选)- ~# cilium status
- /¯¯\
- /¯¯\__/¯¯\ Cilium: OK
- \__/¯¯\__/ Operator: OK
- /¯¯\__/¯¯\ Hubble: OK
- \__/¯¯\__/ ClusterMesh: disabled
- \__/
-
- DaemonSet cilium Desired: 1, Ready: 1/1, Available: 1/1
- Deployment cilium-operator Desired: 1, Ready: 1/1, Available: 1/1
- Deployment hubble-relay Desired: 1, Ready: 1/1, Available: 1/1
- Containers: hubble-relay Running: 1
- cilium Running: 1
- cilium-operator Running: 1
- Image versions cilium quay.io/cilium/cilium:v1.10.3: 1
- cilium-operator quay.io/cilium/operator-generic:v1.10.3: 1
- hubble-relay quay.io/cilium/hubble-relay:v1.10.3: 1
等 hubble 安装完成后,hubble-ui service 修改为 NodePort类型, 即可通过 NodeIP+NodePort 来登录 Hubble 界面 查看相关信息。
Cilium 部署完后,有以下几个组件 operator、hubble(ui, relay),Cilium agent(Daemonset 形式,每个节点一个),其中关键组件为 cilium agent。
Cilium Agent作为整个架构中最核心的组件,通过DaemonSet的方式,以特权容器的模式,运行在集群的每个主机上。Cilium Agent作为用户空间守护程序,通过插件与容器运行时和容器编排系统进行交互,进而为本机上的容器进行网络以及安全的相关配置。同时提供了开放的API,供其他组件进行调用。
Cilium Agent在进行网络和安全的相关配置时,采用eBPF程序进行实现。Cilium Agent结合容器标识和相关的策略,生成 eBPF 程序,并将 eBPF 程序编译为字节码,将它们传递到 Linux 内核。
Cilium agent 中内置了一些调试用的命令,下面介绍,agent 中的 cilium 不同与上述介绍的 cilium cli ( 虽然同为 cilium)。
cilium status
主要展示 cilium
的一些简单配置信息及状态,如下:
- [root@~]# kubectl exec -n kube-system cilium-s62h5 -- cilium status
- Defaulted container "cilium-agent" out of: cilium-agent, ebpf-mount (init), clean-cilium-state (init)
- KVStore: Ok Disabled
- Kubernetes: Ok 1.21 (v1.21.2) [linux/amd64]
- Kubernetes APIs: ["cilium/v2::CiliumClusterwideNetworkPolicy", "cilium/v2::CiliumEndpoint", "cilium/v2::CiliumNetworkPolicy", "cilium/v2::CiliumNode", "core/v1::Namespace", "core/v1::Node", "core/v1::Pods", "core/v1::Service", "discovery/v1::EndpointSlice", "networking.k8s.io/v1::NetworkPolicy"]
- KubeProxyReplacement: Strict [eth0 10.251.247.131 (Direct Routing)]
- Cilium: Ok 1.10.3 (v1.10.3-4145278)
- NodeMonitor: Listening for events on 8 CPUs with 64x4096 of shared memory
- Cilium health daemon: Ok
- IPAM: IPv4: 68/254 allocated from 10.0.0.0/24,
- BandwidthManager: Disabled
- Host Routing: Legacy
- Masquerading: BPF [eth0] 10.0.0.0/24 [IPv4: Enabled, IPv6: Disabled]
- Controller Status: 346/346 healthy
- Proxy Status: OK, ip 10.0.0.167, 0 redirects active on ports 10000-20000
- Hubble: Ok Current/Max Flows: 4095/4095 (100.00%), Flows/s: 257.25 Metrics: Disabled
- Encryption: Disabled
- Cluster health: 1/1 reachable (2021-08-11T09:33:31Z)
cilium service list
展示 service
的实现,使用时可通过 ClusterIP
来过滤,其中,FrontEnd
为 ClusterIP
,Backend
为 PodIP
。
- [root@~]# kubectl exec -it -n kube-system cilium-vsk8j -- cilium service list
- Defaulted container "cilium-agent" out of: cilium-agent, ebpf-mount (init), clean-cilium-state (init)
- ID Frontend Service Type Backend
- 1 10.111.192.31:80 ClusterIP 1 => 10.0.0.212:8888
- 2 10.101.111.124:8080 ClusterIP 1 => 10.0.0.81:8080
- 3 10.101.229.121:443 ClusterIP 1 => 10.0.0.24:8443
- 4 10.111.165.162:8080 ClusterIP 1 => 10.0.0.213:8080
- 5 10.96.43.229:4222 ClusterIP 1 => 10.0.0.210:4222
- 6 10.100.45.225:9180 ClusterIP 1 => 10.0.0.48:9180
- # 避免过多,此处不一一展示
cilium service get
通过 cilium service get < ID> -o json
来展示详情:
- [root@~]# kubectl exec -it -n kube-system cilium-vsk8j -- cilium service get 132 -o json
- Defaulted container "cilium-agent" out of: cilium-agent, ebpf-mount (init), clean-cilium-state (init)
- {
- "spec": {
- "backend-addresses": [
- {
- "ip": "10.0.0.213",
- "nodeName": "n251-247-131",
- "port": 8080
- }
- ],
- "flags": {
- "name": "autoscaler",
- "namespace": "knative-serving",
- "trafficPolicy": "Cluster",
- "type": "ClusterIP"
- },
- "frontend-address": {
- "ip": "10.98.24.168",
- "port": 8080,
- "scope": "external"
- },
- "id": 132
- },
- "status": {
- "realized": {
- "backend-addresses": [
- {
- "ip": "10.0.0.213",
- "nodeName": "n251-247-131",
- "port": 8080
- }
- ],
- "flags": {
- "name": "autoscaler",
- "namespace": "knative-serving",
- "trafficPolicy": "Cluster",
- "type": "ClusterIP"
- },
- "frontend-address": {
- "ip": "10.98.24.168",
- "port": 8080,
- "scope": "external"
- },
- "id": 132
- }
- }
- }
还有很多有用的命令,限于篇幅,此处不一一展示,感兴趣的同学可以尝试探索(cilium status --help
)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。