目次
- はじめに
- 1. 概要
- 2. MTV のインストール
- 3. VMware CBT の有効化
- 4. VDDK イメージの設定
- 5. DNS の設定
- 6. VMware ESXi ホストの NFC サービスメモリーの拡張
- おわりに (予告)
はじめに
VMware vSphere から OpenShift Virtualization (OCPv) へ仮想マシンを移行する際、Red Hat が提供する Migration Toolkit for Virtualization (MTV) は、最も現実的な選択肢の一つです。特に VMware Provider を利用すると、単発の停止移行 (Cold migration) だけでなく、変更ブロック追跡 (Changed Block Tracking; CBT) を活用した増分同期(Warm migration)まで、段階的な移行シナリオを扱える点が魅力です。
一方で、MTV の移行がうまくいかない原因の多くは「MTV 自体の不具合」ではありません。CBT の前提条件、VDDK (VMware Disk Development Kit) の取り込み、ESXi 側の NFC サービス設定、名前解決 (DNS)、必要権限や接続性など、環境側の準備不足 に起因するケースが大半です。実行手順だけを追うと移行の途中で詰まりやすく、原因切り分けにも時間がかかります。
そこで本記事 (#1 準備編) では、MTV による vSphere → OCPv (IBM Cloud 上の ROKS) の Cold/Warm 移行を「実行できる状態」に整えることをゴールに、OCPv 側と VMware 側それぞれの準備作業と確認ポイントを、再現可能な形で整理します。実際の Migration Plan 作成〜移行実行・Cutover は、次回 (#2 実行編) で扱います。
Red Hat OpenShift on IBM Cloud (ROKS) に OpenShift Virtualization を構築し、仮想マシンを起動してみるまでをまとめた記事は下記です。OCPv 環境をこれから用意する場合は参考にしてください。
1. 概要
本記事は、Migration Toolkit for Virtualization (MTV) の VMware Provider を使って、VMware vSphere 上の仮想マシンを OpenShift Virtualization (OCPv / KubeVirt) へ移行するための“準備” を手順化してまとめるものです。
移行作業そのもの (Provider 作成 → Plan 作成 → 実行 → 検証) は #2 実行編 で扱いますが、実務ではその前段の準備で詰まることが多いため、本記事ではまず「移行が実行できる状態」まで環境を整えることをゴールにします。
本記事で扱う範囲は次のとおりです。
- OpenShift Virtualization (OCPv) 側に Migration Toolkit for Virtualization (MTV) Operator をインストールし、基本コンポーネントが正常に起動していることを確認
- Warm migration に必要な変更ブロック追跡 (Changed Block Tracking; CBT) を VMware 側で有効化し、考え方と設定観点を整理
- VMware ディスク転送で利用する VDDK カスタムイメージを IBM Cloud Container Registry (ICR) へ格納し、MTV から参照できるようにする
- ESXi ホストの NFC サービスに関する設定 (メモリー拡張) を確認し、必要に応じて調整する
- OpenShift クラスタから vCenter / ESXi を解決・到達できるようにするための DNS フォワーディング (転送) を設定する
位置付けとして、本記事は 「準備のチェックリスト兼、詰まりポイント集」 です。“ここまで終わっていれば移行作業に進める” という状態を作ることを目的にしています。
1-1. 前提
移行元の VMware vSphere 環境と 移行先の OCPv 環境 が手元にあることを前提とします。また、本検証における VMware vSphere 環境は IBM Cloud VCF for Classic - Automated を利用して構築されていますが、OCPv 環境からネットワーク疎通と名前解決ができる vShpere 環境であれば問題ありません。
参考情報として、筆者の環境情報を下記に記載します。
- OpenShift Virtualization
- プラットフォーム:Red Hat OpenShift on IBM Cloud (ROKS)
- OpenShift:
4.18.30(Kubernetes:1.31.13) - 基盤:IBM Cloud Bare Metal Server for VPC
- Workerノード:3台
- ストレージ(VMディスク用):ODF (OpenShift Data Foundation)
- VM向けStorageClass:ocs-storagecluster-ceph-rbd-virtualization
- ネットワーク:ROKS のコンテナネットワーク (Calico)
- Migration Toolkit for Virtualization Operator version:2.10.1 → 2.10.5
- VMware vSphere
- プラットフォーム:IBM Cloud の VCF for Classic - Automated
- VMware vSphere version:
8.0 - VMware vCenter Server version:
8.0 - NSX Version:
4.2.2.1.0.24765084
2. MTV のインストール
Migration Toolkit for Virtualization (MTV) は、VMware vSphere などの既存仮想基盤上で稼働している仮想マシンを、OpenShift Virtualization (= KubeVirt) へ移行するための Operator ベースの移行ツールです。移行の「Provider 登録」「ネットワーク/ストレージのマッピング」「移行 Plan(実行単位)の作成」「実行と進捗・ログ確認」といった一連の作業を、OpenShift の運用モデル (名前空間 / RBAC / Operators) に統合した形で提供します。
MTV が提供する中核機能は、オープンソースプロジェクト "Forklift" をベースにしています。Forklift は「VM を Kubernetes 上の KubeVirt へ移す (rehost)」ための仕組みを実装したプロジェクトで、移行元のインベントリ取得、移行対象の変換、移行ジョブのオーケストレーション等を担います。
Forklift は、Red Hat と IBM Research が2021年に共同で立ち上げたオープンソースの取り組みである "Konveyor" に端を発しますが、Konveyor の立ち上げ時点では、Forklift は「仮想マシンを KubeVirt に (最小限の停止時間で) 移行する」ためのサブプロジェクトとして位置づけられていました。いずれのサププロジェクトも Operator を軸に「Kubernetes 上で実運用しやすい形で提供する」方針が語られています。その後、Forklift プロジェクトの重心を、より「VM → KubeVirt」領域に近い場所へ戻すため、Konveyor 傘下ではなく KubeVirt コミュニティ側へ移管されました。
MTV は OpenShift に統合された移行ツールですが、実際に詰まりやすいのは MTV 自体ではなく、移行元 vSphere 側の準備や、OpenShift から vCenter/ESXi への名前解決・通信です。つまり「MTVを入れたら終わり」ではなく、移行が成立するための前提条件を揃えることが成功の鍵になります。
本章ではまず、OCPv (移行先) 側に MTV Operator を導入し、MTV のコンポーネントが正しく起動して UI へアクセスできる状態まで整えます。
2-1. 手順
- IBM Cloud コンソール > Clusters から、OpenShift Virtualization がインストールされた ROKS クラスタの [Overview] ページに移動します。
- 右上部の [OpenShift web console] ボタンをクリックし、新規タブとして OpenShift web console ページを開きます。
- コンソールの左ペインから、[Operators] > [OperatorHub] に移動し、「mtv」でフィルターします。その後、「Migration Toolkit for Virtualization Operator」パネルをクリックします。
- 更新チャンネルとバージョンを選択し、[Install] ボタンをクリックします。基本的には最新のバージョンを選択します。筆者の環境のセットアップ時点では「2.10.1」が最新でした。
- MTV の [Install Operator] ページに遷移します。すべてデフォルト設定で [Install] ボタンをクリックします。
-
Installation modeとして、「All namespaces on the cluster (default)」と「A specific namespace on the cluster」の2種類がありますが、 MTV では後者の「A specific namespace on the cluster」しか選択できません。 -
Installed Namespaceとして、推奨かつ自動作成される「openshift-mtv」(デフォルト) を選択します。 -
Update approvalは、「Automatic」を選択します。更新チャンネル内の最新のバージョンを選択している場合に限り「Automatic」を選択できます。
-
- MTV のインストール後に、ForkliftController 用のカスタムリソース (CR) を作成するように促されます。MTV に必須のコンポーネントであるため、[Create ForkliftController] をクリックし、デフォルトの設定のままインストールします。
- OpenShift web console の左ペインに「Migration for Virtualization」というメニューが表示されるようになります。
- 筆者の環境では
Update approval = Automaticの設定により、本記事の執筆時点で、更新チャンネル2.10系の最新バージョン2.10.5に自動アップデートされています。
- 筆者の環境では
- ForkliftController カスタムリソース (CR) が正常にインストールされ、起動していることを確認します。
以上で Migration Toolkit for Virtualization (MTV) のインストールは完了です。
3. VMware CBT の有効化
Changed Block Tracking (CBT) は、ESXi (VMkernel) が 仮想ディスク (VMDK) 上で変更されたブロック領域 を追跡し、後から「前回の時点から変化した部分だけ」を取得できるようにする機能です。もともとは vSphere のバックアップ/レプリケーション用途で広く使われており、vSphere API (VADP: vSphere APIs for Data Protection) を利用する製品は CBT の情報を参照して 増分バックアップ (Changed blocks only) を実現します。
MTV の Warm migration (増分同期) も同様に、移行元 vSphere から「変更されたブロックだけ」を効率よく取り込む必要があります。CBT が無効、または正常に動作していない場合、増分同期が成立せず、結果として フルコピー相当の挙動にフォールバックしたり、同期が極端に遅くなったり、失敗する 可能性があります。そのため Warm migration を前提とする場合、CBT の有効化と健全性確認は重要な準備項目です。
筆者の vSphere 環境では、CBT は既定で 無効 でした。
3-1. 手順
- vSphere Client にログインし、[Inventory] ページを開きます。
- CBT を有効化する仮想マシン (例:
win2019-acs) を停止します。このとき、スナップショットが存在する場合はすべて削除します。
CBT を有効化する前に、対象VMに スナップショットが残っていないこと を必ず確認してください。スナップショットが存在する状態で CBT を有効化すると、変更ブロック情報が不整合になり、QueryChangedDiskAreas などのAPIが 誤った結果を返す/期待どおり動作しない 可能性があります。
- 対象の仮想マシンで、ACTIONS > Edit settings > Advanced Parameters の画面を開きます。
- [Attribute] フィルターに「ctk」と入力して検索して設定済みか否かを確認します。初回設定の場合はAttribute 自体 (
ctkEnabledやscsi0:0.ctkEnabledなど) が存在しないはずです。設定が無ければ後続の手順を実施します。
パラメータ名 ctkEnabled の由来
- CBT (Changed Block Tracking) → 機能本体
- CTK (Change Tracking) → CBT が生成・参照する変更追跡データのファイル (
.ctk)
参考:Enabling or disabling Changed Block Tracking (CBT) on virtual machines
- 仮想マシンの CBT を有効化します。
- Advanced Parameters の画面で、[Attribute] 欄に
ctkEnabled、[Value] 欄にTRUEと入力し、[ADD] ボタンをクリックして、リストに追加します。
- Advanced Parameters の画面で、[Attribute] 欄に
- 仮想マシンに付随する仮想ディスク単位で CBT を有効化します。
- Advanced Parameters の画面で、[Attribute] 欄に
scsiX:Y.ctkEnabled(X,Yは SCSI 番号)、[Value] 欄にTRUEと入力し、[ADD] ボタンをクリックして、リストに追加します。- SCSI 番号が分からない、または一覧を取りたい場合は、方法の一例を下記の子セクション『3-1-1. 各ディスクの SCSI 番号一覧を取得する方法』で紹介していますので、参照ください。
- Advanced Parameters の画面で、[Attribute] 欄に
-
ctkEnabledとscsiX:Y.ctkEnabledを追加できたら、[OK]ボタンをクリックします。 - CBT の設定を反映させるために仮想マシンを起動します。
- 仮想マシンのホームディレクトリで、CBT を有効化したディスク毎に
<VM名>-ctk.vmdkが存在すれば有効化されてる目安になります。
3-1-1. 各ディスクの SCSI 番号一覧を取得する方法
VCF.PowerCLI PowerShell モジュールで vCenter に接続して SCSI 番号を取得できます。
VCF.PowerCLI は VMware.PowerCLI の後継のモジュールであり、現時点で VMware.PowerCLI をインポートすると「WARNING: The module 'VMware.PowerCLI' is deprecated. Please use the module 'VCF.PowerCLI' instead.」のような警告が出ます。
ここでは、PowerShell スクリプトを作成して仮想マシンの SCSI 番号の一覧を取得する方法を紹介します。
-
下記のような PowerShell スクリプト (
get-scsi-mapping.ps1) を作成し、適当なディレクトリ (例:~/Downloads/) に置きます。get-scsi-mapping.ps1param( # 1台でも複数台でも指定できるように string[] にしておく [Parameter(Mandatory = $true)] [string[]]$VMName ) # vCenter に接続している前提 try { $targetVMs = Get-VM -Name $VMName -ErrorAction Stop } catch { Write-Host "Get-VM でエラーが発生しました: $($_.Exception.Message)" -ForegroundColor Red return } if (-not $targetVMs) { Write-Host "指定した VM 名に一致する VM が見つかりませんでした: $($VMName -join ', ')" -ForegroundColor Yellow return } $report = foreach ($vm in $targetVMs) { $vm.ExtensionData.Config.Hardware.Device | Where-Object { $_ -is [VMware.Vim.VirtualDisk] } | ForEach-Object { $disk = $_ $controller = $vm.ExtensionData.Config.Hardware.Device | Where-Object { $_.Key -eq $disk.ControllerKey } $bus = $controller.BusNumber $unit = $disk.UnitNumber [PSCustomObject]@{ VMName = $vm.Name DiskLabel = $disk.DeviceInfo.Label SCSIBus = $bus UnitNumber = $unit SCSIID = "scsi{0}:{1}" -f $bus, $unit CapacityGB = [math]::Round($disk.CapacityInKB / 1MB, 1) } } } $report | Sort-Object VMName, SCSIBus, UnitNumber | Format-Table -AutoSize -
スクリプト実行までの流れ
# HomebrewをUpdate $ brew update # pwshのインストール $ brew install --cask powershell # pwshの起動 $ pwsh # VCF.PowerCLIモジュールのインストール PS /Users/hiroaki.mishima> Install-Module VCF.PowerCLI -Scope CurrentUser # vCenterに接続 PS /Users/hiroaki.mishima> Connect-VIServer -Server vcsosv-vc.corp.example.local -User ■■■■■■■■■■■■■■■■■■■■■■■■■■ -Password ■■■■■■■■■■ # Warning回避のために実行 PS /Users/hiroaki.mishima> Set-PowerCLIConfiguration -Scope User -ParticipateInCEIP $true # スクリプトのディレクトリ(例:~/Downloads/)へ移動 PS /Users/hiroaki.mishima> cd ./Downloads/ # スクリプト実行 PS /Users/hiroaki.mishima/Downloads> ./get-scsi-mapping.ps1 -VMName *-
-VMnameパラメータで SCSI 番号を取りたい仮想マシンの名前をしてします。下記の実行結果例のように、ワイルドカードも使用して、複数の仮想マシンから SCSI 番号を取得できます。PS /Users/hiroaki.mishima/Downloads> ./get-scsi-mapping.ps1 -VMName *acs* VMName DiskLabel SCSIBus UnitNumber SCSIID CapacityGB ------ --------- ------- ---------- ------ ---------- centos-acs-web Hard disk 1 0 0 scsi0:0 16.000 rhel8-acs2 Hard disk 1 0 0 scsi0:0 12.000 rhel8-acs2-clone1 Hard disk 1 0 0 scsi0:0 12.000 rhel9-acs4 Hard disk 1 0 0 scsi0:0 12.000 rhel9-acs4-clone1 Hard disk 1 0 0 scsi0:0 12.000 ubuntu2404-acs Hard disk 1 0 0 scsi0:0 12.000 ubuntu2510-acs Hard disk 1 0 0 scsi0:0 12.000 win10-acs (<ad>¥user1) Hard disk 1 0 0 scsi0:0 16.000 win10-acs2 (<ad>¥user2) Hard disk 1 0 0 scsi0:0 16.000 win2016-acs2 Hard disk 1 0 0 scsi0:0 48.000 win2019-acs Hard disk 1 0 0 scsi0:0 48.000 win2022-acs Hard disk 1 0 0 scsi0:0 16.000 win2025-acs-ad Hard disk 1 0 0 scsi0:0 18.000
-
4. VDDK イメージの設定
VMware vSphere から仮想ディスクを移動する場合は、Migration Toolkit for Virtualization (MTV) を VMware Virtual Disk Development Kit (VDDK) SDK と併用することを強く推奨します。MTV は VM のディスクをコピーするときに VDDK SDK を使います。
この機能を利用するには、VDDK をダウンロードし、VDDK イメージを build して、VDDK イメージをイメージレジストリに push します。VDDK パッケージにはシンボリックリンクが含まれているため、VDDK イメージの作成は、シンボリックリンク (symlink) を保持するファイルシステム上で実行する必要があります。
VDDK イメージをパブリックレジストリに保存すると、VMware ライセンスの条項に違反する可能性があります。そのため、ユーザーが自分で VDDK SDK をダウンロードし、それを組み込んだコンテナイメージ (VDDK イメージ)を build してレジストリに登録する必要があります。
IBM Cloud ROKS の場合は:
- クラスター内部の Image Registry
image-registry.openshift-image-registry.svc:5000/<プロジェクト>/<イメージ>:<tag> - または IBM Cloud Container Registry (ICR) の プライベート名前空間
いずれかの 非公開レジストリ に置くのが安全です。
4-1. 手順: IBM Cloud Container Registry (ICR) の準備
本記事での検証では、VDDK イメージを格納するレジストリとして IBM Cloud Container Registry (ICR) を利用しました。ICR で管理されたプライベート・レジストリに、カスタムした VDDK コンテナイメージを保管します。ICR を利用することで、OCPv on ROKS から利用可能なレジストリを簡単に準備できます。
ICR の 準備だけであれば Web UI での作業でも不都合はありませんが、後続の VDDK の build と ICR への push の作業ではコマンドラインでの実施が簡単です。したがって、Web UI はコマンドの実行結果の確認で利用することに留めます。
-
ibmcloudCLI を作業端末にインストールします。インストーラや Shell を利用した方法など、いくつか選択可能なオプションがあります。下記の参考ページに沿って簡単に導入できます。- [参考] IBM Cloud Docs > Installing the stand-alone IBM Cloud CLI
- container-registry CLI プラグインが未導入の場合は、以下のコマンドで導入します。
ibmcloud plugin install container-registry -r 'IBM Cloud'-
container-registry-
インストールしたいプラグイン名です。
-
例えば以下のような ICR 操作用コマンドが使えるようになります。
-
ibmcloud cr login(ICR にログインして Docker/Podman がpull/pushできる状態にする)
※
cr=container-registryのショートコマンド -
-
-
-r 'IBM Cloud'- IBM 公式のプラグインリポジトリ (名称が “IBM Cloud”) からプラグインを取得します。
-
- 作業端末にコンテナエンジンとして podman をインストールします。
- [参考] Podman Installation Instructions
例 (macOS の場合)
brew install podman podman machine init podman machine start podman info
- [参考] Podman Installation Instructions
MTV の VDDK イメージを ICR に置く用途なら、Podman の代わりに Docker を利用しても問題ありません。後続のコマンド例は Podman を前提に紹介していますが、基本的に本記事内でのコマンドは置き換え可能です。
- 簡易比較
| 観点 | Docker | Podman |
|---|---|---|
| アーキテクチャ | デーモン(dockerd)中心 | デーモンレス |
| 権限 | root 前提傾向(環境次第) | rootless が標準 |
| コマンド互換 | 本家 | 多くが置き換え可能 |
| セキュリティ | 設計次第 | rootless で強い |
| 企業環境(RHEL) | 使えるが方針次第 | Red Hat の推奨寄り |
- コマンドの置き換え例
| やりたいこと | Docker | Podman |
|---|---|---|
| イメージ取得 | docker pull |
podman pull |
| ビルド | docker build |
podman build |
| 起動 | docker run |
podman run |
| 一覧 | docker ps |
podman ps |
| 停止 | docker stop |
podman stop |
| レジストリへpush | docker push |
podman push |
| レジストリログイン | docker login |
podman login |
-
ibmcloudCLI で IBM Cloud にログインします。ibmcloud login -a cloud.ibm.com -r us-south -g OSV-migrate --sso-
ibmcloud login- IBM Cloud CLI でアカウントにログイン
-
-a cloud.ibm.com- API エンドポイント (パブリック IBM Cloud)
-
-r us-south- デフォルトのリージョンを us-south に設定
-
-g <resource_group_name>- デフォルトのリソースグループを設定 (ここでは
OSV-migrate) - リソースグループは、IBM Cloud コンソールで [Manage] > [Account] > [Account resources] > [Resource groups] ページから作成できます。CLI を利用する場合は、
ibmcloud resource group-create OSV-migrateのようなコマンドで作成できます。 - 指定しない場合、
Defaultリソースグループが利用されます。
- デフォルトのリソースグループを設定 (ここでは
-
--sso- シングルサインオン (SSO) でログイン (ブラウザからワンタイムコードを取る方式)
-
-
ibmcloudCLI で ICR にログインします。ibmcloud cr login --client podman- 現在の IBM Cloud ログイン情報を使って、Container Registry (
*.icr.io) に対して Docker/Podman で push/pull できるように認証情報を設定します。 - 明示的に Podman を使用してログインするには、
--client podmanオプションを利用します。- Docker を使用してログインするには、
--client dockerオプションを利用し、ローカル Docker デーモンを IBM Cloud Container Registry にログインさせます。
- Docker を使用してログインするには、
- 現在の IBM Cloud ログイン情報を使って、Container Registry (
- ICR 上に作業用の名前空間を作成します。
ibmcloud cr namespace-add hmishima-ns
4-2. 手順: VDDK イメージの build と ICR への push
MTV の VMware Provider で VMware ディスクを効率よく転送するために、MTV は VMware Virtual Disk Development Kit (VDDK) SDK を利用します。Red Hat ドキュメントでも、MTV インストール後に VDDK イメージを作成し、HyperConverged CR の spec.vddkInitImage に設定する必要があると明記されています。
[参考] Red Hat Documentation > Installing and using the Migration Toolkit for Virtualization
しかし、VDDK は MTV の標準イメージに同梱されていません(Broadcom ライセンス上、配布形態に注意が必要なため)。そのため、利用者が Broadcom から VDDK を入手し、自組織のレジストリ(例:ICR)に置ける“VDDK 配布用コンテナイメージ” としてパッケージ化します。
MTV の移行実行時には、VMware から取り込んだディスクに対して virt-v2v による変換処理を行う conversion Pod が作成されます。このとき spec.vddkInitImage に指定したイメージは init コンテナとして起動され、VDDK 一式を /opt 配下へコピーして、後続の変換・転送処理(conversion pod 側)が VDDK ライブラリを参照できる状態を作ります。
[参考] Red Hat Documentation > Chapter 9. Troubleshooting > 9.3. Architecture
したがって、ここでは「起動したら VDDK ディレクトリを /opt に配置する」だけに役割を絞った最小の VDDK イメージを Dockerfile を使って build し、先ほど用意した ICR の名前空間に push します。手順は下記の通りです。
- 作業端末に VDDK 用の作業用ディレクトリを作成し、これに移動します。
例
# hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [11:58:06] mkdir ~/Downloads/vddk-image && cd ~/Downloads/vddk-image - Web ブラウザーで、下記の VMware VDDK ダウンロードページ に移動します。
- Broadcom Developer Portal > SDKs > VMware Virtual Disk Development Kit (VDDK)
- 筆者の検証時はバージョン 8 系が最新でしたが、本記事の執筆時点では 9 系が最新です。ただし、下記の通りバージョンの選択には注意が必要です。
MTV の VDDK init イメージは必ず「Linux 版 VDDK (tarball for Linux)」を選択してください。OpenShift (ROKS含む) の Pod は Linux コンテナ で動作しているため、コンテナの中では
- Linux カーネル
- Linux のユーザーランド(
/lib64の.soライブラリ)
が前提になっています。したがって、下記の点に留意してください。
- Windows 版 VDDK (DLL) は Linux コンテナからロードできません。
- Windows 版 VDDK をコンテナに入れても、
vixDiskLib.dllを Linux が理解できないので 「Exec format error」や「cannot open shared object file」 になります。
また、VDDK と vSphere のメジャーバージョンを一致させてください。例えば、移行元が vSphere 8 系であれば、VDDK も 8 系を選びます。筆者の環境で確認したところ、vSphere 8 系と VDDK 9 系の組み合わせで下記のエラーが発生しました。VDDK 8 系に切り替えたところ、Warm 移行に成功しました。
nbdkit: error: /opt/vmware-vix-disklib-distrib/lib64/libvixDiskLib.so.8: cannot open shared object file: No such file or directory
-
VDDK アーカイブファイル (
.tar.gz) を先ほど作成した作業用ディレクトリに保存します。 -
VDDK アーカイブファイルを展開します。
# hiroaki.mishima @ HiroakinoMacBook-Pro in ~/Downloads/vddk-image [12:01:28] C:127 $ tar -xzf VMware-vix-disklib-8.0.3-23950268.x86_64.tar.gz- 展開後、
vmware-vix-disklib-distrib/というディレクトリが作成されます。この中にライブラリやバイナリが入っています。
- 展開後、
-
VDDK 一式を、MTV 実行時に生成される conversion pod の init コンテナ内の
/opt配下へ配置するための VDDK 配布用コンテナイメージをローカルで作成します。そのイメージを build するために Dockerfile を用意します。事前にvmware-vix-disklib-distrib/ディレクトリと同じ階層に移動しておきます。# hiroaki.mishima @ HiroakinoMacBook-Pro in ~/Downloads/vddk-image [12:06:48] $ cat > Dockerfile <<EOF FROM registry.access.redhat.com/ubi8/ubi-minimal USER 1001 COPY vmware-vix-disklib-distrib /vmware-vix-disklib-distrib RUN mkdir -p /opt ENTRYPOINT ["cp", "-r", "/vmware-vix-disklib-distrib", "/opt"] EOF-
cat > Dockerfile <<EOF … EOF-
cat > Dockerfile <<EOFから、最後の単独行EOFまでに書かれたテキストをそのまま Dockerfile というファイルに保存する。 - ヒアドキュメント (heredoc) という書き方
-
cat:標準入力をそのまま標準出力に流すコマンド -
>:標準出力をファイルにリダイレクト -
Dockerfile:出力先ファイル名 -
<<EOF:ここから EOF という行が出てくるまでの内容を「標準入力」として cat に渡す
-
-
-
USER 1001(実行ユーザーの指定)- コンテナ内でコマンドを実行するユーザーIDを
1001に指定します。 - root ではなく非特権ユーザーで動かすための指定です。
- コンテナ内でコマンドを実行するユーザーIDを
-
COPY vmware-vix-disklib-distrib /vmware-vix-disklib-distrib(VDDK ファイル群のコピー)- ビルドコンテキスト (
podman buildを実行したディレクトリ) にあるvmware-vix-disklib-distribディレクトリを、コンテナ内の/vmware-vix-disklib-distribにコピーします。→ 事前に tar 展開した VDDK の一式がここに入っている想定です。
- ビルドコンテキスト (
-
RUN mkdir -p /opt(展開先ディレクトリの作成) - コンテナ内に
/optディレクトリを作成します (既にあれば何もしない)。 - あとで VDDK を
/opt配下にコピーするための準備です。
-
-
ENTRYPOINT ["cp", "-r", "/vmware-vix-disklib-distrib", "/opt"](コンテナ起動時に実行されるコマンド)- コンテナが起動されたときに実行されるコマンドを指定しています。
- JSON 配列形式なので、実際には
cp -r /vmware-vix-disklib-distrib /optと同等 -
/vmware-vix-disklib-distribディレクトリを/optの下に再帰コピー (-r) する。結果として、コンテナ起動時に/opt/vmware-vix-disklib-distribが作られる。 - 例えば、下記のようなディレクトリ構造になっていれば良いです。
~/Downloads ├── ... └── vddk-image ├── Dockerfile ├── vmware-vix-disklib-distrib/ └── VMware-vix-disklib-8.0.3-23950268.x86_64.tar.gz
-
VDDK イメージをローカルで build します。
# hiroaki.mishima @ HiroakinoMacBook-Pro in ~/Downloads/vddk-image [13:51:16] $ podman build . -t us.icr.io/hmishima-ns/vddk:8.0.3-amd64-v3 --arch amd64 --os linux-
podman build .- カレントディレクトリ (
.) の Dockerfile を使ってコンテナイメージを build
- カレントディレクトリ (
-
-t us.icr.io/hmishima-ns/vddk:8.0.3-amd64-v2- レジストリ:
us.icr.io(米国リージョンの IBM Cloud Container Registry) - 名前空間:
hmishima-ns← 例 - リポジトリ名:
vddk - タグ:
8.0.3-amd64-v3
- レジストリ:
-
-fオプションを利用して、使用する Dockerfile のパスを指定することもできます。(例:-f Dockerfile2)
-
-
VDDK イメージをレジストリ (ICR) に push します。
# hiroaki.mishima @ HiroakinoMacBook-Pro in ~/Downloads/vddk-image [14:33:50] $ podman push us.icr.io/hmishima-ns/vddk:8.0.3-amd64-v3-
正しく push されたか確認します。例えば、
8.0.3-amd64-v3タグのリポジトリがあることが確認できます。# hiroaki.mishima @ HiroakinoMacBook-Pro in ~/Downloads/vddk-image [14:42:37] C:1 $ ibmcloud cr images --restrict hmishima-ns/vddk イメージをリストしています... リポジトリー タグ ダイジェスト 名前空間 作成日 サイズ セキュリティー状況 us.icr.io/hmishima-ns/vddk 8.0.3-amd64-v3 1a9fea1ff880 hmishima-ns 2 months ago 84 MB - OKIBM Cloud コンソール > Containers > Container Registry > Images からも確認できます。
-
-
IBM Cloud (ROKS) の管理 API から、対象のクラスタに接続するための kubeconfig (接続設定ファイル) を取得します。ROKS クラスタ内で動く conversion pod が ICR から VDDK を pull して使えるようにします。
ibmcloud ks cluster config --cluster ■■■■■■■■■■■■■■■■■■■■ --admin-
ibmcloud ks- IBM Cloud Kubernetes Service (ROKS を含む) の CLI
-
cluster config- 対象クラスタの kubeconfig をローカルにセットアップするコマンド
-
--cluster- でクラスタ ID を指定します。
-
--admin- 管理者権限 (cluster-admin 相当) の kubeconfig を取得
-
-
上記のコマンドを実行後、環境変数
KUBECONFIGが設定され、ocコマンドでそのクラスタを操作可能になります。- まだ OpenShift CLI (
oc) をインストールしていない場合はバイナリをインストールしておきます。
[参考] Red Hat Documentation > 9.8. OpenShift CLI のインストール
- まだ OpenShift CLI (
-
MTV が ICR から VDDK init image を pull できるように、ServiceAccount (SA) に ICR 認証情報 (imagePullSecret) が紐付けます。ROKS では ICR を利用するための image pull secret として
all-icr-ioが用意されており、公式手順でもdefault名前空間にあるall-icr-ioをコピーして各プロジェクトで利用する流れが案内されています。[参考] IBM Cloud Docs > Copying an existing image pull secret
-
default名前空間のall-icr-ioSecret を、MTV の名前空間openshift-mtvと移行予定先の名前空間 (例:ocpv-lab) にコピーします。# hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [10:48:50] C:130 $ NSS=(openshift-mtv ocpv-lab) # hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [15:11:38] $ for ns in "${NSS[@]}"; do echo "==> applying secret/all-icr-io to namespace: ${ns}" out=$( oc get secret -n default all-icr-io -o yaml \ | sed '/^ resourceVersion:/d;/^ uid:/d;/^ selfLink:/d;/^ creationTimestamp:/d;/^ managedFields:/,/^ name:/d' \ | sed "s/^ namespace: default$/ namespace: ${ns}/" \ | oc apply -f - 2>&1 ) echo "[${ns}] ${out}" done ==> applying secret/all-icr-io to namespace: openshift-mtv [openshift-mtv] secret/all-icr-io configured ==> applying secret/all-icr-io to namespace: ocpv-lab [ocpv-lab] secret/all-icr-io configured - 正しくコピーされたか確認します。
# hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [15:34:37] $ ( printf "NAMESPACE\tNAME\tTYPE\tDATA\tAGE\n" for ns in "${NSS[@]}"; do oc get secret -n "${ns}" all-icr-io --no-headers 2>/dev/null \ | awk -v ns="${ns}" 'BEGIN{OFS="\t"} {print ns,$1,$2,$3,$4}' done ) | column -t -s $'\t' NAMESPACE NAME TYPE DATA AGE openshift-mtv all-icr-io kubernetes.io/dockerconfigjson 1 61d ocpv-lab all-icr-io kubernetes.io/dockerconfigjson 1 144m -
defaultServiceAccount (SA) にall-icr-ioSecret を紐付けます。# hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [15:35:04] $ for ns in "${NSS[@]}"; do echo "==> linking pull secret to default SA in namespace: ${ns}" out=$(oc -n "${ns}" secrets link default all-icr-io --for=pull 2>&1) echo "[${ns}] ${out}" done ==> linking pull secret to default SA in namespace: openshift-mtv [openshift-mtv] ==> linking pull secret to default SA in namespace: ocpv-lab [ocpv-lab] - 正しく紐付いたか確認します。
# hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [15:38:39] $ for ns in "${NSS[@]}"; do echo "==> ${ns}: default SA imagePullSecrets" oc -n "${ns}" get sa default -o jsonpath='{range .imagePullSecrets[*]}{.name}{"\n"}{end}' | sort done ==> openshift-mtv: default SA imagePullSecrets all-icr-io default-dockercfg-rlcgp ==> ocpv-lab: default SA imagePullSecrets all-icr-io default-dockercfg-gbw2t - 任意の安全策として、
openshift-mtv名前空間に存在するforklift-controllerSA にも同じ secret を紐付けました。# hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [15:43:05] $ oc -n openshift-mtv secrets link forklift-controller all-icr-io --for=pull - テスト用の一時 Pod を作成し、VDDK init image を pull できるかテストします。
# hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [15:39:03] $ oc run -n openshift-mtv vddk-pulltest \ --restart=Never \ --image=us.icr.io/hmishima-ns/vddk:8.0.3-amd64-v3 pod/vddk-pulltest created # hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [15:40:48] $ oc describe pod -n openshift-mtv vddk-pulltest | sed -n '/Events/,$p' Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 12s default-scheduler Successfully assigned openshift-mtv/vddk-pulltest to kube-d4okn6ad02tla11413g0-acsosvclust-workerp-0000033f Normal AddedInterface 11s multus Add eth0 [172.17.32.203/32] from k8s-pod-network Normal Pulling 11s kubelet Pulling image "us.icr.io/hmishima-ns/vddk:8.0.3-amd64-v3" Normal Pulled 4s kubelet Successfully pulled image "us.icr.io/hmishima-ns/vddk:8.0.3-amd64-v3" in 7.173s (7.173s including waiting). Image size: 196682694 bytes. Normal Created 4s kubelet Created container: vddk-pulltest Normal Started 4s kubelet Started container vddk-pulltest-
Successfully pulled image ...と出力されており、正常にイメージを pull できていることが確認できます。
-
-
5. DNS の設定
MTV の VMware Provider は vCenter への接続自体は IP アドレスでも成立しますが、実際の移行処理(データ転送)では ESXi ホスト (vSphere ホスト )へ FQDN (ホスト名) で接続しようとします。そのため、OpenShift クラスタ (=MTV の Pod) から ESXi のホスト名が名前解決できることは移行成功の前提条件になります。
本記事内の検証で利用している VMware 環境 (VCF for Classic - Automated) において、ESXi ホスト名は VCS インスタンス (DNS) で管理されており、最終的にドメインコントローラー(AD DNS)へ問い合わせが委譲される構成になっています。したがって、移行開始前に VCS 側の対象ドメインをドメインコントローラーへ委譲 (DNS delegation / forwarder) できるように環境を整備し、OpenShift から ESXi の FQDN を解決できる状態にしておく必要があります。
5-1. DNS のステータス確認
- OpenShift クラスタの DNS 機能 (DNS Operator / CoreDNS) がクラスタ全体として健全か否かを確認します。
[参考] Red Hat Documentation > 7.1. Checking the status of the DNS Operator
# hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [17:08:04]
$ oc get clusteroperator/dns
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE MESSAGE
dns 4.18.30 True False False 76d
-
NAME:dns- 対象の ClusterOperator 名です。
-
VERSION:4.18.30- DNS Operator が「この OpenShift バージョン (
4.18.30) 向けの状態」になっている、という意味です。クラスタのバージョンと揃うのが普通です。
- DNS Operator が「この OpenShift バージョン (
-
AVAILABLE:True- DNS 機能は 提供可能(正常稼働)。
- CoreDNS が動いていて、クラスタ内の名前解決が成立している状態です。
-
PROGRESSING:False- 何かの 変更・更新・再構成の途中ではない、という意味です。
- 例えば、DNS の設定を変更してロールアウト中なら True になることがあります。
-
DEGRADED:False- 劣化状態 (エラーや重大な問題) ではない。
- 例えば、CoreDNS Pod が落ち続けている、設定不整合、必要なデプロイができない、などのとき True になります。
clusteroperator は OpenShift の主要コンポーネント (Operator) の状態を表す “クラスタ全体スコープ” のリソースです。/dns はその中の DNS Operator (名前: dns) を指定しています。ここで言う "DNS" は、Pod が名前解決に使う CoreDNS (openshift-dns) と、それを管理する DNS Operator (openshift-dns-operator) の全体を指します。したがって、この結果は「DNS Operator 自体は健全」という確認です。ただし、これは “vCenter/ESXi のドメインが引けるようになっているか” までは保証しません。
標準の OpenShift では、DNS Operator はインストール時に名前空間 openshift-dns-operator の dns-operator という Deployment としてデプロイされます。しかし ROKS では コントロールプレーン系コンポーネント (Operator 含む) の多くを IBM 側が管理します。そのため、名前空間 openshift-dns-operator 内で DNS Operator 本体 (Deployment) が 常にユーザーから見えるとは限りません。
- DNS の設定である
defaultカスタムリソース (CR) の内容を確認します。
[参考] Red Hat Documentation > 7.2. View the default DNS
# hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [12:09:21]
$ oc describe dns.operator/default
Name: default
Namespace:
Labels: <none>
Annotations: <none>
API Version: operator.openshift.io/v1
Kind: DNS
...
Status:
Cluster Domain: cluster.local
Cluster IP: 172.21.0.10
...
-
defaultCR に記述される内容は、下記のような「DNS の論理的な設定」です。- DNS フォワード (どの上流 DNS に投げるか)
- キャッシュ設定
- 追加のゾーン設定
-
Cluster IPは、Pod が名前解決のために問い合わせを行う IP アドレスです。この IP アドレスは、Service CIDR 範囲における10番目のアドレスとして定義されます。 -
名前空間
openshift-dnsに DNS の入口となる Service (openshift-dns/dns-default) が存在することを確認します。# hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [11:00:54] $ oc get svc -n openshift-dns NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE dns-default ClusterIP 172.21.0.10 <none> 53/UDP,53/TCP,9154/TCP 77d-
dns-defaultService は、クラスタ内DNSの入口(ClusterIP) です。Pod は通常、この Service のCLUSTER-IPをnameserverとして参照して DNS クエリを投げます。 -
PORT(S)列の出力-
53/UDP, 53/TCP:DNS クエリ用 -
9154/TCP:CoreDNS メトリクス用(監視)
-
-
-
クラスタ内の任意の(通常の)Pod の
resolv.confが、その Service を nameserver として参照して、実際に名前解決できることを確認します。# hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [11:01:33] $ oc run -n openshift-mtv -it --rm dns-test \ --restart=Never \ --image=registry.access.redhat.com/ubi9/ubi-minimal \ --overrides='{ "apiVersion":"v1", "spec":{ "securityContext":{ "runAsNonRoot":true, "seccompProfile":{"type":"RuntimeDefault"} }, "containers":[{ "name":"dns-test", "image":"registry.access.redhat.com/ubi9/ubi-minimal", "command":["sh","-lc","cat /etc/resolv.conf; echo; getent hosts kubernetes.default.svc"], "securityContext":{ "allowPrivilegeEscalation":false, "capabilities":{"drop":["ALL"]} } }] } }' search ocpv-lab.svc.cluster.local svc.cluster.local cluster.local nameserver 172.21.0.10 options ndots:5 172.21.0.1 kubernetes.default.svc.cluster.local pod "dns-test" deleted- 上記のコマンドでは、
oc runで MTV の名前空間openshift-mtvに一時 Pod を起動し、下記の2点を確認しています。-
cat /etc/resolv.confで Pod の DNS 設定(nameserver, search, ndots)-
nameserver <IP>が、1つ前のステップで確認したopenshift-dns/dns-defaultのCLUSTER-IP(172.21.0.10) と一致したため、Pod はdns-defaultService 経由で CoreDNS を正しく使っている状態と判断できます。
-
-
getent hosts kubernetes.default.svcで 実際に名前解決できること-
172.21.0.1 kubernetes.default.svc.cluster.localから、Pod → DNS(CoreDNS)→ Service 名解決が正常に動作していると判断できます。
-
-
- コマンドの意味
-
oc run -n openshift-mtv -it --rm dns-test ... --restart=Never-
dns-testという一時 Pod を起動して、対話(-it)で実行し、終了後に削除(--rm)します。 -
--restart=Neverは Job/Deployment ではなく Pod を1回だけ実行する指定です。
-
-
--image=registry.access.redhat.com/ubi9/ubi-minimal- 軽量な UBI(Red Hat 公式)イメージで検証します。
-
--overrides='...JSON...'-
oc runの生成 Pod 定義に対して、警告「Warning: would violate PodSecurity "restricted:latest":...」を回避するために、PodSecurity “restricted” を満たすように、実行したいコマンドを明示的な上書きし、後述のsecurityContextを追記します。
-
-
command: ["sh","-lc","cat /etc/resolv.conf; ..."]- Pod 内で以下を順に実行します。
-
cat /etc/resolv.conf:Pod が参照している DNS 設定の確認 -
getent hosts kubernetes.default.svc:Kubernetesの標準 Service 名を引けるか確認
-
- Pod 内で以下を順に実行します。
-
securityContext(restricted の必須要件)-
runAsNonRoot: true:root 実行を禁止 -
allowPrivilegeEscalation: false:権限昇格を禁止 -
containers.seccompProfile: RuntimeDefault:seccomp をデフォルトプロファイルで適用 -
containers.capabilities.drop: ["ALL"]:Linux capability をすべて落とす
-
-
- 上記のコマンドでは、
以上で、DNS のステータス確認は十分です。
5-2. DNS フォワーディングの設定
MTV(VMware Provider)は vCenter だけでなく、移行実行時に ESXi ホストへ接続してデータ転送を行う場面があります。このとき、最終的に OpenShift クラスタ内から ESXi ホストへ FQDN(ホスト名)で到達できること(= DNS で名前解決できること)が重要になります。
そこで、クラスタ内の Pod から vCenter / ESXi の FQDN を解決できるように、OpenShift の DNS Operator(dns.operator/default)に ゾーン単位の DNS フォワーディング(per-zone forwarding) を設定します。
[参考] Red Hat Documentation > 7.3. Using DNS forwarding
- DNS Operator オブジェクトである
defaultカスタムリソース (CR) を変更します。# hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [12:08:31] $ oc edit dns.operator/default- DNS フォワーディングは
/etc/resolv.confのデフォルト転送設定を “ゾーン単位で” 上書きできます。ここではcorp.example.localだけを社内 DNS(例:10.0.0.53)へ転送します。
- DNS フォワーディングは
- 以下を
spec:に追加(または既存を調整)します。spec: servers: - name: addns zones: - corp.example.local forwardPlugin: policy: Random upstreams: - 10.0.0.53 upstreamResolvers: policy: Sequential upstreams: - type: SystemResolvConf port: 53-
spec.servers[]:特定ゾーン向けの転送ルール(per-zone forwarding)-
name: addns:このルールの識別名(任意) -
zones: [corp.example.local]:*.corp.example.localに一致する問い合わせを対象にする -
forwardPlugin.upstreams: [10.0.0.53]:その問い合わせをこの DNS に転送 -
policy: Random:upstreamが複数ある場合の選び方(今回は1個なので実質どれでも同じ)
-
-
spec.upstreamResolvers:serversにマッチしない名前解決の転送先-
type: SystemResolvConf:ノードの/etc/resolv.confを上流として使う
-
-
-
defaultCR の設定が CoreDNS に入っているか確認します。# hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [12:33:48] $ oc get dns.operator/default -o yaml | sed -n '/^spec:/,/^status:/p'-
spec.serversに追加した内容が見えることを確認します。
-
- クラスタ内 Pod から vCenter と ESXi ホスト の FQDN を名前解決できるか確認します。
# hiroaki.mishima @ HiroakinoMacBook-Pro in ~ [12:38:40] $ oc run -n openshift-mtv -it --rm dns-test \ --restart=Never \ --image=registry.access.redhat.com/ubi9/ubi-minimal \ --overrides='{ "apiVersion":"v1", "spec":{ "securityContext":{ "runAsNonRoot":true, "seccompProfile":{"type":"RuntimeDefault"} }, "containers":[{ "name":"dns-test", "image":"registry.access.redhat.com/ubi9/ubi-minimal", "command":["sh","-lc","cat /etc/resolv.conf; getent hosts vcsosv-vc.corp.example.local; getent hosts host-km000.corp.example.local"], "securityContext":{ "allowPrivilegeEscalation":false, "capabilities":{"drop":["ALL"]} } }] } }' search openshift-mtv.svc.cluster.local svc.cluster.local cluster.local nameserver 172.21.0.10 options ndots:5 10.0.0.10 vcsosv-vc.corp.example.local 10.0.0.11 host-km000.corp.example.local pod "dns-test" deleted-
nameserver 172.21.0.10- Pod はクラスタ DNS (名前空間
openshift-dnsのdns-defaultService) を使うことができています。
- Pod はクラスタ DNS (名前空間
-
10.0.0.10 vcsosv-vc.corp.example.local/10.0.0.11 host-km000...- vCenter / ESXI ホストの FQDN が 転送先 DNS により名前解決できています。
-
6. VMware ESXi ホストの NFC サービスメモリーの拡張
MTV の単一の移行プラン (Migration plan) で ESXi ホストから 10 台を超える仮想マシンを移行する場合は、ホストの Network File Copy (NFC) サービスメモリーを増やす必要があります。NFC サービスメモリーは 10 個の並列接続に制限されているため、最大メモリサイズが不足すると VM 移行が失敗します。
任意の設定ですが、実施する場合は下記の Broadcom の記事を参考にしてください。
[参考] vSphere ESXi 7.0 Update 2 以降で Hostd サービスの設定を変更する方法
おわりに (予告)
本記事 (#1 準備編) では、MTV (VMware Provider) で vSphere から OpenShift Virtualization on IBM ROKS へ Cold/Warm 移行を実行するための前提条件を、OCPv 側・VMware 側それぞれの観点で整理しました。具体的には、MTV Operator の導入、Warm 移行に必須となる CBT の有効化、VDDK イメージの作成と ICR への格納、vCenter/ESXi の FQDN を解決するための DNS フォワーディング設定などを確認しています。
ここまでの準備ができていれば、「MTV を触ってみたけど Provider 登録や実行フェーズで詰まる」「Warm を選んだのに増分が効かない」「移行途中で ESXi への接続に失敗する」といった典型的なハマりどころを、かなり手前で潰せるはずです。言い換えると、本記事の到達点は “移行 Plan を作って実行できる状態が整った” というところです。
次回 (#2 実行編) では、いよいよ MTV の VMware Provider を登録し、まずは Cold 移行を確実に成功させます。その上で、Warm 移行として初回同期 → 増分同期 (CBT) → Cutover (停止 → 最終同期 → 切替) までの一連の流れを、UI の画面と確認ポイント (ログ確認、調査観点) を交えて解説します。
