Cilium Socket LB 特性

news/2024/11/17 9:42:57/文章来源:https://www.cnblogs.com/evescn/p/18294781

Cilium Socket LB

一、环境信息

主机 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 SocketLB 模式认知

负载均衡的实现方式通常有如下两种:

  • 客户端负载均衡,自行选择目标端点。这样做的好处是,在建立连接时预先支付负载均衡的成本,并且在连接的生命周期内不存在额外的开销。这种方法的缺点是这对应用程序不透明。
  • 服务端负载均衡,通过一个中间服务将请求转换为对应服务 IP 来执行负载平衡。与客户端负载平衡相比,此方法的优点是透明。应用程序本身不涉及。然而,缺点是每个网络数据包都需要在请求和响应上更改其 IP 地址。

Cilium 1.6 中,引入了基于套接字的负载平衡(socket-based load-balancing),它结合了两种方法的优点:

img

  • Transparent: 负载平衡对应用程序保持 100% 透明。服务是使用标准 Kubernetes svc
  • Highly efficient: 通过转换地址在socket层面执行负载平衡,LB的成本是在建立连接时预先支付的,并且在之后的连接持续时间内不需要额外的ip地址转换。性能与应用程序直接与后端对话相同。

三、传统 kube-proxy 实现 service 负载均衡

img

可以查看此文档 Cilium Native Routing with kubeProxy 模式 中,Service 网络通讯,数据包转发流程一致

四、Cilium Socket LB 如何实现东西向流量的负载均衡

kind 配置文件信息

