Nutanixと暮らす

Nutanixの検証・設計・運用を記録する技術ブログ。本ブログは、Nutanixを中心とした仮想化・インフラ技術について、動作確認・検証結果と考察をまとめた個人技術ブログです。本ブログの内容は、個人の検証および調査に基づく見解です。実環境での利用にあたっては、公式ドキュメント等も併せてご確認のうえ、自己責任にてご判断ください。

CVMのメモリ変更が再起動後に元に戻る理由を調べてみた

はじめに

前回の記事で、自宅ラボで3ノードクラスターを安定稼働させるために、CVMのメモリを削減するという対応を取りました。しかし、AHVやCVM再起動後に、CVMのメモリが削減前の状態に戻っていることに気づきました。今回はこの原因について調べてみました。

CVMのメモリ削減

改めてですが、今回は以下の手順でCVMのメモリを削減していました。

①CVMにログインしシャットダウン。
nutanix@NTNX-xxxxxxxx-A-CVM:[IPアドレス]:~$ cvm_shutdown -P now

②AHV上でCMがシャットダウンしたことを確認。
[root@NTNX-xxxxxxxx-A ~]# virsh list --all
 Id   Name                  State
--------------------------------------
 -    NTNX-xxxxxxxx-A-CVM   shut off

③CVMの設定ファイルを編集。
[root@NTNX-xxxxxxxx-A ~]# virsh edit NTNX-xxxxxxxx-A-CVM

★編集前
  <memory unit='KiB'>16777216</memory>
  <currentMemory unit='KiB'>16777216</currentMemory>
  <numa>
    <cell id='0' cpus='0-1' memory='16777216' unit='KiB' memAccess='shared'/>
  </numa> 

★編集後
  <memory unit='KiB'>12582912</memory>
  <currentMemory unit='KiB'>12582912</currentMemory>
  <numa>
    <cell id='0' cpus='0-1' memory='12582912' unit='KiB' memAccess='shared'/>
  </numa>

④設定が変わったことを確認。
[root@NTNX-xxxxxxxx-A ~]# virsh dominfo NTNX-xxxxxxxx-A-CVM
Id:             -
Name:           NTNX-xxxxxxxx-A-CVM
UUID:           (省略)
OS Type:        hvm
State:          shut off
CPU(s):         2
Max memory:     12582912 KiB
Used memory:    12582912 KiB
Persistent:     yes
Autostart:      disable
Managed save:   no
Security model: selinux
Security DOI:   0

発生した事象

設定変更後、CVMとAHVを再起動しメモリの値を改めて確認すると、16GBに戻っていました。

[root@NTNX-xxxxxxxx-A ~]# virsh dominfo NTNX-xxxxxxxx-A-CVM | grep memory
Max memory:     16777216 KiB
Used memory:    16777216 KiB

当然Prismから見た確認できるクラスターのメモリ使用率も100%となっており、検証用仮想マシンが起動不可の状態でした。

原因調査①:CVMの構成ファイル

"virsh edit NTNX-xxxxxxxx-A-CVM"コマンドで編集するXMLファイルの実体は、"/etc/libvirt/qemu"配下にあるようです。そこで同ファイルのタイムスタンプを見てみました。

■手動でのメモリ削減後
[root@NTNX-xxxxxxxx-A ~]# ls -l /etc/libvirt/qemu/NTNX-xxxxxxxx-A-CVM.xml
-rw-------. 1 root root 4944 May 10 12:22 NTNX-xxxxxxxx-A-CVM.xml
[root@NTNX-xxxxxxxx-A ~]#

■再起動後
[root@NTNX-xxxxxxxx-A ~]# ls -l /etc/libvirt/qemu/NTNX-xxxxxxxx-A-CVM.xml
-rw-------. 1 root root 4944 May 10 12:26 NTNX-xxxxxxxx-A-CVM.xml
[root@NTNX-xxxxxxxx-A ~]#

タイムスタンプが更新されていました。このため、再起動時にXMLファイルが上書きされていることが分かりました。

原因調査②:AHVの/var/log/messages

