资讯详情

用自定义 CRI-O 构建复现 Kubernetes node e2e 测试:GCP VM + Ignition 全流程实战

📅 2026/10/12 5:21:44 | 华诺云谱 👁 阅读
用自定义 CRI-O 构建复现 Kubernetes node e2e 测试:GCP VM + Ignition 全流程实战
云原生容器运行时【免费下载链接】cri-oOpen Container Initiative-based implementation of Kubernetes Container Runtime Interface项目地址https://gitcode.com/gh_mirrors/cr/cri-o点击查看免费下载导读Kubernetes 官方 CI 中有一类以 CRI-O 作为容器运行时CRI的 node e2e 测试它们通常跑在云上的临时节点上本地难以直接复现失败场景。本文基于 CRI-O 仓库 contrib/custom-node-e2e 目录下的工具链完整讲解如何在本地构建自定义 CRI-O 产物、上传到 GCS、生成 Fedora CoreOSFCOS可消费的 Ignition 配置并在 GCP VM 上复现与 CI 等价的 node e2e 测试环境。读完本文你将掌握create-ignition-config.sh与upload-artifacts.sh的每个参数、每步内部行为以及如何注入自定义 CRI-O 配置用于测试调试。一、这套工具要解决什么问题Kubernetes node e2e 测试e2e node tests是覆盖节点侧行为kubelet、容器运行时、网络、存储等的一组端到端测试。在 k8s 官方 CI 中有一类任务以 CRI-O 作为 CRI 运行这些测试CI 会临时创建 GCP 虚拟机机器启动后消费一份 Ignition 配置安装指定版本的 CRI-O再在其上执行 node e2e 测试。CRI-O 开发者经常遇到的痛点在于CI 上测试失败后本地难以复现——本地环境与 CI 的 Fedora CoreOS 节点、内核参数、SELinux 策略、CRI-O 构建方式都不一致。contrib/custom-node-e2e/README.md 给出的方案是把“CI 的那套行为”在本地完整重演一遍。核心思路分为三步本地构建在开发者自己的机器上构建自定义 CRI-O含静态二进制与安装包 bundle上传分发把安装 bundle 上传到用户指定的 GCS bucket远程复现创建 GCP 实例用生成的 Ignition 配置引导 Fedora CoreOS 安装这份自定义 CRI-O随后即可按 kubernetes 社区文档中的“remote”方式对实例运行 node e2e 测试。这套流程正是 CRI-O 开发者在本地复现并调试 node e2e 失败场景的推荐手段它复用了官方 CItest-infra 中jobs/e2e_node/crio同一套实例镜像与安装路径因此测试行为高度接近线上。二、工具链组成与整体工作流该目录下共有三个文件职责划分非常清晰文件职责create-ignition-config.sh主脚本构建 CRI-O、生成安装脚本与 Ignition 配置upload-artifacts.sh辅助脚本把 bundle 与版本标记上传到 GCSREADME.md使用说明本文所依据的文档整体数据流如下本地源码树 (CRIO_DIR) │ make clean / bin/pinns / build-static / docs / crio.conf / bundle ▼ build/bundle/cri-o.ARCH.SHA.tar.gz │ upload-artifacts.shgsutil 上传 写 latest-branch.txt 标记 ▼ gs://BUCKET/artifacts/*.tar.gz gs://BUCKET/latest-branch.txt │ ▼ node_e2e_installer-RAND_ID.sh生成并上传安装脚本 │ ▼ RAND_ID.ign Ignition 3.3.0 配置输出到 IGNITION_OUT_DIR │ ▼ GCP 实例创建 → Fedora CoreOS 消费 ignition → 安装自定义 CRI-O → 运行 node e2e从脚本实现看create-ignition-config.sh主脚本在parse_args校验完参数后会先cd $CRIO_DIR进入源码树依次执行构建、上传、SHA 校验、安装脚本生成、Ignition 生成五个阶段我们逐一展开。三、环境与前置准备运行这套工具前需要准备CRI-O 源码树一个可构建的本地 checkout即-d指向的目录构建过程会使用sudo -E make需要 sudo 权限GCS bucket名称合法、账号具备上传权限并且已配置公开读访问实例启动后需要从公网拉取 bundle。bucket 也可被gsutil直接访问环境需安装gcloud/gsutil认证两种方式任选——通过-s传入 GCP service account JSON 文件或让本机gcloud已正确登录若两者都无upload-artifacts.sh会直接失败构建依赖脚本内部会调用仓库顶层 Makefile 中的目标。其中build-static依赖 nix 构建环境Makefile 中通过容器运行nix build产出静态二进制因此需要可用的容器运行时与网络。四、命令行参数详解脚本用法与 README 完全一致./create-ignition-config.sh -d CRIO_DIR -i IGNITION_OUT_DIR -b GCS_BUCKET_NAME [ -s GCS_SA_PATH ] [ -e EXTRA_CONFIG_PATH ] [ -h ]必选参数参数含义说明-d CRIO_DIRCRI-O 源码路径脚本会cd进入该目录执行构建必须存在且可写-i IGNITION_OUT_DIRIgnition 配置输出目录生成的.ign文件写入该目录文件名带随机 ID-b GCS_BUCKET_NAMEGCS bucket 名称用于上传 bundle、安装脚本与版本标记文件需要公开读权限可选参数参数含义说明-s GCS_SA_PATHGCP service account 文件路径传入时upload-artifacts.sh会执行gcloud auth activate-service-account不传则使用现有gcloud凭据-e EXTRA_CONFIG_PATH附加 CRI-O 配置目录目录内所有文件递归查找会被嵌入安装脚本逐一生成为/etc/crio/crio.conf.d/40.conf-h显示帮助打印参数说明后退出退出码 0参数解析由 parse_args 完成getopts逐项读取随后required_arg_check对三个必选参数做空值校验缺失任一即报错退出退出码 1。注意-e若未指定脚本中EXTRA_CONFIG_PATH为空后续find 相关分支不会执行——即不注入额外配置。五、构建阶段从源码到安装 bundle构建阶段由主脚本 L72-L98 驱动顺序敏感sudo -E make clean清理历史产物保证构建从干净状态开始make bin/pinns构建 pinns 工具。在 Makefile 中该目标委派给pinns/子目录$(MAKE) -C pinnspinns 用于创建/加入命名空间是 CRI-O 沙箱基础设施之一sudo -E make build-static产出静态二进制。依据 Makefile该目标通过容器运行nix build并将结果复制为bin/static产物不依赖宿主动态库便于分发到 Fedora CoreOS架构判定脚本用uname -m判定本地架构并映射为 CRI-O 的命名规范——x86_64→amd64aarch64→arm64其余架构直接报错退出。随后把bin/static复制为bin/static-$ARCH并归还属主make docs生成 man 文档对应 Makefile 的docs目标make crio.conf生成默认配置。该目标实际执行./bin/crio -d --config config crio.conf见 Makefile即用刚构建的二进制输出一份完整默认配置make bundle打安装包。从脚本后续逻辑可知产物为build/bundle/cri-o.ARCH.SHA.tar.gzSHA 即 git commitbundle 中应包含 CRI-O 二进制、pinns、conmon、配置与文档等安装所需文件。从源码结构看make bundle在仓库顶层 Makefile 中并未直接定义其具体实现应来自构建环境内的其他构建系统如 nix flake 派生目标但产物路径与命名由本脚本与上传脚本共同约定是整个分发链路的事实标准。六、上传阶段upload-artifacts.sh 的行为细节upload-artifacts.sh 由主脚本在导出GCS_SA_PATH、GCS_BUCKET_NAME环境变量后调用其内部逻辑认证GCS_SA_PATH为空则复用现有凭据打印Using existing credentials for gsutil否则执行gcloud auth activate-service-account --key-file$GCS_SA_PATH。注意 bucket 默认值是cri-oGCS_BUCKET_NAME${GCS_BUCKET_NAME:-cri-o}主脚本总会显式传入故实际以用户指定为准上传 bundlegsutil -m cp -n build/bundle/*.tar.gz* $BUCKET/artifacts。-m启用并行-n表示不覆盖已存在对象no-clobber通配符带*后缀说明同时上传可能存在的签名文件如.tar.gz.sha256之类写入版本标记以当前 git 分支名作为标记文件名把 HEAD commit 写入latest-branch.txt并上传到 bucket 根目录。若处于 detached HEAD 状态如 checkout 到 tag则用git describe --tags --exact-match取 tag 版本并把标记文件名截取为 tag 的major.minor例如v1.30.0→1.3——这正是安装侧脚本用-b bucket拉取时定位“该分支最新版本”的依据。七、SHA 一致性校验与安装脚本生成版本校验上传完成后主脚本 L105-L112 做了一处关键自检从build/bundle/中找到最新的cri-o.*.tar.gz用sed两次剥离build/bundle/cri-o.$ARCH.前缀与.tar.gz后缀得到 commit SHA即CRIO_SHA再确认该 SHA 出现在刚上传的latest-$GIT_BRANCH.txt中保证本地构建产物与 GCS 上最新标记严格对应避免安装侧拉到过期版本。额外配置注入若指定了-e脚本 L114-L128 会递归收集目录内所有非目录文件每份文件生成一段 heredoc 写入内容形如cat EOF /etc/crio/crio.conf.d/40.conf 原文件内容 EOF编号从 40 递增FILE_COUNTER40刻意排在脚本内置的 10/20/30 号配置之后实现“内置配置为底、自定义配置覆盖”的叠加效果。这些片段随后被嵌入安装脚本的install_crio函数体中。安装脚本的内容主脚本 L130-L184 生成一个随机命名的node_e2e_installer-RAND_ID.shID 形如crio-user-YYYYmmdd-md5前8位上传到gs://$BUCKET/并记录其公网 URL。脚本核心是install_crio()函数安装侧执行的动作包括拉取官方安装脚本curl下载 CRI-O 官方scripts/get安装脚本--fail --retry 5 --retry-delay 3保证网络重试然后以-t $NODE_E2E_COMMIT -b ${GCS_BUCKET_NAME}调用——-t指定 bundle 对应的 commit即本地构建的 SHA-b指定 bucket安装器据此定位并解压安装我们上传的 bundleSELinux 预置创建/var/lib/kubelet并chcon设置system_u:object_r:var_lib_t标签保证 kubelet 数据目录在 Fedora CoreOS 的 SELinux 策略下可正常读写挂载调整mount /tmp /tmp -o remount,exec,suid允许 /tmp 上执行测试相关二进制清理冲突配置删除 podman 遗留的/etc/cni/net.d/87-podman-bridge.conflist避免 CNI 配置干扰日志级别向/etc/sysconfig/crio追加CONTAINER_LOG_LEVELdebug便于失败时拿到详细日志写入三份运行时配置10-crun.conf仅声明[crio.runtime.runtimes.test-handler]段保留 runc/crun 之外的自定义 handler 槽位20-runc.conf显式设置default_runtime runc并声明[crio.runtime.runtimes.runc]段——node e2e 使用 runc 作为默认运行时30-infra-container.confdrop_infra_ctr false即保留 pause 沙箱容器与 node e2e 的 kubelet 行为预期一致注入-e提供的额外配置如有然后systemctl enable/start crio.service启动 CRI-O。这些配置片段直接对应 CRI-O 的 drop-in 配置机制/etc/crio/crio.conf.d/*.conf与仓库 contrib/sysconfig/crio、systemd 单元 crio.service 的安装布局保持一致。八、Ignition 配置生成让 Fedora CoreOS 自举最后主脚本 L190-L230 写出 Ignition 3.3.0 配置到$IGNITION_OUT_DIR/$RAND_ID.ign内容分四块块作用ignition.version 3.3.0指定 Ignition 规范版本FCOS 按此解析kernelArgumentsshouldExist: systemd.unified_cgroup_hierarchy0——强制禁用 cgroup v2 统一层级保持与 node e2e CI 一致的传统 cgroup 布局storage.files写入/etc/zincati/config.d/90-disable-auto-updates.tomlmode 420 即 0644数据 URI 内容为[updates] enabled false——关闭 Zincati 自动更新避免测试中途系统被升级systemd.units注册两个 oneshot 单元dbus-tools-install.service先于安装单元执行rpm-ostree install --apply-live --allow-inactive dbus-tools安装 dbus 工具依赖与crio-install.service下载node_e2e_installer-*.sh到/usr/local/并软链/usr/bin/runc到/usr/local/bin/runc后执行单元依赖关系为dbus-tools-install.service声明Beforecrio-install.service与Afternetwork-online.targetcrio-install.service声明Afternetwork-online.target并注册WantedBymulti-user.target保证开机联网后按序完成“装 dbus 工具 → 装 CRI-O → 启动 crio”。得到.ign文件后在 GCP 创建实例时把它作为 ignition 配置传入FCOS 机器启动即自动完成 CRI-O 安装与启动随后开发者即可按 kubernetes 社区文档中的 remote 方式对实例发起 node e2e 测试——复现链完整闭环。九、实战排查要点结合脚本实现遇到问题时优先检查以下环节参数校验失败三个必选参数缺任一parse_args后即退出先核对-d/-i/-b构建失败build-static依赖容器内 nix 构建Makefile检查容器运行时与 nix flake 缓存是否可用架构非x86_64/aarch64会直接报Unsupported local architecture上传失败确认gsutil/gcloud认证有效、bucket 存在且具备写权限gsutil -m cp -n的-n意味着同名对象不会覆盖若 bundle 已存在可能需手动处理SHA 校验无输出grep $CRIO_SHA latest-$GIT_BRANCH.txt匹配失败时脚本不会显式失败if无 else 分支注意核对分支名与 bundle 是否同源实例侧安装失败查看crio-install.service日志重点检查/usr/local/crio-nodee2e-installer.sh下载是否成功、scripts/get是否按-b找到 bundle、runc 软链是否生效CRI-O 日志级别已预设为 debug可直接看/etc/sysconfig/crio生效情况测试行为与 CI 不一致确认内核参数cgroup v1、drop_infra_ctrfalse、默认运行时 runc 三处与 CI 对齐这是本工具刻意固化的关键环境要素。十、延伸阅读工具本身create-ignition-config.sh、upload-artifacts.sh构建目标定义Makefilebin/pinns、build-static、crio.conf、docs等目标CRI-O 安装与配置布局install.md、contrib/sysconfig/crio、contrib/systemd/crio.service运行时 drop-in 配置示例仓库 test/testdata/config 中可看到同类crio.conf.d配置的组织方式便于理解-e注入的格式约定这套基于 GCP GCS Fedora CoreOS Ignition 的复现链路把“CI 上偶发的 node e2e 失败”变成了开发者本机可控、可重复、可注入自定义配置的调试实验是 CRI-O 开发与排障工具箱中高价值的一环。赞分享云原生容器运行时【免费下载链接】cri-oOpen Container Initiative-based implementation of Kubernetes Container Runtime Interface项目地址https://gitcode.com/gh_mirrors/cr/cri-o点击查看免费下载相关推荐cAdvisor 集成测试完全指南Docker 容器化测试与 Kubernetes node-e2e 远程测试实战cAdvisor 集成测试完全指南Docker 容器化测试与 Kubernetes node e2e 远程测试实战 cAdvisor 的集成测试用于在真实运行可观测性指标监控云原生Kubernetes 测试镜像全流程指南从修改、构建、测试到发布 e2e 测试镜像Kubernetes 测试镜像全流程指南从修改、构建、测试到发布 e2e 测试镜像 Kubernetes 的端到端E2E测试依赖一套独立于主仓库之外维护的云原生容器编排集群管理微服务解决常见问题jQuery Ajax File Uploader Widget调试技巧与错误处理解决常见问题jQuery Ajax File Uploader Widget调试技巧与错误处理 jQuery Ajax File Uploader Widge前端UI库/组件上一篇猫抓 cat-catch浏览器视频嗅探与 M3U8 解析下载工具完整指南下一篇prompt-ops前端界面详解轻松掌握可视化优化工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