【OKD 5.0】 仮想マシンの作成・ライブ マイグレーション(NFS・iSCSI)・経路障害・HA の確認手順

OKD Virtualization で仮想マシンを作り、ライブ マイグレーション(ディスクが NFS の場合と iSCSI の LUN の場合)、iSCSI の 1 経路の障害、ノードの電源断(HA)を確認した手順と結果です。

目次

この記事の前提

コンソールでの仮想マシンの作成

(1) [Virtualization] → [VirtualMachines] で [Create] → [From InstanceType] などから作成ウィザードを開き、[Custom configuration (default)] を選んで [Next] をクリックします。作成先のプロジェクトは default です。

作成方法

(2) [Guest OS] で [Other Linux] を選び、[Guest operating system type] で centos.stream9 を選びます。

ゲスト OS

(3) [Boot source] で、自動で取り込まれた起動用ボリューム(centos-stream9、nfs-csi)を選びます。仮想マシンのディスクは、このボリュームを複製して作られます。

起動ボリューム

(4) [Compute resources] で、インスタンス タイプ(CPU とメモリーの組み合わせ)を選びます。ここでは General Purpose(U シリーズ)の small(1 CPU・2 GiB)にしました。

インスタンス タイプ
シリーズ用途
U(General Purpose)汎用
CX(Compute Exclusive)CPU を専有する(性能重視)
M(Memory Intensive)メモリーの多い構成
O(Overcommitted)メモリーを多めに割り当てる(集約率重視)

(5) [Customization] では、ディスク(Storage)、NIC(Network)、配置(Scheduling)、SSH、初回の設定(Initial run)を変えられます。

カスタマイズ

(6) [Initial run] の cloud-init では、ログインするユーザー(centos)とパスワード(自動で作られる)が設定されます。

初回の設定

(7) [Review and create] で名前と説明を入力し、[Create VirtualMachine] をクリックします。

確認と作成

(8) ディスクの複製(Provisioning)の後、Running になります。

作成中

コンソールのウィザードで作った仮想マシンは、既定の Pod ネットワーク(masquerade)につながります。この NIC の IP アドレスはクラスタ内部のもので、ライブ マイグレーションのたびに変わります(この検証では 10.130.0.89 → 10.128.0.22 → 10.130.0.90)。LAN から使う仮想マシンは、次の YAML のように VM 用ネットワーク(vm-lan)につなぎます。

LAN につないだ仮想マシン(YAML)

試験用に、ディスクが NFS の仮想マシン(vm-lm01、192.168.1.196)と、iSCSI の LUN の仮想マシン(vm-iscsi01、192.168.1.197)を YAML で作ります。違いはストレージ クラスとボリューム モードだけです。

実行する場所:踏み台サーバー(root)

# cat > vm-lm01.yaml <<'EOF'
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: vm-lm01
  namespace: default
spec:
  runStrategy: Always
  instancetype:
    name: u1.small
  preference:
    name: centos.stream9
  dataVolumeTemplates:
  - metadata:
      name: vm-lm01-disk
    spec:
      source:
        pvc:
          namespace: kubevirt-os-images
          name: centos-stream9-27899ea8a37b
      storage:
        storageClassName: nfs-csi        # iSCSI のときは iscsi-static
        volumeMode: Filesystem           # iSCSI のときは Block
        accessModes:
        - ReadWriteMany
        resources:
          requests:
            storage: 20Gi
  template:
    spec:
      domain:
        devices:
          interfaces:
          - name: lan
            bridge: {}
            macAddress: 02:00:00:0d:01:96
      networks:
      - name: lan
        multus:
          networkName: vm-lan
      volumes:
      - name: rootdisk
        dataVolume:
          name: vm-lm01-disk
      - name: cloudinitdisk
        cloudInitNoCloud:
          userData: |
            #cloud-config
            user: centos
            password: P@ssw0rd-okd
            chpasswd: { expire: False }
            ssh_pwauth: True
          networkData: |
            version: 2
            ethernets:
              lan:
                match:
                  macaddress: "02:00:00:0d:01:96"
                set-name: eth0
                addresses: [192.168.1.196/24]
                gateway4: 192.168.1.1
                nameservers:
                  addresses: [192.168.1.254]
