Skip to content

Rocky 9 VM 部署操作日志 — 2026-08-27

目标: 在 KubeVirt 集群 (RKE2, 6 节点, Rocky Linux 9.8) 上通过 hostPath PV 启动一个 Rocky Linux 9 虚拟机。 结果: ✅ 成功。VM rocky9-test 运行中,SSH 可达。


目录

  1. 环境信息
  2. 磁盘镜像准备
  3. PV/PVC 创建
  4. VM 创建与故障排查
  5. 最终验证
  6. VM 配置清单
  7. 经验总结
  8. rocky9-vm3 部署记录 (containerDisk 在线资源)
  9. rocky9-vm2 部署记录

1. 环境信息

项目
集群RKE2 v1.35.6
节点数6 (1 master, 5 worker)
节点 OSRocky Linux 9.8
容器网络Calico VXLAN (CNI)
镜像仓库Harbor 192.168.122.156:30000 (代理 quay.io/kubevirt)
KubeVirt 版本v1.9.0
virt-operator2 副本, Running
virt-controller2 副本, Running
virt-handlerDaemonSet, 6 节点
工作节点 (目标)sza122031.local
镜像源http://192.168.122.9:9001/repo/osiso/

2. 磁盘镜像准备

2.1 下载 qcow2

bash
# 在目标节点 sza122031.local 执行
curl -Lo /tmp/Rocky-9-GenericCloud.qcow2 \
  http://192.168.122.9:9001/repo/osiso/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2
  • 文件大小: ~630 MB (qcow2 压缩格式)
  • 格式: QCOW2 (QEMU Copy-On-Write v2)

2.2 转换为 raw 格式

bash
dnf install -y qemu-img   # 如果没有安装

qemu-img convert -f qcow2 -O raw \
  /tmp/Rocky-9-GenericCloud.qcow2 \
  /tmp/Rocky-9-GenericCloud.raw
  • 原始大小: 10 GiB (raw 格式)
  • 转换时间: 约 30 秒

2.3 放置到 KubeVirt 期望的目录结构

KubeVirt hostPath PVC 要求:

  • PV 的 hostPath.path 指向一个目录
  • 目录中必须有一个名为 disk.img 的文件
  • 不能直接指向文件路径
bash
mkdir -p /var/lib/vm-images/rocky9-disk
mv /tmp/Rocky-9-GenericCloud.raw /var/lib/vm-images/rocky9-disk/disk.img
chmod 666 /var/lib/vm-images/rocky9-disk/disk.img

# 验证
ls -la /var/lib/vm-images/rocky9-disk/
# total 10485764
---

## 3. PV/PVC 创建

### 3.1 PersistentVolume

