InfoQ|在网易轻舟云原生的应用实践,eBPF( 三 )


开发了cpucycles/instructions、llcreferences/misses等一系列针对硬件PMU的监控功能用来支持混合部署中的调度功能 。
更多的监控功能就不一一列举了 , 除了自研的一些监控 , 我们还将BCC工具集中一些功能引入了进来 , 目前主要用来支撑自动诊断、监控报警、性能调优等场景 。
eBPF开发中遇到的问题:一直都在陈述eBPF的优点 , 但是在开发具体监控功能的过程中 , 依然存在诸多限制 , 包括内核实现方面的限制也有eBPF自身的一些限制 , 需要开发者充分的考虑 , 例如在多核平台上如何保证对eBPFMAP中数据修改操作的原子性、如何将监控数据与产生数据的进程关联起来等等 。
有些问题我们可以解决 , 但是也有些问题我们目前也没找到好的解决方法 , 例如将监控数据与产生数据的进程关联起来这个问题 , 这是一个非常常见的问题 , 通常由内核的实现逻辑引入 , 该问题我们在监控TCP连接状态变化的场景中(连接建立过程不在进程上下文) , 通过记录socket创建以及socket继承等操作得到了解决 , 但是在BlockIO相关的监控场景中就没那么好解决了 , 我们依然在这方面不断探索 。
3.2网络性能优化在网络性能优化方面 , 网易轻舟也基于ebpf的sockmap和skredirect功能研发了自己的sockops组件 , 主要用于加速istio架构中sidecar代理和本地进程之间的通信 。
InfoQ|在网易轻舟云原生的应用实践,eBPF
文章图片
Sockops技术原理说明:Sockmap是eBPF提供的一个特殊的eBPFMAP类型 , 主要用于socketredirection , 在socketredirection中 , socket被添加到sockmap中并由key(主要是四元组)引用 , 然后该socket在调用bpf_sockmap_redirect时进行重定向 。
sockops的技术原理如下图所示 , 对于本地通信可以绕过TCP/IP协议栈将报文直接发给对端socket , 以此来提高性能 。 Sockops组件技术原理如下图所示:
InfoQ|在网易轻舟云原生的应用实践,eBPF
文章图片
Sockops数据面对轻舟服务网格场景的适配:如果一个报文的key(主要是四元组)在sockmap中被命中 , 那么该报文将绕过TCP/IP协议栈 , 而被直接发送给接收端的socket , 接收端的socket对应的就是下图中sockmap的value所存储的skops结构 。
InfoQ|在网易轻舟云原生的应用实践,eBPF
文章图片
首先我们监听TCP链接状态的变化 , 在连接建立时 , 填充sockmap 。 然后我们再通过eBPF的sk_msg功能hookTCP的发包流程(sendmsg/sendfile等) , 并在hook函数中调用bpf_sockmap_redirect对socket进行重定向 。
不过在istio环境中 , 该情况会变得稍微复杂一些 , 因为istio通过iptablesredirect将pod访问svc的报文重定向到envoy , 加之sockmap的捕捉是在iptable规则之前 , 所以sockmap捕捉到的反向连接跟正向连接的源、目的地址不是一一对应的 , 找不到正向连接信息 。 我们的解决方案是新增一个eBPFMAP , 并在正向连接建立时 , 以源地址为key , 目的地址作为value存储起来 , 反向连接建立时根据反向链接的目的地址可以直接找到正向连接的完整信息 。 用一张图可以比较清晰的看懂这个过程:
InfoQ|在网易轻舟云原生的应用实践,eBPF
文章图片
Sockops组件完整的架构设计如下图所示:
InfoQ|在网易轻舟云原生的应用实践,eBPF
文章图片
主要分为用户态DaemonSet程序和运行在内核中的eBPF程序两部分组成:
用户态DaemonSet程序 , 主要负责一些管控面的操作 , 包括监控K8S、docker的一些信息或者事件 , 然后动态更新eBPF程序的配置(用来支持细粒度开启关闭sockops功能) , 还包括编译加载eBPF程序、提供整个sockops组件的升级、对接prometheus提供自身的一些监控信息等功能;