当前位置: 首页 > Linux

云原生场景下,如何缓解容器隔离漏洞和监控内核关键路径?

时间:2023-04-06 04:41:22 Linux

简介:OpenCloudOS社区是由操作系统、软硬件厂商、个人共同发起的操作系统社区项目。让我们一起构建一个中立的操作系统开源生态系统。OpenCloudOS社区云原生操作系统作为社区的重要技术方向,开发了一系列云原生特性。本文主要介绍CgroupFS和SLI。一、CgroupFS的特点1.方案背景容器的隔离主要依赖Linux操作系统的Namespace和Cgroup,不同于依赖硬件辅助虚拟化的虚拟机隔离。前者有很多隔离漏洞。随着云原生场景的大规模使用,大量应用的容器化暴露了容器隔离的问题。特别是/proc和/sys文件系统中的一些资源统计信息没有完全容器化,导致物理机/虚拟机运行在容器中时,一些常用命令(如free/top)显示不准确信息来自容器的视角,而是系统层面的全局信息。对于依赖这些系统信息运行的容器化应用,可能会导致运行结果错误甚至无法运行。2、方案探索业界普遍采用lxcfs方案来解决容器隔离漏洞问题。但是lxcfs方案有其先天的缺陷:1)需要依赖lxcfs这个额外的组件;2)lxcfs基于FUSE在用户态实现,开销高于内核;切换时触发挂起,无法获取信息等问题。每个容器需要对应一个lxcfs服务进程3.方案实现CgroupFS方案是基于内核态实现的。它的核心设计是设计一个新的虚拟文件系统,从需要实现的容器的角度,包括/proc、/sys等fs。其目录结构与全局procfs和sysfs保持一致,以确保与用户工具的兼容性。在实际读取相关文件时,通过CgroupFS的reader进程上下文动态生成对应的容器信息视图。以下内容基于OpenCloudOSLTS分支:https://github.com/OpenCloudOS/OpenCloudOS-Kernel/commits/lts/5.4.119-20.00094,方案实现效果1)创建挂载点目录/cgroupfs挂载cgroupfs:mount-tcgroupfscgroupfs/cgroupfs/2)容器启动命令如下:dockerrun-itd--cpus2--cpuset-cpus2,4--memory="512m"--memory-swap="1g"-v/cgroupfs/sys/devices/system/cpu/:/sys/devices/system/cpu-v/cgroupfs/proc/cpuinfo:/proc/cpuinfo-v/cgroupfs/proc/stat:/proc/stat-v/cgroupfs/proc/meminfo:/proc/meminfoimage-id/bin/bash容器启动后,会将cgroupfs下的文件绑定挂载到容器中的相应位置。3)运行实例启用CgroupFS后,在容器中执行常用命令的效果:(容器规格:2个CPU,有限可用内存512M,可用内存和可用swap总计1G)proc文件系统下显示的CPU信息在container:容器内free命令显示内存信息:容器内top命令显示CPU个数信息:容器内nproc显示CPU总数信息二、SLI特点1、解决方案背景大量应用在云原生场景在容器中运行。但在资源利用率高的场景下,容器也存在问题。例如:容器之间的相互干扰、容器资源受限导致的性能抖动等。目前Linux系统的性能指标要么基于进程级的统计数据,要么基于全局的统计数据,无法直观有效地反映容器级的性能问题。SLI是OpenCloudOS社区的容器级性能跟踪机制,从容器的角度跟踪观察CPU和内存资源的竞争情况,为容器性能问题的定位和分析提供可靠的指标。二、方案探索SLI方案选择优缺点内核原生实现1.在内核中实现,跟踪开销最小,性能最优。2、内核所有接口均可调用,功能开发不受限制。1、可扩展性差。2、开发部署周期长(涉及内核升级或热补丁更换)。eBPF1具有良好的可扩展性,eBPF代码可以根据需要动态修改。2、开发部署周期短,开发难度相对简单。1.eBPF代码有很多安全检查,会引入很大的开销,导致跟踪性能开销很大。2、eBPF对调用接口有严格的限制,导致很多内核接口函数无法调用,会严重制约功能开发。SLI是一种规范化的性能跟踪机制,需要跟踪很多内核热点函数,这就要求SLI的实现必须是低开销的。此外,SLI使用了很多kernel核心函数,eBPF无法调用这些函数。所以权衡之后,我们决定在内核中实现SLI机制,尽量减少跟踪性能开销。在mbuf特性容器场景下,每个容器都是一个独立的应用。由于不同的容器在运行过程中的资源使用情况和运行情况不同,因此需要有一个独立的地方来记录不同容器内核级别的异常日志信息。上层应用可以根据日志信息直接定位到相应的容器,从而进行合理的调度等操作;mbuf应运而生。其实mbuf不仅可以应用在容器环境中,内核的其他模块也可以根据自己的需要按照mbuf规范使用;mbuf的实现1)内核启动时,申请一块保留内存,在伙伴系统之外。2)设置支持的最大条目数;每一项都是mbuf的使用单元,mbuf本身维护一个环作为ringbuffer,保证循环不溢出。3.方案实现SLI特性描述用户态通过Cgroup接口周期性收集SLI提供容器性能数据,用户态可以通过这些数据监控容器性能。mbuf问题定位SLI可以在mbuf内存出现问题时打印内核堆栈信息,帮助用户定位性能问题的原因。解决方案监控指标监控指标说明指标含义容器内负载监控容器内R/D状态的平均进程数(分别为容器在1min、5min、15min内的平均负载)R进程数指标:评估容器内进程数是否过载D进程数指示器:D态进程数可用于反馈IO等待、锁竞争等。内核态进程执行时间监控容器进程在内核中的执行时间模式。内核模式时间可能是由系统调用、中断或页面错误异常引起的。如果内核态的执行时间过长,会导致用户业务有较大的延迟,从而造成性能抖动。调度延迟监控容器进程的调度延迟信息(容器进程在调度队列上的等待时间)反馈容器的CPU竞争情况。过多的调度延迟会导致业务性能抖动。iowaitdelay监控容器进程的IO等待延迟信息(进程IO完成造成的延迟时间),反馈容器进程的IO性能问题。过大的IO延迟会导致业务文件访问出现性能问题。内存延迟监控容器进程的内存申请延迟信息反馈容器的内存申请性能。过多的内存申请延迟会导致业务出现性能抖动。4.方案效果1)如何开启SLI:echo1>/proc/sli/sli_enabled2)定期收集使用用户态监控索引访问方式监控容器内负载/sys/fs/cgroup/cpuset//cpuset.loadavg进程在内核态的执行时间/sys/fs/cgroup/cpuacct//cpuacct.sli对应schedlat_longsys项调度延迟/sys/fs/cgroup/cpuacct//cpuacct。sli对应schedlat_rundelay项iowaitdelay/sys/fs/cgroup/cpuacct//cpuacct.sli对应schedlat_ioblock项memorydelay/sys/fs/cgroup/memory//memory.sli3)mbuf问题定位数据获取方法需要先启用mbuf:echo1>/proc/sys/kernel/qos_mbuf_enable触发堆栈保存到mbuf阈值设置监控指标阈值设置进程执行时间延迟阈值设置文件内核态:/proc/sli/sched_latency_threshold例如:echo"schedlat_longsys_thr=4">/proc/sli/sched_latency_threshold调度延迟延迟阈值设置文件:/proc/sli/sched_latency_threshold例如:echo"schedlat_rundelay_thr=24">/proc/sli/sched_latency_thresholdiowaitdelay延迟阈值设置文件:/proc/sli/sched_latency_threshold例如:echo"schedlat_ioblock_thr=16">/proc/sli/sched_latency_threshold内存延迟内存延迟阈值设置文件:/proc/sli/memory_latency_threshold例如:echo"page_alloc_threshold=24">/proc/sli/memory_latency_threshold获取mbuf中的堆栈信息:cat/sys/fs/cgroup/cpuacct//cpuacct.mbuf4)SLI应用示例下图是使用SLI监控rediscontainermemoryinterferencecollection根据测试数据,directrecycling的每一次延迟都对应一次redisjitter三、总结通过OpenCloudOS容器引擎内核支持技术全景图,可以看出CgroupFS和SLI是重要的模块,欢迎扫一扫点击扫描下方二维码加入社区用户群,了解OpenCloudOS最新动态,获取技术支持,分享交流经验。