The change in patches: 1. Fix cache issue when recreate file 2. Introduce CMAKE to build userspace apps 3. CleanCode Signed-off-by: Weifeng Su <suweifeng1@huawei.com>
326 lines
18 KiB
Diff
326 lines
18 KiB
Diff
From 67b7259d810c9e07227e7a1475acdc1141e4424e Mon Sep 17 00:00:00 2001
|
||
From: Weifeng Su <suweifeng1@huawei.com>
|
||
Date: Thu, 8 Jun 2023 14:17:00 +0000
|
||
Subject: Keep doc same with docs in openEuler
|
||
|
||
Signed-off-by: Weifeng Su <suweifeng1@huawei.com>
|
||
---
|
||
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**: 客户端内核模块相关代码,直接在该目录下编译客户端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无感卸载架构
|
||
+
|
||
+
|
||
+
|
||
+如图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)
|
||
+
|
||
+> **说明**:
|
||
+>
|
||
+> 上述操作指导涉及对容器管理面组件的少量改动和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 @@
|
||
+
|
||
+# 容器管理面无感卸载部署指导
|
||
+
|
||
+> **说明**:
|
||
+>
|
||
+> 本指导涉及对容器管理面组件的少量改动和rexec工具修改,这些修改基于指定版本,其他版本可基于实际执行环境做适配修改。文档中提供的patch仅供验证指导使用,不具备实际商用的条件。
|
||
+
|
||
+> **说明**:
|
||
+>
|
||
+> 当前共享文件系统之间通信通过网络完成,可通过网络互连的两台物理机器或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端口号> 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>:<rexec端口号> /usr/bin/rexec /usr/bin/containerd-shim $*
|
||
+```
|
||
+
|
||
+* /another_rootfs/usr/local/bin/remote_kill
|
||
+
|
||
+``` shell
|
||
+#!/bin/bash
|
||
+CMD_NET_ADDR=tcp://<服务端ip>:<rexec端口号> /usr/bin/rexec /usr/bin/kill $*
|
||
+```
|
||
+
|
||
+* /another_rootfs/usr/sbin/modprobe
|
||
+``` shell
|
||
+#!/bin/bash
|
||
+CMD_NET_ADDR=tcp://<服务端ip>:<rexec端口号> /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>:<rexec端口号> /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侧。
|
||
+
|
||
+> **说明**:
|
||
+>
|
||
+> 本指导所述操作只涉及容器管理面进程卸载,不包含容器网络和数据卷volume等卸载,如有相关需求,需要通过额外的网络或存储卸载能力支持。本指导支持不带网络和存储的容器跨节点拉起。
|
||
\ No newline at end of file
|
||
--
|
||
2.33.0
|
||
|