您的位置 首页 > 德语词汇

overview是什么意思,overview的意思翻译、用法、同义词、,Overview

大家好,今天来为大家解答overview是什么意思,overview的意思翻译、用法、同义词、这个问题的一些问题点,包括Overview也一样很多人还不知道,因此呢,今天就来为大家分析分析,现在让我们一起来看看吧!如果解决了您的问题,还望您关注下本站哦,谢谢~

作者:荣旸-阿里云智能基础软件部

overview是什么意思,overview的意思翻译、用法、同义词、,Overview

出处:https://kernel.taobao.org/2020/07/eBPF-Up-and-Running-Overview/

eBPF技术是近几年Linux社区一颗闪亮的明星,如果你还没有开始接触并编写过eBPF程序,那么不要错过,接下来的一系列文章非常适合你。

eBPFUp&Running系列文章目前主要包括下面三篇:

接下来会随着eBPF的发展和大家的反响情况,不断丰富扩展更多的文章。废话不多说,让我们开始接下来的干货时间。

在写第一行代码之前,首先让我们了解一下eBPF技术前世今生。

回到1992年,eBPF的前身BPF(BerkeleyPacketFilter),现在被成为cBPF(classicBPF),主要用于tcpdump和seccomp,场景无外乎是一种灵活的DSL+虚拟机帮助用户筛选数据。用户的过滤条件会被编译为cBPF程序,程序由预先定义的指令组成,这些指令在内核中解释运行,并通过JIT加速执行速度,每当数据经过时,会触发程序执行并判断是否满足筛选条件。

时间很快来到了2011年,eBPF在这一年诞生了。经过社区的不断迭代和完善,eBPF在各个方面得到增强:

eBPF是如何在内核中的执行的?eBPFInternal:InstructionsandRuntime文章中有更详细的介绍,下图展示了eBPF程序的大体执行流程。

其实eBPF本身其实远没有想象中的复杂,我们可以把内核想象成一个庞大而复杂的电路,如果电路出现了异常,我们可以通过使用万用表测量电路,如果当前电路不能满足需求,但又不能推倒重新设计,我们需要串入其他元件。eBPF之于电路,既是万用表,也是各种功能元件。再回到内核中的eBPF,内核预先在各个关键路径埋设了eBPF程序入口,用户可以编写不同类型的eBPF程序,将eBPF程序attach在内核中不同路径中执行。

在编写第一个程序之前,我们需要准备一个顺手的开发环境。内核源码仓库samples/bpf目录下包含了数十个典型的eBPF示例程序,除了可供学习和参考之外,我们可以将程序代码放在这个目录,无需自己额外花时间编写和调试Makefile。

eBPF程序本质上是一种字节码,我们只需将编写的代码编译成eBPF字节码,即可在内核的eBPF虚拟机中运行。理论上我们可以使用各种现有的语言编写eBPF程序,只要确保这门语言具有对应的LLVM前端,帮助我们将其翻译为LLVMIR中间代码,并通过LLVM最终编译为eBPF字节码。通常情况下,推荐使用C进行编写,当前内核提供了完备的Clibrary。因此我们需要确保clang已经正确配置好,如果已经按照上面步骤正确配置了脚手架,我们无需再配置clang和LLVM。

对于大部分场景下eBPF编程模型,eBPF程序不是单独出现,而是由用户态控制平面controlplane和内核态数据平面dataplane两部分组成,经典的数据面和控制面分离。

接下来我们将以samples/bpf/{xdp1_kern.c,xdp1_user.c}程序为例,这个示例不只是简单的打印,它可以统计网卡的数据报文的协议分布数量。

首先是内核态的eBPF代码:xdp1_kern.c,主要功能是从数据报文中解析并判断协议类型,统计数据报文中不同协议的数量分布情况。

