containerd 如何配置 image-verifier 插件在拉取前拦截不符合策略的镜像
【免费下载链接】containerdAn open and reliable container runtime项目地址: https://gitcode.com/GitHub_Trending/co/containerd
如果你在运维一组 containerd 节点,不希望节点拉到来源不受控、不符合安全策略的镜像,可以在镜像拉取(pull)发生之前插入一道校验:containerd 的image-verifier插件(bindir实现)会在镜像被拉取前调用你放置在指定目录中的校验程序(verifier),任何一个 verifier 判定为“不通过”,该镜像的拉取就会被阻止。本文说明如何在 containerd 配置中启用该插件、校验程序需要遵循的接口约定,以及如何判断拦截是否生效。
在 containerd 配置中启用 image-verifier 插件
containerd 提供默认的bindir类型ImageVerifier插件。按 docs/image-verification.md 的说明,在 containerd 配置文件(TOML)中加入如下 stanza:
[plugins] [plugins."io.containerd.image-verifier.v1.bindir"] bin_dir = "/opt/containerd/image-verifier/bin" max_verifiers = 10 per_verifier_timeout = "10s"三个配置项的含义:
bin_dir:存放 verifier 可执行文件的目录。/opt/containerd/image-verifier/bin也是该插件在未显式配置时的默认路径,见 默认配置 和 默认路径。目录中若存在文件,全部文件都必须是符合下文 API 的 verifier 可执行文件。max_verifiers:限制被调用的 verifier 数量。bin_dir中的条目按名称字典序排序,只调用前max_verifiers个,其余跳过;设为负数则不限制数量。per_verifier_timeout:单个 verifier 的执行超时,文档示例为10s。
注意插件注册本身在 plugins/imageverifier/plugin.go 中完成(类型ImageVerifier、IDbindir),你只需要写配置,不需要额外编译或注册。
编写符合 API 的 verifier 程序
containerd 不提供现成的策略实现,策略逻辑由你自己编写的 verifier 程序承担。每个 verifier 必须遵循 文档规定的二进制 API:
命令行参数(containerd 调用时传入):
-name:本次可能被拉取的镜像引用(reference)。-digest:该镜像解析出的 digest。-stdin-media-type:stdin 中 JSON 数据的 media type。
标准输入:接收一段 JSON 编码的 OCI Content Descriptor(application/vnd.oci.descriptor.v1+json),描述本次可能被拉取的镜像。
判定方式:
- 向 stdout 打印一行判定理由(reason);
- 以退出码
0表示允许拉取,其他任意退出码表示阻止拉取。
仓库测试数据中有一个可直接参考的 verifier 示例(测试夹具,展示如何输出理由并以退出码1拒绝):
package main import ( "fmt" "os" ) func main() { fmt.Println("Reason D") os.Exit(1) }参见 reject_reason_d.go。对应的允许示例(打印Reason A并以退出码 0 结束)见 accept_reason_a.go。将你的程序编译为可执行文件后,放入bin_dir指向的目录即可,文件名即排序和日志中使用的 verifier 名。
判定组合规则与边界行为
配置好插件后,判断结果如何产生由 调用方契约 明确规定,这也是你验证配置是否生效的依据:
bin_dir不存在或目录中没有文件时,image verifier不阻止任何镜像拉取。这是排查“配置了插件却没有拦截”的第一步:确认目录存在且里面有 verifier 可执行文件。- 镜像只有在所有被调用的 verifier 都以退出码 0 返回时才会被拉取,即多个 verifier 的判定按
AND组合;任何一个返回非 0,拉取即被阻止。 - 任一 verifier 超过
per_verifier_timeout或 exec 失败时,校验以错误告终并返回nil判定(即不会放行)。 max_verifiers >= 0时超出数量的 verifier 被跳过,且 containerd 会输出警告日志;max_verifiers < 0时无数量限制。- 各 verifier 之间的执行顺序没有保证。
- verifier 的 stderr 由 containerd 以 debug 级别记录(可能被截断);stdout(判定理由)同样可能被截断,实现中截断上限为 32 KiB,见 bindir.go。
- verifier 进程占用的系统资源目前计入并受 containerd 自身 cgroup 约束,文档注明该行为可能变化。
验证拦截是否生效
按上述契约可以这样核对行为,全部依据文档给出的判定规则:
- 确认
bin_dir存在且包含你的 verifier 可执行文件。目录不存在或为空时拉取不会被阻止,属于预期行为而非故障。 - 用一个恒拒绝的 verifier(如上例,退出码
1)拉取任意镜像:拉取应被阻止,阻止原因形如verifier <名称> rejected image (exit code <码>): <reason>,其中<reason>即 verifier 打印到 stdout 的内容,见 拒绝逻辑。 - 用恒通过的 verifier(退出码
0)拉取镜像:拉取正常进行,判定理由形如<名称> => <reason>(多个 verifier 时以逗号拼接各程序的结果)。 - 需要查看 verifier 的 stderr 细节时,将 containerd 日志调到 debug 级别;stdout/stderr 超限部分会被截断,属预期行为。
限制与说明
- containerd 仓库只定义了 verifier 接口与调度逻辑,不提供任何具体策略实现;“不符合策略”的判定标准完全由你编写的 verifier 程序决定。
- 本文涉及的行为均以 docs/image-verification.md 的契约说明为准;verifier 的资源约束(cgroup 计入)等条目文档明确标注“subject to change”,升级 containerd 后应重新核对。
【免费下载链接】containerdAn open and reliable container runtime项目地址: https://gitcode.com/GitHub_Trending/co/containerd
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考