# anolisbox **Repository Path**: anolis/anolisbox ## Basic Information - **Project Name**: anolisbox - **Description**: No description available - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-05-19 - **Last Updated**: 2023-05-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AnolisBox 本项目旨在提供单机资源混部/超卖能力的 标准化、归一化、简单化 解决方案 * 标准化:定义清晰云原生场景下,节点侧资源超卖在覆盖范围、技术指标、运维保障、收益分析等方面的标准,以及可观测、可评估能力的建设 * 归一化:对龙蜥ANCK/袋鼠kangaroo现有的QoS/超卖能力进行整合,抽象出统一且易用的接口形态,降低上层用户开发成本 * 简单化:提供默认集成的QoS配置策略,覆盖云原生常见场景,屏蔽底层复杂的参数配置,降低用户使用门槛 通过以上手段,将通用内核与容器场景的能力进行统一标准化,便于向更多调度平台及开源用户等场景推广和输出,使龙蜥操作系统的能力能够被更多的用户使用。 ## 编译/安装 ### 静态编译 为了保证编译出来的 `anolisbox` 二进制文件可以在各个环境上稳定运行,这里建议使用 `x86_64-unknown-linux-musl` 工具链进行静态编译。 ``` // 将代码clone 到本地 git clone git@gitlab.alibaba-inc.com:kangaroo-cloudnative/anolisbox.git // 进入 anolisbox 代码源文件目录 cd anolisbox/src // 静态编译生成可执行的二进制文件 sudo -E cargo build --target=x86_64-unknown-linux-musl ``` 此时,anolisbox的二进制文件所在的相对路径为`src/target/x86_64-unknown-linux-musl/debug`,此目录下有两个可执行文件: - `anolisbox`: anolisbox 的二进制文件 - `anolixbox_ctl`: anolisbox 对应的cli工具,为了便于调试 默认配置文件在 rpm/ 目录中 可以将编译生成的`anolisbox`可执行文件上传到oss,再下载到 ACK 的节点上,即可运行 ``` chmod a+x anolisbox -c /etc/anolisbox/config.toml sudo ./anolisbox -c /etc/anolisbox/config.toml ``` ### rpm安装 ``` yum install -y http://yum.tbsite.net/taobao/7/x86_64/test/anolisbox/anolisbox-0.1.0-20230411153112.b43ca26.alios7.x86_64.rpm ``` ## 本地测试 ### 单元测试/CI ```shell # 在src目录执行 sudo -E cargo test --package resmanager --lib ``` 所有UT均通过即可。部份UT所测试的功能点需要依赖安装相关rpm,可根据实际情况进行判断。 ### e2e测试 在原生的 k8s 环境下,kubelet 会把 CRI request 发送给 Container Runtime, 也就是 ACK 集群上的 `containerd`,通过 `ps -ef | grep kubelet` 命令可以看到,kubelet启动参数 `container-runtime-endpoint` 的值为 `/var/run/containerd/containerd.sock`,因此需要修改 kubelet 的配置文件,将这个参数的值设置为 anolisbox 所监听的地址。 ``` [root@iZ2zeflaqwum6w3si7mm0kZ ecs-assist-user]# systemctl status kubelet ● kubelet.service - kubelet: The Kubernetes Node Agent Loaded: loaded (/etc/systemd/system/kubelet.service; enabled; vendor preset: disabled) Drop-In: /etc/systemd/system/kubelet.service.d └─10-kubeadm.conf ``` 可以看到, kubelet 的配置文件路径为 `/etc/systemd/system/kubelet.service.d/10-kubeadm.conf`, 编辑此文件,配置如下参数, kubelet的CRI request则会发送到 anolisbox 所监听的uds地址。 ``` --container-runtime-endpoint=/var/run/anolisbox/anolisbox.sock ``` 之后再重启kubelet,并通过`ps -ef | grep kubelet` 命令查看`container-runtime-endpoint`参数配置的正确性 ``` systemctl restart kubelet ps -ef | grep kubelet ``` 此时,kubelet 发送到CRI request会全部发送到 anolisbox,anolisbox在劫持到 CRI request 后,做一些策略上(Qos)的配置,并将其转发到 `containerd` 并接收`containerd`的CRI reply, 最后将 CRI reply转发给kubelet,即可完成全部工作。 在创建 Pod 时, anolisbox会劫持 `run_pod_sandbox` 请求并打印日志,可以通过日志验证是否劫持成功。anolisbox的日志路径为:`/var/log/anolisbox.log`,日志内容如下所示: ``` "message":"run pod sandbox request from kubelet: Request xxx "message":"run pod sandbox reply from containerd: Response xxx ``` ### k8s 相关测试 准备测试 pod yaml ```yaml apiVersion: v1 kind: Pod metadata: name: busybox namespace: default annotations: anolisbox.sh/qoslevel: "BE" spec: containers: - image: registry-vpc.cn-zhangjiakou.aliyuncs.com/acs/busybox command: - sleep - "3600" imagePullPolicy: IfNotPresent name: busybox resources: limits: cpu: "4" memory: "2Gi" requests: cpu: "4" memory: "2Gi" restartPolicy: Always runtimeClassName: runc ``` 启动pod ```shell kubectl create -f test.yaml ``` 观察pod相关参数及指标设置是否符合预期 ## 特性介绍 ### group identity (bvt) 为满足多优先级pod混部要求,内核调度器需要赋予高优先级的任务更多的调度机会来最小化其调度延迟,并把低优先级任务对其带来的影响降到最低,归纳需求如下: * cpu cgroup新增接口来配置调度优先级 * 高优先级任务唤醒时的延迟应当最小化 * 低优先级任务唤醒不应对高优先级任务造成性能影响 * 低优先级任务不应通过SMT共享硬件unit而对高优先级任务造成性能影响 目前针对不同优先级pod的group identity值设置如下: * LSE: 2 * LS: 1 * BE: -1 #### 依赖条件 支持 group identity 的内核列表如下: ``` alinux2: >= kernel-4.19.91-26.4 alinux3: >= kernel-5.10.134-13.al8 ``` 若内核支持该功能,则anolisbox会默认使能该特性。具体可以参考文档: ### Global OOM Priority OOM分为两种: memcg OOM和global OOM。无论哪种OOM,在选择杀进程的时候,内核会有一个算法去选择victim,但通常是找一个oom score最大的进程杀。 在真实的业务场景中,特别是内存超卖环境,当发生global OOM的时候,有理由去选择杀掉那些优先级比较低的离线业务,而保护高优先级在线业务; 当发生离线memcg OOM的时候,有理由去选择杀掉那些优先级比较低的作业,而保高优先级离线作业。 当全局OOM优先级打开时,会从根组开始逐层遍历所有mem cgroup,直到选出优先级最低的cgroup 作为被杀对象 目前针对不同优先级pod的OOM Priority设置如下: * LS: 10 * LSE: 5 * BE: 0 #### 依赖条件 全局OOM优先级,需要打开本机总开关,使能该功能后才能设置相关参数。 ```shell echo 1 > /sys/fs/cgroup/memory/memory.use_priority_oom ``` ### memcg异步回收内存(wmark ratio) 分配memcg内存时,当触及memcg的内存上限时(例如memory.limit_in_bytes, memory.high),会触发memcg级别的直接内存回收,由于是在分配上下文进行的同步回收,会影响当前进程内存分配的性能。 为了解决这个问题,anolisOS借鉴全局kswapd的思想,自研了相应的memcg异步后台回收功能。不同于全局kswapd内核线程,memcg 后台回收并没有创建对应的memcg kswapd内核线程,而是采用了workqueue设计实现。 ### MBA/LLC Control `intel RDT`和`ARM MPAM` 技术支持对业务pod的访存带宽(memory bandwidth)和LLC(Last Level Cache) 进行限制,以减少其对在线业务的干扰。 目前anolisbox 支持三种限制等级,分别是: * LOW: 低优先级pod(LLC限制使用4路,MBA限制20%) * HIGH: 中优先级pod(LLC限制使用8路,MBA限制50%) * ALL: 高优先级pod(无限制,LLC可使用全11路,MBA使用100%) 目前anolisbox默认设置BE pod在LOW组,可以通过annotations 选择配置到其他控制组;非BE pod 默认不设置限制 ```yaml annotations: anolisbox.sh/llc_limit: "high" ``` #### 依赖条件 * 需要硬件支持且OS打开相关内核接口参数 * intel: 内核启动cmdline中存在 rdt=l3cat,mba * arm: 内核启动cmdline中存在 mpam=acpi * 可以通过lscpu查看硬件是否支持该功能 * OS需挂载 /sys/fs/resctrl 接口