はじめに
OpenShift Container Platformで仮想マシン (VM) を起動・管理できる標準機能である「OpenShift Virtualization (以下、OCP-V) 」では、Kubernetes Clusterを構成するBare Metal Nodeを横断して、Live Migrationが可能です。その実験をします。またついでに、OCP-VでVMを操作するコマンドラインツールであるvirtctl
も試しに触ってみましょう。
先に、OCP-VにおけるLive Migrationの仕組みを絵で示します。
すごく絵が雑で恐縮なのですが、VM (がContainer内でプロセスとして実行されているPod) がNode AにDeployされていたとしましょう。
このVMをNode BにLive Migrationさせることを考えます。
Live Migrationを行うと、Node B上に新しいVM (インスタンスとしてはPodです) が新規作成されてきます。
そして新Podが作成され、新旧Podが僅かな時間の間だけ同じPVを読み書きします。この時、VMのステータスはMigrating
となります。また、インスタンスとしては異なる2つのPodが同時に読み書きできるPV、つまりReadWriteMany
でProvisioningされたPVが必要です。「Live MigrationするにはRWXのPVが要る」理由とはここにあります。
↓
↓
という感じでLive Migrationが完了します。とはいえ「本当かよ?」という疑問も湧いてきます。「本当にVMは途中で止まってないの!?」とか。
なので軽く検証してみました。
環境構成
なお、OCP-Vの環境についてはこちらの記事で作成した環境に準じて実施しております。
※記事内に記載の通り、こちらはRed Hatの動作保証外の環境ですので、そこだけご了承ください。
- ROSA (Red Hat OpenShift Service on AWS) v4.15.0
- OpenShift Data Foundation (ODF) にて
BlockDevice
のStorageClass
を使える様にしている
なお、OpenShift Virtualization Operatorインストール済みのOpenShift ClusterでODFにてStorage Clusterを作成すると、VM作成時にデフォルトで選択してくれるStorageClass
であるocs-storagecluster-ceph-rbd-virtualization
も作成されます。
SSH公開鍵を登録してVMを作成
今回はサクッと起動できるFedora VMを利用します。なお、VM作成時にターミナルからSSH接続する為の公開鍵を登録した上でVMを作成します。公開鍵登録はとても簡単にできます。
やっていきましょう。
適当なNameSpace
(私はvirtual-machine
としました)で「+追加」の下の方にある「Virtual Machines」をクリックします。
VMのテンプレート画面に遷移するので、「Fedora VM」をクリックしてください
VM作成画面にいくのですが、今回はSSH公開鍵を登録したいので、「Customize VirtualMachine」をクリックしてください。
タブ「Scripts」から、「Public SSH key」の欄で「Edit」をクリックしてください。
今回は既にNameSpace: virtual-machine
にSecret
として公開鍵をapply済みなので、それを選びます。「Save」をクリックします。
なお、新たに公開鍵を登録したい場合は「Add new」から可能です。PCで作成したSSH keyペアのうち、公開鍵の中身をコピペすればOKです。Secret
名もここで指定します。
VMの名称はお好きなものに変更して(私はfedora-live-migration
としました)、「Create VirtualMachine」をクリックしてVMが起動するのを待ちます。
起動したら、「Console」タブに遷移し、事前に指定されたUser/Password(ここもScriptsで変更できますが今回は特に不要)でログインしておいてください。
これでVMの用意は完了です。
標準出力とログファイルに毎秒UTC時刻を吐くアプリを用意
次にVMがLive Migration中に止まらないか証明する為のアプリケーションをFedora VM上にDeployします。今回はNode.js
のアプリを用意しました。
const fs = require('fs');
// 時刻をファイルに書き込む関数
function logTime() {
const now = new Date().toISOString(); // UTC時刻を取得
console.log(now); // 標準出力に時刻を出力
fs.appendFile('timeLog.txt', now + '\n', (err) => {
if (err) {
console.error('ファイルへの書き込みエラー:', err);
}
});
}
// 1秒ごとにlogTime関数を実行
setInterval(logTime, 1000);
これはChatGPTに「毎秒UTCの時刻を標準出力とホストのディレクトリに出力し続けるNode.jsのアプリケーションのソースコードを教えて下さい」って聞いたら作ってくれました。ChatGPTくん、ありがとうございます。
このアプリをDeployしたいのですが、いかんせんOpenShiftのGUIのコンソールからやるのが結構操作性に難ありな為、SSHで接続してターミナルからやっていきます。その為のSSH公開鍵登録なのでした。。。
ターミナルからVMにSSH接続する
ターミナルからVMにSSHで接続するにはvirtctl
を使います。これはGUIでやっている事をコマンドで操作する為のコマンドラインツールです。インストール方法を含む詳細はこちらを参照ください。
とりあえずvirtctl
がインストールできてPATHも通したというところから以下説明します。
まずはoc login
でOpenShiftにログインしましょう。ご自身のToken
でログインしてください。
oc login --token=sha256hogehogefugafuga
つづいてvirtctl
コマンドを使い、先程建てたVMfedora-live-migration
にSSH接続したいのですが、なんとOpenShiftのコンソール画面でVMの詳細画面からプルダウン「Action」内にある「Copy SSH command」というボタンがあり、ここをクリックするだけでSSHコマンドを取得できます。クリックしてみましょう。
コマンドがコピーできたので、oc login
済みのターミナルにペーストします。
virtctl -n virtual-machine ssh fedora@fedora-live-migration --identity-file=<path_to_sshkey>
ここで、<path_to_sshkey>
は、秘密鍵のPATHを指定してください。
[fedora@fedora-live-migration ~]$
VMにターミナルからログインできました。
Node.jsアプリをFedora VMにDeployする
ここでNode.jsのアプリを作ってしまいます。ここからは特にOCP-V固有の内容ではなく、単にRHEL系LinuxにてNode.jsが使える様にする手順となります。
$ sudo yum install nodejs npm -y
$ npm init -y
$ ls
package.json
npm init
してpackage.json
が作られました。続いてindex.js
をカレントディレクトリにvi
で作っちゃいます。
$ vi index.js
$ ls
index.js package.json
$ cat index.js
const fs = require('fs');
// 時刻をファイルに書き込む関数
function logTime() {
const now = new Date().toISOString(); // UTC時刻を取得
console.log(now); // 標準出力に時刻を出力
fs.appendFile('timeLog.txt', now + '\n', (err) => {
if (err) {
console.error('ファイルへの書き込みエラー:', err);
}
});
}
// 1秒ごとにlogTime関数を実行
setInterval(logTime, 1000);
これで準備完了です。一度Node.jsアプリの動作確認をしておきます。起動コマンドはカレントディレクトリにてnode index.js
です。
$ node index.js
2024-05-14T00:12:06.509Z
2024-05-14T00:12:07.512Z
2024-05-14T00:12:08.513Z
2024-05-14T00:12:09.514Z
2024-05-14T00:12:10.516Z
2024-05-14T00:12:11.519Z
2024-05-14T00:12:12.521Z
2024-05-14T00:12:13.522Z
2024-05-14T00:12:14.523Z
標準出力に1秒ごとにUTC時刻を吐き出しています。ctrl+c
で一度アプリを終了します。カレントディレクトリにてls
するとtimeLog.txt
というログファイルが生成されています。これは標準出力に出力されたものと全く同じ内容が出力されたテキストファイルです。cat
すれば同じ内容であることが確認できますので、見てみてください。
さて、アプリの方も問題無く動きました。さっそくLive Migrationを試します。
OpenShiftのコンソール画面からFedora VMでアプリを起動
既にFedoraにログイン済みかと思うので、このままNode.jsアプリを起動します。
$ node index.js
同じ様に標準出力に毎秒時刻が出力されてきます。タブ「Overview」に遷移します。
中央の「VMC Console」からも小さくVMのコンソールが見えています。この小さい画面でも毎時ログが出力されている動きが見えるはずです。
Live Migration前の稼働中のNode
やIP Address
は以下です。
Node: ip-10-0-64-154.ap-northeast-3.compute.internal
IP Address: 10.129.8.160
右上のプルダウン「Action」から「Migrate」をクリックします。
Live Migratationが始まります。「Status」がRunning
となっているところが一瞬だけMigrating
になるので、見逃さないようにしてください。本当に一瞬です。頑張ってスクショを撮りました。
再びVMのConsoleを見てください。変わらずNode.jsアプリはログを吐き続けています。
今回はstart
コマンドを用いていません(node
コマンドからフォアグラウンドで実行した)ので、仮にVMが停止していた場合はNode.jsアプリも止まるはずです。
アプリは止まっていない。ということはVMも無停止でLive Migrationされたということです。
ただしNode
やIP Address
は変わっています。
Node: ip-10-0-49-4.ap-northeast-3.compute.internal
IP Address: 10.131.4.174
VMインスタンス自体に吐き出したログファイルが失われていないかも確認しておきます。
Macのターミナルの方で確認しておきます。もしMacのターミナルで明示的にFedoraからログアウトしていない場合、MacのターミナルからのSSH接続はLive Migration前後で接続解除されていないことにお気づきでしょうか?
$ ls
index.js package.json timeLog.txt
$ cat timeLog.txt
無事、ログファイルは失われていません。
おわりに
OpenShift VirtualizationにおけるVMのLive Migrationの挙動を見てきました。
Live Migration前後でVMが停止したり再起動したりせず、VM上にDeployされたアプリも動作し続ける事が確認できました。
次回(いつになるか不明...)は、Live Migration前後でIP Address
が固定できるのか試してみる予定です。
続編を書きました。IPアドレス固定を含む本記事の続きはこちらをご参照ください。
UTCではなくJSTで時刻出力したい場合は以下のコードをおつかいください。
const fs = require('fs');
// 時刻をファイルに書き込む関数
function logTime() {
const now = new Date();
now.setHours(now.getHours() + 9); // UTCからJSTへの変換(9時間進める)
const jstTime = now.toISOString().replace('T', ' ').substring(0, 19); // 時刻フォーマットの調整
console.log(jstTime); // 標準出力に時刻を出力
fs.appendFile('timeLog.txt', jstTime + '\n', (err) => {
if (err) {
console.error('ファイルへの書き込みエラー:', err);
}
});
}
// 1秒ごとにlogTime関数を実行
setInterval(logTime, 1000);