EOF
# oc apply -f vm-lm01.yaml
# oc -n default get vmi -o wide

期待する出力:

NAME         AGE   PHASE     IP              NODENAME   READY   LIVE-MIGRATABLE
vm-iscsi01   106s  Running   192.168.1.197   master-3   True    True
vm-lm01      39m   Running   192.168.1.196   master-1   True    True
項目説明
runStrategy: Always常に動かす(止まったら起動し直す)。HA に必要
instancetype / preferenceCPU・メモリーの組み合わせと、OS に合わせた既定値(ディスクのバスなど)
dataVolumeTemplates仮想マシンと一緒に作るディスク。source の PVC(起動用イメージ)を複製する
accessModes: ReadWriteManyライブ マイグレーションに必要。LIVE-MIGRATABLE が True になる
interfaces.bridge + networks.multusVM 用ネットワーク vm-lan(ノードの br-vm)にブリッジでつなぐ
networkDatacloud-init の固定 IP。MAC アドレスで NIC を指定する

コンソールの [VirtualMachines] → [Virtual machines] タブに、LAN の IP アドレスが表示されます。

仮想マシンの一覧

ライブ マイグレーション

コンソールから

(1) 仮想マシンの [Actions] → [Migration] → [Compute] をクリックします([Storage] は、ディスクを別のストレージ クラスへ移す操作です)。

Migration

(2) [Specific Node] を選んで移動先のノードを選び、[Migrate VirtualMachine] をクリックします([Automatically selected Node] ならクラスタが選びます)。

移動先のノード

(3) 移動が終わると、仮想マシンは移動先のノードで Running のままです。

移動後

CLI から

VirtualMachineInstanceMigration を作ると、同じ移動が始まります(virtctl migrate と同じ)。

# cat <<'EOF' | oc create -f -
apiVersion: kubevirt.io/v1
kind: VirtualMachineInstanceMigration
metadata:
  generateName: vm-lm01-mig-
  namespace: default
spec:
  vmiName: vm-lm01
EOF
# oc -n default get vmi vm-lm01 -o jsonpath='{.status.migrationState.sourceNode} -> {.status.migrationState.targetNode} completed={.status.migrationState.completed}{"\n"}'

期待する出力:

master-1 -> master-3 completed=true

結果

踏み台から仮想マシンの LAN の IP アドレスへ 0.2 秒間隔で ping を送りながら、3 回ずつ移動しました。

ディスク移動(migrationState の開始〜終了)ping の最長の途切れ
NFS(Filesystem・RWX)2 秒・2 秒・3 秒1.2 秒・0.4 秒・0.6 秒
iSCSI の LUN(Block・RWX、マルチパス)3 秒・3 秒・2 秒0.8 秒・3.1 秒・0.6 秒

iSCSI の LUN の場合、移動中は移動元と移動先の両方のノードが同じ LUN にログインし、QEMU が書き込む側を切り替えます。移動が終わると、移動元のノードの iSCSI セッションは閉じられ、移動先のノードだけが 2 経路でつながっています。

実行する場所:踏み台サーバー(仮想マシンが動くノード)

# oc debug node/master-1 -q -- chroot /host sh -c 'iscsiadm -m session; multipath -ll'

期待する出力:

tcp: [3] 10.40.81.1:3260,1 iqn.2026-10.lab.hvdoc:okd (non-flash)
tcp: [4] 10.40.82.1:3260,1 iqn.2026-10.lab.hvdoc:okd (non-flash)
mpatha (360014055254428a3dce45d4a6f0fccfc) dm-0 LIO-ORG,vm01
size=20G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
`-+- policy='service-time 0' prio=50 status=active
  |- 8:0:0:0 sdc 8:32 active ready running
  `- 9:0:0:0 sdd 8:48 active ready running

