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) 允许 CiliumIP 地址分配给 LoadBalancer 类型的服务;
    • 在公有云环境中,LB地址通常由云厂商提供。然而在私有云环境中,我们就需要借助其他工具实现了。
  • LB IPAM 通常与 Cilium BGP 等功能结合使用。其中 LB IPAM 负责将 IP 分配和指派给 service 对象, BGP 负责将这些 IP 通告出去
  • LB IPAM 只会分配 LB 地址,不负责路由,无论是集群内还是集群外都无法访问该地址。需要借助其他方案例如 metallb 或者通过cilium BGP 将地址宣告出去,这样外界网络里这个地址就是可路由了
  • Cilium BGPservice LBip 地址宣告出去(更加符合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 参数解释

  1. --set kubeProxyReplacement=strict

    • 含义: 启用 kube-proxy 替代功能,并以严格模式运行。
    • 用途: Cilium 将完全替代 kube-proxy 实现服务负载均衡,提供更高效的流量转发和网络策略管理。
  2. --set tunnel=disabled

    • 含义: 禁用隧道模式。
    • 用途: 禁用后,Cilium 将不使用 vxlan 技术,直接在主机之间路由数据包,即 direct-routing 模式。
  3. --set autoDirectNodeRoutes=true

    • 含义: 启用自动直接节点路由。
    • 用途: 使 Cilium 自动设置直接节点路由,优化网络流量。
  4. --set ipv4NativeRoutingCIDR="10.0.0.0/8"

    • 含义: 指定用于 IPv4 本地路由的 CIDR 范围,这里是 10.0.0.0/8
    • 用途: 配置 Cilium 使其知道哪些 IP 地址范围应该通过本地路由进行处理,不做 snat , Cilium 默认会对所用地址做 snat。
  5. --set bpf.masquerade

    • 含义: 启用 eBPF 功能。
    • 用途: 使用 eBPF 实现数据路由,提供更高效和灵活的网络地址转换功能。
  6. --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

创建 podservice 验证是否分配 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集群 安装开源的项目时候 serviceexternal-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

posted @ 2024-07-12 17:56  evescn  阅读(6)  评论(0编辑  收藏  举报