他に手掛かりがないかをインターネットで調べてみると、「AHVの/var/log/messagesはまず見る場所の1つではある」との情報を見かけました。さらに「今回は "libvirt" に関するログを確認するのが有効」そうであることが分かりました。そこで同ログから、libvirtとCVMの構成ファイル関連の記述を抽出してみました。

[root@NTNX-xxxxxxxx-A ~]# cat /var/log/messages | grep -iE "libvirt.*NTNX-.*-CVM"
(省略)
2026-05-10T12:26:29.591685+00:00 NTNX-xxxxxxxx-A libvirtd[2834]: 2902: info : virDomainAuditResource:714 : success=yes virt=kvm resrc=mem reason=start vm="NTNX-xxxxxxxx-A-CVM" uuid=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx old-mem=0 new-mem=16777216
(省略)
[root@NTNX-xxxxxxxx-A ~]#

出てきたログを見ると、CVMがパワーオン(reason=start)された際に、該当CVMのメモリ設定値が16GB(new-mem=16777216)と定義されていることが分かりました。このタイムスタンプはCVMのXMLファイルが更新されたタイムスタンプと一致しています。これらのログから、"CVM再起動時にvirsh editで定義したメモリが再定義されていること"が分かりました。

なぜ16GBとして定義されるのか?

ここに関して、私自身もまだ調査中ですが、いくつかのポイントから16GiBが基準として扱われているのかもしれません。

まず、CVMはNutanixクラスターにおけるコアコンポーネントであり、非常に多くの常駐プロセスが稼働しています。そのため、クラスター全体の安定稼働のためには、一定以上のメモリ量が必要になると考えられます。

また、Prismから設定できるCVMの最小メモリが16GiBとなっています。そのため、クラスター安定稼働のための最低メモリが16GiBであり、それを下回ることは許されないのかもしれないと想像しています。実際に今回はユーザ側で16GiBを下回る値を設定しても、再起動時に元の値へ戻る挙動が確認されました。

自宅ラボではどうするか?

CVMのメモリを削減しても、それの永続化は無理と分かりました。そのためしばらくは、AHV/CVM起動時に毎回手動でCVMのメモリを16GB→12GBへの変更を行うようにしたいと思います。「運用でカバー」という面が強いので、うまく自動化できる方法がないかは引き続き検討していきたいと考えています。

おわりに

前回の記事で、何とか自宅ラボ環境を安定稼働させることができたと思っていたのですが、なかなかうまくいきませんね。潤沢なメモリがあればもっと楽なのかもしれませんが、こういった苦労も自宅ラボの醍醐味だと感じています。「運用でカバー」の面はありますが、ようやく安定稼働させるための目途が立ったので、これからどんどん検証を進めていきたいです。

ネスト環境でCVMが不定期にダウンする問題を調査してみた

はじめに

前回の記事で、自宅ラボ環境の完成報告を行いました。次に行う検証のために操作感を確認していたのですが、早速とある問題にいきあたりました。

その問題ですが、今回3ノードでクラスターを構成しているのですが、不定期にCVMがダウンする、というものです。このままではノード障害試験などを行うことができないため、その原因について調べてみました。

発生した事象

クラスターのVirtual IPからPrism Elementにログインし、GUI上で操作を行っていたところ、たまにリロードが走る場面がありました。「メモリオーバーコミット環境だからそんなものかな」と思っていたのですが、右上のヘルスウィジェットに目をやると、" Controller VM [CVMのIPアドレス] disconnected from network "とメッセージが出ていました。

Prism Elementから仮想マシンの状態を確認したところ、確かにダウンしています。

対象のCVMが稼働していたAHVにログインし、" virsh list --all "コマンドを実行したところ、" shut off "状態になっていました。完全にCVMがダウンしています。

[root@NTNX-xxxxxxxx-A ~]# virsh list --all
 Id   Name                  State
--------------------------------------
 -    NTNX-xxxxxxxx-A-CVM   shut off

この事象は特定ノード上のCVMだけではなく、3ノードすべてのCVMで発生しています。発生頻度は不定期のため、CVMが不安定のようです。

ただし、この情報だけでは、ゲストOSが正常に停止しただけなのか、何かしらの操作(ハイパーバイザー側など)によって強制停止したのか、までは判別できません。ここからは複数の箇所から原因調査を行いました。