```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: rocky9-vm-disk
  labels:
    type: rocky9-disk
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/var/lib/vm-images/rocky9-disk"   # 指向目录,不是文件!
    type: Directory
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - sza122031.local

3.2 PersistentVolumeClaim

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rocky9-vm-disk
  namespace: default
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  selector:
    matchLabels:
      type: rocky9-disk

3.3 验证绑定

bash
kubectl get pv rocky9-vm-disk
# NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   BOUND
# rocky9-vm-disk   10Gi       RWO            Retain           Bound

kubectl get pvc rocky9-vm-disk -n default
# NAME             STATUS   VOLUME           CAPACITY   ACCESS MODES
# rocky9-vm-disk   Bound    rocky9-vm-disk   10Gi       RWO

4. VM 创建与故障排查

4.1 初始 VM 定义

yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: rocky9-test
  namespace: default
  labels:
    app: rocky9-test
    kubevirt.io/vm: rocky9-test
spec:
  running: true
  template:
    metadata:
      labels:
        app: rocky9-test
        kubevirt.io/vm: rocky9-test
    spec:
      nodeSelector:
        kubernetes.io/hostname: sza122031.local
      domain:
        cpu:
          cores: 2
        memory:
          guest: 2Gi
        devices:
          disks:
          - name: rootdisk
            disk:
              bus: virtio
          - name: cloudinit
            disk:
              bus: virtio
          interfaces:
          - name: default
            masquerade: {}
      networks:
      - name: default
        pod: {}
      volumes:
      - name: rootdisk
        persistentVolumeClaim:
          claimName: rocky9-vm-disk
      - name: cloudinit
        cloudInitNoCloud:
          userData: |
            #cloud-config
            hostname: rocky9-test
            password: xxx
            chpasswd:
              expire: false
            ssh_pwauth: true
            disable_root: false

创建后 VMI 一直卡在 Scheduling 阶段。以下是按排查顺序记录的四个问题:


问题 1: virt-handler 证书缺失

症状:

bash
kubectl logs -n kubevirt -l kubevirt.io=virt-handler -c virt-handler --tail=5
# ERROR: failed to load the certificate /etc/virt-handler/clientcertificates/tls.crt

分析过程:

  1. virt-handler 需要通过 gRPC 与 virt-launcher Pod 通信
  2. gRPC 需要 mTLS 双向认证
  3. virt-handler DaemonSet 未挂载 kubevirt-virt-handler-certs Secret
  4. 尝试 customizeComponents patch → 被 virt-operator 覆盖
  5. 尝试直接修改 DaemonSet → 同样被覆盖

解决方案 (临时):

bash
# 从 Secret 提取证书
kubectl get secret kubevirt-virt-handler-certs -n kubevirt \
  -o jsonpath='{.data.tls\.crt}' | base64 -d > /tmp/handler.crt
kubectl get secret kubevirt-virt-handler-certs -n kubevirt \
  -o jsonpath='{.data.tls\.key}' | base64 -d > /tmp/handler.key

# 复制到 virt-handler Pod
POD=$(kubectl get pods -n kubevirt -l kubevirt.io=virt-handler \
  -o jsonpath='{.items[0].metadata.name}')
kubectl exec -n kubevirt $POD -c virt-handler -- \
  mkdir -p /etc/virt-handler/clientcertificates
kubectl cp /tmp/handler.crt kubevirt/$POD:/etc/virt-handler/clientcertificates/tls.crt \
  -c virt-handler
kubectl cp /tmp/handler.key kubevirt/$POD:/etc/virt-handler/clientcertificates/tls.key \
  -c virt-handler

⚠️ 注意: 此修复在 virt-handler Pod 重启后失效,需重新执行。


问题 2: CDI CRD 存根干扰

症状:

bash
kubectl logs -n kubevirt -l kubevirt.io=virt-controller -c virt-controller --tail=5
# Failed to get filesystem overhead for PVC default/rocky9-vm-disk
# CDI config not initialized

分析过程:

  1. virt-controller 启动时检测到 CDI CRD 存在
  2. 尝试通过 CDIConfig API 获取文件系统开销比例
  3. 但 CDI 只有 CRD 没有完整部署 (之前尝试过 CDI 但未成功)
  4. 导致 virt-controller 一直 re-enqueue VMI

解决方案:

bash
# 删除所有 CDI 相关空壳 CRD
kubectl delete crd cdiconfigs.cdi.kubevirt.io
kubectl delete crd cdis.cdi.kubevirt.io
kubectl delete crd datavolumes.cdi.kubevirt.io
kubectl delete crd storageprofiles.cdi.kubevirt.io
kubectl delete crd datasources.cdi.kubevirt.io
kubectl delete crd dataimportcrons.cdi.kubevirt.io
kubectl delete crd objecttransfers.cdi.kubevirt.io
kubectl delete crd uploadtokenrequests.cdi.kubevirt.io
kubectl delete crd volumeimportsources.cdi.kubevirt.io
kubectl delete crd volumeuploadsources.cdi.kubevirt.io
kubectl delete ns cdi

# 重启 virt-controller 使其重新评估
kubectl delete pods -n kubevirt -l kubevirt.io=virt-controller

📌 关键发现: virt-controller 在启动时检测 CRD 列表。如果 CDI CRD 存在, 它就假设 CDI 已部署并尝试使用 CDIConfig API。删除 CRD 后重启 virt-controller 可让它在启动时跳过 CDI 集成逻辑。


问题 3: EvictionStrategy 冲突

症状:

bash
kubectl get events -n default --sort-by=.lastTimestamp | tail -5
# Warning  Migrated  vmi/rocky9-test
# EvictionStrategy is set but vmi is not migratable;
# cannot migrate VMI: PVC rocky9-vm-disk is not shared,
# live migration requires that all PVCs must be shared
# (using ReadWriteMany access mode)

分析过程:

  1. KubeVirt CR 中配置了全局 evictionStrategy: LiveMigrate
  2. hostPath PV 是 ReadWriteOnce,不支持 LiveMigration
  3. KubeVirt 发现无法迁移但仍尝试,导致 VMI 被驱逐

解决方案:

bash
# 方法 A: 在 VM 级别覆盖 (推荐)
# 在 VM spec.template.spec 中添加:
evictionStrategy: None

# 方法 B: 修改全局 KubeVirt CR (影响所有 VM)
kubectl patch kv kubevirt -n kubevirt --type=merge \
  -p '{"spec":{"configuration":{"evictionStrategy":"None"}}}'

📌 我们在 VM 定义和全局 CR 中都设置了 None


问题 4: 磁盘权限 Permission denied

症状:

bash
kubectl get events -n default --sort-by=.lastTimestamp | tail -5
# Warning  SyncFailed  vmi/rocky9-test
# LibvirtError(Code=1, Domain=10, Message='internal error: process exited
# while connecting to monitor: qemu-kvm: -blockdev {...}:
# Could not open '/var/run/kubevirt-private/vmi-disks/rootdisk/disk.img':
# Permission denied')

分析过程:

  1. virt-handler 成功将 hostPath 挂载到 virt-launcher Pod
  2. 挂载路径: /var/run/kubevirt-private/vmi-disks/rootdisk/disk.img
  3. 实际上是 bind-mount 到 /var/lib/vm-images/rocky9-disk/disk.img
  4. QEMU 进程以 UID 107 (qemu 用户) 运行
  5. 文件权限: -rw------- (600),只有 root 可读

解决方案:

bash
# 方案 1: 修改文件权限 (简单直接)
chmod 666 /var/lib/vm-images/rocky9-disk/disk.img

# 验证
ls -la /var/lib/vm-images/rocky9-disk/disk.img
# -rw-rw-rw-. 1 root root 10737418240 Aug 27 11:14 disk.img

📌 另一个常见错误: PV 的 hostPath 直接指向文件 (type: File) 而不是目录。 KubeVirt 期望 hostPath 指向一个目录,目录内有 disk.img 文件。 如果 PV 直接指向文件路径,KubeVirt 会尝试在文件路径下查找 disk.img, 导致找不到文件。


5. 最终验证

5.1 VM 状态

bash
kubectl get vm,vmi -n default
NAME                                     AGE    STATUS    READY
virtualmachine.kubevirt.io/rocky9-test   5m4s   Running   True

NAME                                             AGE     PHASE     IP              NODENAME          READY
virtualmachineinstance.kubevirt.io/rocky9-test   3m58s   Running   10.22.183.219   sza122031.local   True

5.2 Libvirt 虚拟机状态

bash
kubectl exec -n default virt-launcher-rocky9-test-vblnz -c compute -- virsh list --all
 Id   Name                  State
-------------------------------------
 1    default_rocky9-test   running

5.3 网络连通性

bash
ping -c 2 10.22.183.219
64 bytes from 10.22.183.219: icmp_seq=1 ttl=63 time=1.16 ms
64 bytes from 10.22.183.219: icmp_seq=2 ttl=63 time=0.366 ms

5.4 SSH 登录

bash
sshpass -p rocky ssh -o StrictHostKeyChecking=no \
  -o PreferredAuthentications=password \
  rocky@10.22.183.219 "hostname && uname -a"
rocky9-test
Linux rocky9-test 5.14.0-687.10.1.el9_8.0.1.x86_64 #1 SMP PREEMPT_DYNAMIC Sun May 24 12:01:19 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux

5.5 系统信息

bash
sshpass -p rocky ssh rocky@10.22.183.219 "cat /etc/os-release | grep PRETTY_NAME && free -h | head -2 && df -h / | tail -1"
PRETTY_NAME="Rocky Linux 9.8 (Blue Onyx)"
               total        used        free      shared  buff/cache   available
Mem:           1.7Gi       301Mi       1.3Gi       4.0Mi       236Mi       1.4Gi
/dev/vda4       8.9G 1009M  7.9G  12% /

5.6 Cloud-init 执行日志

从 virt-launcher 的 guest-console-log 容器获取:

Cloud-init v. 24.4-8.el9.rocky.0.1 finished at Thu, 27 Aug 2026 11:42:57 +0000.
Datasource DataSourceNoCloud [seed=/dev/vdb].  Up 54.24 seconds

Rocky Linux 9.8 (Blue Onyx)
Kernel 5.14.0-687.10.1.el9_8.0.1.x86_64 on x86_64

rocky9-test login:

5.7 停止/重启测试

bash
# 停止
kubectl patch vm rocky9-test -n default --type merge \
  -p '{"spec":{"running":false}}'

# 启动
kubectl patch vm rocky9-test -n default --type merge \
  -p '{"spec":{"running":true}}'

停止后 VMI 被删除 (~10秒),重新启动后 VMI 重新创建并进入 Running (~30秒)。

6. VM 配置清单

属性
VM 名称rocky9-test
命名空间default
OSRocky Linux 9.8 (Blue Onyx)
内核5.14.0-687.10.1.el9_8.0.1.x86_64
CPU2 cores
内存2 GiB
磁盘10 GiB (virtio, 实际可用 8.9G)
网络Pod 网络 (masquerade)
VMI IP10.22.183.219 (DHCP, 可能变化)
SSH 用户rocky
SSH 密码xxx
root 密码未设置 (cloud-init 仅设置了 rocky 用户)
节点sza122031.local (固定)
PV 路径/var/lib/vm-images/rocky9-disk/
镜像文件disk.img (10 GiB raw)
EvictionNone (不支持 LiveMigrate)

7. 经验总结

7.1 KubeVirt hostPath PVC 的正确用法

正确 ✅:
  PV hostPath.path: "/var/lib/vm-images/rocky9-disk"
  PV hostPath.type: "Directory"
  目录内容: disk.img

错误 ❌:
  PV hostPath.path: "/var/lib/vm-images/rocky9-disk/disk.img"
  PV hostPath.type: "File"

7.2 KubeVirt 启动流程 (VMI 生命周期)

VM (running: true)
  → virt-controller 创建 VMI
    → virt-controller 调度 VMI 到节点
      → virt-handler 检测到调度
        → virt-handler 创建 virt-launcher Pod
          → virt-launcher 挂载 PVC (hostPath → /var/run/kubevirt-private/vmi-disks/rootdisk/)
            → QEMU 启动 (读取 disk.img)
              → Guest OS boot
                → cloud-init 执行
                  → VMI 进入 Running phase

7.3 常见问题排查命令

bash
# 1. 检查 VMI 阶段和事件
kubectl get vmi -n default
kubectl describe vmi rocky9-test -n default

# 2. 检查 virt-controller 日志 (调度/CDI 问题)
kubectl logs -n kubevirt -l kubevirt.io=virt-controller \
  -c virt-controller --tail=20

# 3. 检查 virt-handler 日志 (节点级问题)
kubectl logs -n kubevirt -l kubevirt.io=virt-handler \
  -c virt-handler --tail=20

# 4. 检查 virt-launcher 日志 (QEMU/libvirt 问题)
kubectl logs -n default -l kubevirt.io=virt-launcher \
  -c compute --tail=20

# 5. 查看 Guest 控制台输出 (boot 日志)
kubectl logs -n default -l kubevirt.io=virt-launcher \
  -c guest-console-log --tail=50

# 6. 检查 Libvirt 虚拟机状态
POD=$(kubectl get pods -n default -l kubevirt.io=virt-launcher \
  -o jsonpath='{.items[0].metadata.name}')
kubectl exec -n default $POD -c compute -- virsh list --all

# 7. 检查已安装的 CRD
kubectl get crd | grep -E '(kubevirt|cdi)'

7.4 virt-handler 证书修复脚本

每次 virt-handler Pod 重启后执行:

bash
#!/bin/bash
# fix-virt-handler-certs.sh
# 修复 virt-handler clientcertificates 缺失问题

set -e

echo "提取证书..."
kubectl get secret kubevirt-virt-handler-certs -n kubevirt \
  -o jsonpath='{.data.tls\.crt}' | base64 -d > /tmp/handler.crt
kubectl get secret kubevirt-virt-handler-certs -n kubevirt \
  -o jsonpath='{.data.tls\.key}' | base64 -d > /tmp/handler.key

for POD in $(kubectl get pods -n kubevirt -l kubevirt.io=virt-handler \
  -o jsonpath='{.items[*].metadata.name}'); do
  echo "修复 $POD..."
  kubectl exec -n kubevirt $POD -c virt-handler -- \
    mkdir -p /etc/virt-handler/clientcertificates
  kubectl cp /tmp/handler.crt \
    kubevirt/$POD:/etc/virt-handler/clientcertificates/tls.crt \
    -c virt-handler
  kubectl cp /tmp/handler.key \
    kubevirt/$POD:/etc/virt-handler/clientcertificates/tls.key \
    -c virt-handler
  echo "  ✓ $POD 已修复"
done

rm -f /tmp/handler.crt /tmp/handler.key
echo "完成!"

7.5 下一步计划

  1. CDI 完整部署: 安装 CDI Operator,支持 DataVolume 自动下载/转换镜像
  2. 多 VM 模板: 创建 VM template 支持快速克隆部署
  3. 存储升级: 配置 NFS/Longhorn 支持 ReadWriteMany + LiveMigration
  4. SSH Service: 创建 NodePort/LoadBalancer Service 暴露 SSH 端口
  5. virt-handler 证书永久修复: 等待 KubeVirt 上游修复或创建 initContainer
  6. 批量 VM 管理: 通过 Web UI 或脚本管理 VM 生命周期

8. rocky9-vm2 部署记录 (第二台 VM)

8.1 部署概要

项目
VM 名称rocky9-vm2
OSRocky Linux 9.8 (Blue Onyx)
CPU2 cores
内存2Gi
磁盘10Gi (hostPath PV)
网络Pod 网络 (masquerade)
VMI IP10.22.183.231
SSH 用户rocky
SSH 密码xxx
节点sza122031.local (固定)
PV 路径/var/lib/vm-images/rocky9-vm2-disk/
镜像文件disk.img (10 GiB raw)
状态✅ Running

8.2 遇到的问题和解决

#问题原因解决方案
1节点 sza122031.local 内存不足多个 stuck/terminating pods 占用内存kubectl delete pod --force --grace-period=0 强制删除
2API Server 端口 6443 无法连接etcd crash loop, kube-apiserver 反复重启使用备用 API endpoint (192.168.122.23:6443 via /tmp/rke2-23.yaml)
3VMI 调度失败: "FailedScheduling"节点 not-ready, kubevirt.io/schedulable=false等待节点恢复 Ready 状态
4virt-launcher pod 卡在 Pending节点不稳定, kubelet 无法处理 pod节点恢复后自动重建
5virt-handler pod Unknown 状态RKE2 重启后旧 pod 状态不同步kubectl delete pod --force 让 DaemonSet 重建
6节点 label kubevirt.io/schedulable=falsevirt-handler 未正常运行标记节点重建 virt-handler pod 后自动修复

8.3 最终状态

bash
$ kubectl get vm rocky9-vm2 -n default
NAME         AGE   STATUS    READY
rocky9-vm2   19m   Running   True

$ kubectl get vmi rocky9-vm2 -n default
NAME         AGE   PHASE     IP              NODENAME          READY
rocky9-vm2   3m    Running   10.22.183.231   sza122031.local   True

$ ssh rocky@10.22.183.231  # password: xxx
=== VM BOOT SUCCESSFUL ===
rocky9-vm2
NAME="Rocky Linux"
VERSION="9.8 (Blue Onyx)"

=== UPTIME ===
 14:39:43 up 2 min

=== MEMORY ===
               total        used        free      shared   buff/cache   available
Mem:           1.7Gi       318Mi       1.3Gi       4.0Mi     236Mi       1.4Gi

=== DISK ===
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda4       8.9G 1009M  7.9G  12% /

8.4 关键操作时间线

时间 (UTC)事件
14:17VM 和 VMI 创建成功
14:17~14:25节点内存不足, API Server 不可达
14:25强制删除 stuck pods, 释放内存
14:28节点恢复 Ready, etcd 连接成功
14:30kube-apiserver (port 6443) 恢复
14:33virt-handler pod 重建并标记节点 schedulable=true
14:33新的 virt-launcher pod 创建并启动
14:36VMI 进入 Running 阶段, Guest Agent 连接
14:39SSH 登录成功, VM 完全可用


9. rocky9-vm3 部署记录 (第三台 VM — containerDisk 在线资源)

9.1 部署概要

项目
VM 名称rocky9-vm3
OSRocky Linux 9.8 (Blue Onyx)
CPU2 cores
内存2Gi
磁盘方式containerDisk (在线 OCI 镜像,无需 hostPath PV)
containerDisk 镜像192.168.122.156:30000/kubevirt-local/rocky9-containerdisk:v9.8
网络Pod 网络 (masquerade)
VMI IP10.22.14.81
SSH 用户rocky
SSH 密码xxx
节点sza122031.local (调度)
状态✅ Running

9.2 containerDisk 方案 vs hostPath PV 对比

维度hostPath PV (vm1/vm2)containerDisk (vm3)
磁盘准备需手动在每个节点放置 disk.img镜像存入 Harbor,按需拉取
PV/PVC需要创建 PV 和 PVC不需要
节点绑定必须 nodeSelector 固定节点可调度到任意节点
部署复杂度需 3 个资源 (PV + PVC + VM)仅需 1 个 VM YAML
镜像来源本地文件Harbor OCI 镜像
适合场景单节点/测试多节点/生产

9.3 OCI 镜像构建过程

使用 skopeo 将 qcow2 磁盘镜像打包为 OCI 镜像并推送到 Harbor:

bash
# 1. 下载 qcow2 源镜像 (617MB)
curl -Lo /tmp/Rocky-9-GenericCloud.qcow2 \
  http://192.168.122.9:9001/repo/osiso/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2

# 2. 构建 OCI image layout
mkdir -p /tmp/oci-build/disk /tmp/oci-build/blobs/sha256
cp /tmp/Rocky-9-GenericCloud.qcow2 /tmp/oci-build/disk/disk.img

# 3. 创建 layer tarball
tar -C /tmp/oci-build -cf /tmp/oci-build/layer.tar disk/

# 4. 计算 SHA256 并组装 OCI manifest/config
LAYER_SHA=$(sha256sum /tmp/oci-build/layer.tar | awk '{print $1}')
# ... (构建 config.json, manifest.json, index.json, oci-layout)

# 5. 推送到 Harbor
skopeo copy --dest-tls-verify=false \
  --dest-creds "admin:xxx" \
  oci:/tmp/oci-build:v9.8 \
  docker://192.168.122.156:30000/kubevirt-local/rocky9-containerdisk:v9.8

9.4 遇到的问题和解决

#问题原因解决方案
1skopeo push unauthorized使用了错误密码 xxx从文档找到正确密码 xxx
2skopeo push denied: proxy projectkubevirt 项目是 proxy 类型,不能直接 push改用 kubevirt-local 普通项目
3ImagePullBackOff: HTTP vs HTTPS节点 containerd hosts.toml 配置 server = "https://..." 但 Harbor 是 HTTP`sed -i 's
4VM spec imagePullSecrets 字段错误KubeVirt 不支持 spec.template.spec.imagePullSecrets改用 containerDisk.imagePullSecret 字段

