Cilium LB IPAM概念(转载)
Cilium LB IPAM概念
一、环境信息
主机 | IP |
---|---|
ubuntu | 172.16.94.141 |
软件 | 版本 |
---|---|
docker | 26.1.4 |
helm | v3.15.0-rc.2 |
kind | 0.18.0 |
kubernetes | 1.23.4 |
ubuntu os | Ubuntu 20.04.6 LTS |
kernel | 5.11.5 内核升级文档 |
二、Cilium
LB IPAM
概念说明
LB IPAM
(LoadBalancer IP Address Management) 允许Cilium
将IP
地址分配给LoadBalancer
类型的服务;- 在公有云环境中,LB地址通常由云厂商提供。然而在私有云环境中,我们就需要借助其他工具实现了。
LB IPAM
通常与Cilium BGP
等功能结合使用。其中LB IPAM
负责将IP
分配和指派给service
对象,BGP
负责将这些IP
通告出去LB IPAM
只会分配LB
地址,不负责路由,无论是集群内还是集群外都无法访问该地址。需要借助其他方案例如metallb
或者通过cilium BGP
将地址宣告出去,这样外界网络里这个地址就是可路由了Cilium BGP
将service LB
的ip
地址宣告出去(更加符合k8s
理念)。不同的是在Calico
中,通过BGP
是将clusterIP
宣告出去的。
三、Cilium LB IPAM 环境搭建
kind
配置文件信息
root@kind:~# cat install.sh
#!/bin/bash
date
set -v
# 1.prep noCNI env
cat <<EOF | kind create cluster --name=cilium-lb-ipam --image=kindest/node:v1.23.4 --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
# kind 默认使用 rancher cni,cni 我们需要自己创建
disableDefaultCNI: true
# 此处使用 cilium 代替 kube-proxy 功能
kubeProxyMode: "none"
nodes:
- role: control-plane
- role: worker
- role: worker
containerdConfigPatches:
- |-
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor.evescn.com"]
endpoint = ["https://harbor.evescn.com"]
EOF
# 2.remove taints
controller_node=`kubectl get nodes --no-headers -o custom-columns=NAME:.metadata.name| grep control-plane`
# kubectl taint nodes $controller_node node-role.kubernetes.io/master:NoSchedule-
kubectl get nodes -o wide
# 3.install cni
helm repo add cilium https://helm.cilium.io > /dev/null 2>&1
helm repo update > /dev/null 2>&1
helm install cilium cilium/cilium \
--set k8sServiceHost=$controller_node \
--set k8sServicePort=6443 \
--version 1.13.0-rc5 \
--namespace kube-system \
--set debug.enabled=true \
--set debug.verbose=datapath \
--set monitorAggregation=none \
--set ipam.mode=cluster-pool \
--set cluster.name=cilium-lb-ipam \
--set kubeProxyReplacement=strict \
--set tunnel=disabled \
--set autoDirectNodeRoutes=true \
--set ipv4NativeRoutingCIDR=10.0.0.0/8 \
--set bpf.masquerade=true \
--set installNoConntrackIptablesRules=true
# 4.install necessary tools
for i in $(docker ps -a --format "table {{.Names}}" | grep cilium)
do
echo $i
docker cp /usr/bin/ping $i:/usr/bin/ping
docker exec -it $i bash -c "sed -i -e 's/jp.archive.ubuntu.com\|archive.ubuntu.com\|security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list"
docker exec -it $i bash -c "apt-get -y update >/dev/null && apt-get -y install net-tools tcpdump lrzsz bridge-utils >/dev/null 2>&1"
done
--set
参数解释
-
--set kubeProxyReplacement=strict
- 含义: 启用 kube-proxy 替代功能,并以严格模式运行。
- 用途: Cilium 将完全替代 kube-proxy 实现服务负载均衡,提供更高效的流量转发和网络策略管理。
-
--set tunnel=disabled
- 含义: 禁用隧道模式。
- 用途: 禁用后,Cilium 将不使用 vxlan 技术,直接在主机之间路由数据包,即 direct-routing 模式。
-
--set autoDirectNodeRoutes=true
- 含义: 启用自动直接节点路由。
- 用途: 使 Cilium 自动设置直接节点路由,优化网络流量。
-
--set ipv4NativeRoutingCIDR="10.0.0.0/8"
- 含义: 指定用于 IPv4 本地路由的 CIDR 范围,这里是
10.0.0.0/8
。 - 用途: 配置 Cilium 使其知道哪些 IP 地址范围应该通过本地路由进行处理,不做 snat , Cilium 默认会对所用地址做 snat。
- 含义: 指定用于 IPv4 本地路由的 CIDR 范围,这里是
-
--set bpf.masquerade
- 含义: 启用 eBPF 功能。
- 用途: 使用 eBPF 实现数据路由,提供更高效和灵活的网络地址转换功能。
-
--set installNoConntrackIptablesRules=true
:- 安装无连接跟踪的 iptables 规则,这样可以减少 iptables 规则集中的连接跟踪负担。
- 安装
k8s
集群和cilium
服务
root@kind:~# ./install.sh
Creating cluster "cilium-lb-ipam" ...
✓ Ensuring node image (kindest/node:v1.23.4) 🖼
✓ Preparing nodes 📦 📦 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing StorageClass 💾
✓ Joining worker nodes 🚜
Set kubectl context to "kind-cilium-lb-ipam"
You can now use your cluster with:
kubectl cluster-info --context kind-cilium-lb-ipam
Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/
- 查看安装的服务
root@kind:~# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system cilium-59qlg 1/1 Running 0 10m
kube-system cilium-hmzms 1/1 Running 0 10m
kube-system cilium-operator-c95c8977-dg8mx 1/1 Running 0 10m
kube-system cilium-operator-c95c8977-jpx6s 1/1 Running 0 10m
kube-system cilium-qsl8t 1/1 Running 0 10m
kube-system coredns-64897985d-v22cf 1/1 Running 0 11m
kube-system coredns-64897985d-v55h6 1/1 Running 0 11m
kube-system etcd-cilium-lb-ipam-control-plane 1/1 Running 0 11m
kube-system kube-apiserver-cilium-lb-ipam-control-plane 1/1 Running 0 11m
kube-system kube-controller-manager-cilium-lb-ipam-control-plane 1/1 Running 0 11m
kube-system kube-scheduler-cilium-lb-ipam-control-plane 1/1 Running 0 11m
local-path-storage local-path-provisioner-5ddd94ff66-9bsl2 1/1 Running 0 11m
cilium
配置信息
root@kind:~# kubectl -n kube-system exec -it ds/cilium -- cilium status
KVStore: Ok Disabled
Kubernetes: Ok 1.23 (v1.23.4) [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 172.18.0.3 (Direct Routing)]
Host firewall: Disabled
CNI Chaining: none
CNI Config file: CNI configuration file management disabled
Cilium: Ok 1.13.0-rc5 (v1.13.0-rc5-dc22a46f)
NodeMonitor: Listening for events on 128 CPUs with 64x4096 of shared memory
Cilium health daemon: Ok
IPAM: IPv4: 5/254 allocated from 10.0.0.0/24,
IPv6 BIG TCP: Disabled
BandwidthManager: Disabled
Host Routing: BPF
Masquerading: BPF [eth0] 10.0.0.0/8 [IPv4: Enabled, IPv6: Disabled]
Controller Status: 31/31 healthy
Proxy Status: OK, ip 10.0.0.195, 0 redirects active on ports 10000-20000
Global Identity Range: min 256, max 65535
Hubble: Ok Current/Max Flows: 4095/4095 (100.00%), Flows/s: 9.47 Metrics: Disabled
Encryption: Disabled
Cluster health: 3/3 reachable (2024-07-12T09:25:07Z)
KubeProxyReplacement: Strict [eth0 172.18.0.3 (Direct Routing)]
- Cilium 完全接管所有 kube-proxy 功能,包括服务负载均衡、NodePort 和其他网络策略管理。这种配置适用于你希望最大限度利用 Cilium 的高级网络功能,并完全替代 kube-proxy 的场景。此模式提供更高效的流量转发和更强大的网络策略管理。
Host Routing: BPF
- 使用 BPF 进行主机路由。
Masquerading: BPF [eth0] 10.0.0.0/8 [IPv4: Enabled, IPv6: Disabled]
- 使用 BPF 进行 IP 伪装(NAT),接口 eth0,IP 范围 10.0.0.0/8 不回进行 NAT。IPv4 伪装启用,IPv6 伪装禁用。
默认情况下 LB IPAM 已随着 Cilium 集群一起安装,查看 API 资源类型
root@kind:~# kubectl api-resources | grep ciliumloadbalancerippools
ciliumloadbalancerippools ippools,ippool,lbippool,lbippools cilium.io/v2alpha1 false CiliumLoadBalancerIPPool
CiliumLoadBalancerIPPool
这个 CRD
规则即是编写 IPAM 的 CRD
规则
创建 LB ippool
# cat ippool.yaml
---
apiVersion: "cilium.io/v2alpha1"
kind: CiliumLoadBalancerIPPool
metadata:
name: "blue-pool"
spec:
cidrs:
- cidr: "20.0.10.0/24"
serviceSelector:
matchExpressions:
- {key: color, operator: In, values: [blue, cyan]}
---
apiVersion: "cilium.io/v2alpha1"
kind: CiliumLoadBalancerIPPool
metadata:
name: "red-pool"
spec:
cidrs:
- cidr: "30.0.10.0/24"
serviceSelector:
matchLabels:
color: red
IP
池有一个可选的.spec.serviceSelector
字段,允许管理员使用标签选择器限制哪些SVC
可以从那个地址池获取IP
root@kind:~# kubectl apply -f ippool.yaml
ciliumloadbalancerippool.cilium.io/blue-pool created
ciliumloadbalancerippool.cilium.io/red-pool created
- 查看创建
LB ippool
信息
root@kind:~# kubectl get ciliumloadbalancerippool
NAME DISABLED CONFLICTING IPS AVAILABLE AGE
blue-pool false False 254 38s
red-pool false False 254 38s
创建 pod
和 service
验证是否分配 LB IP
# cat cni.yaml
apiVersion: apps/v1
kind: DaemonSet
#kind: Deployment
metadata:
labels:
app: cni
name: cni
spec:
#replicas: 1
selector:
matchLabels:
app: cni
template:
metadata:
labels:
app: cni
spec:
containers:
- image: harbor.dayuan1997.com/devops/nettool:0.9
name: nettoolbox
securityContext:
privileged: true
---
apiVersion: v1
kind: Service
metadata:
name: cni
labels:
color: blue
spec:
type: LoadBalancer
selector:
app: cni
ports:
- name: cni
port: 80
targetPort: 80
root@kind:~# kubectl apply -f cni.yaml
daemonset.apps/cni created
service/cni created
- 查看安装服务信息
root@kind:~# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
cni-7t9p4 1/1 Running 0 2m35s 10.244.1.233 cilium-dual-stack-worker <none> <none>
cni-8qgcs 1/1 Running 0 2m35s 10.244.2.245 cilium-dual-stack-worker2 <none> <none>
- 查看
Service
信息
root@kind:~# kubectl get svc
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cni LoadBalancer 10.96.19.109 20.0.10.209 80:31988/TCP 14s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23m
blue-pool
地址池少了一个 IP
地址信息
root@kind:~# kubectl get ciliumloadbalancerippool
NAME DISABLED CONFLICTING IPS AVAILABLE AGE
blue-pool false False 253 24m
red-pool false False 254 24m
cni service
获取到了一个EXTERNAL-IP: 20.0.10.209
,此IP
即从地址池中获取的IP
地址- 但是仅限于给
service
分配一个地址,该地址目前还不可用,需要借助BGP
宣告出去。
之前自建
k8s集群
安装开源的项目时候service
的external-ip
会出现pending
状态。其实我们就可以通过MetalLb(L2/BGP)
或者cilium lb ipam
特性来解决
流量测试
- 查看
Service
信息
root@kind:~# kubectl get svc
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cni LoadBalancer 10.96.19.109 20.0.10.209 80:31988/TCP 14s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23m
kind
宿主机上请求cilium-dsr-control-plane
所在Node
节点32000
端口
root@kind:~# docker exec -it cilium-lb-ipam-control-plane bash
root@cilium-lb-ipam-control-plane:/# curl 172.18.0.2:31988
PodName: cni-2mdj8 | PodIP: eth0 10.0.2.95/32
root@cilium-lb-ipam-control-plane:/# curl 20.0.10.209
PodName: cni-jsnbq | PodIP: eth0 10.0.1.253/32
root@cilium-lb-ipam-control-plane:/# curl 10.96.19.109
PodName: cni-jsnbq | PodIP: eth0 10.0.1.253/32
- Node-IP:nodePort 方式访问正常
- EXTERNAL-IP:port 方式访问正常
- CLUSTER-IP:port 方式访问正常
但是目前 EXTERNAL-IP:port
访问方式仅限 node
节点之间,集群外部没有到达 20.0.10.209
的路由,或者说到的的 20.0.10.209
IP
地址,不是 k8s
集群内 service
的地址,而是公网上别人的 IP
地址
四、转载博客
https://github.com/HFfleming/k8s-network-learning/blob/main/cilium-cni/LB-IPAM/Cilium-LB-IPAM.md