原因調査①:Prism Element

Prism Elementのヘルスウィジェットに表示されたアラートをクリックすると、そのアラートの考えられる原因や関連するKBの案内を表示してくれます。まずはここをクリックしてみました。考えられる原因が複数表示されていましたが、今回はCVM自身がダウンしているため、" Possible Cause 1 "が近そうですね。

Prism Elementおよび案内されていたKB情報を確認しましたが、直接的な原因特定に至りませんでした。そのため、次にハイパーバイザー(AHV)側での停止イベント有無を確認することにしました。

原因調査②:AHV

CVMは、AHV上の仮想マシンとして稼働しています。そのためAHV側の何かしらの手掛かりがないかと考えました。類似の事象がないかインターネットで調べてみると、特にネスト環境においては「プロセスの強制終了によってCVMがダウンする」といった記述を見つけました。そのため、該当CVMが稼働するAHVにログインし、" dmesg "コマンドを実行したところ、原因が分かりました。

[root@NTNX-xxxxxxxx-A ~]# dmesg | grep -E "Out of memory|Killed process"
[ 1154.037126] Out of memory: Killed process 3359 (python3) total-vm:385952kB, anon-rss:36512kB, file-rss:9072kB, shmem-rss:0kB, UID:0 pgtables:636kB oom_score_adj:0
[ 1156.400513] Out of memory: Killed process 38523 (python3) total-vm:383812kB, anon-rss:34124kB, file-rss:10212kB, shmem-rss:0kB, UID:0 pgtables:624kB oom_score_adj:0
[ 1179.484715] Out of memory: Killed process 38649 (python3) total-vm:385464kB, anon-rss:35840kB, file-rss:10292kB, shmem-rss:0kB, UID:0 pgtables:624kB oom_score_adj:0
[ 1180.676428] Out of memory: Killed process 40810 (python3) total-vm:250588kB, anon-rss:27624kB, file-rss:9336kB, shmem-rss:0kB, UID:0 pgtables:500kB oom_score_adj:0
[ 1181.345107] Out of memory: Killed process 2134 (ovs-vswitchd) total-vm:89052kB, anon-rss:17528kB, file-rss:16876kB, shmem-rss:0kB, UID:0 pgtables:212kB oom_score_adj:0
[ 1182.351652] Out of memory: Killed process 40901 (python3) total-vm:203424kB, anon-rss:27708kB, file-rss:6208kB, shmem-rss:0kB, UID:0 pgtables:428kB oom_score_adj:0
[ 1184.345463] Out of memory: Killed process 3489 (qemu-kvm) total-vm:17571760kB, anon-rss:22140kB, file-rss:672kB, shmem-rss:0kB, UID:107 pgtables:532kB oom_score_adj:0
[root@NTNX-xxxxxxxx-A ~]#

一番下のログに着目していただきたいのですが、" Out of memory "によって、" qemu-kvm "プロセスが強制終了させられています。

ここでそれぞれの用語について補足します。まず「Out of memory」ですが、これはOSが利用可能なメモリを使い切り、これ以上プロセスを維持できない状態を意味しています。この状態では、カーネルがメモリ確保のために不要と判断したプロセスを強制終了(OOM Killer)します。

次に「qemu-kvm」ですが、これは仮想マシン(CVM)を実行しているハイパーバイザー上のプロセスです。このプロセスが停止するということは、仮想マシンそのものの稼働が終了することを意味します。

つまり今回の事象は、AHV上で発生したメモリ枯渇によりプロセスの強制終了(OOM Killer)が発動し、その結果としてCVMを実行していたqemu-kvmプロセスが強制終了され、仮想マシン自体が停止状態になったものと考えられます。

なぜ起きたのか?

理由は明らかです。NutanixのKB情報を確認すると、ネスト環境でNutanixを利用する場合は「すべてのゲスト メモリを予約 (すべてロック)」を有効化が必須になっています。今回は、ESXi上の仮想マシン(ネスト構成)としてNutanix CEを動作させていますが、ESXi上ではメモリオーバーコミットを許容しており、メモリの予約ができていない状態でした。

