第8章 KVM ゲストのタイミング管理

仮想化には、ゲスト仮想マシンの時刻管理におけるさまざまな課題が伴います。
  • 仮想マシン内の割り込みは実際の割り込みではなく、ホストマシンがゲスト仮想マシンに挿入しているものです。このため、割り込みは常に同時かつ即時にすべてのゲスト仮想マシンに配信される訳ではありません。
  • ホストは別のゲスト仮想マシンを実行していたり、別のプロセスを実行している場合もあり、したがって割り込みに通常必要となる正確なタイミングを得ることが常に可能であるとは限りません。
セッションの妥当性や移行その他のネットワークアクティビティーの正確性を維持するにはタイムスタンプに依存する必要があるため、正確な時刻管理機能を実行していないゲスト仮想マシンには、ネットワークアプリケーションおよびプロセスに関連した問題が発生する可能性があります。
KVM では、ゲスト仮想マシンに準仮想化クロック (kvm-clock) を提供することでこの問題を回避します。しかし、タイミングをテストしてから、時刻管理が不正確な場合に影響を受ける可能性のあるアクティビティー (ゲストマイグレーション等) を実行することが依然として重要です。

重要

上記の問題を避けるためには、ホストおよびゲスト仮想マシンに Network Time Protocol (NTP) を設定する必要があります。Red Hat Enterprise Linux 6 およびそれ以前のバージョンを使っているゲストの場合、NTP は ntpd サービスで実装されます。詳細は、『Red Hat Enterprise Linux 6 導入ガイド』を参照してください。
Red Hat Enterprise Linux 7 を使っているシステムの場合、NTP 時刻同期サービスは ntpd または chronyd サービスにより提供されます。Chrony には、仮想マシンに対していくつかの優れた点があります。詳細は、『Red Hat Enterprise Linux 7 システム管理者のガイド』の「chrony スイートを使用した NTP 設定」および「ntpd を使用した NTP 設定」の章を参照してください。
ゲスト仮想マシンの同期のしくみ

デフォルトで、ゲストは以下のようにハイパーバイザーと時間を同期します。

  • ゲストシステムが起動すると、ゲストはエミュレートされた RTC (リアルタイムクロック) から時間を読み取ります。
  • NTP プロトコルが開始されていると、ゲストのクロックは自動的に同期されます。それ以降、ゲストが通常の動作をしている間、NTP はゲストのクロック調整を実施します。
  • ゲストが一時停止または復元プロセスの後に再起動する場合は、管理ソフトウェア (virt-manager 等) により、ゲストのクロックを特定の値に同期させるコマンドが発行される必要があります。この同期プロセスは、QEMU ゲストエージェント がゲストにインストールされ、機能をサポートしている場合に限り動作します。通常は、ホストのクロック値にゲストのクロックを同期させます。

一定のタイムスタンプカウンター (TSC: Time Stamp Counter)

最新の Intel と AMD の CPU は、不変タイムスタンプカウンター (TSC) を提供します。不変 TSC のカウント頻度は、たとえば CPU コア自体が節電ポリシーに従うために周波数を変更しても変わりません。不変 TSC の周波数を持つ CPU は、KVM ゲストのクロックソースとして TSC を使用するために必要です。

constant_tsc フラグが付いている場合には、CPU は Constant TSC を搭載しています。CPU に constant_tsc フラグが付いているかどうかを確認するには、以下のコマンドを実行します。
$ cat /proc/cpuinfo | grep constant_tsc
いずれかの出力が表示される場合は、CPU には constant_tsc ビットがあることになります。出力がない場合は、以下の説明に従ってください。
Constant TSC を搭載していないホストの設定

Constant TSC の周波数のないシステムは、仮想マシンのクロックソースに TSC を使用できず、追加設定が必要になります。電源管理機能により正確な時刻管理が妨げられるので、KVM を使用してゲスト仮想マシンの正確な時間を管理するには、この機能を無効にする必要があります。

重要

以下に説明する手順は、AMD リビジョン F の CPU のみが対象となります。
CPU に constant_tsc ビットがない場合には、電源管理機能をすべて無効にします。各システムには、時刻管理に使用する複数のタイマーがあります。TSC はホスト上では安定していません。これは、cpufreq の変化やディープ C ステート、より高速の TSC を搭載したホストへの移行などが原因となる場合があります。ディープ C スリープ状態に入ると、TSC が停止する可能性があります。カーネルがディープ C ステートを使用しないようにするには、カーネルブートに processor.max_cstate=1 を追加します。この変更を永続化させるには、/etc/default/grub ファイルの GRUB_CMDLINE_LINUX キーの値を編集します。たとえば、毎回の起動時に緊急モード (emergency mode) を有効にするには、以下のようにエントリーを編集します。
GRUB_CMDLINE_LINUX="emergency"
GRUB 2 ブートメニューに複数のパラメーターを追加する際と同様に、GRUB_CMDLINE_LINUX キーには複数のパラメーターを指定できることに注意してください。
cpufreq を無効にするには (constant_tsc なしのホスト上の場合のみ)、kernel-tools をインストールし、cpupower.service を有効にします (systemctl enable cpupower.service)。ゲスト仮想マシンが起動されるたびにこのサービスを無効にするには、/etc/sysconfig/cpupower の設定ファイルを変更し、CPUPOWER_START_OPTS および CPUPOWER_STOP_OPTS を変更します。有効な制限については、/sys/devices/system/cpu/cpuid/cpufreq/scaling_available_governors ファイルを参照してください。このパッケージまたは電源管理およびガバナーについての詳細は、Red Hat Enterprise Linux 7 電力管理ガイドを参照してください。

