使用 KubeVirt 基于 ISO 创建 Windows 镜像
本文档介绍基于开源组件 KubeVirt 的虚拟机方案,利用 KubeVirt 虚拟化技术通过 ISO 镜像文件创建 Windows 操作系统镜像。
目录
前提条件
约束与限制
操作步骤
创建镜像
通过准备好的 Windows 和 virtio-win ISO 镜像创建 Docker 镜像,并推送到仓库。本文以 Windows Server 2019 为例。
从 Windows ISO 创建 Docker 镜像
-
进入存放 ISO 镜像的目录,在终端执行以下命令,将 ISO 镜像重命名为 win.iso。
mv <ISO image name> win.iso # 将 <ISO image name> 替换为实际镜像名称,例如 mv en_windows_server_2019_x64_dvd_4cb967d8.iso win.iso
-
执行以下命令创建 Dockerfile。
-
编辑 Dockerfile,添加以下内容并保存。
FROM scratch
ADD --chown=107:107 win.iso /disk/
-
执行以下命令构建 Docker 镜像。
docker build -t build-harbor.example.cn/3rdparty/vmdisks/winiso:2019 . # 根据实际环境替换仓库地址
-
执行以下命令将镜像推送到仓库。
docker push build-harbor.example.cn/3rdparty/vmdisks/winiso:2019 # 根据实际环境替换仓库地址
从 virtio-win ISO 创建 Docker 镜像
-
进入存放 ISO 镜像的目录,执行以下命令创建 Dockerfile。
-
编辑 Dockerfile,添加以下内容并保存。
FROM scratch
ADD --chown=107:107 virtio-win.iso /disk/
-
执行以下命令构建 Docker 镜像。
docker build -t build-harbor.example.cn/3rdparty/vmdisks/win-virtio:latest . # 根据实际环境替换仓库地址
-
执行以下命令将镜像推送到仓库。
docker push build-harbor.example.cn/3rdparty/vmdisks/win-virtio:latest # 根据实际环境替换仓库地址
创建虚拟机
-
进入 容器平台。
-
在左侧导航栏点击 虚拟化 > 虚拟机。
-
点击 创建虚拟机。
-
在表单页面填写必要参数,如 名称、镜像 等。详细参数及配置请参考创建虚拟机。
-
切换至 YAML。
-
将 spec.template.spec.domain.devices.disks 字段下的配置替换为以下内容。
domain:
devices:
disks:
- disk:
bus: virtio
name: cloudinitdisk
- bootOrder: 1
cdrom:
bus: sata
name: containerdisk
- cdrom:
bus: sata
name: virtio
- disk:
bus: sata
name: rootfs
bootOrder: 10
-
在 spec.template.spec.volumes 字段下添加以下内容。
- containerDisk:
image: registry.example.cn:60070/3rdparty/vmdisks/winiso:2019 # 根据实际环境替换镜像地址
name: containerdisk
- containerDisk:
image: registry.example.cn:60070/3rdparty/vmdisks/win-virtio # 根据实际环境替换镜像地址
name: virtio
-
检查 YAML 文件,完成配置后的完整 YAML 如下。
apiVersion: kubevirt.io/v1alpha3
kind: VirtualMachine
metadata:
annotations:
cpaas.io/creator: test@example.io
cpaas.io/display-name: ""
cpaas.io/updated-at: 2024-09-01T14:57:55Z
kubevirt.io/latest-observed-api-version: v1
kubevirt.io/storage-observed-api-version: v1
generation: 16
labels:
virtualization.cpaas.io/image-name: debian-2120-x86
virtualization.cpaas.io/image-os-arch: amd64
virtualization.cpaas.io/image-os-type: debian
virtualization.cpaas.io/image-supply-by: public
vm.cpaas.io/name: aa-test
name: aa-test
namespace: acp-service-self
spec:
dataVolumeTemplates:
- metadata:
creationTimestamp: null
labels:
vm.cpaas.io/reclaim-policy: Delete
vm.cpaas.io/used-by: aa-test
name: aa-test-rootfs
spec:
pvc:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
storageClassName: vm-cephrbd
volumeMode: Block
source:
http:
url: http://192.168.254.12/kube-debian-12.2.0-x86-out.qcow2
running: true
template:
metadata:
annotations:
cpaas.io/creator: test@example.io
cpaas.io/display-name: ""
cpaas.io/updated-at: 2024-09-01T14:55:44Z
kubevirt.io/latest-observed-api-version: v1
kubevirt.io/storage-observed-api-version: v1
creationTimestamp: null
labels:
virtualization.cpaas.io/image-name: debian-2120-x86
virtualization.cpaas.io/image-os-arch: amd64
virtualization.cpaas.io/image-os-type: debian
virtualization.cpaas.io/image-supply-by: public
vm.cpaas.io/name: aa-test
spec:
affinity:
nodeAffinity: {}
architecture: amd64
domain:
devices:
disks:
- disk:
bus: virtio
name: cloudinitdisk
- bootOrder: 1
cdrom:
bus: sata
name: containerdisk
- cdrom:
bus: sata
name: virtio
- disk:
bus: sata
name: rootfs
bootOrder: 10
interfaces:
- bridge: {}
name: default
machine:
type: q35
resources:
limits:
cpu: "4"
memory: 8Gi
requests:
cpu: "4"
memory: 8Gi
networks:
- name: default
pod: {}
nodeSelector:
kubernetes.io/arch: amd64
vm.cpaas.io/baremetal: "true"
volumes:
- cloudInitConfigDrive:
userData: >-
#cloud-config
disable_root: false
ssh_pwauth: true
users:
- default
- name: root
lock_passwd: false
hashed_passwd: $6$0vlhl57e$0rawYwaeu9jL6hBf3XP9lk6XXaMUS9/W6LPbWRinUoXujo39lP3l98VOcOObtr.LDoAv/ylm85FLQmxwNlWFe/
name: cloudinitdisk
- containerDisk:
image: registry.example.cn:60070/3rdparty/vmdisks/winiso:2019 # 根据实际环境替换镜像地址
name: containerdisk
- containerDisk
image: registry.example.cn:60070/3rdparty/vmdisks/win-virtio # 根据实际环境替换镜像地址
name: virtio
- dataVolume:
name: aa-test-rootfs
name: rootfs
-
点击 创建。
-
点击 操作 > VNC 登录。
-
当出现提示 press any key boot from CD or DVD 时,按任意键进入 Windows 安装程序;若未看到提示,请点击页面左上角的 发送远程命令,从下拉菜单选择 Ctrl-Alt-Delete 重启服务器。
注意:若虚拟机详情页顶部出现提示 当前虚拟机有配置变更需重启生效,请重启,可忽略该提示,无需重启。
安装 Windows 操作系统
-
进入安装页面后,按照安装指引完成系统安装。
注意:分区选择步骤中,磁盘总线必须为 sata,系统才能正确识别磁盘。需依次选择每个分区并点击 删除,清除所有分区,由系统自动处理。
-
配置管理员账户密码后,点击页面左上角的 发送远程命令,选择下拉菜单中的 Ctrl-Alt-Delete。
-
出现提示 Ctrl+Alt+Delete 组合键将重启服务器,确认重启 时,点击 确定。
-
输入密码进入 Windows 系统桌面,至此 Windows 操作系统安装完成。
安装 virtio-win-tools
该工具主要包含必要驱动。
-
打开文件资源管理器。
-
双击 CD 驱动器(E:) virtio-win-<version>,运行 virtio-win-guest-tools 目录进入安装页面,按照安装指引完成安装。<version> 部分请根据实际情况替换。
-
安装完成后,关闭 Windows 系统电源。
导出自定义 Windows 镜像
具体操作请参考导出虚拟机镜像。
使用 Windows 镜像
-
进入 容器平台。
-
在左侧导航栏点击 虚拟化 > 虚拟机。
-
点击列表中使用 Windows 镜像创建的虚拟机名称,进入详情页。
-
点击 创建虚拟机。
-
在表单页面填写必要参数,镜像选择导出的 Windows 镜像。详细参数及配置请参考创建虚拟机。
-
(可选)若使用较新操作系统,如 Windows 11,需启用时钟、UEFI、TPM 等功能。切换至 YAML,替换原 YAML 文件为以下内容。
apiVersion: kubevirt.io/v1
kind: VirtualMachineInstance
metadata:
labels:
special: vmi-windows
name: vmi-windows
spec:
domain:
clock:
timer:
hpet:
present: false
hyperv: {}
pit:
tickPolicy: delay
rtc:
tickPolicy: catchup
utc: {}
cpu:
cores: 2
devices:
disks:
- disk:
bus: sata
name: pvcdisk
interfaces:
- masquerade: {}
model: e1000
name: default
tpm: {}
features:
acpi: {}
apic: {}
hyperv:
relaxed: {}
spinlocks:
spinlocks: 8191
vapic: {}
smm: {}
firmware:
bootloader:
efi:
secureBoot: true
uuid: 5d307ca9-b3ef-428c-8861-06e72d69f223
resources:
requests:
memory: 4Gi
networks:
- name: default
pod: {}
terminationGracePeriodSeconds: 0
volumes:
- name: pvcdisk
persistentVolumeClaim:
claimName: disk-windows
- name: winiso
persistentVolumeClaim:
claimName: win11cd-pvc
-
点击 创建。
添加内部路由
通过配置 NodePort 类型的内部路由,暴露远程桌面连接端口。
-
进入 容器平台。
-
在左侧导航栏点击 虚拟化 > 虚拟机。
-
点击列表中使用 Windows 镜像创建的虚拟机名称,进入详情页。
-
在 登录信息 区域,点击 内部路由 旁的 添加 图标。
-
按照以下说明配置参数。
参数 | 说明 |
---|
类型 | 选择 NodePort。 |
端口 | - 协议:选择 TCP。
- 服务端口:使用 3389。
- 虚拟机端口:使用 3389。
- 服务端口名称:使用 rdp。
|
-
点击 确定 返回详情页。
-
点击 登录信息 区域的 内部路由 链接。
-
记录基本信息区域的 虚拟 IP 和端口区域的 主机端口 信息。
远程访问
本文以 Windows 操作系统远程连接为例,其他操作系统可使用支持 RDP 协议的软件进行连接。
-
打开 远程桌面连接。
-
输入在 添加内部路由 步骤中保存的虚拟 IP 和主机端口,格式为 虚拟 IP:主机端口
,例如:192.1.1.1:3389
。
-
点击 连接。