百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

技术干货丨cilium 原理之pod ep,bpf 创建流程

suiw9 2024-10-25 17:08 23 浏览 0 评论

在此前的多篇文章中,我们详细的讲解了cilium 的多个原理,本篇文章我们将通过多个细致流程详解pod ep以及bpf的创建流程。

在pod创建后,到pod的网络就绪,这中间涉及到多个组件的流程:

  1. ip地址分配
  2. lxc网卡创建
  3. cilium endpoint的创建
  4. ebpf程序注入

整体时序图??????


相关说明

  1. cri 以 docker-shim为例,整个网络的初始化,是由cri调用cni的接口触发的
  2. cni 以 cilium 为例,主要分三步:
    1. 调用ipam申请ip
    2. 基于ip初始化lxc网卡
    3. 调用createEndpoint接口

其它的步骤大致调用流程已经在上图中标识,下面将详细说明endpoint的创建过程

1、cilium endpoint初始化流程



关于cilium endpoint有两个特殊的id:endpointIDidentityID。其中,endpointID为单主机唯一,identityID为全局唯一。

1.1、endpointID的生成

通过mgr.expose(ep)调用,本地加互斥锁,生成endpointID

// ids is a slice of IDs available in this idCache.
  ids map[ID]struct{}
  // 初始化时,将65535个id保存在ids中。每次取第一个。
  for id := range c.ids {
    delete(c.ids, id)
    return id
  }
  // 释放时,将id保存回来
  c.ids[id] = struct{}{}
  // id是可以反复复用的

1.2、identityID的生成

上图中,有个 d.identityAllocator 对象,用于管理identityID的生成

由于identity需要全局唯一,所以基于分布式锁,cilium实现了一个backend接口。而这里主要讲基于k8s的crd实现的逻辑。

因为k8s的crd的name+namespace是全局唯一的,所以只需要基于id创建ciliumIdentity资源,能创建成功,就表示获取了全局唯一资源。

[root@c7-1 ~]# k get ciliumidentity
NAME    NAMESPACE     AGE
17392   default       131d
2151    default       167d
22412   kube-system   257d
25213   kube-system   257d
35453   default       131d
3734    default       256d
43561   default       256d
60364   kube-system   257d

从程序逻辑上,ciliumIdentity 是基于labels要求全局唯一的。为实现这个功能,cilium会先确保所有ciliumIdentity资源都同步到本地,然后基于本地id池中分配一个可用的,完成id到labels的关联。

最后梳理下核心:ebpf程序的加载

1.3、ebpf程序加载流程

ebpf程序加载会发生在几种情况下:

  1. 第一次创建时进行初始化
  2. cilium重启时,会进行一次regenerate(按需初始化)
  3. 用户执行cilium endpoint regenerate 时(按需)
  4. 用户执行ciluim config时(按需)

staus状态机:

由于状态机是基于代码流程梳理出来,实际代码中,并没有严格的状态控制。所以状态切换场景可能是不完整的。

重新编译ebpf级别:DatapathRegenerationLevel

  1. 0 -> “invalid” (未设置)
  2. 1:RegenerateWithoutDatapath -> “no-rebuild”
  3. 2:RegenerateWithDatapathLoad -> “reload”
  4. 3:RegenerateWithDatapathRewrite -> “rewrite+reload” (ep第一次创建时,为该级别)
  5. 4:RegenerateWithDatapathRebuild -> “compile+reload”

1.3.1、第一次初始化
第一次初始化时,编译级别设置为3

二、重启时reload
编译级别设置为3

三、cilium endpoint regenrate
编译级别设置为4

// pkg/endpoint/endpoint.go
// func (e *Endpoint) identityLabelsChanged
regenMetadata := ?eneration.ExternalRegenerationMetadata{
    Reason:            "updated security labels",
    RegenerationLevel: regeneration.RegenerateWithDatapathRewrite,
  }

四、cilium config
比如调用 cilium config debug=true,会触发所有ebpf程序的重新生成与加载,组编译级别为3
五、regenerate ebpf

总体流程图

从上图可看出,基于编译级别,会分别调用三个函数来处理。下面将单独分析这三个函数

  • CompileAndLoad 完全编译并且加载ebpf程序(编译级别=4时触发)

