Linuxスクリプトで仮想マシンで実行されていることを検出する方法

仮想マシンは、物理ハードウェアで実行されていることをオペレーティングシステムに納得させるために、非常に努力しています。では、Linuxコマンドラインから、コンピューターが物理であるか仮想であるかを判断できますか?

仮想マシンとハイパーバイザー

従来のコンピューターは物理的なオブジェクトです。さまざまなハードウェアを接続して組み合わせて、オペレーティングシステムをロードし、アプリケーションをインストールして起動し、それらを使用できるようにしたものです。

ハードウェアは高価です。1台の物理コンピューターで1つのオペレーティングシステムに制限されると、複数のオペレーティングシステムを実行するためのコストはすぐに禁止的になります。より良い解決策は、1台の物理コンピューターで複数のオペレーティングシステムを同時に実行できるようにし、それぞれが独自のハードウェアで実行されていると考えることです。

ハイパーバイザーはこれを可能にします。ハイパーバイザー(仮想マシンマネージャーまたは仮想マシンモニターとも呼ばれる)は、仮想マシンを作成できるソフトウェアです。これらは、同じ物理ホストで実行され、そのハードドライブスペース、メモリ、およびCPUコアを共有しますが、個々の物理コンピューターであるかのように動作します。

もちろん、ホストコンピューターは、仮想マシンのコレクションの要求に対処するのに十分な能力を持っている必要がありますが、ホストに十分なRAMと処理能力があれば、仮想マシンはほぼベアメタルの速度で実行できます。

Linuxは、2007年の2.6.20カーネルのリリース以来、KernelベースのVirtual Machineをサポートしており、すぐに組み込まれています。Linuxには、VirtualBox、GNOME Boxes、QEMU-KVMなどのハイパーバイザーがいくつか用意されています。これらは、LinuxのネイティブKVM機能を利用し、ネイティブカーネル機能を基盤として、ユーザーインターフェイスや仮想マシンのスナップショットを撮る機能などの機能を追加しています。

仮想マシンは、コスト削減、効率化、展開の簡素化、そして適切にプロビジョニングされた場合のセキュリティ上の利点を提供します。また、スケーラビリティも促進します。サービスの需要が増加すると、新しいサーバーを自動的に起動し、需要が低下するとシャットダウンできます。これにより、クラウドとオンプレミスインフラストラクチャの両方で非常に人気があります。

おそらく、Linuxサーバーをリモートで管理しており、それが仮想マシンなのか物理ボックスなのかを知りたいでしょう。または、実行しているプラットフォームの種類を知る必要があるスクリプトがあります。作業しているコンピューターが物理なのか仮想なのかを検出する方法はいくつかあります。

dmidecodeコマンド

dmidecodeコマンドは、多数のオプションと修飾子をサポートしています。デスクトップ管理インターフェイス(DMI)テーブルを照会し、ターミナルウィンドウに情報を印刷します。

-s(単一の文字列を表示)オプションを使用して、システム製品名を取得します。sudoを使用する必要があることに注意してください。

Ubuntu 22.04を実行しているVirtualBox VMでコマンドを実行します。

sudo dmidecode -s system-product-name

プラットフォームはVirtualBoxとして正しく識別されています。

Fedora 35を実行しているQEMU-KVM VMでは、この出力が得られます。

sudo dmidecode -s system-product-name

これは標準PCとして報告されていますが、Q35タイプの標準QEMU仮想PCです。したがって、プラットフォームは仮想マシンとして正しく認識されます。

同じコマンドを物理コンピューターで実行すると、製造元に関する情報が得られます。

sudo dmidecode -s system-product-name

このコンピューターは、製品コードがMS-7B86のMicro-Star International Company Limitedマザーボードに基づくカスタムビルドです。

lshwコマンド

lshwコマンドは、幅広いコンピューターハードウェアの詳細をリストします。lshwが報告するハードウェアのクラスを選択できます。

system修飾子を使用して-classオプションを使用します。このコマンドにsudoを使用すると、すべての詳細が表示されます。

このコマンドをUbuntu VirtualBox VMで実行します。

sudo lshw -class system

  • "description"フィールドには、"computer"という一般的なエントリがあります。
  • "product"フィールドは、これがVirtualBoxで実行されている仮想マシンであることを示しています。
  • "vendor"フィールドには、VirtualBoxを作成したドイツの企業の名前であるInnotek GmbHが含まれています。Innotekは、2010年にOracle CorporationがSun Microsystems, Inc.を買収した際に買収されました。

Fedoraにlshwをインストールする必要がありました。

sudo dnf install lshw

GNOME Boxesで実行されているFedora VMでそのコマンドを試してみましょう。

sudo lshw -class system

  • ここでも、「説明」フィールドには「コンピューター」という一般的なエントリがあります。
  • 「製品」フィールドには、dmidecodeコマンドで見たのと同じ標準的なQEMU PC情報が表示されます。
  • 「ベンダー」フィールドには「QEMU」が含まれており、これは仮想マシンであることをはっきりと示しています。