その結果、AHVに割り当てられるメモリが不安定となり、qemu-kvmを含むプロセスの強制終了が発生し、CVMのダウンにつながったと考えられます。

どう対策するか?

本番環境であれば十分なメモリを確保するのが正しい対応になります。ただし今回の対象はあくまでも検証用途の自宅ラボになります。そのためベストプラクティスからは外れますが、今の環境内でできる対策を行ってみます。

※以下の方法はあくまでも私の自宅ラボで、3ノードクラスターを安定稼働させるために実施したものです。根本原因の排除ではなく、リソース競合を回避するための調整として実施したものであるため、本番環境では非推奨です。

海外のブログ等を見てみると、以下の対応を行っている記事を見つけました。こちらを対応してみます。

  • " virsh setmem / setmaxmem "コマンドでCVMが利用するメモリを削減する
  • Nutanix CEの仮想マシンに割り当てているメモリを削減する
  • Nutanix CEの仮想マシンの「すべてのゲスト メモリを予約」を有効にする

CVMの利用メモリの削減

" virsh setmem / setmaxmem "コマンドでCVMが利用するメモリを確認したところ、どちらも16GBに設定されていました。これより下げると今度は別の問題が発生しそうなので、今回はここは手を加えずにおいておきます。

[root@NTNX-xxxxxxxx-A ~]# virsh dominfo NTNX-xxxxxxxx-A-CVM
Id:             -
Name:           NTNX-xxxxxxxx-A-CVM
UUID:           xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
OS Type:        hvm
State:          shut off
CPU(s):         2
Max memory:     16777216 KiB
Used memory:    16777216 KiB
Persistent:     yes
Autostart:      disable
Managed save:   no
Security model: selinux
Security DOI:   0
[root@NTNX-xxxxxxxx-A ~]#

Nutanix CEの仮想マシン割り当てメモリの削減

Nutanix CEの仮想マシン割り当てメモリの削減ですが、以前の記事で、Nutanix CEの最小リソーステストを行った際の結果を参考にしました。この時は「メモリ24GBあれば動く」との結論にしていましたが、その後のSNSのやりとりで「20GBまでいけるかも…」というコメントもありましたので、今回は32GB→20GBに減らしてみることにします。

Nutanix CEの仮想マシンの「すべてのゲスト メモリを予約」を有効化

物理メモリ64GBに対して、20GB×3台=60GBになるので、要件通り「すべてのゲスト メモリを予約」を有効化しました。しかし、ESXiのオーバーヘッド等を踏まえると、実際にはメモリが不足していたのようで、3ノード目のNutanix CEが起動できませんでした。そのため、「すべてのゲスト メモリを予約」を無効状態のまま稼働させてみます。

[追記]構成変更後の結果

本記事公開後、さらに検証を行った結果、当初の構成では安定稼働しないケースがあったため、設定の見直しを実施しました。本章では、その検証結果および最終的に安定した構成について整理します。

確認結果

構成 メモリ予約 起動
結果
備考
20GB×3 on 起動不可 メモリ確保不可のため3ノード目が起動しない
20GB×3 off 起動可 CVM含めて起動したがクラスタのメモリ使用率が100%張り付き
(キャプチャの通り)
18GB×3 on 起動不可 Nutanix CEは起動するが中のCVMが起動しない
18GB×3 off 起動不可 Nutanix CEは起動するが中のCVMが起動しない

この結果から、ESXi上で表示される空きメモリと、実際に仮想マシンに割り当て可能なメモリには乖離があることが分かりました。特にネスト環境では、ESXiのオーバーヘッドやメモリの断片化などの要因により、理論値通りにメモリを割り当てられないケースがあるようです。

また唯一起動に成功したパターンでも、クラスタの空きメモリがないため、検証用の仮想マシンも起動できない状態になっていました。

CVMメモリをさらに削減してみる(16GB→12GB)

当初は、CVMのメモリはデフォルトの16GBから変更しない方針としていました。 これは、CVMはクラスタのコアコンポーネントであり、過度なリソース削減は別の不具合を引き起こす可能性があると考えたためです。

しかし、前述の検証結果の通り、仮想マシン側のメモリを削減してもCVMが起動しないケースが発生し、CVM自身のメモリに手を加えないと意図した挙動にならない可能性があると思いました。