tc 编译命令详细说明:

  1. 编译了 bpf_lxc.dbg.o,bpf_lxc.asm,bpf_lxc.c,bpf_lxc.o ,除了bpf_lxc.o用于运行外,其它是用于debug的
  2. 命令都基本类似,先由clang编译生成.c文件,再由llc编译生成.o文件
  3. 编译的bpf_lxc.c是所有程序大集合,可以方便我们阅读代码,
  4. 不过,正式运行时,除了 bpf_lxc.o 会保留外,其它文件都会清理
# build dbg.o
clang -emit-llvm -g -O2 -target bpf -std=gnu89 -nostdinc -D__NR_CPUS__=8 -Wall -Wextra -Werror -Wshadow -Wno-address-of-packed-member -Wno-unknown-warning-option -Wno-gnu-variable-sized-type-not-at-end -Wdeclaration-after-statement -Wimplicit-int-conversion -Wenum-conversion -D__MAGIC_FILE__=8 -I/var/run/cilium/state/globals -I3703_next -I/var/lib/cilium/bpf -I/var/lib/cilium/bpf/include -c /var/lib/cilium/bpf/bpf_lxc.c -o - | llc -mattr=dwarfris -march=bpf -mcpu=v2 -filetype=obj -o 3703_next/bpf_lxc.dbg.o


# build .asm
clang -emit-llvm -g -O2 -target bpf -std=gnu89 -nostdinc -D__NR_CPUS__=8 -Wall -Wextra -Werror -Wshadow -Wno-address-of-packed-member -Wno-unknown-warning-option -Wno-gnu-variable-sized-type-not-at-end -Wdeclaration-after-statement -Wimplicit-int-conversion -Wenum-conversion -D__MAGIC_FILE__=8 -I/var/run/cilium/state/globals -I3703_next -I/var/lib/cilium/bpf -I/var/lib/cilium/bpf/include -c /var/lib/cilium/bpf/bpf_lxc.c -o - |llc -march=bpf -mcpu=v2 -filetype=asm -o 3703_next/bpf_lxc.asm


# build .c
clang -E -O2 -target bpf -std=gnu89 -nostdinc -D__NR_CPUS__=8 -Wall -Wextra -Werror -Wshadow -Wno-address-of-packed-member -Wno-unknown-warning-option -Wno-gnu-variable-sized-type-not-at-end -Wdeclaration-after-statement -Wimplicit-int-conversion -Wenum-conversion -D__MAGIC_FILE__=8 -I/var/run/cilium/state/globals -I3703_next -I/var/lib/cilium/bpf -I/var/lib/cilium/bpf/include -c /var/lib/cilium/bpf/bpf_lxc.c -o 3703_next


# build lxc.o
clang -emit-llvm -g -O2 -target bpf -std=gnu89 -nostdinc -D__NR_CPUS__=8 -Wall -Wextra -Werror -Wshadow -Wno-address-of-packed-member -Wno-unknown-warning-option -Wno-gnu-variable-sized-type-not-at-end -Wdeclaration-after-statement -Wimplicit-int-conversion -Wenum-conversion -D__MAGIC_FILE__=8 -I/var/run/cilium/state/globals -I3703_next -I/var/lib/cilium/bpf -I/var/lib/cilium/bpf/include -c /var/lib/cilium/bpf/bpf_lxc.c -o - | llc -mattr=dwarfris -march=bpf -mcpu=v2 -filetype=obj -o 3703_next/bpf_lxc.o


# bind to lxc
tc filter replace dev lxc56c1f1723430 ingress prio 1 handle 1 bpf da obj 3703_next/bpf_lxc.o sec from-container

cilium bpf migrate-maps是个隐藏命令,cilium bpf -h是看不到的,cilium bpf migrate-maps -h可以。命令也是可执行的。

  • CompileOrLoad 编译加载或者只是单纯加载ebpf程序(编译级别=3时触发)

1.3.6、ebpf程序重新加载说明

基于官方的回复:

Changing settings via cilium config should not cause any in-progress connections to be dropped. In fact, Cilium is designed such that restarting the agent should not affect pod networking - including existing and new connections during agent restart.

因为ebpf程序加载到内核,是原子性操作,而且加载失败时,不影响旧的程序的运行。所以cilium的重启与重加载ebpf是安全的。但有一点,cilium早期版本,比如1.9时,由于安装部署设计的不好,导致cilium pod重启时,bpf目录会卸载并重新挂载,导致了epbf程序会出现失效,新版本从1.10开始,已经完善了该问题。

