Cilium DSR 特性(转载)

news/2024/11/16 3:33:31/文章来源:https://www.cnblogs.com/evescn/p/18297815

Cilium DSR(转载)

一、环境信息

主机 IP
ubuntu 10.0.0.234
软件 版本
docker 26.1.4
helm v3.15.0-rc.2
kind 0.18.0
kubernetes 1.23.4
ubuntu os Ubuntu 22.04.6 LTS
kernel 5.15.0-106 内核升级文档

使用 5.11.5 内核版本的 20.04 版本,发起 curl 请求无法代理到 pod 上去 curl: (7) Failed to connect to 172.18.0.2 port 32000: Connection refused,换成了 22.04 默认的 5.15 内核版本,可能是 dsr 对内核有要求

二、Cilium DSR 模式架构对比

传统模式下:

  • 外部流量通过 NodePort、ExternalIPs 或 LoadBalancer 访问 Kubernetes 服务,当backend pod运行在与请求发送到的节点不同的节点上时,Kubernetes 工作节点可能会将请求重定向到远程节点。

  • 请求将经过 SNAT处理,这也会导致后端不会看到客户端的源 IP 地址。此外,后端的回程报文将通过初始节点(在该节点执行反向 SNAT 转换)再发送回客户端,这会引入额外的网络开销和延迟。

img


Cilium Direct server return(DSR)模式:

  • 虽然Kubernetes 提供了 externalTrafficPolicy=Local,如果接收请求的节点不运行任何后端pod,它会通过删除对服务的请求来保留客户端源 IP 地址(访问失败)。然而,这也会使负载均衡的实现变得更加复杂,并可能导致负载均衡失效。
  • 为了解决上述问题从cilium 1.7开始,借助ebpf实现了direct server return,从而加速了南北向流量的通信效率(在向客户端回包时避免额外的一跳),同时也增加了保持客户端源IP特性。

img

三、Cilium DSR 模式的约束

  • Cilium DSR 不支持在VXLAN模式下运行,只能在native routing模式下运行。UDP报文没有SYN包。对于 TCP 服务,Cilium 仅对 SYN 数据包的服务 IP/端口进行编码

  • 由于underlay 网路结构可能会删除 cilium特定的ip包的扩展头信息,因此在某些公共云提供商环境中使用 DSR 模式可能不起作用。

  • 在某些实施源/目标 IP 地址检查(例如 AWS)的公共云提供商环境中,必须禁用该检查才能使 DSR 模式正常工作

四、Cilium DSR 模式环境搭建

kind 配置文件信息

root@kind:~# cat install.sh#!/bin/bash
date
set -v# 1.prep noCNI env
cat <<EOF | kind create cluster --name=cilium-dsr --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>&1helm 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-dsr \--set kubeProxyReplacement=strict \--set tunnel=disabled \--set autoDirectNodeRoutes=true \--set ipv4NativeRoutingCIDR="10.0.0.0/8" \--set bpf.masquerade=true \--set installNoConntrackIptablesRules=true \--set loadBalancer.mode=dsr# 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 loadBalancer.mode=dsr:

    • 设置负载均衡器(Load Balancer)的模式为 DSR(Direct Server Return),这是一种负载均衡技术,允许负载均衡器将数据包直接发送回源服务器,而不是经过负载均衡器本身。
  • 安装 k8s 集群和 cilium 服务
root@kind:~# ./install.shCreating cluster "cilium-dsr" ...✓ 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-dsr"
You can now use your cluster with:kubectl cluster-info --context kind-cilium-dsrNot 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.78, 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: 7.19   Metrics: Disabled
Encryption:              Disabled
Cluster health:          3/3 reachable   (2024-07-11T09:53:13Z)root@kind:~# kubectl -n kube-system exec -it ds/cilium -- cilium status --verbose
......
KubeProxyReplacement Details:Status:                 StrictSocket LB:              EnabledSocket LB Tracing:      EnabledDevices:                eth0 172.18.0.3 (Direct Routing)# 启用了 DSR 功能Mode:                   DSRBackend Selection:      Random
......
  • 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 get pods -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP           NODE                 NOMINATED NODE   READINESS GATES
cni-8zxj9   1/1     Running   0          16m   10.0.2.123   cilium-dsr-worker    <none>           <none>
cni-m7tjc   1/1     Running   0          16m   10.0.0.216   cilium-dsr-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        21m
serversvc    NodePort    10.96.172.235   <none>        80:32000/TCP   17m
  • kind 宿主机上请求 cilium-dsr-control-plane 所在 Node 节点 32000 端口