9.5 最终状态

bash
$ kubectl get vm rocky9-vm3 -n default
NAME         AGE     STATUS    READY
rocky9-vm3   3m36s   Running   True

$ kubectl get vmi rocky9-vm3 -n default -o wide
NAME         AGE    PHASE     IP            NODENAME          READY   LIVE-MIGRATABLE
rocky9-vm3   116s   Running   10.22.14.81   sza122031.local   True    True

$ ssh rocky@10.22.14.81  # password: xxx
rocky9-vm3
NAME="Rocky Linux"
VERSION="9.8 (Blue Onyx)"
    inet 10.0.2.2/24 brd 10.0.2.255 scope global dynamic noprefixroute eth0

9.6 关键操作时间线

时间 (UTC)事件
14:47开始在 192.168.122.31 构建 OCI 镜像
15:01OCI layer tarball 完成 (342MB → 526MB → 完成)
15:01OCI manifest/config 生成完成
15:01首次推送失败: unauthorized (密码错误)
15:03使用正确密码推送到 kubevirt 项目失败: proxy project
15:04推送到 kubevirt-local 项目成功
15:05创建 VM, 调度到 sza122023.local, ImagePullBackOff
15:06修复所有可访问节点 hosts.toml: https → http
15:07删除失败 Pod, 重新调度
15:08新 Pod 拉取镜像成功, Init 阶段
15:09VM 状态 Running=True, VMI Running
15:10SSH 登录成功, VM 完全可用

9.7 注意事项

  1. Harbor 密码: xxx (记录在 15-harbor-admin-密码重置实战.md)
  2. kubevirt 项目是 proxy 类型: 只能做镜像代理,不能直接推送镜像。推送用 kubevirt-local
  3. hosts.toml 会被 RKE2 覆盖: 如果 RKE2 重启,hosts.toml 会重新生成为 HTTPS。需要修改 registries.yaml 中的 configs 段去掉 tls 配置,或在 RKE2 重启后再次修复。
  4. 未修复的节点: 192.168.122.28 和 192.168.122.29 SSH 不通,未修复 hosts.toml。如果 VM 调度到这两个节点会拉取失败。

日志记录时间: 2026-08-27
操作人: AI Agent (自动化部署)