[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ]
0x00 简述介绍
什么是 Cilium?
Cilium 是一款开源软件,它基于一种名为eBPF的新的Linux内核技术提供动力,用于透明地保护使用 Docker 和 Kubernetes 等Linux 容器管理平台中部署的应用程序服务之间的网络连接,Cilium 主要使用场景是在 Kubernetes 中,但 Cilium 的优势并不仅限于 Kubernetes 环境。
在 Kubernetes 环境中,Cilium 可充当网络插件,提供 pod 之间的连接。它通过执行网络策略 (network policy) 和透明加密来提供安全性,而 Cilium 的 Hubble 组件则提供了网络流量流的深度可见性(监控功能)。
得益于 eBPF,Cilium 的网络、安全和可观察性逻辑可以 直接编程到内核 中,从而使 Cilium 和 Hubble 的功能对应用工作负载完全透明。这些将是 Kubernetes 集群中的容器化工作负载,不过 Cilium 也能连接虚拟机和标准 Linux 进程等传统工作负载。
项目地址:https://github.com/cilium/cilium
文档地址:https://docs.cilium.io/en/stable/
能看到此文的看友,说明冥冥之中,必有定数,何不关注一下作者!
为啥用 Cilium & Hubble?
背景:现代数据中心应用程序的开发已转向面向服务的架构(即微服务
) ,其中大型应用程序被拆分为小型独立服务,这些服务与通过使用 HTTP 等轻量级协议的 API 相互连接。微服务应用程序往往是高度动态的,单个容器在应用程序横向扩展/缩减时启动或销毁,以适应负载变化以及作为持续交付的一部分部署的滚动更新期间。传统的Linux网络安全方法(如iptables)会过滤IP地址和TCP/UDP端口,但IP地址在动态微服务环境中经常变动。容器的高度不稳定的生命周期导致这些方法难以与应用程序并行扩展,因为负载平衡表和访问控制列表承载了数十万条规则,这些规则需要以不断增长的频率进行更新。出于安全目的,协议端口(例如用于HTTP流量的TCP端口80)不能再用于区分应用程序流量,因为该端口用于跨服务的各种消息。另一个挑战是提供准确可见性的能力,因为传统系统使用IP地址作为主要识别工具,在微服务架构中,IP地址的寿命可能会大大缩短,只有几秒钟。
解决:通过利用Linux eBPF,Cilium保留了透明地插入安全可见性 强制执行的能力,但这种方式是基于 service / pod / container 的(与传统系统中的IP地址标识相反),并且可以在应用层进行过滤(例如HTTP)。它能原生理解容器和 Kubernetes 身份,并解析 HTTP、gRPC 和 Kafka 等 API 协议,提供比传统防火墙更简单、更强大的可视性和安全性。总得来说,Cilium 就是为大规模、高动态的容器化环境而设计的,实现了对系统和应用程序的可高性能、安全性以及观察性(可见性)。
功能:
- Protect and secure APIs transparently:保护现代应用程序协议,如 REST/HTTP、gRPC和Kafka。
- Secure service to service communication based on identities:将安全标识分配给共享相同安全策略的应用程序容器组。
- Secure access to and from external services:除了支持基于标签的安全性的访问控制,还支持基于CIDR(IP地址段)来限定对于应用程序容器的访问。
- Simple Networking: 支持多节点网络模型,例如,overlay 跨所有主机的基于封装的虚拟网络,Native Routing 使用原生路由使得能够访问到应用程序的IP地址。
- Load Balancing:为应用程序容器和外部服务之间的流量实现分布式负载平衡,并能够完全替换kube-proxy等组件,支持 南北/东西流量类型的负载均衡。
- Bandwidth Management: 通过高效的基于EDT(最早出发时间)的速率限制(eBPF)来实现带宽管理,以用于节点出口的容器流量。
- Monitoring and Troubleshooting: 可使用 Hubble 针对应用程序容器和外部服务之间的所有流量进行监控和故障排除,支持 Prometheus 指标的导出。
Cilium 组件概述
Cilium 和 Hubble 的部署由以下组件组成,这些组件运行 在集群中:
Cilium
- Cilium Operator:可理解为 Cilium 的管理平面或操作运维平面, 它不处于任何转发或网络策略决策的关键路径上,所以即使 Operator 暂时不可用,集群一般也能继续运行。
- Cilium Agent :以 daemonset 形式在集群中的每个节点上运行,侦听来自编排系统的事件,管理 Linux 内核用于控制所有网络的 eBPF 程序访问这些容器,与 K8S API 进行交互同步,也与 Linux Kernel 进行交互,通过文件系统 socket 与 Cilium CNI 插件可执行文件交互以获得新调度工作负载的通知,根据要求的网络策略,按需创建 DNS 和 Envoy Proxy 服务器,启用 Hubble 时创建 Hubble gRPC 服务。
- Cilium CLI client :Cilium Agent 守护进程中的每个 pod 都带有一个 Cilium Client 可执行文件,可用于检查该节点上安装的 Cilium Agent 和 eBPF map 资源的状态,它是 Cilium 的 REST API 交互 代理程序,用于与检查运行状态和 本地代理的状态。
- CNI Plugin: 此插件可执行文件安装到 Kubernetes 主机文件系统中,并重新配置节点的 CNI 以使用该插件。CNI 插件可执行文件与 Cilium Agent 分开,作为 Agent 守护程序初始化的一部分进行安装(即 install-cni-binaries init container)。需要时,Cilium CNI 插件将使用主机文件系统 socket 与运行中的 Cilium Agent 通信。
Hubble
- Hubble Server: 运行在集群中,在每个节点上运行并检索基于 eBPF 的可见性 来自 Cilium。
- Hubble Relay: 一个独立的组件,暴露所有运行 Hubble 服务器,并通过连接到它们各自的 gRPC API 并提供代表所有服务器的 API 在集群中,从而实现集群范围内的可观测性,集群中将添加 hubble relay deploy 以及两个附加服务:Hubble Observer 服务和 the Hubble Peer 服务。
- Client (CLI):一个命令行工具,可以连接到Hubble-relay的gRPC API或本地服务器以检索流事件。
- Graphical UI (GUI):图形用户界面(hubble-ui),提供图形化的服务依赖关系和连接图。
eBPF
eBPF 是一个Linux内核字节码解释器,最初用于过滤网络数据包,例如tcpdump和套接字过滤器。此后,它被扩展了额外的数据结构,如哈希表和数组,以及支持数据包处理、转发、封装等的额外操作。内核内验证器确保eBPF程序安全运行,JIT编译器将字节码转换为CPU架构特定的指令,以提高本机执行效率。eBPF程序可以在内核中的各种挂钩点运行,例如用于传入和传出数据包。Cilium 能够探测Linux内核的可用功能,并在检测到最新功能时自动使用这些功能。
Data Store
Cilium 需要一个数据存储来在 agent 之间传播 state,通常使用 Kubernetes 自定义资源定义 (CRD)或者KV存储数据库(etcd),注:可以直接利用 Kubernetes 的 etcd 集群,或者 维护专用的 etcd 集群。
weiyigeek.top-Cilium 组件概览图
Cilium 重要概念
Cilium Endpoints:
容器 Pod 及其分配的 IP 地址,你可简单理解为基本等价于 Kubernetes 的 endpoints, 但是包含的信息更多。
代码语言:javascript复制$ kubectl get ciliumendpoints.cilium.io -A
# NAMESPACE NAME SECURITY IDENTITY ENDPOINT STATE IPV4 IPV6
# cilium-test-1 perf-client-6cf4c7f9d7-prkrv 4668 ready 172.20.0.64
# cilium-test-1 perf-client-other-node-6d4b466c98-p72p8 16752 ready 172.20.1.189
# cilium-test-1 perf-server-89f58b7c8-jzj24 37138 ready 172.20.0.87
# default nfs-storage-225-nfs-subdir-external-provisioner-6f5496bb9-86q6d 10286 ready 172.20.3.78
# default nginx 17741 ready 172.20.3.128
# kube-system coredns-5b59764654-2zkws 9223 ready 172.20.3.172
# kube-system coredns-5b59764654-qrvpn 9223 ready 172.20.2.40
# kube-system hubble-relay-6c7d5d9445-qpg4p 28844 ready 172.20.3.138
# kube-system hubble-ui-59bb4cb67b-jn8s8 36286 ready 172.20.3.242
由上可看出,coredns 的两个 Pod 其 SECURITY IDENTITY 都是同一个 9223 。
Cilium Identity(身份):
它是 Cilium 能高效工作的关键概念,有 Cilium Endpoints 都有一个基于标签的标识。
weiyigeek.top-Cilium Identity(身份标识)图
Cilium 身份由标签决定,在整个集群中是唯一的。端点会被分配与端点安全相关标签相匹配的身份,也就是说,共享同一组安全相关标签的所有端点将共享相同的身份。与每个身份相关的唯一数字标识符会被 eBPF 程序用于网络数据路径中的快速查找,这也是 Hubble 能够提供 Kubernetes 感知网络可观察性的基础。
当网络数据包进入或离开节点时,Cilium 的 eBPF 程序会将源地址和目标 IP 地址映射到相应的数字身份标识符,然后根据引用这些数字身份标识符的策略配置来决定应采取哪些数据路径行动。每个 Cilium Agent 负责通过观察相关 Kubernetes 资源的更新,用与节点上本地运行的端点相关的数字标识符更新与身份相关的 eBPF 映射。
例如,查看集群中 ciliumidentities 资源信息。
代码语言:javascript复制kubectl get ciliumidentities.cilium.io -A | grep -v "argocd"
# NAME NAMESPACE AGE
# 10286 default 13d
# 16752 cilium-test-1 5h12m
# 17741 default 17d
# 28844 kube-system 17d
# 36286 kube-system 28h
# 37138 cilium-test-1 5h12m
# 4668 cilium-test-1 5h12m
# 9223 kube-system 18d
0x01 快速上手
1.Cilium 安装要求
在安装 Cilium 之前,请确保您的系统满足最低要求要求如下。
- 1.使用容器镜像运行 Cilium 时,需要在具有 AMD64 或 AArch64 架构的主机 以及Linux 内核 >= 5.4 或同等版本(例如,RHEL 8.6 上的 4.18)
- 2.使用二进制方式运行 Cilium 时,将其作为原生进程运行时 必须满足以下以下额外要求
clang LLVM >= 10.0
,etcd >= 3.1.0
Requirement | Minimum Version | In cilium container |
---|---|---|
Linux kernel | >= 5.4 or >= 4.18 on RHEL 8.6 | no |
Key-Value store (etcd) | >= 3.1.0 | no |
clang LLVM | >= 10.0 | yes |
系统要求参考文档:https://docs.cilium.io/en/stable/operations/system_requirements/
2.Cilium 安装实践
实践环境:
代码语言:javascript复制$ kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master-197 Ready control-plane 19d v1.30.3 192.168.10.197 <none> Kylin Linux Advanced Server V10 (Lance) 4.19.90-52.39.v2207.ky10.x86_64 containerd://1.7.20
master-198 Ready control-plane 19d v1.30.3 192.168.10.198 <none> Kylin Linux Advanced Server V10 (Lance) 4.19.90-52.39.v2207.ky10.x86_64 containerd://1.7.20
master-199 Ready control-plane 19d v1.30.3 192.168.10.199 <none> Kylin Linux Advanced Server V10 (Lance) 4.19.90-52.39.v2207.ky10.x86_64 containerd://1.7.20
node-200 Ready work 19d v1.30.3 192.168.10.200 <none> Kylin Linux Advanced Server V10 (Lance) 4.19.90-52.26.v2207.ky10.x86_64 containerd://1.7.20
由上实践环境可知,作者在 Kylin Linux Advanced Server V10 (Lance)
系统中部署了最新的 Kubernetes 集群,其内核版本为 4.19.90-52.39.v2207.ky10.x86_64
,其版本低于 Cilium 全部功能要求的最低版本>= 5.4
,这并不是说此版本集群中不能运行 Cilium,而是一些 Cilium 高级功能可能依赖于较新的内核版本,你可以按照自身需要,自行通过升级到更新的内核版本来启用。
Cilium Feature | Minimum Kernel Version |
---|---|
Bandwidth Manager | >= 5.1 |
Egress Gateway | >= 5.2 |
VXLAN Tunnel Endpoint (VTEP) Integration | >= 5.2 |
WireGuard Transparent Encryption | >= 5.6 |
Full support for Session Affinity | >= 5.7 |
BPF-based proxy redirection | >= 5.7 |
Socket-level LB bypass in pod netns | >= 5.7 |
L3 devices | >= 5.8 |
BPF-based host routing | >= 5.10 |
Multicast Support in Cilium (Beta) (AMD64) | >= 5.10 |
IPv6 BIG TCP support | >= 5.19 |
Multicast Support in Cilium (Beta) (AArch64) | >= 6.0 |
IPv4 BIG TCP support | >= 6.3 |
快速安装
Step 1.下载指定版本的 Cilium 客户端(cilium-cli)。
代码语言:javascript复制# 系统架构
CLI_ARCH=amd64
# 稳定版本
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/master/stable.txt)
# 验证是否为 aarch64 系统架构
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
# 拉取 cilium cli 客户端及其校验文件
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
# 国内环境代理下载
# curl -L --remote-name-allhttps://down.npee.cn/?https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz{,.sha256sum}
# 校验是否被串改
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
# cilium-linux-amd64.tar.gz: OK
# 解压 cilium-cli 到 /usr/local/bin
sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
# 查看客户端版本
cilium version --client
# cilium-cli: v0.16.15 compiled with go1.22.5 on linux/amd64
# cilium image (default): v1.16.0
除此之外,还可通 helm 方式安装 Cilium 到集群中,选择其中一种安装即可,其参数应该八字。
代码语言:javascript复制# 添加仓库
helm repo add cilium https://helm.cilium.io/
# 部署cilium
helm install cilium cilium/cilium --version 1.16.0
--namespace kube-system
--set operator.replicas=1
--set k8sServiceHost=dev-lb.k8s.weiyigeek.top
--set k8sServicePort=16443
--set tunnel=disabled
--set autoDirectNodeRoutes=true
--set ipv4NativeRoutingCIDR=172.20.0.0/16
--set hubble.relay.enabled=true
--set hubble.ui.enabled=true
Step 2.查看可以用 Cilium 版本列表。
代码语言:javascript复制cilium install --list-versions | head -n 10
# v1.16.0 (default)
# v1.16.0-rc.2
# v1.16.0-rc.1
# v1.16.0-rc.0
# v1.16.0-pre.3
Step 3.安装 Cilium 到 Kubernetes 集群中。
代码语言:javascript复制# 默认安装 Cilium 1.16.0 版本,其缺省参数为如下:
cilium install --dry-run-helm-values
# cluster:
# name: kubernetes
# operator:
# replicas: 1
# routingMode: tunnel
# tunnelProtocol: vxlan
# 自定义安装,注意将Pod池设置为在创建 Kubernetes 集群时 podSubnet 参数指定的值 172.16.0.0/16 ,并且启用 Hubble 来可视化展示 Cilium 网络通信关系。
cilium install
--set ipam.mode=kubernetes
--set ipam.operator.clusterPoolIPv4PodCIDRList=172.20.0.0/16
--set ipam.Operator.ClusterPoolIPv4MaskSize=24
--set ipv4NativeRoutingCIDR=172.20.0.0/16
--set tunnel=disabled
--set routingMode=native
--set autoDirectNodeRoutes=true
--set ingressController.enabled=true
--set ingressController.loadbalancerMode=shared
--set hubble.enabled="true"
--set hubble.listenAddress=":4244"
--set hubble.relay.enabled="true"
--set hubble.ui.enabled="true"
# 高级特性
# 开启 bpf masquerade
--set bpf.masquerade=true
# 启用 bpf LegacyRouting
--set bpf.hostLegacyRouting=true
# 设置负载均衡模式
--set loadBalancer.mode=dsr # dsr 模式
--set loadBalancer.mode=hybrid # 混合模式,即dsr和snat两种
温馨提示:建议看友们安装时禁用隧道(tunnel)进行VXLAN 封装,而是启用本地路由(Native-Routing)可提升网络最大吞吐量,
Step 4.安装完毕后等待一会查看 Cilium 在集群中部署运行状态。
代码语言:javascript复制$ cilium status --wait
/¯¯
/¯¯__/¯¯ Cilium: OK
__/¯¯__/ Operator: OK
/¯¯__/¯¯ Envoy DaemonSet: OK
__/¯¯__/ Hubble Relay: disabled
__/ ClusterMesh: disabled
DaemonSet cilium Desired: 4, Ready: 4/4, Available: 4/4
DaemonSet cilium-envoy Desired: 4, Ready: 4/4, Available: 4/4
Deployment cilium-operator Desired: 1, Ready: 1/1, Available: 1/1
Containers: cilium Running: 4
cilium-envoy Running: 4
cilium-operator Running: 1
Cluster Pods: 2/2 managed by Cilium
.....
weiyigeek.top-查看 Cilium 运行状态图
温馨提示:若安装报错请验证系统内核版本是否满足要求,其次是所需镜像是否拉取成功,若无法拉取镜像可以使用访问国外网站的代理方式拉取镜像到本地或私有镜像仓库中,或者在containerd设置 quay.io 仓库的镜像站点,若仍然报错请使用如下命令kubectl logs -f -n kube-system
查看 Cilium Pod 运行日志。
# Image versions
cilium quay.io/cilium/cilium:v1.16.0@sha256:46ffa4ef3cf6d8885dcc4af5963b0683f7d59daa90d49ed9fb68d3b1627fe058: 4
cilium-envoy quay.io/cilium/cilium-envoy:v1.29.7-39a2a56bbd5b3a591f69dbca51d3e30ef97e0e51@sha256:bd5ff8c66716080028f414ec1cb4f7dc66f40d2fb5a009fff187f4a9b90b566b: 4
hubble-relay quay.io/cilium/hubble-relay:v1.16.0@sha256:33fca7776fc3d7b2abe08873319353806dc1c5e07e12011d7da4da05f836ce8d: 1
cilium-operator quay.io/cilium/operator-generic:v1.16.0@sha256:d6621c11c4e4943bf2998af7febe05be5ed6fdcf812b27ad4388f47022190316: 1
hubble-ui quay.io/cilium/hubble-ui:v0.13.1@sha256:e2e9313eb7caf64b0061d9da0efbdad59c6c461f6ca1752768942bfeda0796c6: 1
hubble-ui quay.io/cilium/hubble-ui-backend:v0.13.1@sha256:0e0eed917653441fded4e7cdb096b7be6a3bddded5a2dd10812a27b1fc6ed95b: 1
温馨提示:若想拉取 docker hub 仓库镜像到本地或私有镜像仓库中,请使用如下脚本快速拉取并上传,需要科学代理地址。
代码语言:javascript复制# skopeo-proxy-copy.sh
#!/bin/bash
export proxy="http://10.10.172.106:10809"
export http_proxy=$proxy
export https_proxy=$proxy
export no_proxy="localhost, 127.0.0.1, ::1, harbor.weiyigeek.top"
src=$1
dest=harbor.weiyigeek.top/devops/${src#*/}
echo "src images : $src"
echo "dest images : $dest"
skopeo copy --insecure-policy --src-tls-verify=false --dest-tls-verify=false docker://$1 docker://${dest}
相关文章参考:
- 运维实践 | KylinOS国产系统部署Harbor企业私有镜像仓库
- 运维实践 | 巧用CF的Workers完美解决Docker镜像国内无法拉取
- 运维工具 | 如何使用Skopeo做一个优雅的镜像搬运工
- 网安等保 | 主机安全之KylinOS银河麒麟服务器配置优化与安全加固基线文档脚本分享
Step 5.进行 Cilium 网络通信压力和Pod连通性测试。
代码语言:javascript复制# 连通性测试
$ cilium connectivity test --request-timeout 30s --connect-timeout 10s
# ℹ️ Monitor aggregation detected, will skip some flow validation steps
# ✨ [kubernetes] Creating namespace cilium-test-1 for connectivity check...
# ✨ [kubernetes] Deploying echo-same-node service...
# ✨ [kubernetes] Deploying DNS test server configmap...
# ✨ [kubernetes] Deploying same-node deployment...
# ✨ [kubernetes] Deploying client deployment...
# ✨ [kubernetes] Deploying client2 deployment...
# ✨ [kubernetes] Deploying client3 deployment...
# ✨ [kubernetes] Deploying echo-other-node service...
# ✨ [kubernetes] Deploying other-node deployment...
# ✨ [host-netns] Deploying kubernetes daemonset...
# ✨ [host-netns-non-cilium] Deploying kubernetes daemonset...
# ℹ️ Skipping tests that require a node Without Cilium
# ⌛ [kubernetes] Waiting for deployment cilium-test-1/client to become ready...
# ⌛ [kubernetes] Waiting for deployment cilium-test-1/client2 to become ready...
# ⌛ [kubernetes] Waiting for deployment cilium-test-1/echo-same-node to become ready...
# 使用本地路由 (Native-Routing) 压力测试
cilium connectivity perf
-------------------------------------------------------------------------------------