そのため、海外の検証事例を参考にしつつ、あくまで検証用途に限定した上で、CVMのメモリ削減(16GB → 12GB)を試すことにしました。手順は以下の通りです。

①CVMにログインしシャットダウン。
nutanix@NTNX-xxxxxxxx-A-CVM:[IPアドレス]:~$ cvm_shutdown -P now

②AHV上でCMがシャットダウンしたことを確認。
[root@NTNX-xxxxxxxx-A ~]# virsh list --all
 Id   Name                  State
--------------------------------------
 -    NTNX-xxxxxxxx-A-CVM   shut off

③CVMの設定ファイルを編集。
[root@NTNX-xxxxxxxx-A ~]# virsh edit NTNX-xxxxxxxx-A-CVM

★編集前
  <memory unit='KiB'>16777216</memory>
  <currentMemory unit='KiB'>16777216</currentMemory>
  <numa>
    <cell id='0' cpus='0-1' memory='16777216' unit='KiB' memAccess='shared'/>
  </numa> 

★編集後
  <memory unit='KiB'>12582912</memory>
  <currentMemory unit='KiB'>12582912</currentMemory>
  <numa>
    <cell id='0' cpus='0-1' memory='12582912' unit='KiB' memAccess='shared'/>
  </numa>

④設定が変わったことを確認。
[root@NTNX-xxxxxxxx-A ~]# virsh dominfo NTNX-xxxxxxxx-A-CVM
Id:             -
Name:           NTNX-xxxxxxxx-A-CVM
UUID:           (省略)
OS Type:        hvm
State:          shut off
CPU(s):         2
Max memory:     12582912 KiB
Used memory:    12582912 KiB
Persistent:     yes
Autostart:      disable
Managed save:   no
Security model: selinux
Security DOI:   0

⑤CVMを起動。
[root@NTNX-xxxxxxxx-A ~]# virsh start NTNX-xxxxxxxx-A-CVM

⑥CVMのメンテナンスモードを解除。 ※今回はクラスタ内の別CVMから実施しました。
nutanix@NTNX-xxxxxxxx-A-CVM:[IPアドレス]:~$ acli host.list ※対象CVMのHost UUIDを確認
nutanix@NTNX-xxxxxxxx-A-CVM:[IPアドレス]:~$ acli host.exit_maintenance_mode [対象CVMのHost UUID]

⑦クラスター状態を確認。 ※対象CVMのステータスが「maintenance」から「up」になっていればOK。
nutanix@NTNX-xxxxxxxx-A-CVM:[IPアドレス]:~$ cluster status

CVMメモリ削減後の結果

CVMのメモリを12GBに変更した結果、以下のような挙動となりました。

  • 3ノードすべてでCVMが正常起動
  • クラスタ全体が安定稼働し、CVMダウンは発生もなくなった
  • メモリ使用率は依然として高い(キャプチャの通り)が、qemu-kvmの強制終了は発生しなくなった

今回の構成では、ESXi上でメモリオーバーコミットが発生しており、AHVに割り当てられるメモリが状況によって変動しています。そのため、AHV上のqemu-kvmプロセスがOOM Killerの対象となり、CVMの強制停止が発生していたと考えられます。

CVMのメモリを16GBから12GBへ削減したことで、Nutanix CE自体のメモリ使用量に余裕が生まれ、OOM発生条件が緩和された結果、qemu-kvmが強制終了されにくくなり、CVMの安定稼働につながったと推測されます。

最終構成

本検証環境では、以下の構成で安定稼働を確認しました。

  • Nutanix CE VM:20GB × 3ノード
  • メモリ予約:OFF
  • CVMメモリ:12GB

※改めてですが、本構成はあくまでネスト環境かつ検証用途での暫定的なチューニングです。本番環境では推奨されません。

おわりに

今回は自宅ラボのCVMが不安定であるということからスタートしました。最初は焦りましたが、原因にたどり着いて安心しています。

今回の事象から、「ハイパーバイザー層のリソース競合」が、ネスト構成では顕著に現れることを再認識しました。シングルノードシングルクラスター環境では絶対に意識することのない内容だと思うので、自宅ラボ環境を整備してよかったな、と前向きにとらえています。

