kubevirt 构建镜像

1 阅读3分钟

在 KubeVirt 的构建体系中,make push 是将源代码转化为可部署镜像的最关键动作。它不仅仅是一个简单的“上传”命令,而是一个复杂的自动化流水线。

基于第一性原理,我们可以将 make push 的作用拆解为以下三个核心阶段:


1. 核心流程逻辑:从代码到仓库

make push 在底层实际上调用了 Bazel 的 push-images 目标。其执行路径如下:

A. 交叉编译(Cross-Compilation)

Bazel 首先在 builder 容器内并行编译 KubeVirt 的所有核心二进制文件,包括:

  • virt-api
  • virt-controller
  • virt-handler
  • virt-launcher
  • virt-operator

这些二进制文件是针对特定的目标架构(通常是 amd64arm64)进行静态编译的。

B. 镜像分层构建(Image Layering)

注意: KubeVirt 并不使用 docker build

它利用 Bazel 的 OCI 规则(如 rules_oci),在不依赖本地 Docker Daemon 的情况下,直接计算并打包出符合 OCI 标准的镜像层。它会将编译好的二进制文件与基础镜像(Base Image)进行合并。

C. 推送/加载(The "Push" Action)

这是该命令名字的由来。它会将构建好的所有镜像推送到由环境变量定义的仓库。


2. 关键环境变量的影响

make push 的行为完全受你在 Shell 中导出的变量控制。这是区分“本地测试”和“发布镜像”的关键:

变量名作用示例
DOCKER_PREFIX定义镜像仓库的地址或命名空间。quay.io/your-idlocalhost:5000
DOCKER_TAG定义镜像的版本标签。qos-testv1.2.0
KUBEVIRT_PULL_POLICY定义生成的 YAML 里的拉取策略。IfNotPresent

逻辑推演:

如果你设置了 DOCKER_PREFIX=kubevirtDOCKER_TAG=qos-test,那么执行 make push 后,远端(或本地 Registry)会出现:

  • kubevirt/virt-api:qos-test
  • kubevirt/virt-handler:qos-test
  • (以此类推,涵盖所有 5 个核心组件)

3. make pushmake manifests 的协同关系

在开发 KubeVirt 时,这两个命令通常是成对出现的:

  1. make manifests:生成 YAML 文件。这些 YAML 里的镜像地址会根据你的 DOCKER_PREFIXDOCKER_TAG 进行硬编码
  2. make push:产生对应的镜像实体。

只有当这两者完全匹配时,你部署到集群里的 KubeVirt 才会运行你修改后的代码。


4. 为什么在你的环境下它很重要?

由于你正在处理 qos-test 相关的修改,make push 的意义在于:

  • 环境一致性:它确保了你在机器上修改的 Go 代码,能够被打包进镜像并被 Kubernetes 节点(如其他 Node)拉取到。
  • 规避本地隔离:通过 make push 将镜像推送到一个可达的 Registry(哪怕是本地临时 Registry),可以解决 K8s 节点无法直接访问 Docker 内部构建缓存的问题。
  • 全自动化:它一次性处理 5 个以上的组件镜像。如果手动执行 docker build,你需要写 5 个 Dockerfile 并手动维护 Tag,极其容易出错。

总结

执行 make push 意味着你正式完成了从**“代码逻辑”“分发实体”**的跨越。它是构建闭环中最后一步重型任务,此后你只需执行 kubectl apply 即可看到你的改动。