/*其他省略,完整源码请参考samples/bpf/xdp1_kern.c*/\n\n/*定义数据结构存放统计信息*/\nstructbpf_map_defSEC("maps")rxcnt={\n.type=BPF_MAP_TYPE_PERCPU_ARRAY,\n.key_size=sizeof(u32),\n.value_size=sizeof(long),\n.max_entries=256,\n};\n\nSEC("xdp1")\n/*eBPFXDP类型程序的特定函数签名,ctx包含数据包的上下文信息*/\nintxdp_prog1(structxdp_md*ctx)\n{\n/*报文结束位置*/\nvoid*data_end=(void*)(long)ctx->data_end;\n/*报文开始位置*/\nvoid*data=(void*)(long)ctx->data;\nstructethhdr*eth=data;\nlong*value;\nu16h_proto;\nu64nh_off;\nu32ipproto;\n\nnh_off=sizeof(*eth);\nif(data+nh_off>data_end)\n\t\t/*对于非法报文直接返回XDP_DROP并丢弃*/\nreturnXDP_DROP;\n\nh_proto=eth->h_proto;\n\n/*接下来会根据数据报文依次解析协议类型*/\nif(h_proto==htons(ETH_P_8021Q)||h_proto==htons(ETH_P_8021AD)){\nstructvlan_hdr*vhdr;\n\nvhdr=data+nh_off;\nnh_off+=sizeof(structvlan_hdr);\n\t\t/*判断数据包是否合法,否则直接丢弃*/\nif(data+nh_off>data_end)\nreturnXDP_DROP;\nh_proto=vhdr->h_vlan_encapsulated_proto;\n}\nif(h_proto==htons(ETH_P_8021Q)||h_proto==htons(ETH_P_8021AD)){\nstructvlan_hdr*vhdr;\n\nvhdr=data+nh_off;\nnh_off+=sizeof(structvlan_hdr);\n\t\t/*判断数据包是否合法,否则直接丢弃*/\nif(data+nh_off>data_end)\nreturnXDP_DROP;\nh_proto=vhdr->h_vlan_encapsulated_proto;\n}\n\nif(h_proto==htons(ETH_P_IP))\n\t\t/*从payload中解析Ipv4protocol*/\nipproto=parse_ipv4(data,nh_off,data_end);\nelseif(h_proto==htons(ETH_P_IPV6))\n\t\t/*从payload中解析Ipv6protocol*/\nipproto=parse_ipv6(data,nh_off,data_end);\nelse\nipproto=0;\n\n/*统计不同协议的访问次数*/\nvalue=bpf_map_lookup_elem(&rxcnt,&ipproto);\nif(value)\n*value+=1;\n\n/*返回XDP_PASS传递报文至下层处理逻辑*/\nreturnXDP_PASS;\n}

接下来是用户态代码:xdp1_user.c,主要功能是载入eBPF程序到内核中,并从内核共享的map中获得统计信息并展示。

/*其他省略,完整源码请参考samples/bpf/xdp1_kern.c*/\n\nstaticintifindex;\nstatic__u32xdp_flags;\n\nstaticvoidint_exit(intsig)\n{\n/*将XDP与网卡解绑*/\nbpf_set_link_xdp_fd(ifindex,-1,xdp_flags);\nexit(0);\n}\n\nstaticvoidpoll_stats(intmap_fd,intinterval)\n{\nunsignedintnr_cpus=bpf_num_possible_cpus();\nconstunsignedintnr_keys=256;\n__u64values[nr_cpus],prev[nr_keys][nr_cpus];\n__u32key;\ninti;\n\nmemset(prev,0,sizeof(prev));\n\nwhile(1){\nsleep(interval);\n\nfor(key=0;key<nr_keys;key++){\n__u64sum=0;\n/*从map中获取统计信息*/\nassert(bpf_map_lookup_elem(map_fd,&key,values)==0);\nfor(i=0;i<nr_cpus;i++)\nsum+=(values[i]-prev[key][i]);\nif(sum)\nprintf("proto%u:%10llupkt/s\\n",\nkey,sum/interval);\nmemcpy(prev[key],values,sizeof(values));\n}\n}\n}\n\nintmain(intargc,char**argv)\n{\nstructrlimitr={RLIM_INFINITY,RLIM_INFINITY};\nstructbpf_prog_load_attrprog_load_attr={\n\t\t/*指定程序类型,这里为XDP*/\n.prog_type=BPF_PROG_TYPE_XDP,\n};\nconstchar*optstr="SN";\nintprog_fd,map_fd,opt;\nstructbpf_object*obj;\nstructbpf_map*map;\ncharfilename[256];\n\nwhile((opt=getopt(argc,argv,optstr))!=-1){\nswitch(opt){\ncase'S':\n\t\t\t\t\t/*XDP两种工作模式,第三篇文章会详细展开*/\nxdp_flags|=XDP_FLAGS_SKB_MODE;\nbreak;\ncase'N':\n/*XDP两种工作模式,第三篇文章会详细展开*/\nxdp_flags|=XDP_FLAGS_DRV_MODE;\nbreak;\ndefault:\nusage(basename(argv[0]));\nreturn1;\n}\n}\n\n/*省略不重要代码*/\n\nsnprintf(filename,sizeof(filename),"%s_kern.o",argv[0]);\nprog_load_attr.file=filename;\n\n/*载入eBPF字节码至内核*/\nif(bpf_prog_load_xattr(&prog_load_attr,&obj,&prog_fd))\nreturn1;\n\nmap=bpf_map__next(NULL,obj);\nif(!map){\nprintf("findingamapinobjfilefailed\\n");\nreturn1;\n}\n/*获得eBPF中定义的数据结构,用以获取统计信息*/\nmap_fd=bpf_map__fd(map);\n\n/*省略不重要代码*/\n\n/*设置XDP与网卡的绑定,eBPF字节码将会在指定网卡收包路径执行*/\nif(bpf_set_link_xdp_fd(ifindex,prog_fd,xdp_flags)<0){\nprintf("linksetxdpfdfailed\\n");\nreturn1;\n}\n\n/*定时从mapfd中轮询统计数据*/\npoll_stats(map_fd,2);\n\nreturn0;\n}编译运行

