# FS-Distribution **Repository Path**: yanruinku/FS-distribution ## Basic Information - **Project Name**: FS-Distribution - **Description**: 基于容器的系统配置文件分发管理设计与实现 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-04-08 - **Last Updated**: 2023-06-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: Python, Docker, podman ## README # FS-Distribution ## 介绍 本仓库存储的是本人的毕业设计课题「基于容器的系统配置文件分发管理设计与实现」的相关代码 课题简介如下: > 云原生领域主要采用容器技术与容器编排技术实现业务发布、运维,与底层环境高度解耦。但是在该场景下, > 开发人员总会需要在服务器上对各个节点的底层运行环境进行维护,在经过许多次大大小小的修改后,各个 > 节点由于不同配置增加了开发人员管理维护的成本开销,因此带来了运维技术栈不统一、运维平台重复建设等问题。 > > 为解决该问题,本课题基于容器技术来实现业务与底层操作系统运维的一致性,利用容器技术完成文件系统的 > 统一分发与部署,对各个节点进行统一配置和修改,从而保证云原生场景下各个节点底层运行环境的一致性。 > > 功能模块: > > 1. 文件系统制作:制作可用于分发部署的linux文件系统 > 2. 系统镜像打包:利用容器技术对文件系统打包 > 3. 镜像分发:将容器镜像分发至各个运行节点 > 4. 系统配置文件部署:基于容器镜像将系统配置文件部署在各个运行节点 本项目使用 Docker 官方的SDK `Docker-Py` 进行镜像定制阶段的开发。使用 Podman 命令行作为镜像部署阶段的工具。 在开发初期,采用 Docker 的原因是作者本人之前对于 Docker 有较多的了解,且 Docker 提供了官方 SDK。这使得进行开发过程比较顺利。 但在了解了 Podman 之后,本人发现 Podman 相比于 Docker 有很多好处,比如不需要 root 用户的权限,下载镜像的保存位置与用户的目录 相关,访问比较随意等等。因此,本项目在后期会尝试完成基于 Podman 的镜像定制工具。这样可以方便不喜欢安装配置 Docker 的用户。 关于 Docker 的安装,可以参考[这个链接](https://yeasy.gitbook.io/docker_practice/install/ubuntu) ## 软件架构 软件主要包含三大部分: 1. 以 automate.py 作为入口点的「镜像定制」模块, 此部分需要在「**镜像制作端**」执行 2. 以 autodeploy.py 作为入口点的「镜像部署」模块, 此部分通过另外一个文件的SSH控制在「**镜像部署端**」执行 3. 以 ssh-autodeploy.py 作为入口点的「镜像部署」模块, 此部分一般在「**镜像制作端**」执行,控制 SSH 连接到「**镜像部署端**」执行 autodeploy.py 除了以上三个文件,其余文件的用途如下: - fileutils.py: 文件操作相关的工具函数, 是被 autodeploy.py 依赖的模块 - log.py: 日志模块, 用于记录程序运行过程中的日志, 同样是被 autodeploy.py 依赖的模块 - servers.json: 用于存储「镜像部署端」的信息, 以 JSON 格式存储, 由 ssh-autodeploy.py 读取, 批量对服务器进行部署操作 - running.log (程序运行时自动生成): 用于记录 automate.py, autodeploy.py 的运行日志(只记录本机上的运行日志) - ssh-running.log (程序运行时自动生成):用于记录 ssh-autodeploy.py 的运行日志(只记录本机上的运行日志) - .database: 里面存放了初始化的日志文件,用于记录部署过程中所有的操作日志,以及版本变更信息 - .database/status.log: 用于记录当前的部署状态,可以查看文件内容获取一些当前部署的信息,比如应用了哪一个diff文件夹中的变更, 变更包含哪些步骤。此文件的内容将在下一次部署时被更新。 - .database/last-oper.log: 用于记录上次部署的操作日志,可以查看文件内容获取上次部署的信息,比如应用(或者撤销)了哪一个diff文件夹中的变更, 变更包含哪些步骤。此文件中的内容将会在下一次部署时被覆盖。 - .database/operations.log: 用于记录从开始以来的全部部署日志。其中的信息来自于每次 last-oper.log 的内容。此文件中的内容将会在下一次部署时被追加。 - cmds(样例文件): 此目录中存放了 automate.py 进行镜像定制所需的「定制脚本」样例。有 txt 和 sh 文件两种格式 - todo.md: 用于记录项目的开发进度(并非从头开始记录,只是中途开始的) - README.md: 项目的说明文档 提示: automate.py 的运行会检测 Docker 的安装, 如果没有安装,程序会尝试自动安装。 autodeploy.py 的运行会检测 Podman 的安装, 如果没有安装, 程序同样会尝试自动安装 ## 安装教程 代码运行环境:`Ubuntu LTS 20.04` 及更高版本可稳定运行, 其他 Linux 环境需要手动处理 Docker, Podman 的安装问题 首先将此仓库clone到「镜像制作端」 安装 [`Docker-Py`](https://docker-py.readthedocs.io/en/stable/index.html),此模块是运行 automate.py 的必须; 安装 paramiko,此模块是运行 ssh-autodeploy.py 的必须 ```shell python3 -m pip install docker paramiko ``` 本项目需要「执行总控端」能够SSH登录到「被控制的部署端」, 请在`servers.json`中配置「被控制的部署端」的信息 如果使用私钥登录,则无需配置 password 字段. ## 使用说明 本项目中的三个主要python文件均使用 argparse 模块进行命令行参数的解析,因此可以通过 `python3 XX.py -h` 查看帮助信息 如果打开各个python文件,在每个文件头部,都有一些描述信息,可以参考。 下面是摘录的一些帮助信息 ```shell python3 automate.py -h 通过指定镜像启动容器, 将本地文件上传到容器中, 在容器中执行bash命令, 并将容器commit得到镜像, 最后推送到本地镜像仓库。 注意:有几点需要说明: 1. 如果没有安装docker, 会自动下载并安装docker 2. 如果执行此脚本的用户没有root权限, 会自动创建docker用户组, 并将当前用户加入docker用户组 3. 如果没有启动本地镜像仓库, 会自动启动本地镜像仓库 (通过提供-l来指定) 4. -i IMAGE 对应于 docker run 的参数 5. -o OUT_IMAGE, -a AUTHOR, -m MESSAGE 对应于 docker commit 的参数 6. -s SRC, -d DEST 对应于 docker cp 的参数 7. -c CMD, -u USER, -w WORKDIR 对应于 docker exec 的参数 options: -h, --help show this help message and exit -i IMAGE, --image IMAGE 用于启动容器的镜像名,格式为 <仓库名>:<标签>,如 docker.io/ubuntu:latest -o OUT_IMAGE, --out-image OUT_IMAGE 得到的镜像名,格式为 <仓库名>:<标签>,如 localhost:5000/ubuntu:v1.0 -s SRC, --src SRC 欲上传的本地文件路径,如 /home/xxx/xxx, 支持文件或目录, 必须与 -d 参数同时使用 -d DEST, --dest DEST 上传至容器内部的路径,如 /root/xxx/xxx, 必须与 -s 参数同时使用 -c COMMAND_FILE, --command-file COMMAND_FILE 欲在容器中执行的命令文件,可以是.txt或.sh文件 -u USER, --user USER 容器中执行命令的用户,如 root -w WORKDIR, --workdir WORKDIR 容器中执行命令的工作目录,如 /root -a AUTHOR, --author AUTHOR 镜像作者,如 xxx -m MESSAGE, --message MESSAGE 镜像描述信息,如 xxx -l, --local-registry 启动一个本地镜像存储库 Example: python3 automate.py -i ubuntu:20.04 -o localhost:5000/ubuntu:v1.0 \ -c cmd_file.sh \ -a 'HYR ' -m "My ubuntu image, version 1.0" \ -l ``` ```shell python3 ssh-autodeploy.py -h usage: ssh-autodeploy.py [-h] {init,deploy,undeploy,clear,purge} ... 使用SSH功能模块进行部署脚本的批量传输和批量运行 options: -h, --help show this help message and exit 子命令列表: {init,deploy,undeploy,clear,purge} init 初始化 servers.json 中各个服务器的日志仓库,上传部署过程依赖的脚本文件,仅仅需要执行一次! deploy 使用 servers.json 中的信息部署镜像,此过程中每个服务器记录自己的部署日志。 undeploy 撤销 servers.json 中所有服务器的部署,还原到部署前的状态。 clear 清除 servers.json 中每一台服务器上的部署日志,数据一旦清除无法找回!部署结果的撤销依赖日志数据库,所以请谨慎操作! purge 清除 servers.json 中所有服务器上因为部署而拉取的所有镜像。(不会影响已部署的结果,设计此选项仅为节省空间) ``` ```shell python3 ssh-autodeploy.py deploy -h usage: ssh-autodeploy.py deploy [-h] [--image IMAGE] [--target-dir TARGET_DIR] [--force] deploy 命令用于执行部署操作, 在服务器端执行部署脚本。 部署分为两种模式: 默认的自动模式以及使用 --force参数开启的强制模式。 使用后一种模式需要先仔细阅读用法信息(在此脚本文件的开始部分)。否则后果自负! options: -h, --help show this help message and exit --image IMAGE, -i IMAGE 如果未提供此选项, 部署时, 每个服务器使用的镜像将会从servers.json中读取。 如果提供了此选项, 所有服务器上部署的镜像将由此选项的值统一指定。 (If not provided, the images specified in servers.json for each server will be used to deploy. This argument is used to uniformly specify the image to be deployed in every server.) --target-dir TARGET_DIR, -t TARGET_DIR 部署操作的目标目录 (target dir), 默认为根目录 / --force, -f 指定使用强制部署 (force deploy)模式, 默认为自动部署 (auto deploy)模式 ``` ```shell python3 ./autodeploy.py -h usage: autodeploy.py [-h] [--interactive] [--quiet] {deploy,undeploy,info,clear,purge} ... 将指定镜像对应的文件系统部署在本机上, 或撤销部署 options: -h, --help show this help message and exit --interactive, -i 交互式操作 --quiet, -q 不输出冗余的信息,不进行过多提问 (quiet) 子命令列表: {deploy,undeploy,info,clear,purge} deploy 部署镜像并记录部署日志 undeploy 根据日志文件撤销部署 info 显示部署信息 clear 清除日志 purge 清除所有镜像 Example: python3 autodeploy.py deploy --image='localhost:5000/ubuntu:v4.0' --target-dir='~/test' ``` ```shell python3 ./autodeploy.py deploy -h usage: autodeploy.py deploy [-h] --image IMAGE [--target-dir TARGET_DIR] [--force] [--quiet] deploy 命令用于将镜像部署在本机上, 并记录部署日志。 部署分为两种模式: 默认的自动模式以及使用 -f 或 --force参数开启的强制模式。 使用后一种模式需要先仔细阅读用法信息(在脚本文件的开始部分)。否则后果自负! options: -h, --help show this help message and exit --image IMAGE, -i IMAGE 指定用于部署的镜像, 必选参数 (image to deploy) --target-dir TARGET_DIR, -t TARGET_DIR 部署操作的目标目录 (target dir), 默认为根目录 / --force, -f 指定使用强制部署 (force deploy)模式, 默认为自动部署 (auto deploy)模式 --quiet, -q 不输出冗余的信息,不进行过多提问 (quiet) Example: python3 autodeploy.py deploy --image='localhost:5000/ubuntu:v4.0' --target-dir='~/test' ``` ## 一个普通的流程 常见的场景如下: 1. 定制一个文件系统,采用镜像的方式保存 2. 将镜像部署在本机上,或者在多台服务器上部署 3. 部署完成后,可以撤销部署,也可以清除部署日志,或者清除所有镜像垃圾 4. 部署迭代升级,使用新的文件系统代替原来老旧的版本 ### 场景1 对于第一条需求,一般编写一个Shell脚本文件即可定制文件系统, 可以参考 `cmds/cmd_file.sh` 假设我们需要使用 `ubuntu:latest` 镜像定制一个文件系统,版本定为`v1.0`, 使用的脚本是`cmds/cmd_file.sh`. 我们可以使用如下命令: ```shell python3 automate.py --image='ubuntu:latest' -o 'localhost:5000/ubuntu:v1.0' -c 'cmds/cmd_file.sh' -l ``` 默认的参数有 --user=root, --workdir=/root. 如果需要将文件上传到容器内部,成为文件系统的一部分,可以通过指定 --src SRC 和 --dest DEST 参数来实现。例如: SRC 和 DEST 可以是文件或者目录,需要保证分别存在于本地和容器内部 注意的是,在使用之前,**最好先配置好私有镜像存储库**,这里推荐使用 Docker Registry 来作为私有镜像存储库 一行命令即可搞定: ```sh docker run -d -p 5000:5000 --restart=always --name registry registry ``` -l 参数就是用于自动执行上面这条命令的,如果不需要自动执行,可以不加 -l 参数。 注意端口号可能不一样。 ### 场景2 如果只是在本机部署,可以直接使用 `autodeploy.py` 脚本,例如: ```shell python3 autodeploy.py deploy --image='localhost:5000/ubuntu:v1.0' --target-dir='~/test' ``` 需要注意的是:**如果运行时不是以root用户身份**,必须保证当前用户具有改动 target-dir 目录的权限, 否则会报错 **permission denied**。 -------- 如果是在多台服务器上批量执行部署,可以使用 `ssh-autodeploy.py` 脚本,需要写好 `servers.json` 文件。 注意,在`deploy`之前,需要先`init`,把需要执行的脚本和日志样例文件传输到`servers.json`中指定的各个服务器上。 ```shell python3 ssh-autodeploy.py init ``` ```shell python3 ssh-autodeploy.py deploy --image='192.168.40.134:5000/ubuntu:v1.0' --target-dir='/' ``` 注意,这里不可以使用 `localhost`,因为这里是在远程服务器上执行部署操作, 需要指定在其他服务器上可以访问的「镜像存储库」的地址 ### 场景3 如果需要撤销部署,使用`undeploy`命令即可,命令行使用的帮助可以通过`-h`参数查看。 如果需要清除部署日志,使用`clear`命令即可,命令行使用的帮助可以通过`-h`参数查看。 如果需要清除所有镜像垃圾,使用`purge`命令即可,命令行使用的帮助可以通过`-h`参数查看。 ### 场景4 如果需要升级,继续使用`deploy`命令,只需要使用`--image`指定新版本的镜像。旧的部署将会依据日志文件自动撤销,然后执行新的部署。 命令行使用的帮助可以通过`-h`参数查看。 注意:新的部署和旧的部署的部署目录**必须是同一个**,不能在一个机器上同时进行多个部署,目前的日志存储库不支持多target-dir部署。 ## 如果运行出错了怎么办? 查看日志信息!日志信息!日志信息! 在运行过程中会产生大量的日志,包括 `running.log` 和 `ssh-running.log`,分别对应操作本机和管理服务器集群的日志。 在`.database`目录中的`.log`文件都是部署时更改详情的日志文件,可以通过查看日志文件来定位错误。 不过,一般情况下,如果出错了,终端会有提示的。同时 exit code 也会不为 0(使用 echo $? 查看).