2、扩展

  1. ipam是 ip allocate manager ,可基于该模块实现固定ip相关功能。cilium的ip分配信息都保存在 ciliumnode 中,并在启动时加载到本地缓存中,按需同步更新到 ciliumnode 上,减少 apiserver 的压力
  2. 关于 cilium 的运行观察,可以在 /var/run/cilium/state 目录下执行 inotifywait -r -m . -e open -e move -e create -e delete 查看相关文件的生成情况
  3. cilium 在完成ep的初始化后,后续将详细介绍网络数据包的流转目录

本期作者丨沃趣科技产品研发部

版权作品,未经许可禁止转载

相关推荐

Qt编程进阶(99):使用OpenGL绘制三维图形

一、Qt中的OpenGL支持...

OpenGL基础图形编程(七)建模(opengl教程48讲)

七、OpenGL建模  OpenGL基本库提供了大量绘制各种类型图元的方法,辅助库也提供了不少描述复杂三维图形的函数。这一章主要介绍基本图元,如点、线、多边形,有了这些图元,就可以建立比较复杂的模型了...

ffmpeg cv:Mat编码成H265数据流(ffmpeg编码mp4视频)

流程下面附一张使用FFmpeg编码视频的流程图。使用该流程,不仅可以编码H.264的视频,而且可以编码MPEG4/MPEG2/VP8等等各种...

986g超轻酷睿本,联想ThinkPad X1 Carbon 2025 Aura评测

今年3月份,联想首发了搭载Intel酷睿Ultra移动平台的ThinkPadX1CarbonGen12轻薄本,其续航表现令人惊喜。时隔9个月,IT之家收到了ThinkPad...

拆解五六年前的国产平板,这做工!

之前在论坛有幸运得被抽到奖,就是猎奇手机镜头,到手的时候玩了下鱼眼和广角微距,效果见图,用手机拍的那么就进入正题来说下拆鸡过程,外壳我就不拍出来了,免得打广告之嫌,拆出背面外壳就出现了一个裸板。第...

什么是闭合GOP和开放GOP?(闭合式和开放式区分)

翻译|Alex技术审校|李忠本文来自OTTVerse,作者为KrishnaRaoVijayanagar。...

拆解五六年前的国产平板(国产平板怎么拆开)

之前在论坛有幸运得被抽到奖,就是猎奇手机镜头,到手的时候玩了下鱼眼和广角微距,效果见图,用手机拍的那么就进入正题来说下拆鸡过程,外壳我就不拍出来了,免得打广告之嫌,拆出背面外壳就出现了一个裸板。第...

如何使用PSV播放MP4 视频自动退出怎么办

作者:iamwin来源:巴士论坛(点此进入)看到有很多同学在为psv无法播放视频而困扰,自己研究了下,发一个可以解决PSV出现播放视频播放到一半就跳出的问题。就是这个问题:首先,请大家先升级到版本≥1...

2023-03-21:音视频解混合(demuxer)为MP3和H264...

2023-03-21:音视频解混合(demuxer)为MP3和H264,用go语言编写。答案2023-03-21:...

FFmpeg解码H264及swscale缩放详解

本文概要:...

CasaOS保姆级喂饭教程!网心云OEC-Turbo安装CasaOS系统固件!

本内容来源于@什么值得买APP,观点仅代表作者本人|作者:柒叶君...

Firefox 33将整合思科开源编解码器OpenH264

思科去年在BSD许可证下开源了支持H.264编解码的OpenH264,Mozilla则在当时宣布将在Firefox中整合思科的二进制模块。现在,最新的FirefoxNightly(Firefox3...

为什么传输视频流的时候需要将YUV编码成H.264?

首先开始的时候我们借用一张雷神的图帮助大家理解一下从上图可以看出我们要做的,就是将像素层的YUV格式,编码出编码层的h264数据。...

FFmpeg学习(1)开篇(ffmpeg开发教程)

FFmpeg学习(1)开篇...

喜欢看视频必须了解 AV1编码那点事

喜欢看视频的小伙伴大概都有点感觉,AV1这个不太熟悉的视频格式,最近闹出的事情可不少,比如视频网站为了节约带宽偷偷默认使用AV1格式,让电脑狂转;比如Intel专门给旧CPU发布了相关工具;再比如GP...

取消回复欢迎 发表评论: