写点什么

eBPF 完美搭档:连接云原生网络的 Cilium

  • 2022 年 2 月 22 日
  • 本文字数:5039 字

    阅读完需:约 17 分钟

Cilium 作为近两年最火的云原生网络方案,可谓是风头无两。作为第一个通过 ebpf 实现了 kube-proxy 所有功能的网络插件,它的神秘面纱究竟是怎样的呢?本文主要介绍 Cilium 的发展演进,功能介绍以及具体使用示例。


背景


随着云原生的普及率越来越高,各大厂商基本上或多或少都实现了业务的 K8s 容器化,头部云计算厂商更是不用说。


而且随着 K8s 的 普及,当前集群逐渐呈现出以下两个特点:


  1. 容器数量越来越多,比如:K8s 官方单集群就已经支持 150k pod

  2. Pod 生命周期越来越短,Serverless 场景下甚至短至几分钟,几秒钟


随着容器密度的增大,以及生命周期的变短,对原生容器网络带来的挑战也越来越大。

当前 K 8s Service 负载均衡 的实现现状

在 Cilium 出现之前, Service 由 kube-proxy 来实现,实现方式有 userspaceiptablesipvs 三种模式。

Userspace

当前模式下,kube-proxy 作为反向代理,监听随机端口,通过 iptables 规则将流量重定向到代理端口,再由 kube-proxy 将流量转发到 后端 pod。Service 的请求会先从用户空间进入内核 iptables,然后再回到用户空间,代价较大,性能较差。

Iptables

存在的问题:


  1. 可扩展性差。随着 service 数据达到数千个,其控制面和数据面的性能都会急剧下降。原因在于 iptables 控制面的接口设计中,每添加一条规则,需要遍历和修改所有的规则,其控制面性能是O(n²)。在数据面,规则是用链表组织的,其性能是O(n)

  2. LB 调度算法仅支持随机转发。

Ipvs 模式

IPVS 是专门为 LB 设计的。它用 hash table 管理 service,对 service 的增删查找都是 O(1)的时间复杂度。不过 IPVS 内核模块没有 SNAT 功能,因此借用了 iptables 的 SNAT 功能。


IPVS 针对报文做 DNAT 后,将连接信息保存在 nf_conntrack 中,iptables 据此接力做 SNAT。该模式是目前 Kubernetes 网络性能最好的选择。但是由于 nf_conntrack 的复杂性,带来了很大的性能损耗。


Cilium 的发展

Cilium 是基于 eBpf 的一种开源网络实现,通过在 Linux 内核动态插入强大的安全性、可见性和网络控制逻辑,提供网络互通,服务负载均衡,安全和可观测性等解决方案。简单来说可以理解为 Kube-proxy + CNI 网络实现。


Cilium 位于容器编排系统和 Linux Kernel 之间,向上可以通过编排平台为容器进行网络以及相应的安全配置,向下可以通过在 Linux 内核挂载 eBPF 程序,来控制容器网络的转发行为以及安全策略执行。




简单了解下 Cilium 的发展历程:


  1. 2016 Thomas Graf 创立了 Cilium, 现为 Isovalent (Cilium 背后的商业公司)的 CTO

  2. 2017 年 DockerCon 上 Cilium 第一次发布

  3. 2018 年 发布 Cilium 1.0

  4. 2019 年 发布 Cilium 1.6 版本,100% 替代 kube-proxy

  5. 2019 年 Google 全面参与 Cilium

  6. 2021 年 微软、谷歌、FaceBook、Netflix、Isovalent 在内的多家企业宣布成立 eBPF 基金会(Linux 基金会下)


功能介绍



查看官网,可以看到 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 支持多集群间的负载,可观测性以及安全管控


  • 可观测性




  1. 提供生产可用的可观测性工具 hubble, 通过 pod 及 dns 标识来识别连接信息

  2. 提供 L3/L4/L7 级别的监控指标,以及 Networkpolicy 的 行为信息指标

  3. API 层面的可观测性 (http,https)

  4. Hubble 除了自身的监控工具,还可以对接像 Prometheus、Grafana 等主流的云原生监控体系,实现可扩展的监控策略


  • 安全

  • 不仅支持 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.gztar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
复制代码


cilium install --kube-proxy-replacement=strict # 此处选择的是完全替换,默认情况下是 probe,(该选项下 pod hostport 特性不支持)


  • 可视化组件 hubble(选装)


cilium hubble enable --ui
复制代码


  • 等待 pod ready 后,查看 状态如下:


~# 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/1Deployment cilium-operator Desired: 1, Ready: 1/1, Available: 1/1Deployment hubble-relay Desired: 1, Ready: 1/1, Available: 1/1Containers: hubble-relay Running: 1 cilium Running: 1 cilium-operator Running: 1Image 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 statusDefaulted container  cilium-agent  out of: cilium-agent, ebpf-mount (init), clean-cilium-state (init)KVStore:                Ok   DisabledKubernetes:             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 memoryCilium health daemon:   OkIPAM:                   IPv4: 68/254 allocated from 10.0.0.0/24,BandwidthManager:       DisabledHost Routing:           LegacyMasquerading:           BPF   [eth0]   10.0.0.0/24 [IPv4: Enabled, IPv6: Disabled]Controller Status:      346/346 healthyProxy Status:           OK, ip 10.0.0.167, 0 redirects active on ports 10000-20000Hubble:                 Ok   Current/Max Flows: 4095/4095 (100.00%), Flows/s: 257.25   Metrics: DisabledEncryption:             DisabledCluster health:         1/1 reachable   (2021-08-11T09:33:31Z)
复制代码


  • cilium service list


展示 service 的实现,使用时可通过 ClusterIP 来过滤,其中,FrontEnd 为 ClusterIPBackend 为 PodIP


[root@~]# kubectl exec -it -n kube-system cilium-vsk8j -- cilium service listDefaulted container "cilium-agent" out of: cilium-agent, ebpf-mount (init), clean-cilium-state (init)ID    Frontend                 Service Type   Backend1     10.111.192.31:80         ClusterIP      1 => 10.0.0.212:88882     10.101.111.124:8080      ClusterIP      1 => 10.0.0.81:80803     10.101.229.121:443       ClusterIP      1 => 10.0.0.24:84434     10.111.165.162:8080      ClusterIP      1 => 10.0.0.213:80805     10.96.43.229:4222        ClusterIP      1 => 10.0.0.210:42226     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)。



用户头像

边创未来,连接生活 2018.10.09 加入

火山引擎边缘计算官方账号

评论

发布
暂无评论
eBPF 完美搭档:连接云原生网络的 Cilium