8.1. Red Hat Enterprise Linux ゲストで必要な時刻管理パラメーター

一部の Red Hat Enterprise Linux ゲスト仮想マシンでは、システムの時刻を正しく同期させるために追加のカーネルパラメーターが必要です。これらのパラメーターは、ゲスト仮想マシンの /etc/grub2.cfg ファイルの /kernel 行の末尾に追記することで設定できます。

注記

Red Hat Enterprise Linux 5.5 以降、Red Hat Enterprise Linux 6.0 以降、および Red Hat Enterprise Linux 7 は、デフォルトのクロックソースに kvm-clock を使用します。kvm-clock を実行すると追加のカーネルパラメーターが必要なくなるので、Red Hat ではこれを推奨しています。
以下の表は、Red Hat Enterprise Linux のバージョンと各システムで必要となるパラメーターを表示しています。

表8.1 カーネルパラメーターの要件

Red Hat Enterprise Linux バージョンゲストの追加カーネルパラメーター
AMD64 および Intel 64 システム上の 7.0 およびそれ以降 (kvm-clock を実行)追加のパラメーターは必要ありません
AMD64 および Intel 64 システム上の 6.1 およびそれ以降 (kvm-clock を実行)追加のパラメーターは必要ありません
AMD64 および Intel 64 システム上の 6.0 (kvm-clock を実行)追加のパラメーターは必要ありません
AMD64 および Intel 64 システム上の 6.0 (kvm-clock を実行せず)notsc lpj=n
AMD64 および Intel 64 システム上の 5.5 (kvm-clock を実行)追加のパラメーターは必要ありません
AMD64 および Intel 64 システム上の 5.5 (kvm-clock を実行せず)notsc lpj=n
32 ビット AMD および Intel システム上の 5.5 (kvm-clock を実行)追加のパラメーターは必要ありません
32 ビット AMD および Intel システム上の 5.5 (kvm-clock を実行せず)clocksource=acpi_pm lpj=n
AMD64 および Intel 64 システム上の 5.4notsc
32 ビット AMD および Intel システム上の 5.4clocksource=acpi_pm
AMD64 および Intel 64 システム上の 5.3notsc
32 ビット AMD および Intel システム上の 5.3clocksource=acpi_pm

注記

lpj パラメーターは、ゲスト仮想マシンが稼働する特定の CPU の loops per jiffy 値と同じ値を必要とします。この値が不明な場合は、lpj パラメーターを設定しないでください。

警告

divider カーネルパラメーターはこれまで、高い即応性要件のない Red Hat Enterprise Linux 4 および 5 ゲスト仮想マシンやゲスト密度の高いシステム上にある Red Hat Enterprise Linux 4 および 5 ゲスト仮想マシンに推奨されてきました。しかし現在は、Red Hat Enterprise Linux 4 およびバージョン 5.8 より前の Red Hat Enterprise Linux 5 バージョンを実行するゲストでこのカーネルパラメーターを使用することは推奨されていません。
Red Hat Enterprise Linux 5 のバージョン 5.8 およびそれ以降において、divider は、タイマー割り込みの頻度を下げることでスループットを改善できます。たとえば、HZ=1000 の場合に divider10 に設定される (つまり、divider=10) と、期間ごとのタイマー割り込み数がデフォルト値 (1000) から 100 (デフォルト値の 1000 ÷ divider 値 10) に変わります。
BZ#698842 では、divider パラメーターによる割り込みや tick recording との対話について記述されています。この不具合は Red Hat Enterprise Linux 5.8 で修正されています。ただし、Red Hat Enterprise Linux 4 またはバージョン 5.8 より前の Red Hat Enterprise Linux 5 バージョンを使用するゲストでは、依然として divider パラメーターによるカーネルパニックが発生する可能性があります。
Red Hat Enterprise Linux 6 以降には、割り込み数が固定されたクロック割り込みはありません。このバージョンは ティックレスモード (tickless mode) で動作し、随時タイマーを動的に使用します。divider パラメーターは Red Hat Enterprise Linux 6 および Red Hat Enterprise Linux 7 では有用ではないため、これらのシステム上にあるゲストはこの不具合による影響を受けません。