From 67b7259d810c9e07227e7a1475acdc1141e4424e Mon Sep 17 00:00:00 2001 From: Weifeng Su Date: Thu, 8 Jun 2023 14:17:00 +0000 Subject: Keep doc same with docs in openEuler Signed-off-by: Weifeng Su --- qtfs/doc/overview.md | 11 ++ ...77\347\224\250\346\211\213\345\206\214.md" | 69 ++++++++ ...40\346\204\237\345\215\270\350\275\275.md" | 31 ++++ ...50\347\275\262\346\214\207\345\257\274.md" | 166 ++++++++++++++++++ 7 files changed, 277 insertions(+) create mode 100644 qtfs/doc/overview.md create mode 100644 "qtfs/doc/qtfs\345\205\261\344\272\253\346\226\207\344\273\266\347\263\273\347\273\237\346\236\266\346\236\204\345\217\212\344\275\277\347\224\250\346\211\213\345\206\214.md" create mode 100644 "qtfs/doc/\345\256\271\345\231\250\347\256\241\347\220\206\351\235\242\346\227\240\346\204\237\345\215\270\350\275\275.md" create mode 100644 "qtfs/doc/\346\227\240\346\204\237\345\215\270\350\275\275\351\203\250\347\275\262\346\214\207\345\257\274.md" diff --git a/qtfs/doc/overview.md b/qtfs/doc/overview.md new file mode 100644 index 0000000..518deb0 --- /dev/null +++ b/qtfs/doc/overview.md @@ -0,0 +1,11 @@ +# 容器管理面DPU无感卸载指南 + +本文档介绍基于openEuler操作系统的容器管理面DPU无感卸载功能特性及安装部署方法,该特性可以通过操作系统提供的统一抽象层,屏蔽容器管理面跨主机资源访问的差异,实现容器管理面业务无感卸载到DPU上。 + +本文档适用于使用openEuler系统并希望了解和使用操作系统内核及容器的社区开发者、开源爱好者以及相关合作伙伴。使用人员需要具备以下经验和技能: + +- 熟悉Linux基本操作 + +- 熟悉linux内核文件系统相关基础机制 + +- 对kubernetes和docker有一定了解,熟悉docker及kubernetes部署及使用 \ No newline at end of file diff --git "a/qtfs/doc/qtfs\345\205\261\344\272\253\346\226\207\344\273\266\347\263\273\347\273\237\346\236\266\346\236\204\345\217\212\344\275\277\347\224\250\346\211\213\345\206\214.md" "b/qtfs/doc/qtfs\345\205\261\344\272\253\346\226\207\344\273\266\347\263\273\347\273\237\346\236\266\346\236\204\345\217\212\344\275\277\347\224\250\346\211\213\345\206\214.md" new file mode 100644 index 0000000..8088f48 --- /dev/null +++ "b/qtfs/doc/qtfs\345\205\261\344\272\253\346\226\207\344\273\266\347\263\273\347\273\237\346\236\266\346\236\204\345\217\212\344\275\277\347\224\250\346\211\213\345\206\214.md" @@ -0,0 +1,69 @@ +# qtfs + +## 介绍 + +qtfs是一个共享文件系统项目,可部署在host-dpu的硬件架构上,也可以部署在2台服务器之间。以客户端服务器的模式工作,使客户端能通过qtfs访问服务端的指定文件系统,得到本地文件访问一致的体验。 + +qtfs的特性: + ++ 支持挂载点传播; + ++ 支持proc、sys、cgroup等特殊文件系统的共享; + ++ 支持远程文件读写的共享; + ++ 支持在客户端对服务端的文件系统进行远程挂载; + ++ 支持特殊文件的定制化处理; + ++ 支持远端fifo、unix-socket等,并且支持epoll,使客户端和服务端像本地通信一样使用这些文件; + ++ 支持基于host-dpu架构通过PCIe协议底层通信,性能大大优于网络; + ++ 支持内核模块形式开发,无需对内核进行侵入式修改。 + +## 软件架构 + +软件大体框架图: + +![qtfs-arch](./figures/qtfs-arch.png) + +## 安装教程 + +目录说明: + ++ **qtfs**: 客户端内核模块相关代码,直接在该目录下编译客户端ko。 + ++ **qtfs_server**: 服务端内核模块相关代码,直接在该目录下编译服务端ko和相关程序。 + ++ **qtinfo**: 诊断工具,支持查询文件系统的工作状态以及修改log级别等。 + ++ **demo**、**test**、**doc**: 测试程序、演示程序以及项目资料等。 + ++ 根目录: 客户端与服务端通用的公共模块代码。 + +首先找两台服务器(或虚拟机)配置内核编译环境: + + 1. 要求内核版本在5.10或更高版本。 +  2. 安装内核开发包:yum install kernel-devel。 + +服务端安装: + + 1. cd qtfs_server + 2. make clean && make + 3. insmod qtfs_server.ko qtfs_server_ip=x.x.x.x qtfs_server_port=12345 qtfs_log_level=WARN + 4. ./engine 4096 16 + +客户端安装: + + 1. cd qtfs + 2. make clean && make + 3. insmod qtfs.ko qtfs_server_ip=x.x.x.x qtfs_server_port=12345 qtfs_log_level=WARN + +## 使用说明 + +安装完成后,客户端通过挂载把服务端的文件系统让客户端可见,例如: + + mount -t qtfs / /root/mnt/ + +客户端进入"/root/mnt"后便可查看到server端的所有文件,以及对其进行相关操作。 diff --git "a/qtfs/doc/\345\256\271\345\231\250\347\256\241\347\220\206\351\235\242\346\227\240\346\204\237\345\215\270\350\275\275.md" "b/qtfs/doc/\345\256\271\345\231\250\347\256\241\347\220\206\351\235\242\346\227\240\346\204\237\345\215\270\350\275\275.md" new file mode 100644 index 0000000..2e4be2f --- /dev/null +++ "b/qtfs/doc/\345\256\271\345\231\250\347\256\241\347\220\206\351\235\242\346\227\240\346\204\237\345\215\270\350\275\275.md" @@ -0,0 +1,31 @@ +# 容器管理面无感卸载介绍 + +## 概述 + +在数据中心及云场景下,随着摩尔定律失效,通用处理单元CPU算力增长速率放缓,而同时网络IO类速率及性能不断攀升,二者增长速率差异形成的剪刀差,即当前通用处理器的处理能力无法跟上网络、磁盘等IO处理的需求。传统数据中心下越来越多的通用CPU算力被IO及管理面等占用,这部分资源损耗称之为数据中心税(Data-center Tax)。据AWS统计,数据中心税可能占据数据中心算力的30%以上,部分场景下甚至可能更多。 + +DPU的出现就是为了将这部分算力资源从主机CPU上解放出来,通过将管理面、网络、存储、安全等能力卸载到专有的处理器芯片(DPU)上进行处理加速,达成降本增效的结果。目前主流云厂商如AWS、阿里云、华为云都通过自研芯片完成管理面及相关数据面的卸载,达成数据中心计算资源100%售卖给客户。 + +管理面进程卸载到DPU可以通过对组件源码进行拆分达成,将源码根据功能逻辑拆分成独立运行的两部分,分别运行在主机和DPU,达成组件卸载的目的。但是这种做法有以下问题:一是影响组件的软件兼容性,组件后续版本升级和维护需要自己维护相关patch,带来一定的维护工作量;二是卸载工作无法被其他组件继承,后续组件卸载后仍需要进行代码逻辑分析和拆分等工作。为解决上述问题,本方案提出DPU的无感卸载,通过OS提供的抽象层,屏蔽应用在主机和DPU间跨主机访问的差异,让业务进程近似0改动达成卸载到DPU运行的目标,且这部分工作属于操作系统通用层,与上层业务无关,其他业务进行DPU卸载时也可以继承。 + +## 架构介绍 + +#### 容器管理面DPU无感卸载架构 + +**图1**容器管理面DPU无感卸载架构 + +![offload-arch](./figures/offload-arch.png) + +如图1所示,容器管理面卸载后,dockerd、kubelet等管理进程运行在DPU侧,容器进程本身运行在HOST,进程之间的交互关系由系统层提供对应的能力来保证: + +* 通信层:DPU和主机之间可能通过PCIe或网络进行通信,需要基于底层物理连接提供通信接口层,为上层业务提供通信接口。 + +* 内核共享文件系统qtfs:容器管理面组件kubelet、dockerd与容器进程之间的主要交互通过文件系统进行;管理面工具需要为容器进程准备rootfs、volume等数据面路径;还需要在运行时通过proc文件系统、cgroup文件系统等控制和监控容器进程的资源及状态。共享文件系统的详细介绍参考[共享文件系统介绍](qtfs共享文件系统架构及使用手册.md) + +* 用户态卸载环境:用户态需要使用qtfs为容器管理面准备卸载后的运行时环境,将主机的容器管理及运行时相关目录远程挂载到DPU;另外由于需要挂载proc、sys、cgroup等系统管理文件系统,为防止对DPU原生系统功能的破坏,上述挂载动作都在chroot环境内完成。另外管理面(运行于DPU)和容器进程(运行于主机)之间仍存在调用关系,需要通过远程二进制执行工具(rexec)提供对应功能。 + +容器管理面无感卸载的操作步骤可参考[部署指导文档](./无感卸载部署指导.md) + +> ![](./public_sys-resources/icon-note.gif)**说明**: +> +> 上述操作指导涉及对容器管理面组件的少量改动和rexec工具修改,这些修改基于指定版本,其他版本可基于实际执行环境做适配修改。文档中提供的patch仅供验证指导使用,不具备实际商用的条件 \ No newline at end of file diff --git "a/qtfs/doc/\346\227\240\346\204\237\345\215\270\350\275\275\351\203\250\347\275\262\346\214\207\345\257\274.md" "b/qtfs/doc/\346\227\240\346\204\237\345\215\270\350\275\275\351\203\250\347\275\262\346\214\207\345\257\274.md" new file mode 100644 index 0000000..c15eed9 --- /dev/null +++ "b/qtfs/doc/\346\227\240\346\204\237\345\215\270\350\275\275\351\203\250\347\275\262\346\214\207\345\257\274.md" @@ -0,0 +1,166 @@ + +# 容器管理面无感卸载部署指导 + +> ![](./public_sys-resources/icon-note.gif)**说明**: +> +> 本指导涉及对容器管理面组件的少量改动和rexec工具修改,这些修改基于指定版本,其他版本可基于实际执行环境做适配修改。文档中提供的patch仅供验证指导使用,不具备实际商用的条件。 + +> ![](./public_sys-resources/icon-note.gif)**说明**: +> +> 当前共享文件系统之间通信通过网络完成,可通过网络互连的两台物理机器或VM模拟验证。 +> +> 建议用户验证前先搭建可正常使用的kubernetes集群和容器运行环境,针对其中单个节点的管理面进程进行卸载验证,卸载环境(DPU)可选择一台具备网络连接的物理机或VM。 + +## 简介 + +容器管理面,即kubernetes、dockerd、containerd、isulad等容器的管理工具,而容器管理面卸载,即是将容器管理面卸载到与容器所在机器(以下称为HOST)之外的另一台机器(当前场景下是指DPU,一个具备独立运行环境的硬件集合)上运行。 + +我们使用共享文件系统qtfs将HOST上与容器运行相关的目录挂载到DPU上,使得容器管理面工具(运行在DPU)可以访问到这些目录,并为容器(运行在HOST)准备运行所需要的环境,此处,因为需要挂载远端的proc和sys等特殊文件系统,所以,我们创建了一个专门的rootfs以作为kubernetes、dockerd的运行环境(以下称为`/another_rootfs`)。 + +并且通过rexec执行容器的拉起、删除等操作,使得可以将容器管理面和容器分离在不同的两台机器上,远程对容器进行管理。 + +## 相关组件补丁介绍 + +#### rexec介绍 + +rexec是一个用go语言开发的远程执行工具,基于docker/libchan下的[rexec](https://github.com/docker/libchan/tree/master/examples/rexec)示例工具改造而成,实现远程调用远端二进制的功能,为方便使用在rexec中增加了环境变量传递和监控原进程退出等能力。 + +rexec工具的具体使用方式为在服务器端用`CMD_NET_ADDR=tcp://0.0.0.0:<端口号> rexec_server`的方式拉起rexec服务进程,然后在客户端用`CMD_NET_ADDR=tcp://<服务端ip>:<端口号> rexec [要执行的指令] `的方式启动,便可以调用rexec_server执行需要执行的指令,并等待指令执行结果返回。 + +#### dockerd相关改动介绍 + +对dockerd的改动基于18.09版本。 + +在containerd中,暂时注释掉了通过hook调用libnetwork-setkey的部分,此处不影响容器的拉起。并且,为了docker load的正常使用,注释掉了在mounter_linux.go 中mount函数中一处错误的返回。 + +最后,因为在容器管理面的运行环境中,将`/proc`挂在了服务端的proc文件系统,而本地的proc文件系统则挂载在了`/local_proc`,所以,dockerd以及containerd中的对`/proc/self/xxx`或者`/proc/getpid()/xxx`或者相关的文件系统访问的部分,我们统统将`/proc`改为了`/local_proc`。 + +#### containerd相关改动介绍 + +对于containerd的改动基于containerd-1.2-rc.1版本。 + +在获取mountinfo时,因为`/proc/self/mountinfo`只能获取到dockerd本身在本地的mountinfo,而无法获取到服务端的mountinfo,所以,将其改为了`/proc/1/mountinfo`,使其通过获取服务端1号进程mountinfo的方式得到服务端的mountinfo。 + +在contaienrd-shim中,将与containerd通信的unix socket改为了用tcp通信,containerd通过`SHIM_HOST`环境变量获取containerd-shim所运行环境的ip,即服务端ip。用shim的哈希值计算出一个端口号,并以此作为通信的端口,来拉起containerd-shim. + +并且,将原来的通过系统调用给contaienr-shim发信号的方式,改为了通过远程调用kill指令的方式向shim发信号,确保了docker杀死容器的行为可以正确的执行。 + +#### kubernetes相关改动介绍 + +kubelet暂不需要功能性改动,可能会遇到容器QoS管理器首次设置失败的错误,该错误不影响后续Pods拉起流程,暂时忽略该报错。 + +## 容器管理面卸载操作指南 + +在服务器端和客户端,都要拉起rexec_server。服务器端拉起rexec_server,主要是用于客户端创建容器时用rexec拉起containerd-shim,而客户端拉起rexec_server,则是为了执行containerd-shim对dockerd和containerd的调用。 + +#### 服务器端 + +创建容器管理面所需要的文件夹,然后插入qtfs_server.ko,并拉起engine进程。 + +此外在服务器端,还需要创建rexec脚本/usr/bin/dockerd. + +``` shell +#!/bin/bash +CMD_NET_ADDR=tcp://<客户端ip>: rexec /usr/bin/dockerd $* +``` + +#### 客户端 + +需要准备一个rootfs,作为dockerd与containerd的运行环境,通过如下的脚本,将dockerd、containerd所需要的服务端目录挂载到客户端。并且,需要确保在以下脚本中被挂载的远程目录在服务端和客户端都存在。 + +``` shell +#!/bin/bash +mkdir -p /another_rootfs/var/run/docker/containerd +iptables -t nat -N DOCKER +echo "---------insmod qtfs ko----------" +insmod /YOUR/QTFS/PATH/qtfs.ko qtfs_server_ip=<服务端ip> qtfs_log_level=INFO + +# chroot环境内的proc使用DPU的proc共享文件系统替换,需要将本机真实proc文件系统挂载到local_proc下使用 +mount -t proc proc /another_rootfs/local_proc/ + +# 将chroot内环境与外部环境bind,方便进行配置和运行 +mount --bind /var/run/ /another_rootfs/var/run/ +mount --bind /var/lib/ /another_rootfs/var/lib/ +mount --bind /etc /another_rootfs/etc + +mkdir -p /another_rootfs/var/lib/isulad + +# 在chroot环境内创建并挂载dev、sys和cgroup文件系统 +mount -t devtmpfs devtmpfs /another_rootfs/dev/ +mount -t sysfs sysfs /another_rootfs/sys +mkdir -p /another_rootfs/sys/fs/cgroup +mount -t tmpfs tmpfs /another_rootfs/sys/fs/cgroup +list="perf_event freezer files net_cls,net_prio hugetlb pids rdma cpu,cpuacct memory devices blkio cpuset" +for i in $list +do + echo $i + mkdir -p /another_rootfs/sys/fs/cgroup/$i + mount -t cgroup cgroup -o rw,nosuid,nodev,noexec,relatime,$i /another_rootfs/sys/fs/cgroup/$i +done + +## common system dir +mount -t qtfs -o proc /proc /another_rootfs/proc +echo "proc" +mount -t qtfs /sys /another_rootfs/sys +echo "cgroup" + +# 挂载容器管理面所需要的共享目录 +mount -t qtfs /var/lib/docker/containers /another_rootfs/var/lib/docker/containers +mount -t qtfs /var/lib/docker/containerd /another_rootfs/var/lib/docker/containerd +mount -t qtfs /var/lib/docker/overlay2 /another_rootfs/var/lib/docker/overlay2 +mount -t qtfs /var/lib/docker/image /another_rootfs/var/lib/docker/image +mount -t qtfs /var/lib/docker/tmp /another_rootfs/var/lib/docker/tmp +mkdir -p /another_rootfs/run/containerd/io.containerd.runtime.v1.linux/ +mount -t qtfs /run/containerd/io.containerd.runtime.v1.linux/ /another_rootfs/run/containerd/io.containerd.runtime.v1.linux/ +mkdir -p /another_rootfs/var/run/docker/containerd +mount -t qtfs /var/run/docker/containerd /another_rootfs/var/run/docker/containerd +mount -t qtfs /var/lib/kubelet/pods /another_rootfs/var/lib/kubelet/pods +``` + +在/another_rootfs中,需要创建以下脚本,用来支持部分跨主机操作。 + +* /another_rootfs/usr/local/bin/containerd-shim + +``` shell +#!/bin/bash +CMD_NET_ADDR=tcp://<服务端ip>: /usr/bin/rexec /usr/bin/containerd-shim $* +``` + +* /another_rootfs/usr/local/bin/remote_kill + +``` shell +#!/bin/bash +CMD_NET_ADDR=tcp://<服务端ip>: /usr/bin/rexec /usr/bin/kill $* +``` + +* /another_rootfs/usr/sbin/modprobe +``` shell +#!/bin/bash +CMD_NET_ADDR=tcp://<服务端ip>: /usr/bin/rexec /usr/sbin/modprobe $* +``` + +在chroot到dockerd和containerd运行所需的rootfs后,用如下的命令拉起dockerd和containerd + +* containerd +``` shell +#!/bin/bash +SHIM_HOST=<服务端ip> containerd --config /var/run/docker/containerd/containerd.toml --address /var/run/containerd/containerd.sock +``` + +* dockerd +``` shell +#!/bin/bash +SHIM_HOST=<服务端ip> CMD_NET_ADDR=tcp://<服务端ip>: /usr/bin/dockerd --containerd /var/run/containerd/containerd.sock +``` + +* kubelet + +在chroot环境内使用原参数拉起kubelet即可。 + +因为我们已经将/var/run/和/another_rootfs/var/run/绑定在了一起,所以可以在正常的rootfs下,通过docker来访问docker.sock接口进行容器管理。 + +至此,完成容器管理面卸载到DPU,可以通过docker相关操作进行容器创建、删除等操作,也可以通过kubectl在当前节点进行pods调度和销毁,且实际容器业务进程运行在HOST侧。 + +> ![](./public_sys-resources/icon-note.gif)**说明**: +> +> 本指导所述操作只涉及容器管理面进程卸载,不包含容器网络和数据卷volume等卸载,如有相关需求,需要通过额外的网络或存储卸载能力支持。本指导支持不带网络和存储的容器跨节点拉起。 \ No newline at end of file -- 2.33.0