在Linux源码仓库根目录执行makesamples/bpf/,编译完成后会在samples/bpf目录下会得到用户态可执行文件xdp1和eBPF字节码文件xdp1_kern.o,直接在当前目录直接执行即可。如果是自己编写的代码,可以将文件放入samples/bpf目录下,并在Makefile中加入这对应文件的编译配置。

如果遇到了任何环境或者编译的问题,可以参考内核文档samples/bpf/README.rst。

通过上面的示例程序之后,想必大家已经对如何编写一个eBPF程序有了初步的印象。以刚才编写的程序为例,我们可以发现eBPF程序包含三个基础的概念:程序类型、数据结构和helpers。

eBPF的程序类型(programtype),决定了eBPF程序如何载入内核,以及在内核哪些路径执行eBPF程序。例如需要kprobe跟踪函数执行,则需要在载入时指定eBPF程序的类型为BPF_PROG_TYPE_KPROBE。对于XDP则需要指定为BPF_PROG_TYPE_XDP;

以XDP类型eBPF程序为例,用户通过netlink调用dev_change_xdp_fd为指定dev设置eBPF程序,例如veth网卡XDP的支持在4.14内核引入,通过veth_xdp_set为网卡绑定eBPF字节码,当NAPIpoll执行时于每个XDPframe依次调用veth_xdp_rcv_one,并执行对应的eBPF程序,根据eBPF程序的返回结果决定丢弃、通过或者重定向报文。

全量的程序类型定义在include/uapi/linux/bpf.h,如需了解详细的程序类型请参考:BCC文档。

对于任何程序而言,都离不开各种各样的数据结构。eBPF提供了各种常用的数据结构,从而实现内核内部数据的组织,以及用户态和内核态的通信;

当前eBPF定义了26中基础的数据结构,涵盖了hash、stack、array和ringbuf。以hash为例,可以指定key、leaf的数据类型以及大小,同时提供了相应的helpers操作函数BPF_FUNC_map_lookup_elem()和BPF_FUNC_map_push_elem()等。

全量的数据结构定义在include/uapi/linux/bpf.h,如需了解详细的数据结构列表请参考:BCC文档。

如同其他语言生态会提供丰富的library,eBPF也包含了各种常用的helpers函数,例如打印输出BPF_FUNC_trace_printk等;

eBPF定义的helpers函数不仅为了简化复杂的eBPF操作,同时也会将部分危险的操作封装成安全的helpers函数,对于内核数据结构的访问和操作需要借助helper完成,确保了eBPF程序的安全性。

全量的helpers定义在include/uapi/linux/bpf.h,详细的helps列表请参考:BCC文档

学习并掌握一门技术的最好方式是付诸于实践。现在你的脑海中可能已经迸发出各种各样的想法,迫不及待编写eBPF程序验证和实践。为了更方便的去验证和实践,除了上面提到的基于samples/bpf示例程序之外,我们还可以基于下面一些社区已有的可供我们快速上手的应用。

BCC是一个包含丰富的内核跟踪分析的eBPF工具集,用户也可以基于BCC创建自己的eBPF工具。当前BCC工具提供了Python/Lua和Go语言的binding,用户可以使用这三种语言编写自己的eBPF工具。BCC提供一个非常友好的tutorial可供大家快速上手。其中iovisor/gobpf库,可以通过Go生态将eBPF与云原生、k8s或各种运维工具相结合。

如果使用过systemtap动态跟踪分析内核,那么bpftrace是一个很好的替代方案。bpftrace提供了一种类awk和C的语言,使用bpftrace语言编写各种跟踪和分析脚本,并编译成eBPF字节码与内核交互,从而实现动态跟踪Linux内核。使用文档可以参考:使用bpftrace分析内核,和ThebpftraceOne-LinerTutorial;

假如对于eBPF字节码和虚拟机非常感兴趣,ubpf提供了一个用户态实现的虚拟机,包含了解释运行和JIT特性。不仅帮助我们更好的理解eBPF虚拟机的实现,而且可以将ubpf嵌入到应用中,以执行编写好的eBPF程序,从而实现Lua或WASM的功能。generic-ebpf则更进一步,提供了更完善的运行时机制和库函数,并将eBPF作为一种通用的字节码嵌入到交换机等硬件中并运用在生产环境。

eBPF为内核提供了更多的可能性,社区仍在不断拓宽eBPF的场景,通过这篇文章我们了解了如何编写eBPF程序,接下来几篇文章将会为大家带来eBPF在跟踪和网络方面的特性和应用。

作者:荣旸-阿里云智能基础软件部

出处:https://kernel.taobao.org/2020/07/eBPF-Up-and-Running-Overview/

overview是什么意思,overview的意思翻译、用法、同义词、和Overview的问题分享结束啦,以上的文章解决了您的问题吗?欢迎您下次再来哦!

本站涵盖的内容、图片、视频等数据,部分未能与原作者取得联系。若涉及版权问题,请及时通知我们并提供相关证明材料,我们将及时予以删除!谢谢大家的理解与支持!

Copyright © 2023