KubeVirt 镜像制作

简介: KubeVirt 镜像制作

KubeVirt 镜像制作

一、概述

KubeVirt 中的虚拟机镜像主要有以下几种形式:

类型 说明 适用场景
Container Disk 将磁盘镜像打包为 OCI 容器镜像 只读系统盘、快速部署
PVC 镜像 直接写入 PersistentVolumeClaim 需要持久化写入
DataVolume CDI 管理的增强型 PVC 自动导入、克隆、上传

二、Container Disk 镜像制作

2.1 什么是 Container Disk

Container Disk 是 KubeVirt 特有的镜像格式,将虚拟机磁盘镜像(qcow2/raw)打包为标准 OCI 容器镜像,存储在任何容器镜像仓库中。

优势:

  • 复用现有容器镜像基础设施(Docker Hub、Harbor 等)
  • 无需额外存储管理
  • 支持镜像分层和缓存
  • 启动速度快(无需数据拷贝)

2.2 从现有镜像制作 Container Disk

方法一:使用 Dockerfile(推荐)

# Dockerfile
FROM scratch

# 添加虚拟机磁盘镜像
# 磁盘文件必须放在容器的根目录 / 下
ADD disk.img /disk.img
# 准备磁盘镜像
# 如果是 qcow2 格式,建议先转换为 raw
qemu-img convert -f qcow2 -O raw ubuntu-22.04.qcow2 disk.img

# 构建容器镜像
docker build -t my-registry/ubuntu-vm:1.0 .

# 推送到镜像仓库
docker push my-registry/ubuntu-vm:1.0

方法二:使用 virtctl 上传

# 直接从本地文件上传为 Container Disk
virtctl image-upload \
  --image-path=./ubuntu-22.04.qcow2 \
  --size=10Gi \
  --storage-class=standard \
  --uploadproxy-url=https://<cdi-upload-proxy> \
  pvc ubuntu-disk

2.3 从零制作 Linux 镜像

步骤 1:创建空白磁盘

# 创建 20GB 的 qcow2 磁盘
qemu-img create -f qcow2 linux-base.img 20G

# 或创建 raw 格式
qemu-img create -f raw linux-base.raw 20G

步骤 2:使用 virt-install 安装系统

# 下载 ISO 安装镜像
wget https://releases.ubuntu.com/22.04/ubuntu-22.04-live-server-amd64.iso

# 使用 virt-install 安装
virt-install \
  --name kubevirt-ubuntu \
  --memory 2048 \
  --vcpus 2 \
  --disk path=./linux-base.img,format=qcow2 \
  --cdrom ./ubuntu-22.04-live-server-amd64.iso \
  --os-variant ubuntu22.04 \
  --network network=default \
  --graphics vnc,listen=0.0.0.0 \
  --noautoconsole

步骤 3:配置 cloud-init

安装完成后,在虚拟机内配置 cloud-init 支持:

# 在虚拟机内部执行
sudo apt-get update
sudo apt-get install -y cloud-init cloud-utils

# 配置 cloud-init
sudo tee /etc/cloud/cloud.cfg << 'EOF'
# The top level settings are always merged module data
# and then the module's data.
users:
  - default

disable_root: false

preserve_hostname: false

cloud_init_modules:
  - migrator
  - seed_random
  - bootcmd
  - write-files
  - growpart
  - resizefs
  - disk_setup
  - mounts
  - set_hostname
  - update_hostname
  - update_etc_hosts
  - rsyslog
  - users-groups
  - ssh

cloud_config_modules:
  - emit_upstart
  - snap
  - ssh-import-id
  - locale
  - set-passwords
  - grub-dpkg
  - apt-pipelining
  - apt-configure
  - ntp
  - timezone
  - disable-ec2-metadata
  - runcmd
  - byobu-by-default

cloud_final_modules:
  - package-update-upgrade-install
  - fan
  - puppet
  - chef
  - mcollective
  - salt-minion
  - rightscale_userdata
  - scripts-vendor
  - scripts-per-once
  - scripts-per-boot
  - scripts-per-instance
  - scripts-user
  - ssh-authkey-fingerprints
  - keys-to-console
  - final-message

