概述
Cilium v1.14.4 默認(rèn)安裝不會(huì)設(shè)置 kubeProxyReplacement
參數(shù),默認(rèn)情況下只會(huì)開啟 ClusterIP,也就是可以部分支持 Service 的功能,如果還需要 NodePort 功能,還需要單獨(dú)設(shè)置。
# helm get values cilium
USER-SUPPLIED VALUES:
cni:
chainingMode: generic-veth
configMap: cni-configuration
customConf: true
enableIPv4Masquerade: false
k8sServiceHost: 192.168.1.200
k8sServicePort: 6443
routingMode: native
本文主要分析 Cilium 是如何實(shí)現(xiàn) ClusterIP 功能,以及分析 Flannel 結(jié)合 cilium-chain 下,ClusterIP 是如何于其他 CNI 合作。
配置信息
查看 cilium-agent 內(nèi)部的一些信息(省略了跟Service無關(guān)的部分)。
# cilium status --verbose
Kubernetes: Ok 1.20 (v1.20.3) [linux/amd64]
KubeProxyReplacement: False
CNI Chaining: generic-veth
Cilium: Ok 1.14.4 (v1.14.4-87dd2b64)
IPAM: IPv4: 1/254 allocated from 10.0.2.0/24,
KubeProxyReplacement Details:
Status: False
Socket LB: Disabled
Socket LB Tracing: Disabled
Socket LB Coverage: Full
Session Affinity: Disabled
Graceful Termination: Enabled
NAT46/64 Support: Disabled
Services:
- ClusterIP: Enabled
- NodePort: Disabled
- LoadBalancer: Disabled
- externalIPs: Disabled
- HostPort: Disabled
BPF Maps: dynamic sizing: on (ratio: 0.002500)
Name Size
Auth 524288
Non-TCP connection tracking 65536
TCP connection tracking 131072
Endpoint policy 65535
IP cache 512000
IPv4 masquerading agent 16384
IPv6 masquerading agent 16384
IPv4 fragmentation 8192
IPv4 service 65536
IPv6 service 65536
IPv4 service backend 65536
IPv6 service backend 65536
IPv4 service reverse NAT 65536
IPv6 service reverse NAT 65536
Metrics 1024
NAT 131072
Neighbor table 131072
Global policy 16384
Session affinity 65536
Sock reverse NAT 65536
Tunnel 65536
代碼框架
cilium-agent 會(huì) watch Kubernetes 關(guān)于 Service/Endpoint/EndpointSlice 等資源,然后根據(jù)這些資源的變化,對(duì) eBPF 的 Service LB 的 Map 做 CRUD。
d.k8sWatcher.RunK8sServiceHandler() //daemon/cmd/daemon.go
|-k8s.UpdateService //pkg/k8s/watchers/watcher.go
|-K8sWatcher.addK8sSVCs //pkg/k8s/watchers/watcher.go
|-k.svcManager.UpsertService(p) //pkg/k8s/watchers/watcher.go
|-s.upsertService(params) //pkg/service/service.go
|-s.upsertServiceIntoLBMaps //pkg/service/service.go
|-s.lbmap.AddBackend //pkg/service/service.go
|-LBBPFMap.AddBackend //pkg/maps/lbmap/lbmap.go
|-updateBackend //pkg/maps/lbmap/lbmap.go
|-backend.Map().OpenOrCreate() //pkg/maps/lbmap/lbmap.go
|-s.lbmap.UpsertService(p) //pkg/service/service.go
|-upsertServiceProto //pkg/maps/lbmap/lbmap.go
|-LBBPFMap.UpsertService //pkg/maps/lbmap/lbmap.go
|-updateServiceEndpoint //pkg/maps/lbmap/lbmap.go
|-Update //pkg/bpf/map_linux.go
|- Update //vendor/github.com/cilium/ebpf/map.go
|- MapUpdateElem
|- BPF(cmd Cmd, attr unsafe.Pointer, size uintptr)
|- unix.Syscall(unix.SYS_BPF, uintptr(cmd), uintptr(attr), size) //系統(tǒng)調(diào)用
Service IP到Pod IP
這里的 Pod IP 是指 Service 關(guān)聯(lián)的 Endpoint,也可以理解成是 Service 的后端 Pod IP。
// bpf/bpf_lxc.c
測(cè)試案例
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: kube-system
name: nm-test
spec:
selector:
matchLabels:
app: nm-test
template:
metadata:
labels:
app: nm-test
spec:
nodeSelector:
kubernetes.io/os: linux
os-type: openeuler
kubernetes.io/hostname: 10.189.212.124
containers:
- name: nm-test
image: runzhliu/network-multitool:latest
command: ["/bin/bash", "-c", "sleep infinity"]
securityContext:
privileged: true
EOF
可用范圍
從上面的分析可以知道,Cilium 之所以聲稱可以完全的 kube-proxy free,是因?yàn)?cilium-agent 在節(jié)點(diǎn)層面上,維護(hù)了一個(gè) lbMap 的結(jié)構(gòu),這個(gè)結(jié)構(gòu)會(huì)將 Service 的 ClusterIP 和后端的 Endpoint 的 IP 完成映射,并且一直會(huì) watch 整個(gè)集群內(nèi)部的 Service 等相關(guān)的資源的變化情況。
因此在沒有部署 cilium-agent 的節(jié)點(diǎn)上,也包括 Kubernetes 集群外,Service 的 ClusterIP 是無法使用的,因?yàn)楣?jié)點(diǎn)上沒有相關(guān)的 lbMap 結(jié)構(gòu)來完成 Service IP 到 Endpoint 的映射。
另外關(guān)于一些開源組件的 webhook 等應(yīng)用,在當(dāng)前我們的 Kubernetes 架構(gòu)上也無法直接使用,本質(zhì)原因是我們集群的 kube-apiserver 是獨(dú)立部署,而不是用靜態(tài) Pod 這些形式搭建的,也就是說 kube-apiserver 的節(jié)點(diǎn)上,同樣是沒有 cilium-agent,因此如果需要使用 webhook 等功能,還是需要像之前的集群那樣,通過注冊(cè) VGW 等形式曲線實(shí)現(xiàn)。
總結(jié)
cilium-chain 的 ClusterIP 的實(shí)現(xiàn)跟 Cilium 本身沒有本質(zhì)的區(qū)別,區(qū)別主要是在于后端綁定的 Pod IP 是 cilium-chain 的主網(wǎng)卡還是 Cilium 自行創(chuàng)建的。