設定調整後の再発有無の確認として、今後もPrism Elementのアラート履歴やdmesgログは継続的に見ていきたいと思います。安定していることが分かれば、次の検証に進みたいです。

自宅Nutanix CE環境が完成したのでご紹介(マルチクラスタ構成)

はじめに

以前、設計ポイントをご紹介した、自宅Nutanix CE環境が完成しました。本格的に触っていくのはこれからですが、構築完了時点の状態をご紹介したいと思います。本環境は、以前の記事で整理した通り、マルチクラスター間の挙動やDR関連機能の検証を主な目的として構成しています。

Prism Element&Prism Centralのダッシュボード

まず、Prism Centralのダッシュボードです。設計通り、2クラスター("Main-Site"および"DR-Site")が認識されていることを確認できました。マルチクラスター環境としての管理が可能な状態になっていますね。それぞれのクラスターは正常に登録されており、構築直後としては安定した状態になっていると言えそうです。

次にPrism Elementです。各ノードやストレージ、仮想マシンの状態も問題なく認識されており、基本的な運用や検証を開始できる状態が整っていることを確認しました。一部アラートが表示されていますが、内容としてはAHVホストのパスワード関連などの設定に起因するものであり、現時点での動作に致命的な影響はないものです。

  • メインクラスター

  • DRクラスター

一方で、CPU・メモリともに潤沢に余裕があるわけではないですが、検証用途としては問題ないと考えています。

実際の操作感

現時点では簡単な操作しか行っておりませんが、思ったよりは快適に動作しています。Prism CentralやPrism Elementの画面遷移や基本操作については、体感的に大きなストレスは感じませんでした。たまに待ち時間はあるものの、検証用途としては十分なレスポンスだと感じています。今後、検証内容によってどのように変化するのか、それとも快適なままなのかも確認していきたいと思います。

環境構築で詰まった点

ESXiやNutanix CEのインストールは以前やっていたこともありスムーズだったのですが、、、ノードのSSD増設時に固定用のネジ穴と手元のドライバーの規格が合わず、そのままでは増設ができないという想定外のトラブルがありました。急遽新しいドライバーを購入し、無事に増設できました。まさか物理的な問題で作業がストップするとは思わなかったですが、良い経験でした。

おわりに

ようやく自宅Nutanix CE環境が完成しました。GW前に構築を終えることができ、これからの検証に向けて非常にモチベーションが高まっています。この環境を使って、どんどん手を動かしていきたいです。まずはマルチクラスター環境下でこそ試せる、クラスターを跨いだ障害対策や保護設定(DR)など、本番環境を意識した操作をしていく予定です。引き続きよろしくお願いします!

NutanixとvSANのネットワーク要件と設計思想について比較してみた

はじめに

Nutanixのネットワーク要件の1つに、「10Gbps以上のNICが必要」と書かれています。一方で、同じHCIであるVMware vSANのネットワーク要件にも、「10GbpsのNICが必要」と書かれています。どちらも「10Gbps NICがあれば十分」という考え方に見えますが、「10Gbpsをどんな考え方で利用するか?」といった設計思想が異なっているようです。そこで今回はそれらの比較と整理をしてみたいと思います。

※厳密にはvSANのドキュメントには、「共有の10Gbps NICか、専用の1Gbps NICが必要」と書かれていますが、本番環境において1Gbps NICを利用する場面は少ない気がするので、今回は割愛しています。

なぜ10Gbpsなのか?

そもそもなぜ最低が「10Gbps」なのでしょうか?これは従来の3-Tier構成に由来しているようです。

従来の3-Tier構成では、サーバーとストレージ間をつなぐために、「ファイバーチャネル」を利用したSAN(ストレージ専用ネットワーク)を構成していました。そしてこのファイバーチャネルは、8Gbps / 16Gbps / 32Gbpsといった大きな帯域をもっていました。

その後HCIが登場し、LAN上でサーバーとストレージが通信できるようになりましたが、LANにはストレージ用の通信だけでなく、通常のサービス用通信も流れます。そのため、1Gbpsでは到底足りず、ネットワークがボトルネックになる可能性があります。また、近年のストレージ(ディスク)性能に対して、1Gbpsという帯域は非常に細く、十分なスループットが出せない可能性もあります。

