ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

KubeVirt Root Disk Mutation Hook Sidecar 实战指南:用注解改写引导磁盘镜像名

KubeVirt Root Disk Mutation Hook Sidecar 实战指南:用注解改写引导磁盘镜像名 云原生【免费下载链接】kubevirtKubernetes Virtualization API and runtime in order to define and manage virtual machines.项目地址https://gitcode.com/gh_mirrors/ku/kubevirt点击查看免费下载在 KubeVirt 中虚拟机的引导磁盘boot disk默认使用容器磁盘或 PVC 中的原始镜像文件名而某些场景如按模板动态生成镜像、需要以固定文件名引导的场景要求 libvirt domain XML 中的磁盘路径指向一个特定的镜像名。cmd/sidecars/disk-mutation目录提供了一个开箱即用的 hook sidecar 示例它通过 VMI 注解请求注入 sidecar并依据diskimage.vm.kubevirt.io/bootImageName注解在 domain 定义阶段重写引导磁盘的镜像文件名。读完本文你将掌握该 sidecar 的两个核心注解的用法、完整 VMI 示例以及其底层OnDefineDomain钩子的源码级实现原理并了解如何基于 BUILD.bazel 构建自己的 hook 镜像。一、Hook Sidecar 机制速览KubeVirt 的 hook sidecar 机制允许用户在 virt-launcher 生成 libvirt domain XML 的过程中介入修改。整个过程分为两步请求注入 sidecar在 VMI 的metadata.annotations中声明hooks.kubevirt.io/hookSidecars其值为一个 JSON 数组描述要注入的 sidecar 容器镜像及启动参数sidecar 通过 gRPC 暴露钩子sidecar 内部实现OnDefineDomaindomain 定义前回调等钩子点virt-launcher 在生成 domain 后会调用这些钩子sidecar 返回修改后的 domain XML。注解常量定义于 pkg/hooks/hooks.goconst HookSidecarListAnnotationName hooks.kubevirt.io/hookSidecars const HookSocketsSharedDirectory /var/run/kubevirt-hookssidecar 与 virt-launcher 通过/var/run/kubevirt-hooks目录下的 unix socket 通信gRPC由 pkg/hooks/manager.go 中的collectSideCarSockets轮询收集各个 sidecar 暴露的 socket 并注册回调。hook sidecar 整体能力可参考 cmd/sidecars/README.md。二、使用 Disk Mutation Sidecar 的两个注解根据 关联文档使用该 hook 只需在 VMI 上配置两个注解annotations: # 请求注入 hook sidecar 容器 hooks.kubevirt.io/hookSidecars: [{image: registry:5000/kubevirt/example-disk-mutation-hook-sidecar:devel}] # 指定新的引导磁盘镜像文件名 diskimage.vm.kubevirt.io/bootImageName: virt-disk.img1.hooks.kubevirt.io/hookSidecars请求注入 sidecar该注解的值是一个 JSON 数组每项对应一个 sidecar 容器。上例仅指定了image。除此之外pkg/hooks/hooks.go 中HookSidecar结构体还支持更多字段字段类型说明imagestringsidecar 镜像地址必填imagePullPolicystring镜像拉取策略command[]string覆盖容器启动命令args[]string覆盖容器启动参数例如[--version, v1alpha2]configMapobject从 ConfigMap 注入 hook 脚本/二进制含name、key、hookPath三个子字段pvcobject从 PVC 挂载 hook 脚本/二进制含name、volumePath、sharedComputePath例如 examples/vmi-with-sidecar-hook.yaml 展示了带args的写法hooks.kubevirt.io/hookSidecars: [{args: [--version, v1alpha2], image: registry:5000/kubevirt/example-hook-sidecar:devel}]而 examples/vmi-with-sidecar-hook-configmap.yaml 展示了通过 ConfigMap 提供脚本的写法hooks.kubevirt.io/hookSidecars: [{args: [--version, v1alpha2], configMap: {name: my-config-map, key: my_script.sh, hookPath: /usr/bin/onDefineDomain}}]注意--version参数用于选择 hook 协议版本sidecar-shim 支持v1alpha1、v1alpha2、v1alpha3见 cmd/sidecars/sidecar_shim.go其中v1alpha3还额外注册了Shutdown钩子点以便优雅退出。2.diskimage.vm.kubevirt.io/bootImageName指定新的引导镜像名该注解的值是一个文件名如virt-disk.imgsidecar 会用它替换 domain XML 中引导磁盘的source.file文件名部分。常量定义在 cmd/sidecars/disk-mutation/diskimage.goconst bootDiskImageNameAnnotation diskimage.vm.kubevirt.io/bootImageName如果 VMI 上未设置该注解sidecar 不会做任何修改直接返回原始 domain XML源码中会打印提示日志。这保证了 sidecar 的幂等性与向后兼容。三、完整 VMI 示例将上述两个注解组合到一份最小化的 VMI 清单中即可验证完整流程apiVersion: kubevirt.io/v1 kind: VirtualMachineInstance metadata: annotations: # 请求注入 disk-mutation hook sidecar hooks.kubevirt.io/hookSidecars: [{image: registry:5000/kubevirt/example-disk-mutation-hook-sidecar:devel}] # 将引导磁盘镜像名改写为 virt-disk.img diskimage.vm.kubevirt.io/bootImageName: virt-disk.img name: vmi-with-disk-mutation spec: domain: devices: disks: - disk: bus: virtio name: containerdisk - disk: bus: virtio name: cloudinitdisk rng: {} memory: guest: 1024M resources: {} terminationGracePeriodSeconds: 0 volumes: - containerDisk: image: registry:5000/kubevirt/fedora-with-test-tooling-container-disk:devel name: containerdisk - cloudInitNoCloud: userData: |- #cloud-config password: fedora chpasswd: { expire: False } name: cloudinitdisk保存为vmi-disk-mutation.yaml后通过 kubectl 创建kubectl create -f vmi-disk-mutation.yaml创建成功后sidecar 会在 virt-launcher 定义 domain 时介入把引导磁盘的镜像文件名改写为virt-disk.img。由于磁盘路径的目录部分保持不变此操作对容器磁盘的挂载布局透明适用于“目录不变、文件名改写”的镜像重命名场景。四、源码级原理OnDefineDomain的执行流程disk-mutation 的核心逻辑全部位于 cmd/sidecars/disk-mutation/diskimage.go 的OnDefineDomain函数第 41-78 行。它接收两个输入vmiJSON当前 VMI 的 JSON 序列化domainXMLvirt-launcher 生成的 libvirt domain XML。执行流程如下反序列化 VMIjson.Unmarshal将vmiJSON解析为vmSchema.VirtualMachineInstance失败则直接返回错误读取注解通过vmiSpec.GetAnnotations()检查diskimage.vm.kubevirt.io/bootImageName是否存在若不存在打印日志并原样返回domainXMLdiskimage.go反序列化 domainxml.Unmarshal将domainXML解析为domainSchema.DomainSpec来自pkg/virt-launcher/virtwrap/api定位引导磁盘取domainSpec.Devices.Disks[0].Source.File——即列表中的第一个磁盘也就是引导磁盘的镜像绝对路径diskimage.go改写文件名用filepath.Split拆分目录与文件名再用注解值替换文件名并filepath.Join重组路径diskimage.go。若新文件名与当前文件名相同则跳过修改直接返回原 XML序列化回 XMLxml.Marshal生成修改后的 domain XML 并返回字符串供 virt-launcher 使用。主函数diskimage.go使用pflag解析--vmi与--domain两个命令行参数校验非空后调用OnDefineDomain并把结果打印到标准输出——这正是 sidecar-shim 调用外部二进制时的约定接口。五、sidecar-shim 与完整调用链cmd/sidecars/disk-mutation的镜像构建在通用的 sidecar-shim 之上。shim 本身是一个 gRPC 服务其工作流程为根据--version参数选择协议版本v1alpha1/v1alpha2/v1alpha3并在/var/run/kubevirt-hooks下创建随机命名的 unix socketsidecar_shim.go通过Info服务通告自己支持的钩子点OnDefineDomain与PreCloudInitIsosidecar_shim.go。它会在$PATH中查找onDefineDomain二进制只有找到才注册该钩子点收到OnDefineDomain调用时shim 以--vmi和--domain为参数执行onDefineDomain外部程序sidecar_shim.go并把程序 stdout 输出作为新的 domain XML 返回给 virt-launchervirt-launcher 侧的钩子管理由 pkg/hooks/manager.go 负责其Collect方法按优先级排序各 sidecar 的回调随后在定义 domain 时逐个调用。完整的调用链可以概括为virt-launcher 生成 domain XML ↓ gRPC/var/run/kubevirt-hooks/*.sock sidecar-shimOnDefineDomain 钩子 ↓ exec onDefineDomain --vmi json --domain xml diskimage.go 的 OnDefineDomain 函数 ↓ 改写 Disks[0].Source.File 文件名 返回修改后的 domain XML 给 virt-launcher六、镜像构建与部署方式disk-mutation sidecar 的镜像构建规则定义在 cmd/sidecars/disk-mutation/BUILD.bazel 中go_binary(name onDefineDomain)将 diskimage.go 编译为可执行文件pkg_tar把二进制打包安装到镜像的/usr/bin目录使 shim 能在$PATH中找到onDefineDomainkubevirt_image以//cmd/sidecars:sidecar-shim-image为基础镜像entrypoint 为/sidecar-shim叠加该 tar 生成example-disk-mutation-hook-sidecar-image。这正是 README 中注解image使用registry:5000/kubevirt/example-disk-mutation-hook-sidecar:devel的原因devel是 KubeVirt 开发环境的镜像 tag 惯例可参考 hack/builder/publish.sh 中镜像发布的 tag 规则。在自有环境使用时请将镜像地址替换为你实际构建并推送的镜像仓库地址。若希望自定义镜像名可参照该 BUILD 规则新建自己的 Bazel target 并推送若希望完全避免镜像构建也可以把脚本或二进制通过 ConfigMap/PVC 注入 sidecar对应configMap/pvc字段见 pkg/hooks/hooks.go此时镜像只需包含sidecar-shim即可。七、使用注意事项引导磁盘取第一个磁盘OnDefineDomain固定修改domainSpec.Devices.Disks[0]即 VMI 磁盘列表中的第一个磁盘会被视为引导磁盘。请确保你的 VMI 磁盘顺序符合预期只改文件名、不改目录filepath.Split保留原目录仅替换文件名部分因此新镜像名对应的文件必须仍存在于原目录中注解缺失时的行为未设置bootImageName注解时sidecar 原样返回 domain XML不影响 VMI 正常启动新文件名与旧文件名一致时同样直接返回避免无意义的重写协议版本一致性若在hookSidecars中通过args传入--version需确保与实际部署的 shim 支持的版本一致v1alpha1/v1alpha2/v1alpha3测试验证该 sidecar 属于示例性质源码注释注明“Inspired by cmd/example-hook-sidecar”实际生产使用前建议结合 pkg/hooks/manager_test.go 中钩子管理的测试思路验证目标镜像环境的 domain XML 结构后再上线。八、参考资源核心实现cmd/sidecars/disk-mutation/diskimage.go通用 shimcmd/sidecars/sidecar_shim.go注解与 sidecar 结构定义pkg/hooks/hooks.go钩子管理pkg/hooks/manager.go构建规则cmd/sidecars/disk-mutation/BUILD.bazel相关示例examples/vmi-with-sidecar-hook.yaml、examples/vmi-with-sidecar-hook-configmap.yaml至此你已掌握 KubeVirt 磁盘镜像名改写 sidecar 的完整使用与实现两个注解的语义、最小可运行 VMI 清单、OnDefineDomain的逐行逻辑、shim 与 virt-launcher 的 gRPC 调用链以及基于 Bazel 的镜像构建方式可以据此在自己的集群中复现或定制该能力。赞分享云原生【免费下载链接】kubevirtKubernetes Virtualization API and runtime in order to define and manage virtual machines.项目地址https://gitcode.com/gh_mirrors/ku/kubevirt点击查看免费下载相关推荐KubeVirt 容器磁盘镜像container-disk完全指南官方镜像清单与自定义测试镜像构建实战KubeVirt 容器磁盘镜像container disk完全指南官方镜像清单与自定义测试镜像构建实战 本文围绕 KubeVirt 项目中的 contai云原生KubeVirt Hook Sidecar 实战指南用 sidecar-shim 在 VMI 启动前注入自定义逻辑KubeVirt Hook Sidecar 实战指南用 sidecar shim 在 VMI 启动前注入自定义逻辑 本指南以 KubeVirt 仓库中 cmd云原生KubeVirt 容器化磁盘实战Registry Disk 与 container-disk-v2alpha 机制详解KubeVirt 容器化磁盘实战Registry Disk 与 container disk v2alpha 机制详解 KubeVirt 允许把虚拟机VMI云原生上一篇FastLED电源管理终极指南5V/12V LED灯带的功率计算与保护设计下一篇JavaScript应用重写艺术Garann Means在Must-Watch JavaScript的演讲创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表