iSCSI の 1 経路の障害

vm-iscsi01 が動いているノード(master-1)の iSCSI 1 系統目(ens19、10.40.81.x)のリンクを、仮想化基盤の側で切りました。仮想マシンの中では 1.5 GB の書き込み(dd、oflag=direct)を続けました。

マルチパスの状態(リンクを切った後):

`-+- policy='service-time 0' prio=50 status=active
  |- 8:0:0:0 sdc 8:32 failed faulty offline
  `- 9:0:0:0 sdd 8:48 active ready  running
項目結果
マルチパス1 系統目(sdc)が failed、2 系統目(sdd)で継続
書き込み止まらずに完了(1.5 GB、31 秒、50.3 MB/s)
仮想マシンへの ping欠落なし
リンクを戻した後sdc が自動で active に戻った

HA(ノードの電源断)

vm-lm01 が動いているノード(master-3)の電源を強制的に切りました。

(1) [Compute] → [Nodes] で、master-3 が Not Ready になります。

ノードの停止

(2) Node Health Check が異常を見つけ、Self Node Remediation がノードの復旧(SelfNodeRemediation)を始めます。止まったノードの仮想マシンは、安全に再起動したとみなせるまで待った後、別のノードで起動し直します。

# oc get snr -A
# oc get nodehealthcheck nhc-control-plane -o jsonpath='{.status.phase} {.status.healthyNodes}/{.status.observedNodes}{"\n"}'

期待する出力(復旧中):

NAMESPACE                         NAME             AGE
openshift-workload-availability   master-3-7jvbd   3m8s
Remediating 2/3
経過(電源断から)状態
78 秒ノードが NotReady
152 秒SelfNodeRemediation が作られた(NotReady が 60 秒続いた後)
289 秒仮想マシンが別のノードへ(Scheduling)
295 秒master-2 で Running
331 秒ゲストが起動し ping が通った(途切れは 330 秒)

Node Health Check と Self Node Remediation を入れていないと、止まったノードの仮想マシンは「Running(止まったノード)」のまま、別のノードでは起動しません。止まったノードで実は動き続けている場合に、同じディスクを 2 か所で使って壊すのを防ぐためです。

(3) 止めたノードの電源を入れると、ノードが Ready に戻り、SelfNodeRemediation が消えて、NodeHealthCheck が Enabled 3/3 に戻ります。

この検証では、電源を入れたノードが NotReady のまま戻りませんでした。 強制的な電源断でコンテナ ランタイム(CRI-O)が「正常に終了しなかった」と判断して既存のコンテナを片付け、その後の状態確認で CNI の multus-shim を呼んだまま応答しなくなりました。multus-shim は multus の Pod(デーモン)を待ちますが、その Pod は CRI-O が動かないと起動できないため、互いに待ち合う状態です。CRI-O は systemd のウォッチドッグ(1 分)で強制終了と起動を繰り返していました(journalctl -u crio に「Watchdog timeout」「Killing process … (multus-shim)」)。

次の手順で戻りました。multus の Pod が起動すると、00-multus.conf は自動で書き直されます。

実行する場所:止めたノード(ssh core@<ノード>)

sudo systemctl stop kubelet crio

sudo mkdir -p /root/cni-bak && sudo mv /etc/kubernetes/cni/net.d/00-multus.conf /root/cni-bak/

sudo systemctl start crio && sudo systemctl start kubelet

約 1 分でノードが Ready に戻りました。

結果のまとめ

試験NFSiSCSI(マルチパス)
ライブ マイグレーション2〜3 秒、途切れ 0.4〜1.2 秒2〜3 秒、途切れ 0.6〜3.1 秒
経路の障害(NFS は 1 経路のため試験なし)書き込み継続、ping の欠落なし
ノードの電源断(HA)295 秒で別ノードで起動、331 秒で ping 応答(同じ仕組み)

次の手順

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次