これらの理由から、「最低でも10Gbps必要」というのが共通認識になっているようです。

vSANの考え方:ネットワーク利用を前提とする設計

Nutanixには「データローカリティ」という考えがありますが、vSANにはありません。vSANでは、データはクラスタ全体に分散配置されます。

  • データは複数ノードに分散して保存。
  • データ読み取りは複数ノードにまたがって実施。(ラウンドロビン)
  • ユーザーVMからはデータの場所を意識させない。

これらの内容から、データがどこにあっても同じように読み書きできる状態を目指していると思われます。ネットワーク越しのアクセスを前提として性能が成立する仕組みですね。

つまり、10Gbps前提であれば、データの保管場所(ローカル・リモート)の差を意識させない設計です。

Nutanixの考え方:ネットワーク利用は最小化する設計

一方でNutanixには「データローカリティ」という考えがあります。この考えで強調されている点として以下があります。

  • データをリモート保存するとネットワーク遅延の影響を受ける。
  • 帯域は無制限ではない。
  • サーバーの近くにデータを置くことで、エクスペリエンスを大幅に改善。
  • 読み取りは可能な限りローカルノード上で実施。

これらの内容から、不要なネットワークトラフィックを抑制することが意識されています。

つまり、vSANとは対照的に、ネットワークをコストとして捉え、ストレージトラフィック量を可能な限り削減することで性能を安定させる考え方です。

おわりに

今回はネットワーク要件の1つである「10Gbps」に着目して、NutanixとvSANの設計思想の調査や比較を行ってみました。要件としては同じなのに、その裏側の考え方は対照的だということが分かり、調べていて面白かったです。実際に設計する際もただの要件として見るだけでなく、その意図や設計思想まで考えることで、「過剰なスペックの機器を入れない」や「帯域以外でボトルネックを作らない」など、より適切な設計につながると感じました。

Nutanixのスナップショット機能の仕組みを整理してみた(VMwareとの比較)

はじめに

仮想化環境を利用するエンジニアにとって、「スナップショット機能」は非常に馴染みのある機能ではないでしょうか。仮想マシンに対して、ミドルウェアのバージョンアップやOSのパッチ当てなどの作業を行う際は、事前にスナップショットを取得する、というのが私の中では必須項目になっています。

一方で、取得したスナップショットを削除し忘れて差分データが肥大化したり、肥大化したスナップショットを削除する際にスタンが発生し仮想マシンを止めてしまったりと、別の意味でも印象的な機能です。

Nutanixにもスナップショット機能がありますが、これは私が想像していたものとは少し違った実装になっているようでした。そこで今回はNutanixのスナップショット機能の仕様やその設計思想について整理してみたいと思います。

スナップショットとは?

まずはじめに、スナップショットについて簡単におさらいしてみたいと思います。

ざっくり表現すると、「ある時点の仮想マシンの状態を保存すること」です。スナップショットを取得した仮想マシンは、この機能を利用することで、後から「スナップショット取得時点の状態」に戻すことができます。

冒頭に「ミドルウェアのバージョンアップやOSのパッチ当てなどの作業を行う際は、事前にスナップショットを取得する」と記載していたのは、この機能を利用することで「作業後に何かあっても、作業前の状態に切り戻しができるようにするため」です。切り戻しが容易というのは仮想環境の大きなメリットの一つではないでしょうか。

※対象サーバーの用途によっては、スナップショットからの切り戻しが難しい場合もあります。DBサーバやファイルサーバ、メールサーバなど、作業中に変更が加わる可能性があるものです。安易にスナップショットから切り戻すと不整合が発生する可能性があります。

何を保存している?

便利なスナップショット機能ですが、実際は何を保存しているか?という点を整理してみたいと思います。ここではVMwareに着目します。

