文|余硕
上海交通大学22届毕业生阿里云开发工程师
从事云原生底层体系的开发和探究作业。
本文 6369 字 阅览16 分钟
GitLink 编程夏令营是在 CCF 我国计算机学会辅导下,由 CCF 开源开展委员会(CCF ODC)举行的面向全国高校学生的暑期编程活动。
这是今年的夏令营活动中,余硕同学参加 Nydus 开源项意图总结,首要介绍了 Nydus 为支撑镜像扫描与修正所做的研讨与相关作业。
PART. 1 课题布景
Nydus 开源镜像加快结构
Nydus 是 CNCF 孵化项目 Dragonfly 的子项目,它供给了容器镜像,代码包按需加载的才能。Nydus 使用时无需等候全部数据下载完结便可开始服务。
Nydus 在出产环境中现已支撑了每日百万级别的加快镜像容器创立。它在容器发动性能、镜像空间占用、网络带宽功率、端到端数据一致性等方面比较 OCI v1 格局有着巨大优势,并可扩展至其它数据分发场景,比方 NPM 包懒加载等。
现在 Nydus 由蚂蚁集团、阿里云、字节跳动联合开发。Containerd、Podman 社区现已接受了 Nydus 运转时作为其社区子项目,它也是 Kata Containers 以及 Linux v5.19 内核态原生支撑的镜像加快计划。
有关 Nydus 镜像加快开源项意图详细介绍,能够参阅:Nydus——下一代容器镜像的探究实践。
项目描绘
为 Nydus 镜像增加一个扫描和修正的指令行东西,包括以下功用:
-
供给一个 Nydus 镜像 url 和需求替换的文件列表;
-
运用东西拉取镜像 Bootstrap;
-
找到镜像中对应的文件并替换;
-
打包成新的镜像并上传回 Registry。
归纳来说,原有项目方针是为 Nydus 镜像完结一个扫描和修正的指令行东西,其间这些功用是这个东西或许东西组的完结流程。
但此项目具有一定的实验性,其间心是为 Nydus 格局的镜像供给扫描和修正的功用或许指引。假如存在更好的办法,项目终究纷歧定要依照原有项目描绘去完结。因而在接下来的课题完结进程中,咱们首先对已有镜像扫描/修正的东西与服务进行了调研,来确认此课题计划的终究形态。
镜像扫描东西及服务
扫描和修正
镜像扫描和修正能够被拆解为两个进程。扫描不更改原有的镜像内容,只需求寻找扫描方针是否存在某种缺陷;镜像修正则需求依据缺陷改动镜像,包括但不限于镜像内容,镜像层级安排等。咱们调研发现,当时主流开源镜像扫描引擎包括云厂商镜像安全服务都只触及镜像扫描的功用, 不会主动增加镜像修正的功用。
咱们剖析首要的原因有:
-
直接进行镜像修正或许引进新的安全问题;
-
镜像扫描的内容存在不同品种,很或许需求为不同品种的镜像安全问题设计不同的修正办法;
-
镜像修正功用能够经过从头打包镜像代替。
所以,镜像安全服务暂时只是供给扫描成果的安全陈述,详细的修正操作由用户自行决定。咱们也准备沿用这样的思路:在本课题中,为镜像完结安全扫描的功用,并供给陈述作为用户镜像修正的参阅依据。
咱们也探究评论了镜像修正的支撑,或许 Nydus 特性在镜像修正场景下的增强,比方镜像内包替换后的去重与重组等,或许这些能够是未来 Nydus 中增加的功用特性。
镜像扫描介绍
镜像扫描的原因与内容
容器镜像是当时容器/软件分发的根底,里面包括了容器隔离环境以及软件履行环境的相关内容。因而确保其安全性变得十分重要。镜像扫描即是要扫描镜像中的一切内容,及时发现或许包括的安全漏洞或许隐私泄露。
综合来看,镜像扫描需求关注镜像的安全性与健壮性,扫描的内容首要分为三类:
1. 安全漏洞。 包括体系软件包和使用软件库中或许存在的安全漏洞。能够经过比对镜像中这些库/软件包的来历、版本等与 CVE 数据库中陈述的漏洞的包的来历、版本来定位或许存在的安全漏洞。
2. 装备。 包括镜像运转的环境装备和镜像中相关内容组合或许带来的问题。协助尽早定位装备过错以及装备过错或许带来的安全风险。
3. 隐私。 需求扫描的是用户指定的一些隐私信息。比方用户不小心将密钥等信息存入镜像。假如在扫描装备中进行指定,扫描进程或许发现这些隐私信息,防止隐私泄露以及或许带来的安全问题。
扫描引擎
常见的扫描引擎有 Trivy、Synk 等。Docker 官方运用的是 Synk,但它比较商业化;Trivy 是 CNCF 的项目,开放性较好。
镜像扫描的运用办法
在咱们的调研中,镜像扫描首要使用办法有三种:
1. 根底运用。 镜像扫描的进程能够直接经过集成了镜像扫描引擎的容器运转时或许镜像扫描引擎指令行触发。比方运转$ docker scan image-url
,能够扫描镜像,并输出相应的陈述。
source:docs.docker.com/engine/scan…
2. 流程集成。 镜像扫描的进程能够集成到镜像中心或许 CI/CD 流程中。比方将镜像扫描集成到数据中心,在每次镜像上传到数据中心时触发镜像扫描,能够确保从数据中心下载的镜像总是经过安全扫描的;集成在 CI/CD 流程中,设置触发条件,能够确保镜像生成,镜像部署等进程所运用的镜像的安全性。
source:www.containiq.com/post/contai…
3. 扫描服务。 云厂商供给了镜像安全的服务。它们背后或许是基于前两种运用办法完结,可是还能够有许多种功用的增强。用户想运用镜像扫描的功用也能够直接购买相似的安全服务,并进行灵敏的装备。
source:cloud.google.com/container-a…
PART. 2 课题处理思路
根本思路
课题首先要处理的根本思路是,如项目描绘一般为 Nydus 完结一个专属的镜像扫描东西;仍是复用已有的镜像扫描引擎,在 Nydus 侧完结对接支撑,然后完结 Nydus 镜像扫描的功用完结。
咱们终究挑选了结合已有镜像扫描引擎的完结思路。虽然为 Nydus 完结一个专属的镜像扫描东西能够更好的运用 Nydus 的特性,可是从镜像功用生态上考虑,这并不是一个很好的办法。复用或许集成到现有的镜像扫描东西,一方面能够直接运用已完结的镜像扫描引擎中全面的内容扫描才能;另一方面,与上层镜像安全服务的对接也不用再重写相关接口。这样也能够削减一些功用定制,削减用户运用的负担。因而此课题挑选了后一种完结的根本思路。
扫描思路:FileSystem vs Image
Trivy 扫描功用完结的结构
1. 操控途径。
Trivy 在镜像扫描上由以下途径操控,每触发一次指令,会由一个 Scanner 操控。其间要害的是artifact
和driver
。扫描引擎一般能够支撑多种格局的扫描,比方 OCI v1 镜像或许镜像 Rootfs,同时一般也支撑本地或许远端存储信息等。这些一般可由ScannerConfig
装备或许主动解析。
atifact
存储着镜像 (包括文件体系) 元信息,假如现已扫描过其间的内容,还能够存储部分解析后的信息。别的,load 到本地的 CVE 数据等也可经过 Artifact 获取。Driver 里的 Scan 办法表示的则是使用在特定扫描进程中的查看办法。
2. 要害动作。
-
local.Scanner
-
Applier
Trivy 中 Local Scanner 是前文说到的本地进行扫描的操控结构。能够看出 Scanner 里界说的行为是 Apply Layer。也便是将对镜像逐层进行扫描。Applier 保存了 Artifact 信息,是联络详细扫描办法和存储信息的结构体。
3. 解析镜像。
上述两个进程理解了整体 Scan 的进程操控,以及详细针对镜像的扫描办法。与镜像相关的还有一个要害进程是如何针对性的解析扫描镜像信息。这一进程完结在 Artifact 中。
- Artifact
- Walker-Analyzer
Artifact 中有镜像元信息,还有保存解析镜像信息的 Cache 等。首要要考虑的是当时 Trivy 支撑的不同品种镜像而进行不同的设置。
另一要害的是 Analyzer。Analyzer 对应的是镜像分层的操作。对不同品种的镜像操作不同。比方关于 OCI v1 的镜像,或许便是每层镜像拉取的完整数据流进行剖析。关于 FileSystem,便是层次遍历文件树。
计划挑选
了解了 Trivy 的完结后,咱们发现直接把 Nydus 打包成 OCI v1 相似的镜像去扫描并不合适。Nydus 镜像内容中层次安排现已发生了改变,也具有按需加载的特点。若直接拉取,纷歧定确保拉取信息的齐备,想要齐备支撑镜像的拉取也会丢掉 Nydus 的特性。
因而咱们终究挑选在 FS Artifact 办法下优先拓宽 Nydus 的镜像扫描才能。
相关的指令是:
$trivy image nydus-image-url ✗
$trivy fs /path/to/nydus_imgae_mountpoint ✓
这样做的好处一是能够运用 Nydus 按需加载的特性。咱们发现关于许多软件包的扫描并不需求完整的文件内容的下载,许多时分一些部分信息甚至元信息即可判别。这一特点能够运用上 Nydus 的按需加载,然后加快整个镜像扫描的进程。二是特殊格局的镜像都会有挂载文件体系这一操作。这样的办法能够推广到更多的特殊格局镜像。
本课题终究是以东西办法为 Nydus 集成了加快镜像文件体系挂载的才能,这能够适配主流的镜像扫描结构,未来咱们能够考虑为社区镜像扫描计划做更深度的集成,比方 Trivy、Clair、Anchore Engine 等,支撑直接指定 Nydus 镜像 Reference 做扫描,优化端到端的用户领会。
计划完结
在 Nydus 侧供给镜像扫描的支撑,简单指令进程为:
$ nydusify view localhost:5000/ubuntu:latest-nydus
/path/to/root_path
[比起容器简单,直接拿到文件树]
$ trivy fs /path/to/rootpath
Nydusify 是 Nydus 供给的镜像转化,校验与镜像文件体系挂载东西,运用办法能够参阅:github.com/dragonflyos…。
上面完结在 Nydusify 中的中心功用由FileSystemViewer
结构体操控:
此结构体需求保存的成员变量有此进程的一些输入信息和装备信息。SourceParser
用于解析镜像 url。MountPath
是能够指定的文件体系 Mount 的地址。NydusdConfig
是 Mount 进程 Nydus Daemon 的装备。image-url
是有必要供给的输入信息。View()
是调用办法。
当nydusify view
被调用时,首要将发生三个步骤:
-
解析
image-url
; -
依据解析信息,拉取文件体系元数据 Bootstrap;
-
依据 Bootstrap,Nydusd Mount 文件体系到指定途径。
之后trivy fs
被调用时,或许发生:
-
层次遍历挂载的文件体系;
-
打开镜像挂载点中某个文件时,会触发 FUSE 恳求到 Nydus Daemon (Nydusd) ,Nydusd 会从远端镜像中心按需拉取文件的 Chunk 数据,以供给给扫描引擎剖析文件内容。
PART. 3 课题展现
Demo 展现
咱们完结了这一功用,如 demo 中演示:
性能测验
咱们在 Ubuntu、Wordpress、Tensorflow 等镜像上进行了测验。
测验成果如下:
以扫描时延作为衡量标准,能够看出 Nydus 的安全扫描时间要显著少于根本 OCI v1 镜像。这其间优化的幅度与镜像文件体系复杂程度,测验网络环境等因素有关。
咱们还从实践镜像扫描场景了解到,许多时分出现安全问题时,例如一些 0day 漏洞,咱们需求对大批量镜像进行特定的少量文件元数据或数据的侦测。这种状况就更能体现出 Nydus 镜像懒加载的优势,安全扫描速度能够大幅度进步。
当然,Trivy 对 OCI v1 镜像的扫描优化会影响比照成果。咱们 Trivy Image 屡次对同一镜像进行扫描,可得到下面的成果:
能够看出,屡次扫描之后花费的时延下降。如之前说到,扫描信息匹配会存到 local Cache 中。这是会依据 Blob ID 做为 key 来存储的。因而 Trivy 在扫描同一镜像时能够直接去查询 Cache 而不用重复拉取镜像构成优化。咱们在未来也想集成相似的优化,这也是之后咱们也想在扫描引擎社区推进更好的支撑的原因。
PART. 4 课题拓宽
描绘
除了扫描镜像内容的安全性,Nydus 本身供给了指令东西nydus-image inspect
对 Nydus 镜像进行查看。nydus-image inspect
指令经过检索 Nydus 镜像中包括的文件体系元数据信息,能够查看 Nydus 镜像的安排状况。进一步能够判别 Nydus 镜像是否损坏等。
随着 Nydus 的开展,它支撑文件体系 Layout 也从 v5 扩展到 v6。RAFS v6 能够兼容 EROFS,由此获得性能上的进一步提高。nydus-image inspect
在 RAFS v5 时现已设计,扩展到 RAFS v6 之后,一些子指令为了兼容进行了扩展。可是这样的扩展是为 v5/v6 分开写成的,也便是需求履行子指令时还需求对文件体系格局进行一次判别。
此外,还有一些子指令没有做到兼容性扩展。这样的不完全支撑存在一定的遗留问题,没有做到功用的齐备和一致。这样的代码安排也丢失了易读性,不利于后续的维护,不同 RAFS 格局相关功用的迭代升级中也比较容易发生问题。
事实上,Nydus 现已为这两种格局的文件体系元数据完结了一致的 API 接口。
比方对RafsSuperInodes
,RafsSuperBlock
等结构有一致的办法进行信息的获取,对不同的底层完结进行了屏蔽。因而在此根底之上,有必要对nydus-image inspect
指令的相关功用进行一次重构。
完结
原有的架构中,存在一个Executor
结构依据子指令判别调用哪一个详细的办法。比方Executor
收到子指令 stats 时会调用 cmd_stats 函数,履行并完结成果的输出显示。
咱们需求重构的是针对每一便条指令所调用的办法,上层的调用逻辑保持不变,详细而言子指令办法有:
-
cmd_stats
-
cmd_list_dir
-
cmd_change_dir
-
cmd_stat_file
-
cmd_list_blobs
-
cmd_list_prefetch
-
cmd_show_chunk
-
cmd_check_inode
这里不再对每一便条指令调用办法的修正进行详细描绘。大约做法是运用 RAFS mod 中一致的 API 完结一切本来的功用逻辑。
测验
咱们完结了两种测验。两种测验的意图都是为了保持重构前后功用完结的一致。
测验一: 交互办法比对输出成果。
这是一种功用测验。针对每条指令每种或许出现的状况,选取代表性镜像进行测验与比对。
测验二: 集成冒烟测验。
这是一项冒烟测验。nydus-image inspect
指令还有request mode
能够将一便条指令的输出序列化成 json 格局的成果。咱们将原有代码的成果序列化成 json 格局作为参阅输出,再将重构后代码的输出与之一一比对。选取的镜像为 Nydus 仓库中用于冒烟测验的镜像。这一部分的测验也集成在 Nydus 仓库中,在今后的 CI 里也能够确保这项功用的正确性没被破坏。
成果
Prompt Mode
Stats
ls
Cd
Stat File
Blobs
Prefetch
Chunk Offset
Icheck Index
Request Mode
Stats
Prefetch
Blobs
PART. 5 收益与展望
收益
我非常荣幸能参加这次项意图开发,也要向项目安排老师赵新、项目辅导助理姚胤楠、严松老师以及 Nydus 社区表示衷心的感谢。
经过这次项意图开发,我收成了许多:知识上,我复习并更深入了解了文件体系,学习了容器镜像格局的安排,还初次尝试了 Go 语言开发,也开始了解软件测验;技能上,我锻炼了协调时间,开放评论,问题定位的才能。
更重要的是,我认为参加这次项目增加了我对容器场景使用的见识,也提高完整处理计划与体系设计的才能。当然,或许最大的收益是收成了一次高兴的领会!领会了开源合作的高兴,也领会到了开源价值发生的高兴。
展望
此次项目首要是为 Nydus 增加了镜像扫描功用的支撑,别的重构了 Nydus 的 Inspect 剖析东西。如前文所说,后续还要继续探究 Nydus 镜像扫描集成到扫描引擎的办法,镜像扫描和修正的优化也值得探究。关于 Nydus 镜像格局细节,用户态文件体系,EROFS 等,我还有许多需求学习。
希望能一直参加社区,不断丰富自己容器存储方面的知识,同时也能为社区做出更大的贡献。
了解更多…
Nydus Star 一下✨:
github.com/dragonflyos…
本周推荐阅览
Nydus —— 下一代容器镜像的探究实践
Nydus 镜像加快插件迁入 Containerd 旗下
Nydus | 容器镜像根底
Dragonfly 和 Nydus Mirror 模式集成实践