system_info:
  default_user:
    name: ubuntu
    lock_passwd: True
    gecos: Ubuntu
    groups: [adm, audio, cdrom, dialout, dip, floppy, lxd, netdev, plugdev, sudo, video]
    sudo: ["ALL=(ALL) NOPASSWD:ALL"]
    shell: /bin/bash
  distro: ubuntu
  paths:
    cloud_dir: /var/lib/cloud/
    templates_dir: /etc/cloud/templates/
  ssh_svcname: ssh
EOF

步骤 4:清理和转换

# 在虚拟机关机后执行

# 清理虚拟机内的临时文件(在虚拟机内)
sudo apt-get clean
sudo rm -rf /var/lib/apt/lists/*
sudo rm -rf /tmp/*
sudo cloud-init clean --logs

# 转换为 raw 格式(Container Disk 推荐 raw)
qemu-img convert -f qcow2 -O raw linux-base.qcow2 disk.img

# 验证镜像
qemu-img info disk.img

步骤 5:打包为 Container Disk

# Dockerfile
FROM scratch
ADD disk.img /disk.img
# 构建
docker build -t my-registry/ubuntu-base:22.04 .

# 推送
docker push my-registry/ubuntu-base:22.04

2.4 从零制作 Windows 镜像

步骤 1:准备 VirtIO 驱动

# 下载 VirtIO Windows 驱动
wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso

步骤 2:创建磁盘并安装

# 创建磁盘
qemu-img create -f qcow2 windows-base.qcow2 50G

# 安装 Windows
virt-install \
  --name kubevirt-windows \
  --memory 4096 \
  --vcpus 2 \
  --disk path=./windows-base.qcow2,format=qcow2 \
  --cdrom ./Windows_Server_2022.iso \
  --disk path=./virtio-win.iso,device=cdrom \
  --os-variant win2k22 \
  --network network=default,model=virtio \
  --graphics vnc,listen=0.0.0.0 \
  --noautoconsole

步骤 3:安装 VirtIO 驱动

在 Windows 虚拟机内部:

  1. 打开设备管理器
  2. 挂载 VirtIO ISO
  3. 安装所有驱动(网络、存储、内存气球等)
  4. 安装 QEMU Guest Agent
# 在 Windows 内安装 QEMU Guest Agent
# 从 VirtIO ISO 中运行
msiexec /i guest-agent\qemu-ga-x86_64.msi /quiet

步骤 4:打包

# 转换为 raw
qemu-img convert -f qcow2 -O raw windows-base.qcow2 disk.img

# 构建 Container Disk
docker build -t my-registry/windows-base:2022 .
docker push my-registry/windows-base:2022

三、使用 CDI 导入镜像

3.1 CDI 概述

Container Storage Interface(CDI)是 KubeVirt 的存储管理组件,支持:

  • 从 HTTP/S3/Registry 导入镜像
  • 克隆现有 PVC
  • 上传本地镜像
  • 自动格式转换

3.2 从 HTTP 导入

apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: ubuntu-import
spec:
  source:
    http:
      url: "https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img"
      # 可选:添加认证头
      # secretRef: "http-auth-secret"
  pvc:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 10Gi
    storageClassName: standard

3.3 从容器镜像仓库导入

apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: ubuntu-from-registry
spec:
  source:
    registry:
      url: "docker://my-registry/ubuntu-base:22.04"
      # 可选:拉取密钥
      # secretRef: "registry-secret"
  pvc:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 10Gi
    storageClassName: standard

3.4 克隆 PVC

apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: ubuntu-clone
spec:
  source:
    pvc:
      name: ubuntu-import      # 源 PVC 名称
      namespace: default       # 源 PVC 命名空间
  pvc:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 10Gi
    storageClassName: standard

3.5 上传本地镜像

# 使用 virtctl 上传
virtctl image-upload dv ubuntu-upload \
  --size=10Gi \
  --image-path=./local-image.qcow2 \
  --storage-class=standard

# 或使用 kubectl virt plugin
kubectl virt image-upload dv ubuntu-upload \
  --size=10Gi \
  --image-path=./local-image.qcow2

四、镜像优化

4.1 镜像瘦身

# 1. 清理系统缓存(在虚拟机内)
sudo apt-get clean
sudo rm -rf /var/log/*
sudo rm -rf /tmp/*
sudo rm -rf /var/tmp/*
sudo history -c

# 2. 零填充空闲空间(减小 raw 镜像体积)
dd if=/dev/zero of=/EMPTY bs=1M || true
rm -f /EMPTY
sync

# 3. 转换为 qcow2(压缩)
qemu-img convert -f raw -O qcow2 -c disk.raw disk.qcow2

# 4. 缩小镜像
qemu-img resize disk.qcow2 --shrink 20G

4.2 镜像预配置

# 使用 virt-customize 预配置镜像(需要 libguestfs-tools)
sudo apt-get install -y libguestfs-tools

# 设置 root 密码
virt-customize -a disk.qcow2 --root-password password:mysecret

# 安装软件包
virt-customize -a disk.qcow2 --install nginx,curl,wget

# 运行自定义脚本
virt-customize -a disk.qcow2 --run-command "systemctl enable nginx"

# 设置 hostname
virt-customize -a disk.qcow2 --hostname my-vm

4.3 镜像格式对比

特性 raw qcow2
性能 最佳 略低
大小 固定大小 支持精简配置
压缩 不支持 支持
快照 不支持 支持
加密 不支持 支持
推荐场景 Container Disk PVC/DataVolume

五、在 KubeVirt 中使用镜像

5.1 使用 Container Disk

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: ubuntu-vm
spec:
  running: true
  template:
    spec:
      domain:
        cpu:
          cores: 2
        memory:
          guest: 2Gi
        devices:
          disks:
            - name: rootdisk
              disk:
                bus: virtio
            - name: cloudinitdisk
              disk:
                bus: virtio
      volumes:
        - name: rootdisk
          containerDisk:
            image: my-registry/ubuntu-base:22.04
        - name: cloudinitdisk
          cloudInitNoCloud:
            userData: |-
              #cloud-config
              password: ubuntu
              chpasswd: {
    expire: False }

5.2 使用 DataVolume

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: ubuntu-dv-vm
spec:
  running: true
  template:
    spec:
      domain:
        cpu:
          cores: 2
        memory:
          guest: 2Gi
        devices:
          disks:
            - name: rootdisk
              disk:
                bus: virtio
      volumes:
        - name: rootdisk
          dataVolume:
            name: ubuntu-dv
  dataVolumeTemplates:
    - metadata:
        name: ubuntu-dv
      spec:
        source:
          registry:
            url: "docker://my-registry/ubuntu-base:22.04"
        pvc:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 10Gi
          storageClassName: standard

六、镜像仓库管理

6.1 使用 Harbor 私有仓库

# 登录 Harbor
docker login harbor.example.com

# 推送镜像
docker tag my-registry/ubuntu-base:22.04 harbor.example.com/kubevirt/ubuntu-base:22.04
docker push harbor.example.com/kubevirt/ubuntu-base:22.04
# 创建镜像拉取密钥
apiVersion: v1
kind: Secret
metadata:
  name: harbor-registry-secret
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: <base64-encoded-docker-config>

# 在 CDI 中使用
spec:
  source:
    registry:
      url: "docker://harbor.example.com/kubevirt/ubuntu-base:22.04"
      secretRef: harbor-registry-secret

6.2 镜像版本管理

# 使用语义化版本
docker build -t my-registry/ubuntu-base:22.04.1 .
docker build -t my-registry/ubuntu-base:22.04.2 .
docker build -t my-registry/ubuntu-base:latest .

# 推送所有版本
docker push my-registry/ubuntu-base:22.04.1
docker push my-registry/ubuntu-base:22.04.2
docker push my-registry/ubuntu-base:latest

七、常见问题

7.1 Container Disk 启动失败

# 检查镜像是否正确
docker run --rm my-registry/ubuntu-base:22.04 ls -la /disk.img

# 确保磁盘文件在根目录
# 错误:/disk/disk.img
# 正确:/disk.img

7.2 DataVolume 导入失败

# 检查 CDI Pod 日志
kubectl logs -n cdi deployment/cdi-importer

# 检查 DataVolume 状态
kubectl describe dv ubuntu-dv

# 检查 PVC 状态
kubectl get pvc

7.3 镜像格式不兼容

# 检查镜像格式
qemu-img info disk.img

# 转换为兼容格式
qemu-img convert -f vmdk -O qcow2 disk.vmdk disk.qcow2
qemu-img convert -f vdi -O raw disk.vdi disk.raw

7.4 镜像过大

# 查看实际占用空间
qemu-img measure disk.qcow2

# 压缩 qcow2 镜像
qemu-img convert -O qcow2 -c input.qcow2 output-compressed.qcow2

# 使用 sparsify 精简镜像
virt-sparsify input.qcow2 output-sparse.qcow2
相关文章
|
1月前
|
运维 Cloud Native 应用服务中间件
阿里云微服务引擎 MSE 及 API 网关 2026 年 6 月产品动态
阿里云微服务引擎 MSE 面向业界主流开源微服务项目, 提供注册配置中心和分布式协调(原生支持 Nacos/ZooKeeper/Eureka )、云原生网关(原生支持Higress/Nginx/Envoy,遵循Ingress标准)、微服务治理(原生支持 Spring Cloud/Dubbo/Sentinel,遵循 OpenSergo 服务治理规范)能力。API 网关 (API Gateway),提供 APl 托管服务,覆盖设计、开发、测试、发布、售卖、运维监测、安全管控、下线等 API 生命周期阶段。帮助您快速构建以 API 为核心的系统架构.满足新技术引入、系统集成、业务中台等诸多场景需要
|
2月前
|
Kubernetes Ubuntu 网络协议
|
23天前
|
消息中间件 算法 Java
百炼网关实践:用 RocketMQ LiteTopic 让限流比降了 10 倍
LiteTopic 提供的 “轻量队列 + 差异化订阅 + Suspend 控速” 三件套,让百炼网关的限流比降低了 10 倍。
|
1月前
|
运维 自然语言处理 监控
把运维能力装进 Qoder,一句话就能定位根因
每个研发都踩过这个坑:遇到线上故障时,定位根因要跨五个平台,学数套查询语法,故障排查半小时起步。当STAROps长在Qoder里,在对话框里用自然语言提问:跨域诊断、多轮追问、生成修复代码、自动提 MR,全程不出 Qoder。三步上手,3 分钟看见效果。
268 11
|
2月前
|
消息中间件 人工智能 安全
7 月 9 日香港,AI Agent 工程化实战专场邀您参会
AI Agent正规模化落地,但多智能体协作、安全治理、高并发稳定运行及决策可解释性等挑战亟待解决。7月9日香港,阿里云将分享“可信、可控、可观测”的企业级Agent工程化实战方案,涵盖Agent Teams、AI网关、RocketMQ for AI与STAROps等全栈能力。
|
22天前
|
存储 Kubernetes 调度
|
22天前
|
Kubernetes 并行计算 算法框架/工具
|
22天前
|
JSON 人工智能 网络协议
【Azure Application Insights】公网白名单应用如何使用 Application Insights 可用性测试?
Azure VM应用启用AI可用性测试后探测失败,因探测源自微软托管节点IP,未在公网白名单中。解决方案:下载中国云IP范围JSON,提取ApplicationInsightsAvailability和ActionGroup的addressPrefixes,手动添加对应CIDR至NSG/防火墙白名单,并定期同步更新。
|
22天前
|
Shell 开发工具
|
22天前
|
存储 Prometheus Kubernetes
Kubeasz 部署 K8s 生产方案
Kubeasz 部署 K8s 生产方案