従来のハイパーバイザー(VMware vSphere)が提供するスナップショット機能では、仮想マシンの実体であるvmdkファイルを保存します。具体的には以下の通りです。

  • スナップショット取得時に仮想マシンのvmdkファイルが分割(オリジナル+差分用)、オリジナルのvmdkファイルは読み取り専用へ変更。
  • 以降のデータ書き込みは、差分用のvmdkファイルに対して実施。
  • 分割したファイルはチェーン状に繋がっており、データ読み書き時はオリジナルから差分用のファイル全てにアクセス。
  • 複数スナップショットを取得することも可能だが、その分差分用ファイルが増えるためリスクもある。
    • データ読み書き時のI/Oが遅くなる。
    • vmdkファイルのいずれかが壊れるとチェーン構造が崩れるため、仮想マシンの破損につながる可能性がある。
    • スナップショット削除時は、差分ファイルのデータをオリジナルのvmdkに書き戻す(マージする)必要があり、差分データが肥大化していた場合は負荷がかかる。冒頭で触れた「仮想マシンのスタン」はこの負荷によって引き起こされます。

ここに書いた内容が私が想像していたスナップショットの概要でした。しかしNutanixでは、ハイパーバイザーではなくストレージがスナップショット機能を提供しており、全く異なる実装となっていました。

仮想ディスクはストレージ上にどう存在している?

Nutanixのスナップショット機能に触れる前に、まずVMwareとNutanixにおいて、「仮想マシンのディスクがストレージ上にどう存在しているのか?」に触れたいと思います。

VMwareの場合は、仮想マシンのディスク(実体)は単一の「vmdkファイル」です。共有ストレージ上には仮想マシンごとにvmdkファイルが存在しており、この単一のファイルに対してデータ読み書きが行われています。スナップショット取得時は、オリジナルの「vmdkファイル」を起点として、差分用ファイルがチェーン状に構成されていきます。

一方Nutanixの場合は、仮想マシンのディスクとして「vDisk」と呼ばれるものがあります。ただしこれは、「vmdkファイル」のように物理的にファイルが存在しているのではなく、AOS内部で統合された論理的なファイルです。この「vDisk」は内部的には「vBlock」という細かな論理ブロックに分割されており、その物理的な実体は、ストレージ内にバラバラに保存された「エクステント」と呼ばれるブロックデータの集合体です。

この「ファイル単位ではなくブロック単位で管理している」という違いが、Nutanixのスナップショットの実装に関係しています。

Nutanixのスナップショット機能

VMwareのスナップショット機能は「ハイパーバイザー(ESXi)」が主体となって「vmdkファイルの分割や統合」を行っているのに対し、Nutanixのスナップショット機能は「ストレージ(AOS)」が主体となって「ブロックデータの管理」を行っています。処理を行うレイヤーが異なることが大きな違いです。

Nutanixではブロックデータ単位で管理を行うことで、「Redirect-on-Write(RoW)」と呼ばれる仕組みを利用することが可能となっています。この「RoW」では、スナップショット取得時に差分用ファイルを作成することはありません。代わりに、vBlockが参照しているエクステントの向き先を変更(ポインタ操作)することで対応しています。

Nutanixでスナップショットを取得した後、仮想マシンから新しいデータの書き込みが発生すると、以下のような動作をします。「新しい場所に書いて、参照先を更新する」という仕組みです。

  1. オリジナルのデータブロック(エクステント)を読み取り専用へ変更。
  2. 差分ファイルは作らず、別のエクステントに新しいデータを直接書き込む。
  3. 「このvBlockは新しいエクステントを参照して」と、向き先(ポインタ)を変更。

こういった仕組みのため、何世代スナップショットを取得してもチェーンが伸びることもなく、読み込みが遅くなることはありません。また、一番の課題であった「不要になったスナップショットの削除」の際も、重いデータの書き戻し(マージ処理)は発生しません。単純に「古いエクステントの参照を破棄する」だけで完了します。これにより、Nutanixのスナップショット機能では「仮想マシンのスタンが起きない」設計になっています。

おわりに

今回は個人的にも興味のあったスナップショットの仕組みについて整理してみました。同じスナップショットであっても、VMwareとNutanixで実装に差があるのが面白いところですね。Nutanixのスナップショットはスタンを気にすることがないので、一時的な取得ではなく長期的な保存にも技術的には可能そうですね。ただ、バックアップとしては要件が異なるため、外部へのバックアップ等の別の仕組みと組み合わせた設計が必要になります。