root@KinD:~# kubectl get node -o wide
NAME                       STATUS   ROLES                  AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE       KERNEL-VERSION       CONTAINER-RUNTIME
cilium-dsr-control-plane   Ready    control-plane,master   22m   v1.23.4   172.18.0.2    <none>        Ubuntu 21.10   5.15.0-106-generic   containerd://1.5.10
cilium-dsr-worker          Ready    <none>                 21m   v1.23.4   172.18.0.4    <none>        Ubuntu 21.10   5.15.0-106-generic   containerd://1.5.10
cilium-dsr-worker2         Ready    <none>                 21m   v1.23.4   172.18.0.3    <none>        Ubuntu 21.10   5.15.0-106-generic   containerd://1.5.10

cilium-dsr-control-plane 所在 Node 节点 IP: 172.18.0.2

root@kind:~# curl 172.18.0.2:32000
PodName: cni-8zxj9 | PodIP: eth0 10.0.2.123/32

并在客户端 kind 节点 172.18.0.1 网卡 抓包查看

root@KinD:~# tcpdump -pne -i br-67ecd2c684e4 -w /tmp/client.cap
root@KinD:~# sz /tmp/client.cap

img

从抓包数据显示,3次握手和4次护手均正常,有 172.18.0.1172.18.0.2 建立连接

cilium-dsr-control-plane 节点 eth0 网卡 抓包查看

root@cilium-dsr-control-plane:~# tcpdump -pne -i eth0 -w dsr-1.cap
root@cilium-dsr-control-plane:~# sz dsr-1.cap

img

  • 抓包数据显示:
    • 第一个 SYN 信息: 172.18.0.1:58726 ==> 172.18.0.2:32000 即客户端和访问节点之间的第一跳,符合正常逻辑
    • 第二个 SYN 信息: 172.18.0.1 ==> 10.0.2.123:80 10.0.2.123 是目标 pod ipSYN 需要继续转发,直到目标 POD
    • 第一个 ACK 信息: 172.18.0.1 ==> 172.18.0.2:32000SYN
    • 第二个 ACK 信息: 172.18.0.1 ==> 10.0.2.123:80 同第二个 SYN

我们知道TCP 三次握手🤝,流程是:

  • SYN ==> SYN+ACK ==> ACK
    但是在该节点上抓包并没有发现完整的TCP三次握手信息。

网络的本质应该是从哪去,从哪回来。但是 cilium 通过一些特殊的方式进行了 SYN+ACK 的回程包,并达到了客户端源IP保持和更高的网络通信效率。

cilium-dsr-control-worker 节点 eth0 网卡 抓包查看

root@cilium-dsr-worker:~# tcpdump -pne -i eth0 -w dsr-2.cap
root@cilium-dsr-worker:~# sz dsr-2.cap

img

  • 抓包数据显示:
    • 第一个 SYN 信息: 172.18.0.1 ==> 10.0.2.123:80 ,即 dsr-1.cap 文件中第二 SYN 信息 SYN 信息
    • 第一个 SYN + ACK 信息: 172.18.0.2 ==> 172.18.0.1:58726 ,是 cilium-dsr-control-worker 节点返回的客户端的 SYN + ACK 信息。
      • 172.18.0.2cilium-dsr-control-worker 节点 eth0 网卡 IP ?根本不是,cilium-dsr-control-worker 节点 eth0 网卡 IP: 172.18.0.4,这个 IP 是属于 第一跳经过的节点ip地址(cilium-dsr-control-plane)
      • 172.18.0.2:32000client 节点访问的服务端信息,即 cilium-dsr-control-plane 节点 eth0 网卡抓包的第一个 SYN 信息
      • 目标 POD 节点是如何知道客户端访问的 第一跳经过的节点 ip 地址和端口
      • DSR 模式就是需要 POD 直接响应客户端请求,所以需要使用 第一跳经过的节点i ip 地址和端口 封装数据包信息返回给客户端,因为对于客户端来说,如果收到的 ip 信息不是自己发出去的数据包中的ip,该数据包就会被丢掉。
    • 第一个 ACK 信息: 172.18.0.1 ==> 10.0.2.123:80 ,即 dsr-1.cap 文件中第二 ACK 信息 ACK 需要继续转发,直到目标 POD

那在 cilium-dsr-worker 节点中,封装 SYN + ACK 数据包是如何得到 client ip + port 的?

数据信息就来自于 cilium-dsr-control-worker (第一跳经过的节点) 节点 往后转发的数据包信息中

img

在这个包的IP头里面有个 Option 字段,这个报文中有额外封装的 8字节 ,这是 ciliumSYN 报文进行额外封装的一部分,借此达到DSR 特性, POD 直接返回源地址的效果。

  • 从右往左依次是: ac 12 00 02 7d00
  • 对应 10进制: 172 18 0 2 32000

可以看到服务端进行回包的 第一跳经过的节点 ip 地址和端口 就藏在这个封装的包里

这个信息也在 cilium-dsr-worker 收到的转发的 第一个 SYN 信息 包中,这个信息最终会送往 POD 节点, POD 获知 第一跳经过的节点 ip 地址和端口信息

img

目的POD 节点 eth0 网卡抓包

