# 具備API感知的網絡和安全性管理的開源軟件Cilium
Cilium是一個純開源軟件,沒有哪家公司提供商業化支持,也不是由某一公司開源,該軟件用于透明地保護使用Linux容器管理平臺(如Docker和Kubernetes)部署的應用程序服務之間的網絡連接。
Cilium的基礎是一種名為BPF的新Linux內核技術,它可以在Linux本身動態插入強大的安全可見性和控制邏輯。由于BPF在Linux內核中運行,因此可以應用和更新Cilium安全策略,而無需對應用程序代碼或容器配置進行任何更改。

基于微服務的應用程序分為小型獨立服務,這些服務使用**HTTP**、**gRPC**、**Kafka**等輕量級協議通過API相互通信。但是,現有的Linux網絡安全機制(例如iptables)僅在網絡和傳輸層(即IP地址和端口)上運行,并且缺乏對微服務層的可見性。
Cilium為Linux容器框架(如[**Docker**](https://www.docker.com/)和[**Kubernetes)**](https://kubernetes.io/)帶來了API感知網絡安全過濾。使用名為**BPF**的新Linux內核技術,Cilium提供了一種基于容器/容器標識定義和實施網絡層和應用層安全策略的簡單而有效的方法。
**注**:Cilium中文意思是“纖毛“,它十分細小而又無處不在。
## BPF
**柏克萊封包過濾器**(Berkeley Packet Filter,縮寫 BPF),是[類Unix](https://zh.wikipedia.org/wiki/%E7%B1%BBUnix)系統上[數據鏈路層](https://zh.wikipedia.org/wiki/%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82)的一種原始接口,提供原始鏈路層[封包](https://zh.wikipedia.org/wiki/%E5%B0%81%E5%8C%85)的收發,除此之外,如果網卡驅動支持[洪泛](https://zh.wikipedia.org/wiki/%E6%B4%AA%E6%B3%9B)模式,那么它可以讓網卡處于此種模式,這樣可以收到[網絡](https://zh.wikipedia.org/wiki/%E7%BD%91%E7%BB%9C)上的所有包,不管他們的目的地是不是所在[主機](https://zh.wikipedia.org/wiki/%E4%B8%BB%E6%A9%9F)。參考[維基百科](https://zh.wikipedia.org/wiki/BPF)和[eBPF簡史](https://www.ibm.com/developerworks/cn/linux/l-lo-eBPF-history/index.html)。
## 特性
以下是Cilium的特性。
**基于身份的安全性**
Cilium可見性和安全策略基于容器編排系統的標識(例如,Kubernetes中的Label)。在編寫安全策略、審計和故障排查時,再也不用擔心網絡子網或容器IP地址了。
**卓越的性能**
BPF利用Linux底層的強大能力,通過提供Linux內核的沙盒可編程性來實現數據路徑,從而提供卓越的性能。
**API協議可見性+安全性**
傳統防火墻僅根據IP地址和端口等網絡標頭查看和過濾數據包。Cilium也可以這樣做,但也可以理解并過濾單個HTTP、gRPC和Kafka請求,這些請求將微服務拼接在一起。
**專為擴展而設計**
Cilium是為擴展而設計的,在部署新pod時不需要節點間交互,并且通過高度可擴展的鍵值存儲進行所有協調。
## 為什么選擇Cilium?
現代數據中心應用程序的開發已經轉向面向服務的體系結構(SOA),通常稱為*微服務*,其中大型應用程序被分成小型獨立服務,這些服務使用HTTP等輕量級協議通過API相互通信。微服務應用程序往往是高度動態的,作為持續交付的一部分部署的滾動更新期間單個容器啟動或銷毀,應用程序擴展/縮小以適應負載變化。
這種向高度動態的微服務的轉變過程,給確保微服務之間的連接方面提出了挑戰和機遇。傳統的Linux網絡安全方法(例如iptables)過濾IP地址和TCP/UDP端口,但IP地址經常在動態微服務環境中流失。容器的高度不穩定的生命周期導致這些方法難以與應用程序并排擴展,因為負載均衡表和訪問控制列表要不斷更新,可能增長成包含數十萬條規則。出于安全目的,協議端口(例如,用于HTTP流量的TCP端口80)不能再用于區分應用流量,因為該端口用于跨服務的各種消息。
另一個挑戰是提供準確的可見性,因為傳統系統使用IP地址作為主要識別工具,其在微服務架構中的壽命可能才僅僅幾秒鐘,被大大縮短。
利用Linux BPF,Cilium保留了透明地插入安全可視性+強制執行的能力,但這種方式基于服務/pod/容器標識(與傳統系統中的IP地址識別相反),并且可以根據應用層進行過濾 (例如HTTP)。因此,通過將安全性與尋址分離,Cilium不僅可以在高度動態的環境中應用安全策略,而且除了提供傳統的第3層和第4層分割之外,還可以通過在HTTP層運行來提供更強的安全隔離。 。
BPF的使用使得Cilium能夠以高度可擴展的方式實現以上功能,即使對于大規模環境也不例外。
## 功能概述
### 透明的保護API
能夠保護現代應用程序協議,如REST/HTTP、gRPC和Kafka。傳統防火墻在第3層和第4層運行,在特定端口上運行的協議要么完全受信任,要么完全被阻止。Cilium提供了過濾各個應用程序協議請求的功能,例如:
- 允許所有帶有方法`GET`和路徑`/public/.*`的HTTP請求。拒絕所有其他請求。
- 允許`service1`在Kafka topic上生成`topic1`,`service2`消費`topic1`。拒絕所有其他Kafka消息。
- 要求HTTP標頭`X-Token: [0-9]+`出現在所有REST調用中。
詳情請參考[7層協議](http://docs.cilium.io/en/stable/policy/#layer-7)。
### 基于身份來保護服務間通信
現代分布式應用程序依賴于諸如容器之類的技術來促進敏捷性并按需擴展。這將導致在短時間內啟動大量應用容器。典型的容器防火墻通過過濾源IP地址和目標端口來保護工作負載。這就要求不論在集群中的哪個位置啟動容器時都要操作所有服務器上的防火墻。
為了避免受到規模限制,Cilium為共享相同安全策略的應用程序容器組分配安全標識。然后,該標識與應用程序容器發出的所有網絡數據包相關聯,從而允許驗證接收節點處的身份。使用鍵值存儲執行安全身份管理。
### 安全訪問外部服務
基于標簽的安全性是集群內部訪問控制的首選工具。為了保護對外部服務的訪問,支持入口(ingress)和出口(egress)的傳統基于CIDR的安全策略。這允許限制對應用程序容器的訪問以及對特定IP范圍的訪問。
### 簡單網絡
一個簡單的扁平第3層網絡能夠跨越多個集群連接所有應用程序容器。使用主機范圍分配器可以簡化IP分配。這意味著每個主機可以在主機之間沒有任何協調的情況下分配IP。
支持以下多節點網絡模型:
- **Overlay**:基于封裝的虛擬網絡產生所有主機。目前VXLAN和Geneve已經完成,但可以啟用Linux支持的所有封裝格式。
何時使用此模式:此模式具有最小的基礎架構和集成要求。它幾乎適用于任何網絡基礎架構,唯一的要求是主機之間可以通過IP連接。
- **本機路由**:使用Linux主機的常規路由表。網絡必須能夠路由應用程序容器的IP地址。
何時使用此模式:此模式適用于高級用戶,需要了解底層網絡基礎結構。此模式適用于:
- 本地IPv6網絡
- 與云網絡路由器配合使用
- 如果您已經在運行路由守護進程
### 負載均衡
應用程序容器和外部服務之間的流量的分布式負載均衡。負載均衡使用BPF實現,允許幾乎無限的規模,并且如果未在源主機上執行負載均衡操作,則支持直接服務器返回(DSR)。
**注意**:負載均衡需要啟用連接跟蹤。這是默認值。
### 監控和故障排除
可見性和故障排查是任何分布式系統運行的基礎。雖然我們喜歡用`tcpdump`和 `ping`,它們很好用,但我們努力為故障排除提供更好的工具。包括以下工具:
- 使用元數據進行事件監控:當數據包被丟棄時,該工具不僅僅報告數據包的源IP和目標IP,該工具還提供發送方和接收方的完整標簽信息等。
- 策略決策跟蹤:為什么丟棄數據包或拒絕請求。策略跟蹤框架允許跟蹤運行工作負載和基于任意標簽定義的策略決策過程。
- 通過Prometheus導出指標:通過Prometheus導出關鍵指標,以便與現有儀表板集成。
### 集成
- 網絡插件集成:[CNI](https://github.com/containernetworking/cni)、[libnetwork](https://github.com/docker/libnetwork)
- 容器運行時:[containerd](https://github.com/containerd/containerd)
- Kubernetes:[NetworkPolicy](https://kubernetes.io/docs/concepts/services-networking/network-policies/)、[Label](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)、[Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)、[Service](https://kubernetes.io/docs/concepts/services-networking/service/)
- 日志記錄:syslog、[fluentd](http://www.fluentd.org/)
## 參考
- [Cilium官方網站 - cilium.io](https://cilium.io)
- [eBPF 簡史 - ibm.com](https://www.ibm.com/developerworks/cn/linux/l-lo-eBPF-history/index.html)
- [網絡層攔截可選項 - zhihu.com](https://zhuanlan.zhihu.com/p/25672552)
- 序言
- 云原生
- 云原生(Cloud Native)的定義
- CNCF - 云原生計算基金會簡介
- CNCF章程
- 云原生的設計哲學
- Play with Kubernetes
- 快速部署一個云原生本地實驗環境
- Kubernetes與云原生應用概覽
- 云原生應用之路——從Kubernetes到Cloud Native
- 云原生編程語言
- 云原生編程語言Ballerina
- 云原生編程語言Pulumi
- 云原生的未來
- Kubernetes架構
- 設計理念
- Etcd解析
- 開放接口
- CRI - Container Runtime Interface(容器運行時接口)
- CNI - Container Network Interface(容器網絡接口)
- CSI - Container Storage Interface(容器存儲接口)
- Kubernetes中的網絡
- Kubernetes中的網絡解析——以flannel為例
- Kubernetes中的網絡解析——以calico為例
- 具備API感知的網絡和安全性管理開源軟件Cilium
- Cilium架構設計與概念解析
- 資源對象與基本概念解析
- Pod狀態與生命周期管理
- Pod概覽
- Pod解析
- Init容器
- Pause容器
- Pod安全策略
- Pod的生命周期
- Pod Hook
- Pod Preset
- Pod中斷與PDB(Pod中斷預算)
- 集群資源管理
- Node
- Namespace
- Label
- Annotation
- Taint和Toleration(污點和容忍)
- 垃圾收集
- 控制器
- Deployment
- StatefulSet
- DaemonSet
- ReplicationController和ReplicaSet
- Job
- CronJob
- Horizontal Pod Autoscaling
- 自定義指標HPA
- 準入控制器(Admission Controller)
- 服務發現
- Service
- Ingress
- Traefik Ingress Controller
- 身份與權限控制
- ServiceAccount
- RBAC——基于角色的訪問控制
- NetworkPolicy
- 存儲
- Secret
- ConfigMap
- ConfigMap的熱更新
- Volume
- Persistent Volume(持久化卷)
- Storage Class
- 本地持久化存儲
- 集群擴展
- 使用自定義資源擴展API
- 使用CRD擴展Kubernetes API
- Aggregated API Server
- APIService
- Service Catalog
- 資源調度
- QoS(服務質量等級)
- 用戶指南
- 資源對象配置
- 配置Pod的liveness和readiness探針
- 配置Pod的Service Account
- Secret配置
- 管理namespace中的資源配額
- 命令使用
- Docker用戶過度到kubectl命令行指南
- kubectl命令概覽
- kubectl命令技巧大全
- 使用etcdctl訪問kubernetes數據
- 集群安全性管理
- 管理集群中的TLS
- kubelet的認證授權
- TLS bootstrap
- 創建用戶認證授權的kubeconfig文件
- IP偽裝代理
- 使用kubeconfig或token進行用戶身份認證
- Kubernetes中的用戶與身份認證授權
- Kubernetes集群安全性配置最佳實踐
- 訪問Kubernetes集群
- 訪問集群
- 使用kubeconfig文件配置跨集群認證
- 通過端口轉發訪問集群中的應用程序
- 使用service訪問群集中的應用程序
- 從外部訪問Kubernetes中的Pod
- Cabin - Kubernetes手機客戶端
- Kubernetic - Kubernetes桌面客戶端
- Kubernator - 更底層的Kubernetes UI
- 在Kubernetes中開發部署應用
- 適用于kubernetes的應用開發部署流程
- 遷移傳統應用到Kubernetes中——以Hadoop YARN為例
- 最佳實踐概覽
- 在CentOS上部署Kubernetes集群
- 創建TLS證書和秘鑰
- 創建kubeconfig文件
- 創建高可用etcd集群
- 安裝kubectl命令行工具
- 部署master節點
- 安裝flannel網絡插件
- 部署node節點
- 安裝kubedns插件
- 安裝dashboard插件
- 安裝heapster插件
- 安裝EFK插件
- 生產級的Kubernetes簡化管理工具kubeadm
- 使用kubeadm在Ubuntu Server 16.04上快速構建測試集群
- 服務發現與負載均衡
- 安裝Traefik ingress
- 分布式負載測試
- 網絡和集群性能測試
- 邊緣節點配置
- 安裝Nginx ingress
- 安裝配置DNS
- 安裝配置Kube-dns
- 安裝配置CoreDNS
- 運維管理
- Master節點高可用
- 服務滾動升級
- 應用日志收集
- 配置最佳實踐
- 集群及應用監控
- 數據持久化問題
- 管理容器的計算資源
- 集群聯邦
- 存儲管理
- GlusterFS
- 使用GlusterFS做持久化存儲
- 使用Heketi作為Kubernetes的持久存儲GlusterFS的external provisioner
- 在OpenShift中使用GlusterFS做持久化存儲
- GlusterD-2.0
- Ceph
- 用Helm托管安裝Ceph集群并提供后端存儲
- 使用Ceph做持久化存儲
- 使用rbd-provisioner提供rbd持久化存儲
- OpenEBS
- 使用OpenEBS做持久化存儲
- Rook
- NFS
- 利用NFS動態提供Kubernetes后端存儲卷
- 集群與應用監控
- Heapster
- 使用Heapster獲取集群和對象的metric數據
- Prometheus
- 使用Prometheus監控kubernetes集群
- Prometheus查詢語言PromQL使用說明
- 使用Vistio監控Istio服務網格中的流量
- 分布式跟蹤
- OpenTracing
- 服務編排管理
- 使用Helm管理Kubernetes應用
- 構建私有Chart倉庫
- 持續集成與發布
- 使用Jenkins進行持續集成與發布
- 使用Drone進行持續集成與發布
- 更新與升級
- 手動升級Kubernetes集群
- 升級dashboard
- 領域應用概覽
- 微服務架構
- 微服務中的服務發現
- 使用Java構建微服務并發布到Kubernetes平臺
- Spring Boot快速開始指南
- Service Mesh 服務網格
- 企業級服務網格架構
- Service Mesh基礎
- Service Mesh技術對比
- 采納和演進
- 定制和集成
- 總結
- Istio
- 安裝并試用Istio service mesh
- 配置請求的路由規則
- 安裝和拓展Istio service mesh
- 集成虛擬機
- Istio中sidecar的注入規范及示例
- 如何參與Istio社區及注意事項
- Istio教程
- Istio免費學習資源匯總
- 深入理解Istio Service Mesh中的Envoy Sidecar注入與流量劫持
- 深入理解Istio Service Mesh中的Envoy Sidecar代理的路由轉發
- Linkerd
- Linkerd 使用指南
- Conduit
- Condiut概覽
- 安裝Conduit
- Envoy
- Envoy的架構與基本術語
- Envoy作為前端代理
- Envoy mesh教程
- SOFAMesh
- SOFAMesh中的Dubbo on x-protocol
- SOFAMosn
- 使用 SOFAMosn 構建 SOFAMesh
- 大數據
- Spark standalone on Kubernetes
- 運行支持Kubernetes原生調度的Spark程序
- Serverless架構
- 理解Serverless
- FaaS-函數即服務
- OpenFaaS快速入門指南
- 邊緣計算
- 人工智能