root@kind:~# cat install.sh#!/bin/bash
date
set -v# 1.prep noCNI env
cat <<EOF | kind create cluster --name=cilium-socket-lb --image=kindest/node:v1.23.4 --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:# kind 默认使用 rancher cni,cni 我们需要自己创建disableDefaultCNI: true# kind 安装 k8s 集群需要禁用 kube-proxy 安装,是 cilium 代替 kube-proxy 功能kubeProxyMode: "none"nodes:- role: control-plane- role: worker- role: workercontainerdConfigPatches:
- |-[plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor.evescn.com"]endpoint = ["https://harbor.evescn.com"]
EOF# 2.remove taints
controller_node_ip=`kubectl get node -o wide --no-headers | grep -E "control-plane|bpf1" | awk -F " " '{print $6}'`
#kubectl taint nodes $(kubectl get nodes -o name | grep control-plane) 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# Direct Routing Options(--set kubeProxyReplacement=strict --set tunnel=disabled --set autoDirectNodeRoutes=true --set ipv4NativeRoutingCIDR="10.0.0.0/8")
# Host Routing[EBPF](--set bpf.masquerade=true)helm install cilium cilium/cilium \--set k8sServiceHost=$controller_node_ip \--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-socket-lb \--set kubeProxyReplacement=strict \--set tunnel=disabled \--set autoDirectNodeRoutes=true \--set ipv4NativeRoutingCIDR="10.0.0.0/8" \--set bpf.masquerade=true \--set installNoConntrackIptablesRules=true \--set socketLB.enabled=true# 4.install necessary tools
for i in $(docker ps -a --format "table {{.Names}}" | grep cilium) 
doecho $idocker cp /usr/bin/ping $i:/usr/bin/pingdocker 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 规则集中的连接跟踪负担。
  7. --set socketLB.enabled=true:

    • 启用 Socket Load Balancer(SLB),用于优化服务之间的负载均衡。
  • 安装 k8s 集群和 cilium 服务
root@kind:~# ./install.shCreating cluster "cilium-socket-lb" ...✓ 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-socket-lb"
You can now use your cluster with:kubectl cluster-info --context kind-cilium-socket-lbNot sure what to do next? 😅  Check out https://kind.sigs.k8s.io/docs/user/quick-start/

cilium 配置信息

root@kind:~# kubectl -n kube-system exec -it ds/cilium -- cilium statusKVStore:                 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: 6/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:       35/35 healthy
Proxy Status:            OK, ip 10.0.0.231, 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: 6.85   Metrics: Disabled
Encryption:              Disabled
Cluster health:          3/3 reachable   (2024-06-27T09:06:44Z)root@kind:~# kubectl -n kube-system exec -it ds/cilium -- cilium status --verbose
......
KubeProxyReplacement Details:Status:                 Strict# 启用了 Socket LB 功能Socket LB:              EnabledSocket LB Tracing:      Enabled
......
  • 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 伪装禁用。
  • Socket LB: Enabled
    • 启用了 Socket LB 功能,Service 服务访问时,之间使用后端 pod ip port 进行数据返回。

k8s 集群安装 Pod 测试网络

# cat cni.yamlapiVersion: apps/v1
kind: DaemonSet
#kind: Deployment
metadata:labels:app: cniname: cni
spec:#replicas: 1selector:matchLabels:app: cnitemplate:metadata:labels:app: cnispec:containers:- image: harbor.dayuan1997.com/devops/nettool:0.9name: nettoolboxsecurityContext:privileged: true---
apiVersion: v1
kind: Service
metadata:name: serversvc
spec:type: NodePortselector:app: cniports:- name: cniport: 80targetPort: 80nodePort: 32000
root@kind:~# kubectl apply -f cni.yaml
daemonset.apps/cni created
service/serversvc createdroot@kind:~# kubectl run net --image=harbor.dayuan1997.com/devops/nettool:0.9
pod/net created
  • 查看安装服务信息
root@kind:~# kubectl get pods -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP           NODE                       NOMINATED NODE   READINESS GATES
cni-gzclc   1/1     Running   0          32s   10.0.2.6     cilium-socket-lb-worker2   <none>           <none>
cni-sd4vv   1/1     Running   0          32s   10.0.1.145   cilium-socket-lb-worker    <none>           <none>
net         1/1     Running   0          20s   10.0.2.40    cilium-socket-lb-worker2   <none>           <none>

Service 网络通讯

  • 查看 Service 信息
root@kind:~# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        31m
serversvc    NodePort    10.96.195.193   <none>        80:32000/TCP   43s
  • net 服务上请求 Pod 所在 Node 节点 32000 端口
root@kind:~# kubectl exec -ti net -- curl 172.18.0.2:32000
PodName: cni-sd4vv | PodIP: eth0 10.0.1.145/32

并在 net 服务 eth0 网卡 抓包查看

net~$ tcpdump -pne -i eth0
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
10:20:26.931025 1a:fc:47:2b:d4:54 > 7a:b0:1f:00:ee:0a, ethertype IPv4 (0x0800), length 74: 10.0.2.40.36664 > 10.0.1.145.80: Flags [S], seq 1753200349, win 64240, options [mss 1460,sackOK,TS val 1674156063 ecr 0,nop,wscale 7], length 0
10:20:26.931401 7a:b0:1f:00:ee:0a > 1a:fc:47:2b:d4:54, ethertype IPv4 (0x0800), length 74: 10.0.1.145.80 > 10.0.2.40.36664: Flags [S.], seq 2087706195, ack 1753200350, win 65160, options [mss 1460,sackOK,TS val 3868244688 ecr 1674156063,nop,wscale 7], length 0
10:20:26.931546 1a:fc:47:2b:d4:54 > 7a:b0:1f:00:ee:0a, ethertype IPv4 (0x0800), length 66: 10.0.2.40.36664 > 10.0.1.145.80: Flags [.], ack 1, win 502, options [nop,nop,TS val 1674156064 ecr 3868244688], length 0
10:20:26.931965 1a:fc:47:2b:d4:54 > 7a:b0:1f:00:ee:0a, ethertype IPv4 (0x0800), length 146: 10.0.2.40.36664 > 10.0.1.145.80: Flags [P.], seq 1:81, ack 1, win 502, options [nop,nop,TS val 1674156064 ecr 3868244688], length 80: HTTP: GET / HTTP/1.1
10:20:26.932279 7a:b0:1f:00:ee:0a > 1a:fc:47:2b:d4:54, ethertype IPv4 (0x0800), length 66: 10.0.1.145.80 > 10.0.2.40.36664: Flags [.], ack 81, win 509, options [nop,nop,TS val 3868244689 ecr 1674156064], length 0
10:20:26.932588 7a:b0:1f:00:ee:0a > 1a:fc:47:2b:d4:54, ethertype IPv4 (0x0800), length 302: 10.0.1.145.80 > 10.0.2.40.36664: Flags [P.], seq 1:237, ack 81, win 509, options [nop,nop,TS val 3868244689 ecr 1674156064], length 236: HTTP: HTTP/1.1 200 OK
10:20:26.932851 7a:b0:1f:00:ee:0a > 1a:fc:47:2b:d4:54, ethertype IPv4 (0x0800), length 113: 10.0.1.145.80 > 10.0.2.40.36664: Flags [P.], seq 237:284, ack 81, win 509, options [nop,nop,TS val 3868244690 ecr 1674156064], length 47: HTTP
10:20:26.933138 1a:fc:47:2b:d4:54 > 7a:b0:1f:00:ee:0a, ethertype IPv4 (0x0800), length 66: 10.0.2.40.36664 > 10.0.1.145.80: Flags [.], ack 237, win 501, options [nop,nop,TS val 1674156065 ecr 3868244689], length 0
10:20:26.933425 1a:fc:47:2b:d4:54 > 7a:b0:1f:00:ee:0a, ethertype IPv4 (0x0800), length 66: 10.0.2.40.36664 > 10.0.1.145.80: Flags [.], ack 284, win 501, options [nop,nop,TS val 1674156065 ecr 3868244690], length 0
10:20:26.936328 1a:fc:47:2b:d4:54 > 7a:b0:1f:00:ee:0a, ethertype IPv4 (0x0800), length 66: 10.0.2.40.36664 > 10.0.1.145.80: Flags [F.], seq 81, ack 284, win 501, options [nop,nop,TS val 1674156068 ecr 3868244690], length 0
10:20:26.936954 7a:b0:1f:00:ee:0a > 1a:fc:47:2b:d4:54, ethertype IPv4 (0x0800), length 66: 10.0.1.145.80 > 10.0.2.40.36664: Flags [F.], seq 284, ack 82, win 509, options [nop,nop,TS val 3868244694 ecr 1674156068], length 0
10:20:26.937084 1a:fc:47:2b:d4:54 > 7a:b0:1f:00:ee:0a, ethertype IPv4 (0x0800), length 66: 10.0.2.40.36664 > 10.0.1.145.80: Flags [.], ack 285, win 501, options [nop,nop,TS val 1674156069 ecr 3868244694], length 0

抓包数据显示, net 服务使用随机端口和 10.0.2.202 80 端口进行 tcp 通讯。

  • 三次握手的过程, srcIPpodIP 地址, dstIP 不再是 node 节点 IP 地址,在 cilium socket LB 的加持下,将serviceIP 转换成了后端 podIP 地址。
  • 通过 ebpf 的劫持,没有必要将 nat 的过程传递到 root namespace 中去了,不再需要 root namespace 中的 iptables 规则了,节省了网络开销。
  • 在数据包从源 pod 中出去的时候,已经做了替换,进入 root namespace 的时候,就变成了一个简单的跨节点 pod 间的通信,相比基于 iptable 来说效率更高
  • 不再依赖 iptables 规则

那么 cilium 是如何查询 service 信息,并返回后端 Pod ip 地址给请求方的?其实 cilium 把数据保存在自身内部,使用 cilium 子命令可以查询到 service 信息

  • cilium 查询 service 信息
root@kind:~# kubectl -n kube-system exec cilium-mphpk -- cilium service list
ID   Frontend           Service Type   Backend                         
1    10.96.36.130:443   ClusterIP      1 => 172.18.0.2:4244 (active)   
2    10.96.0.1:443      ClusterIP      1 => 172.18.0.3:6443 (active)   
3    10.96.0.10:53      ClusterIP      1 => 10.0.0.112:53 (active)     2 => 10.0.0.63:53 (active)      
4    10.96.0.10:9153    ClusterIP      1 => 10.0.0.63:9153 (active)    2 => 10.0.0.112:9153 (active)   
8    10.96.195.193:80   ClusterIP      1 => 10.0.2.6:80 (active)       2 => 10.0.1.145:80 (active)     
9    172.18.0.2:32000   NodePort       1 => 10.0.2.6:80 (active)       2 => 10.0.1.145:80 (active)     
10   0.0.0.0:32000      NodePort       1 => 10.0.2.6:80 (active)       2 => 10.0.1.145:80 (active) 

查看上面的 service 信息得到, 172.18.0.2:32000 后端有 2ip 地址信息,并且后端端口为 80cilium 劫持到 Pod 需要访问 service 信息,即会查询该 service 对应的后端 Pod 地址和端口返回给客户端,让客户端使用此地址发起 http 请求

五、参考博客

https://bbs.huaweicloud.com/blogs/417788

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/741844.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高考后第一次Codeforces Round 952 (Div. 4)

A Creating Words 思路:拿一个容器交换两数值即可 #include<bits/stdc++.h> using namespace std; const int N = 100001; char a[N],b[N]; int main() {int n;scanf("%d",&n);while(n--){scanf("%s %s",a,b);char jiaohuan = a[0];a[0] = b[0]…

前端如何取消接口调用

🧑‍💻 写在开头 点赞 + 收藏 === 学会🤣🤣🤣 1. xmlHttpRequest是如何取消请求的?实例化的XMLHttpRequest对象上也有abort方法const xhr = new XMLHttpRequest(); xhr.addEventListener(load, function(e) {console.log(this.responseText); }); xhr.open(GET, htt…

篮球比赛电子计分牌

在学习单片机课设“篮球比赛电子计分牌”的时候遇到了很多问题。在网上搜索到的资源很杂很乱,很多内容都需要付费,在学习的过程遇到了不少的阻力,因此我打算把我所做的拿出来与大家共同讨论,不足的地方还请多多指教哈。学艺不精,成绩仅为良好,大家参考就行。另外能激发后…

学习SpringCloud环境搭配

今天准备学习一下springcloud,在网上找了一个最新的学习视频需要更新一下之前安装的软件版本。突然想起来我还有个博客园的账号,就想记录一下环境搭建。 主要是分为以下几个部分Java 17+ Maven 3.9+ Mysql 8.0+ cloud 2023.0.0 boot 3.2.0 cloud alibaba 2022.0.0.0 之前…

进度报告4

(1)代码案例练习 1.public class helloworld { public static void main(String[] args) { double Price;int month;String x; Price=price(1000,6,"头等舱") ; System.out.println("优惠价为:"+Price); } public static double price(double a,int b,St…

day2

SSRF漏洞 1.SSRF漏洞介绍 SSRF(Server-Side Request Forgery)服务端请求为伪造,SSRF是⼀种由攻击者构造形成由服务端发起请求的⼀个安全漏洞。 ⼀般情况下,SSRF攻击的⽬标是从外⽹⽆法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连⽽与外⽹隔离…

[二、状态管理]2管理组件拥有的状态(4)@Provide装饰器和@Consume装饰器:与后代组件双向同步

@Provide和@Consume,应用于与后代组件的双向数据同步,应用于状态数据在多个层级之间传递的场景。不同于上文提到的父子组件之间通过命名参数机制传递,@Provide和@Consume摆脱参数传递机制的束缚,实现跨层级传递。 其中@Provide装饰的变量是在祖先节点中,可以理解为被“提供…

dedecms搭建网站怎么更换编辑器

入口: 系统 > 系统设置 > 系统基本参数 > 核心设置 > 编辑器默认可选参数: wangEditor 、 ckeditor 、 fck本文来自博客园,作者:黄文Rex,转载请注明原文链接:https://www.cnblogs.com/hwrex/p/18294690

DedeCMS网站安装成功后点击登录网站后台报404错误怎么办?

DedeCMS 默认的管理后台路径为 /dede 。遇到这个问题,需先检查 /dede 目录是否被重命名了。如果被重命名了,改回 /dede 即可。或直接在浏览器地址栏手动输入相应的管理后台路径,就可以打开后台登录页面了。本文来自博客园,作者:黄文Rex,转载请注明原文链接:https://www.…

关于DedeCMS版本号的说明

DedeCMS V5.7.73及后续的版本将采用 Semantic Versioning Specification (SemVer)(语义化版本 2.0.0) 进行维护。 语义化版本 2.0.0版本格式:主版本号.次版本号.修订号,版本号递增规则如下: 1、主版本号:当你做了不兼容的 API 修改, 2、次版本号:当你做了向下兼容的功能性…

zblog报错“Invalid argument supplied for foreach”或者“unserialize(): Error at offset”的解决办法

大部分的报错提示是:”Invalid argument supplied for foreach“也有提示”unserialize(): Error at offset“的,本文来分享下这个bug的原因和解决办法。 BUG原因: zblog1.7版本改造了system的config表,这个表里面存放的是程序的核心内容,例如域名、语言版本、网站名称等等…

PC触摸屏之设备维护【PackGo】

TIA Portal V16平台Pack&Go功能如何使用? TIA Portal V16平台Pack&Go功能如何使用 (siemens.com.cn)简介 当我们无法建立从组态PC到HMI设备的直接连接,例如,现场PC未安装TIA Portal软件,还需要将项目下载到HMI设备,除了使用U盘方式下载程序外,还可以创建P…