root@KinD:~# kubectl exec -it cni-8zxj9 bash 
cni-8zxj9~$ tcpdump -pne -i eth0 -w cni.cap
cni-8zxj9~$ sz cni.cap

img

五、转载博客

https://blog.51cto.com/liujingyu/5285535

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

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

相关文章

上传恶意代码服务器和数据库的操作

在通过访问端对服务器上传一句话木马的时候,我们需要对服务器进行部分操作: 1.打开服务器远程目录权限: (1)在windows服务器上,将文件夹的只读方式去掉; (2)在linux服务器上,将文件夹的权限改为pwd 2.开启数据库secure_file_priv权限 (1)我这里使用的是mysql5.7.2…

Zabbix 5.0 LTS URL 健康监测

更多细节详情看【zabbix官方文档】 需求 Zabbix 的URL健康监测功能允许你检测 Web 地址是否可用、正常工作以及响应速度。这对于监控网站的可用性和性能非常有用。例如,你可以监控公司网站、API 端点或其他关键服务的 URL。【官方表述 Web monitoring items】【官方表述 Trigg…

idea 修改 git 提交用户名

本项目 修改配置文件 修改当前项目目录下的 config 文件添加以下数据[user]name = **email = **@gmail.com全局修改 git config --global user.name gitlab注册用户名 git config --global user.email gitlab注册邮箱

ChatMoney,你的就业指导明灯

本文由 ChatMoney团队出品介绍说明 Hey!亲爱的小伙伴们,今天我要给大家带来一个职场利器——AI就业指导机器人!🤖 在这个充满变数的职场江湖,找到一份既能养家糊口又能实现自我价值的工作是多么重要。但是,职业道路上的选择和决策并不总是那么容易。有时候,我们需要的不…

AI就业指导机器人,你的专属职业导航灯!

本文由 ChatMoney团队出品介绍说明 Hey!亲爱的小伙伴们,今天我要给大家带来一个职场利器——AI就业指导机器人!🤖 在这个充满变数的职场江湖,找到一份既能养家糊口又能实现自我价值的工作是多么重要。但是,职业道路上的选择和决策并不总是那么容易。有时候,我们需要的不…

IDEA工具使用Git回滚代码

回滚已经commit但未push到远程仓库的代码点击git,然后右键选择你要退回的那条记录,选择undo commit(撤销提交) ,代码回滚就完成了! 此操作只是回滚,并不会删除你的操作内容回滚已经push到远程仓库的代码1. 先回滚提交到本地仓库的代码选择需要回滚到那个版本的提交记录,右键…

转-Java 异常处理的 20 个最佳实践,你知道几个?

‍ 作  者:武培轩 出  处:https://www.cnblogs.com/wupeixuan 原文链接:https://www.cnblogs.com/wupeixuan/p/11746117.html 异常处理是 Java 开发中的一个重要部分,是为了处理任何错误状况,比如资源不可访问,非法输入,空输入等等。Java 提供了几个异常处理特性,以…

vue 混合方法mixins 协可以写入公共的方法

新建一个文件夹mixins 同views 同级export default {data() {return {};},mounted() {},methods: {// 修改标题方法ready(callback) {// 如果 jsbridge 已经注入则直接调用if (window.AlipayJSBridge) {callback && callback();} else {// 如果没有注入则监听注入的事…

小白记录Java后端学习遇到的问题

在访问swagger接口测试工具时,进不去在用 localhost 访问的地址的时候出现访问不到的问题,但是把 localhost 换成本地的地址 却可以访问到, 我心想localhost不就是我本地的地址嘛,解决: 发现如果设置了地址 就不能通过localhost访问到 如果不设置默认的话, 就可以访问 ht…

小红书卡片生成,使用W外链制作小红书卡片

在数字营销和社交媒体盛行的今天,小红书以其独特的社区氛围和购物推荐功能,成为了众多品牌和个人推广产品、分享经验的热门平台。而W外链作为一种高效的链接工具,能够帮助用户快速创建小红书卡片,实现内容的高效传播。本文将详细介绍如何使用W外链制作小红书卡片,并分享一…

解读代码检查规则语言CodeNavi的表达式节点和属性

本文将介绍 CodeNavi 检查规则语言如何描述代码中的表达式。本文分享自华为云社区《CodeNavi 中代码表达式的节点和节点属性》,作者: Uncle_Tom。 根据代码检查中的一些痛点,提出了希望寻找一种适合编写静态分析规则的语言。可以满足用户对代码检查不断增加的各种需求; 使用…

Centos 7 Network is unreachable 出错不能联网解决方法

进入配置目录,看下文件列表 1、cd /etc/sysconfig/network-scripts/ 2 ls 看下有没有以 ifcfg-en***开头的文件,各个电脑不同文件名不同, 3 如果有,用vi 打开该文件进行编辑,将最后一行的 onboot=no 改为 noboot=yes 保存退出,重启系统活到老,学到老。