これは、物理コンピューターで同じコマンドを実行した結果です。

sudo lshw -class system

これは、Micro-Starマザーボードを搭載したハードウェアコンピューターであることがわかります。

  • ハードウェアはデスクトップコンピューターとして識別されます。
  • 「製品」フィールドには、マザーボードの種類であるMS-7B86が表示されます。
  • 「ベンダー」フィールドには、製造元の名前が含まれています。

hostnamectlコマンド

このコマンドは、実行するためにsudo権限を持つ必要がないという利点があります。ただし、systemd対応ディストリビューションでのみ使用できます。ほとんどの最新のディストリビューションではsystemdが使用されています。

これは、Ubuntu VirtualBox VMでコマンドを実行したときの応答です。

hostnamectl

  • 「アイコン名」フィールドに「-vm」が追加されています。
  • 「シャーシ」フィールドには「vm」が含まれています。
  • 「仮想化」フィールドには「oracle」が含まれています。
  • 「ハードウェアベンダー」フィールドには「innotek GmbH」が含まれています。
  • 「ハードウェアモデル」フィールドには「VirtualBox」が含まれています。

GNOME Boxes内のFedora VMでの出力は非常に似ています。

hostnamectl

  • 「アイコン名」フィールドに「-vm」が追加されています。
  • 「シャーシ」フィールドには「vm」が含まれています。
  • 「仮想化」フィールドには「kvm」が含まれています。
  • 「ハードウェアベンダー」フィールドには「QEMU」が含まれています。
  • 「ハードウェアモデル」フィールドには「Standard PC (Q35 + ICH9, 2009)」が含まれています。

物理デスクトップでhostnamectlコマンドを使用すると、出力には「仮想化」行が含まれません。

hostnamectl

「仮想化」フィールドがない場合は、ベアメタルで動作している必要があります。

systemd-detect-virtコマンド

できるだけ短い回答を取得したい場合は、systemd-detect-virtが最適でしょう。これもまたsystemd対応ディストリビューションが必要ですが、sudo権限は必要ありません。これと簡潔な出力により、スクリプトでの使用に適しています。

これは、Ubuntu VirtualBox VMでコマンドを実行した結果です。

systemd-detect-virt

GNOME Boxesで実行されているFedoraのコピーは、KVM仮想化を使用していると報告されています。

systemd-detect-virt

ハードウェアマシンでsystemd-detect-virtを実行すると、「none」がターミナルに出力されます。

systemd-detect-virt

プラットフォームを意識したスクリプト

スクリプトに仮想化環境で実行されているのか、物理ハードウェアで実行されているのかを検出する機能を持たせるには、systemd-detect-virtコマンドを使用し、Bashのcaseステートメントを使用してオプションを処理します。

これは使用するスクリプトです。このテキストをコピーして、「platform.sh」というファイルに保存します。

#!/bin/bash
shopt -s nocasematch
case $(systemd-detect-virt) in
none)
echo "Physical Hardware"
;;
*)
echo "Virtual Machine"
;;
esac

このスクリプトは、shoptを使用して大文字と小文字を区別しない照合を選択します。systemd-detect-virtコマンドは、caseステートメントで使用されます。このコマンドの出力は、一致が見つかるまで、caseステートメントの本体にある各case句と比較されます。一致しないものはすべて、デフォルトの句「*)」でキャプチャされます。

最も簡単な方法は、systemd-detect-virtからの応答が「none」であるかどうかをテストすることです。そうであれば、スクリプトは物理ハードウェアで実行されています。それ以外のすべてのケースでは、スクリプトは仮想マシンで実行されている必要があります。

スクリプトを実行する前に、chmodを使用して実行可能にする必要があります。

chmod +x platform.sh

Ubuntu VirtualBox VMを仮想マシンとして正しく識別します。

./platform.sh

Fedoraを実行しているGNOME Boxes VMも正しく検出します。

./platform.sh

スクリプトは、物理マシンで実行されている場合も正しく検出します。

./platform.sh

さまざまなcase句は、スクリプトの他の場所でチェックされてさまざまなタイプの処理を実行したり、スクリプト内の特定の関数を呼び出したりする変数を設定できます。

スクリプトでさまざまなタイプの仮想環境を検出して対応させる必要がある場合は、systemd-detect-virtが返すことができるさまざまな文字列を検索して、さらにcase句を追加できます。--listオプションを使用すると、考えられる応答の完全なリストを確認できます。すべてを一度に見やすくするために、出力columnコマンドにパイプします。

systemd-detect-virt --list | column

赤い錠剤を飲む

これらのテクニックにより、スクリプトは裸のハードウェアで実行されているときと、仮想マシン内で実行されているときを知ることができます。

マトリックスのネオのように、何が現実で何がそうでないかがわかります。