基于 ISO 制作 Windows 镜像的 KubeVirt 操作
本文档讨论了一种基于开源组件 KubeVirt 的虚拟机解决方案,通过 KubeVirt 虚拟化技术使用 ISO 镜像文件创建 Windows 操作系统镜像。
前提条件
约束与限制
操作步骤
创建镜像
创建由准备好的 Windows 和 virtio-win ISO 镜像构成的 Docker 镜像,并将其推送至仓库中,本文档以 Windows Server 2019 为例。
从 Windows ISO 创建 Docker 镜像
-
进入 ISO 镜像存放目录,在终端中执行以下命令将 ISO 镜像重命名为 win.iso。
mv <ISO 镜像名称> win.iso # 用实际镜像名称替换 <ISO 镜像名称>,例如: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 # 根据实际环境替换仓库
创建虚拟机
-
访问 Container Platform。
-
在左侧导航栏中,点击 虚拟化 > 虚拟机。
-
点击 创建虚拟机。
-
在表单页面中填写必要的参数,如 名称、镜像等,具体参数和配置请参考 创建虚拟机。
-
切换到 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 才能正确识别,因此需要逐个选择每个分区并点击 Delete 删除所有分区,让系统自动处理。
-
完成管理员账号密码配置后,点击页面左上角的 发送远程命令,在下拉菜单中选择 Ctrl-Alt-Delete。
-
当提示 Ctrl+Alt+Delete 组合键将重启服务器,确定重启 时,点击 确定。
-
输入密码以访问 Windows 系统桌面,此时 Windows 操作系统安装已完成。
安装 virtio-win-tools
此工具主要包含所需的驱动程序。
-
打开文件资源管理器。
-
双击 CD Drive(E:) virtio-win-<version>,运行目录下的 virtio-win-guest-tools 进入安装页面,并根据安装指引进行安装。<version> 部分需根据实际情况确认。
-
安装完成后,关闭 Windows 系统。
导出自定义 Windows 镜像
具体操作请参考 导出虚拟机镜像。
使用 Windows 镜像
-
访问 Container Platform。
-
在左侧导航栏中,点击 虚拟化 > 虚拟机。
-
点击 创建虚拟机。
-
在表单页面中填写必要参数。对于镜像,选择已导出的 Windows 镜像。具体详细参数和配置请参考 创建虚拟机。
-
(可选)如果使用较新的操作系统,例如 Windows 11,则可能需要启用 clock、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 类型的内部路由,将远程桌面连接的端口进行暴露。
-
访问 Container Platform。
-
在左侧导航栏中,点击 虚拟化 > 虚拟机。
-
单击列表中用于创建 Windows 镜像的虚拟机名称,进入详情页面。
-
单击 登录信息 区域中 内部路由 右侧的 添加 图标。
-
根据以下说明配置参数。
参数 | 说明 |
---|
类型 | 选择 NodePort。 |
端口 | - 协议:选择 TCP。
- 服务端口:使用 3389。
- 虚拟机端口:使用 3389。
- 服务端口名称:使用 rdp。
|
-
点击 确定 返回详情页面。
-
在 登录信息 区域中点击 内部路由 链接。
-
保存基本信息区域中的 虚拟 IP 以及端口区域的 主机端口。
远程访问
本文档以使用 Windows 操作系统进行远程连接为例进行说明。其他操作系统可以使用支持 RDP 协议的软件进行连接。
-
打开 远程桌面连接。
-
输入 添加内部路由 步骤中保存的虚拟 IP 和主机端口,格式为 虚拟 IP:主机端口,例如:192.1.1.1:3389。
-
点击 连接。