# Gear-image **Repository Path**: gotgyu/gear-image ## Basic Information - **Project Name**: Gear-image - **Description**: Gear以细粒度文件索引替代传统镜像层级组织方式的新思路,打破了传统镜像部署时层级拉取的固有模式,通过构建镜像文件元数据索引系统,实现了在运行时初始化阶段仅按需加载关键启动文件,其余部分在运行过程中动态加载,有效避免不必要的镜像数据下载。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 4 - **Created**: 2025-04-30 - **Last Updated**: 2025-04-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Gear-image ## gear build 由 docker image 构建 gear image 将原始镜像中普通文件替换为 hashvalue 与其他文件一起压缩一个tmp.tar,再使用原生 docker build 形成单层镜像 ### 实现 - InitBuilder - 分析出镜像名与tag - docker cli inspect 获取镜像信息 - 创建构建目录 /var/lib/gear/build/IP:5000/ubuntu-gear:latest/下的 files 与 build 目录 - 获取原始镜像upperdir id - Build - recordfiles 两个参数为nil - tarAndCopy: - 使用overlay2获取id对于的镜像层挂载信息 - 在gear image的build目录(init时创建)创建tmp.tar - `在mergeddir创建gear-image软链接指向当前gear镜像名:tag` - 遍历merged文件夹, - 如果是普通文件,生成文件内容hash值,在files文件夹创建以hash值为名的普通文件,将普通文件内容写入该hash文件,修改hash文件权限为原始文件权限;并将文件内容替换为hash,加入tmp.tar - 否则,不需压缩直接加入 - createDocekrfile: 根据原dockerfile构建一个新docerfile,并加入 add tmp.tar 命令,Dockerfile写入Build目录 - buildGearImage: - 打包Dockerfile与tmp.tar,构建Dockerfile,生成 gear 镜像 ## gear push 负责把 镜像文件(files文件夹) 同步到存储库(请求发送给manager),不负责push gear镜像 ## gear monitor 监控 registry 转换镜像 还包括一个服务器,处理 event (依赖于 manager,gear push 需要manager ip) 在 /var/lib/gear/ 下构建 ### docker /var/lib/docker/overlay2 目录 镜像层/init层(存放hostname /etc/hosts 等文件)/读写层都在这个文件夹 /var/lib/docker/overlay2/xxxx/ link普通文件 存放当前层软链接名字 /var/lib/docker/overlay2/xxxx/ lower普通文件 存放下一层软链接名字,如果当前层为最底层则不存在该文件 /var/lib/docker/overlay2/xxxx/ diff 文件夹 存放当前层文件 /var/lib/docker/overlay2/l 下都是软链接,指向 /var/lib/docker/overlay2/xxx/diff/ 目录 /var/lib/docker/image/overlay2/imagedb/content/sha256/ 存放镜像metadata,以镜像ID命名的普通文件 ### 实现(Monitor函数) - 启动服务器 - 获取待处理镜像以及tag,过滤转换过的镜像(通过gear后缀) - Image Pull下载原始镜像 - 调用 build 模块执行构建 - push 转换后的镜像到 registry ## gear manager 启动一个服务器,处理这些请求: ``` e.GET("/nodes", handleNodes) e.POST("/join/:IP/:Port", handleJoin) e.POST("/pull/:CID", handlePull) e.POST("/query/:CID", handleQuery) e.POST("/push/:CID", handlePush) e.POST("/prefetch", handlePreFetch) ``` ## gear graphdriver 给docker提供调用接口 会调用 gear fs download image 时调用 ApplyDiff,会生成 gear-diff目录(原diff目录变为空),生成gear-lower链接,并删除原始lower,创建gear-work文件夹 ### 一些文件 gear-lower:软链接,容器层目录中的直接指向底层镜像 gear-image:软链接,容器目录中的指向镜像名 ### 实现 [docker graphdriver 协议](https://docs.docker.com/engine/extend/plugins_graphdriver/) - Create 作用:为镜像层创建目录 - 直接基于overlay2 Create,docker镜像和gear镜像可以公用 - CreateReadWrite 作用:创建读写层 - 先调用overlay2 CreateReadWrite - 判断parent目录是否存在 gear-lower,如果存在表示为gear镜像,给当前读写层添加gear-lower软链接,与parent gear-lower 相同,指向gear单层镜像; - lower 文件添加 gear-work - Remove 作用:删除id目录(层) - 直接调用overlay2 Remove - Get 作用:获取ID指定的挂载点,绝对路径 - 不存在gear-lower则直接调用overlay2的Get - 否则检测是否有lower,有表明是gear容器目录:查找gear-diff的gear-image指向的镜像名,从而获取对应私有文件缓存目录;挂载 gear fs,挂载 gear-lower 指向的(父层)diff ,本目录是Upper. 第一次挂载则启动fs,否则引用加一。 - StartAndNotify:imagePath是镜像路径+gear-diff,upperPath是当前目录的diff,mountPoint是镜像的diff目录,initlayer 是镜像的gear-work目录 - 否则? - 调用 overlay2 Get. - Put 作用:卸载ID对应的挂载 - 调用 overlay2 Put - 检查当前ID目录是否有Gear-lower,有需要卸载gear-lower指向的目录的diff目录挂载点(fuse) - Exists 作用:判断ID层是否存在 - 直接判断graphdirver是否有对应目录 - Status 作用:获取graphdriver信息 - GetMetadata 作用:获取id对应的层信息,lowdir/upperdir merge work - 直接调用overlay2 GetMetadata - Cleanup 作用:卸载graphdriver - 直接卸载 graphdirver 主目录 - Diff - Changes - ApplyDiff 作用:docker pull 存放镜像层 - 直接将数据解压到graphdriver diff 目录 - 检测diff目录是否存在gear-image,存在表示是gear镜像,不是直接返回 - 是gear镜像,`将diff重命名为gear-diff`, - `创建gear-lower指向自己id目录` - 删除原 lower 文件? - 创建diff文件夹 - 创建 gear-work 文件夹 - 对于gear镜像,数据在gear-diff目录,存在gear-image软连接,创建gear-lower软链接指向本目录 # 使用方法 依赖: go 1.11 docker 18.09.6 0、三个节点,node1为 registry节点;node2为 monitor节点;node3为 client 1、在 node1 启动 register ``` sudo docker run -d --rm --name=registry --restart=always -p 5000:5000 -v /var/lib/registry:/var/lib/registry registry ``` 2、在node2 node3上,修改docker daemon.json ip为node1 ``` { "insecure-registries":["192.168.203.129:5000"] } ``` 3、在 node1 启动 manager ``` sudo ./gear manager ``` 4、在 node2 启动 monitor,需要manager ip, registryip (均为node1 ip) ``` sudo ./gear monitor --manager-ip=192.168.203.129 192.168.203.129:5000 ``` 5、在 node3 启动 gear graphdriver (保证已经修改 daemon.json,dockerd已经停掉) ``` sudo ./gear graphdriver --manager-ip 192.168.203.129 --monitor-ip 192.168.203.130 ``` 6、在 node3 启动dockerd: ``` dockerd --experimental -s geargraphdriver ``` 7、从 node2/node3 推送普通镜像到 registry,monitor会自动转换成gear镜像,在node3上运行gear镜像即可