8.14. 高度な仮想マシン管理
8.14.1. 仮想マシンのリソースクォータの使用
仮想マシンのリソースクォータの作成および管理
8.14.1.1. 仮想マシンのリソースクォータ制限の設定
リクエストのみを使用するリソースクォータは、仮想マシン (VM) で自動的に機能します。リソースクォータで制限を使用する場合は、VM に手動でリソース制限を設定する必要があります。リソース制限は、リソース要求より少なくとも 100 MiB 大きくする必要があります。
手順
VirtualMachine
マニフェストを編集して、VM の制限を設定します。以下に例を示します。apiVersion: kubevirt.io/v1 kind: VirtualMachine metadata: name: with-limits spec: running: false template: spec: domain: # ... resources: requests: memory: 128Mi limits: memory: 256Mi 1
- 1
- この設定がサポートされるのは、
limits.memory
値がrequests.memory
値より少なくとも100Mi
大きいためです。
-
VirtualMachine
マニフェストを保存します。
8.14.1.2. 関連情報
8.14.2. 仮想マシンのノードの指定
ノードの配置ルールを使用して、仮想マシン (VM) を特定のノードに配置することができます。
8.14.2.1. 仮想マシンのノード配置について
仮想マシン (VM) が適切なノードで実行されるようにするには、ノードの配置ルールを設定できます。以下の場合にこれを行うことができます。
- 仮想マシンが複数ある。フォールトトレランスを確保するために、これらを異なるノードで実行する必要がある。
- 2 つの相互間のネットワークトラフィックの多い chatty VM がある。冗長なノード間のルーティングを回避するには、仮想マシンを同じノードで実行します。
- 仮想マシンには、利用可能なすべてのノードにない特定のハードウェア機能が必要です。
- 機能をノードに追加する Pod があり、それらの機能を使用できるように仮想マシンをそのノードに配置する必要があります。
仮想マシンの配置は、ワークロードの既存のノードの配置ルールに基づきます。ワークロードがコンポーネントレベルの特定のノードから除外される場合、仮想マシンはそれらのノードに配置できません。
以下のルールタイプは、VirtualMachine
マニフェストの spec
フィールドで使用できます。
nodeSelector
- 仮想マシンは、キーと値のペアまたはこのフィールドで指定したペアを使用してラベルが付けられたノードに Pod をスケジュールできます。ノードには、一覧表示されたすべてのペアに一致するラベルがなければなりません。
affinity
より表現的な構文を使用して、ノードと仮想マシンに一致するルールを設定できます。たとえば、ルールがハード要件ではなく基本設定になるように指定し、ルールの条件が満たされない場合も仮想マシンがスケジュールされるようにすることができます。Pod のアフィニティー、Pod の非アフィニティー、およびノードのアフィニティーは仮想マシンの配置でサポートされます。Pod のアフィニティーは仮想マシンに対して動作します。
VirtualMachine
ワークロードタイプはPod
オブジェクトに基づくためです。注記アフィニティールールは、スケジューリング時にのみ適用されます。OpenShift Container Platform は、制約を満たさなくなった場合に実行中のワークロードを再スケジューリングしません。
tolerations
- 一致するテイントを持つノードで仮想マシンをスケジュールできます。テイントがノードに適用される場合、そのノードはテイントを容認する仮想マシンのみを受け入れます。
8.14.2.2. ノード配置の例
以下の YAML スニペットの例では、nodePlacement
、affinity
、および tolerations
フィールドを使用して仮想マシンのノード配置をカスタマイズします。
8.14.2.2.1. 例: nodeSelector を使用した仮想マシンノードの配置
この例では、仮想マシンに example-key-1 = example-value-1
および example-key-2 = example-value-2
ラベルの両方が含まれるメタデータのあるノードが必要です。
この説明に該当するノードがない場合、仮想マシンはスケジュールされません。
仮想マシンマニフェストの例
metadata: name: example-vm-node-selector apiVersion: kubevirt.io/v1 kind: VirtualMachine spec: template: spec: nodeSelector: example-key-1: example-value-1 example-key-2: example-value-2 ...
8.14.2.2.2. 例: Pod のアフィニティーおよび Pod の非アフィニティーによる仮想マシンノードの配置
この例では、仮想マシンはラベル example-key-1 = example-value-1
を持つ実行中の Pod のあるノードでスケジュールされる必要があります。このようなノードで実行中の Pod がない場合、仮想マシンはスケジュールされません。
可能な場合に限り、仮想マシンはラベル example-key-2 = example-value-2
を持つ Pod のあるノードではスケジュールされません。ただし、すべての候補となるノードにこのラベルを持つ Pod がある場合、スケジューラーはこの制約を無視します。
仮想マシンマニフェストの例
metadata: name: example-vm-pod-affinity apiVersion: kubevirt.io/v1 kind: VirtualMachine spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: 1 - labelSelector: matchExpressions: - key: example-key-1 operator: In values: - example-value-1 topologyKey: kubernetes.io/hostname podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: 2 - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: example-key-2 operator: In values: - example-value-2 topologyKey: kubernetes.io/hostname ...
8.14.2.2.3. 例: ノードのアフィニティーによる仮想マシンノードの配置
この例では、仮想マシンはラベル example.io/example-key = example-value-1
またはラベル example.io/example-key = example-value-2
を持つノードでスケジュールされる必要があります。この制約は、ラベルのいずれかがノードに存在する場合に満たされます。いずれのラベルも存在しない場合、仮想マシンはスケジュールされません。
可能な場合、スケジューラーはラベル example-node-label-key = example-node-label-value
を持つノードを回避します。ただし、すべての候補となるノードにこのラベルがある場合、スケジューラーはこの制約を無視します。
仮想マシンマニフェストの例
metadata: name: example-vm-node-affinity apiVersion: kubevirt.io/v1 kind: VirtualMachine spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: 1 nodeSelectorTerms: - matchExpressions: - key: example.io/example-key operator: In values: - example-value-1 - example-value-2 preferredDuringSchedulingIgnoredDuringExecution: 2 - weight: 1 preference: matchExpressions: - key: example-node-label-key operator: In values: - example-node-label-value ...
8.14.2.2.4. 例: 容認 (toleration) を使用した仮想マシンノードの配置
この例では、仮想マシン用に予約されるノードには、すでに key=virtualization:NoSchedule
テイントのラベルが付けられています。この仮想マシンには一致する tolerations
があるため、これをテイントが付けられたノードにスケジュールできます。
テイントを容認する仮想マシンは、そのテイントを持つノードにスケジュールする必要はありません。
仮想マシンマニフェストの例
metadata: name: example-vm-tolerations apiVersion: kubevirt.io/v1 kind: VirtualMachine spec: tolerations: - key: "key" operator: "Equal" value: "virtualization" effect: "NoSchedule" ...
8.14.2.3. 関連情報
8.14.3. 証明書ローテーションの設定
証明書ローテーションパラメーターを設定して、既存の証明書を置き換えます。
8.14.3.1. 証明書ローテーションの設定
これは、Web コンソールでの OpenShift Virtualization のインストール時に、または HyperConverged
カスタムリソース (CR) でインストール後に実行することができます。
手順
以下のコマンドを実行して
HyperConverged
CR を開きます。$ oc edit hco -n openshift-cnv kubevirt-hyperconverged
以下の例のように
spec.certConfig
フィールドを編集します。システムのオーバーロードを避けるには、すべての値が 10 分以上であることを確認します。golangParseDuration
形式 に準拠する文字列として、すべての値を表現します。apiVersion: hco.kubevirt.io/v1beta1 kind: HyperConverged metadata: name: kubevirt-hyperconverged namespace: openshift-cnv spec: certConfig: ca: duration: 48h0m0s renewBefore: 24h0m0s 1 server: duration: 24h0m0s 2 renewBefore: 12h0m0s 3
- YAML ファイルをクラスターに適用します。
8.14.3.2. 証明書ローテーションパラメーターのトラブルシューティング
1 つ以上の certConfig
値を削除すると、デフォルト値が以下のいずれかの条件と競合する場合を除き、デフォルト値に戻ります。
-
ca.renewBefore
の値はca.duration
の値以下である必要があります。 -
server.duration
の値はca.duration
の値以下である必要があります。 -
server.renewBefore
の値はserver.duration
の値以下である必要があります。
デフォルト値がこれらの条件と競合すると、エラーが発生します。
以下の例で server.duration
値を削除すると、デフォルト値の 24h0m0s
は ca.duration
の値よりも大きくなり、指定された条件と競合します。
例
certConfig: ca: duration: 4h0m0s renewBefore: 1h0m0s server: duration: 4h0m0s renewBefore: 4h0m0s
これにより、以下のエラーメッセージが表示されます。
error: hyperconvergeds.hco.kubevirt.io "kubevirt-hyperconverged" could not be patched: admission webhook "validate-hco.kubevirt.io" denied the request: spec.certConfig: ca.duration is smaller than server.duration
エラーメッセージには、最初の競合のみが記載されます。続行する前に、すべての certConfig の値を確認します。
8.14.4. 管理タスクの自動化
Red Hat Ansible Automation Platform を使用すると、OpenShift Virtualization 管理タスクを自動化できます。Ansible Playbook を使用して新規の仮想マシンを作成する際の基本事項を確認します。
8.14.4.1. Red Hat Ansible Automation について
Ansible は、システムの設定、ソフトウェアのデプロイ、およびローリング更新の実行に使用する自動化ツールです。Ansible には OpenShift Virtualization のサポートが含まれ、Ansible モジュールを使用すると、テンプレート、永続ボリューム要求 (PVC) および仮想マシンの操作などのクラスター管理タスクを自動化できます。
Ansible は、oc
CLI ツールや API を使用しても実行できる OpenShift Virtualization の管理を自動化する方法を提供します。Ansible は、KubeVirt モジュール を他の Ansible モジュールと統合できる点でユニークであると言えます。
8.14.4.2. 仮想マシン作成の自動化
kubevirt_vm
Ansible Playbook を使用し、Red Hat Ansible Automation Platform を使用して OpenShift Container Platform クラスターに仮想マシンを作成できます。
前提条件
- Red Hat Ansible Engine バージョン 2.8 以降。
手順
kubevirt_vm
タスクを含むように Ansible Playbook YAML ファイルを編集します。kubevirt_vm: namespace: name: cpu_cores: memory: disks: - name: volume: containerDisk: image: disk: bus:
注記このスニペットには Playbook の
kubevirt_vm
部分のみが含まれます。namespace
、cpu_cores
の数、memory
、およびdisks
を含む、作成する必要のある仮想マシンを反映させるように値を編集します。以下に例を示します。kubevirt_vm: namespace: default name: vm1 cpu_cores: 1 memory: 64Mi disks: - name: containerdisk volume: containerDisk: image: kubevirt/cirros-container-disk-demo:latest disk: bus: virtio
仮想マシンを作成後すぐに起動する必要がある場合には、
state: running
を YAML ファイルに追加します。以下に例を示します。kubevirt_vm: namespace: default name: vm1 state: running 1 cpu_cores: 1
- 1
- この値を
state: absent
に変更すると、すでに存在する場合に仮想マシンは削除されます。
Playbook のファイル名を引数としてのみ使用して、
ansible-playbook
コマンドを実行します。$ ansible-playbook create-vm.yaml
出力を確認し、プレイが正常に実行されたかどうかを確認します。
出力例
(...) TASK [Create my first VM] ************************************************************************ changed: [localhost] PLAY RECAP ******************************************************************************************************** localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Playbook ファイルに
state: running
を含めず、すぐに仮想マシンを起動する必要がある場合には、state: running
を含めるようにファイルを編集し、Playbook を再度実行します。$ ansible-playbook create-vm.yaml
仮想マシンが作成されたことを確認するには、仮想マシンコンソールへのアクセス を試行します。
8.14.4.3. 例: 仮想マシンを作成するための Ansible Playbook
kubevirt_vm
Ansible Playbook を使用して仮想マシン作成を自動化できます。
以下の YAML ファイルは kubevirt_vm
Playbook の例です。これには、Playbook を実行する際に独自の情報を置き換える必要のあるサンプルの値が含まれます。
--- - name: Ansible Playbook 1 hosts: localhost connection: local tasks: - name: Create my first VM kubevirt_vm: namespace: default name: vm1 cpu_cores: 1 memory: 64Mi disks: - name: containerdisk volume: containerDisk: image: kubevirt/cirros-container-disk-demo:latest disk: bus: virtio
8.14.5. 仮想マシンの EFI モードの使用
Extensible Firmware Interface (EFI) モードで仮想マシンを起動できます。
8.14.5.1. 仮想マシンの EFI モードについて
レガシー BIOS などの Extensible Firmware Interface (EFI) は、コンピューターの起動時にハードウェアコンポーネントやオペレーティングシステムのイメージファイルを初期化します。EFI は BIOS よりも最新の機能とカスタマイズオプションをサポートするため、起動時間を短縮できます。
これは、.efi
拡張子を持つファイルに初期化と起動に関する情報をすべて保存します。このファイルは、EFI System Partition (ESP) と呼ばれる特別なパーティションに保管されます。ESP には、コンピューターにインストールされるオペレーティングシステムのブートローダープログラムも含まれます。
OpenShift Virtualization は、EFI モードを使用する場合、セキュアブートを使用した仮想マシン (VM) のみをサポートします。セキュアブートが有効にされていない場合は、仮想マシンが繰り返しクラッシュします。ただし、仮想マシンはセキュアブートに対応していない可能性があります。仮想マシンを起動する前に、仮想マシン設定を確認して、これがセキュアブートに対応していることを確認します。
8.14.5.2. EFI モードでの仮想マシンのブート
仮想マシンまたは VMI マニフェストを編集して、仮想マシンを EFI モードで起動するように設定できます。
前提条件
-
OpenShift CLI (
oc
) をインストールしている。
手順
仮想マシンオブジェクトまたは Virtual Machine Instance (VMI) オブジェクトを定義する YAML ファイルを作成します。サンプル YAML ファイルのファームウェアの スタンザを使用します。
セキュアブートがアクティブな状態の EFI モードでのブート
apiversion: kubevirt.io/v1 kind: VirtualMachineInstance metadata: labels: special: vmi-secureboot name: vmi-secureboot spec: domain: devices: disks: - disk: bus: virtio name: containerdisk features: acpi: {} smm: enabled: true 1 firmware: bootloader: efi: secureBoot: true 2 ...
- 1
- OpenShift Virtualization では、EFI モードでセキュアブートを実行するために
SMM
(System Management Mode) を有効にする必要があります。 - 2
- OpenShift Virtualization は、EFI モードを使用する場合、セキュアブートを使用した仮想マシン (VM) のみをサポートします。セキュアブートが有効にされていない場合は、仮想マシンが繰り返しクラッシュします。ただし、仮想マシンはセキュアブートに対応していない可能性があります。仮想マシンを起動する前に、仮想マシン設定を確認して、これがセキュアブートに対応していることを確認します。
以下のコマンドを実行して、マニフェストをクラスターに適用します。
$ oc create -f <file_name>.yaml
8.14.6. 仮想マシンの PXE ブートの設定
PXE ブートまたはネットワークブートは OpenShift Virtualization で利用できます。ネットワークブートにより、ローカルに割り当てられたストレージデバイスなしにコンピューターを起動し、オペレーティングシステムまたは他のプログラムを起動し、ロードすることができます。たとえば、これにより、新規ホストのデプロイ時に PXE サーバーから必要な OS イメージを選択できます。
8.14.6.1. 前提条件
- Linux ブリッジが 接続されている。
- PXE サーバーがブリッジとして同じ VLAN に接続されていること。
8.14.6.2. MAC アドレスを指定した PXE ブート
まず、管理者は PXE ネットワークの NetworkAttachmentDefinition
オブジェクトを作成し、ネットワーク経由でクライアントを起動できます。次に、仮想マシンインスタンスの設定ファイルでネットワーク接続定義を参照して仮想マシンインスタンスを起動します。また PXE サーバーで必要な場合には、仮想マシンインスタンスの設定ファイルで MAC アドレスを指定することもできます。
前提条件
- Linux ブリッジが接続されていること。
- PXE サーバーがブリッジとして同じ VLAN に接続されていること。
手順
クラスターに PXE ネットワークを設定します。
PXE ネットワーク
pxe-net-conf
のネットワーク接続定義ファイルを作成します。apiVersion: "k8s.cni.cncf.io/v1" kind: NetworkAttachmentDefinition metadata: name: pxe-net-conf spec: config: '{ "cniVersion": "0.3.1", "name": "pxe-net-conf", "plugins": [ { "type": "cnv-bridge", "bridge": "br1", "vlan": 1 1 }, { "type": "cnv-tuning" 2 } ] }'
注記仮想マシンインスタンスは、必要な VLAN のアクセスポートでブリッジ
br1
に割り当てられます。
直前の手順で作成したファイルを使用してネットワーク接続定義を作成します。
$ oc create -f pxe-net-conf.yaml
仮想マシンインスタンス設定ファイルを、インターフェイスおよびネットワークの詳細を含めるように編集します。
PXE サーバーで必要な場合には、ネットワークおよび MAC アドレスを指定します。MAC アドレスが指定されていない場合、値は自動的に割り当てられます。
bootOrder
が1
に設定されており、インターフェイスが最初に起動することを確認します。この例では、インターフェイスは<pxe-net>
というネットワークに接続されています。interfaces: - masquerade: {} name: default - bridge: {} name: pxe-net macAddress: de:00:00:00:00:de bootOrder: 1
注記複数のインターフェイスおよびディスクのブートの順序はグローバル順序になります。
オペレーティングシステムのプロビジョニング後に起動が適切に実行されるよう、ブートデバイス番号をディスクに割り当てます。
ディスク
bootOrder
の値を2
に設定します。devices: disks: - disk: bus: virtio name: containerdisk bootOrder: 2
直前に作成されたネットワーク接続定義に接続されるネットワークを指定します。このシナリオでは、
<pxe-net>
は<pxe-net-conf>
というネットワーク接続定義に接続されます。networks: - name: default pod: {} - name: pxe-net multus: networkName: pxe-net-conf
仮想マシンインスタンスを作成します。
$ oc create -f vmi-pxe-boot.yaml
出力例
virtualmachineinstance.kubevirt.io "vmi-pxe-boot" created
仮想マシンインスタンスの実行を待機します。
$ oc get vmi vmi-pxe-boot -o yaml | grep -i phase phase: Running
VNC を使用して仮想マシンインスタンスを表示します。
$ virtctl vnc vmi-pxe-boot
- ブート画面で、PXE ブートが正常に実行されていることを確認します。
仮想マシンインスタンスにログインします。
$ virtctl console vmi-pxe-boot
仮想マシンのインターフェイスおよび MAC アドレスを確認し、ブリッジに接続されたインターフェイスに MAC アドレスが指定されていることを確認します。この場合、PXE ブートには IP アドレスなしに
eth1
を使用しています。他のインターフェイスeth0
は OpenShift Container Platform から IP アドレスを取得しています。$ ip addr
出力例
... 3. eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether de:00:00:00:00:de brd ff:ff:ff:ff:ff:ff
8.14.6.3. テンプレート: PXE ブートの仮想マシンインスタンス設定ファイル
apiVersion: kubevirt.io/v1 kind: VirtualMachineInstance metadata: creationTimestamp: null labels: special: vmi-pxe-boot name: vmi-pxe-boot spec: domain: devices: disks: - disk: bus: virtio name: containerdisk bootOrder: 2 - disk: bus: virtio name: cloudinitdisk interfaces: - masquerade: {} name: default - bridge: {} name: pxe-net macAddress: de:00:00:00:00:de bootOrder: 1 machine: type: "" resources: requests: memory: 1024M networks: - name: default pod: {} - multus: networkName: pxe-net-conf name: pxe-net terminationGracePeriodSeconds: 0 volumes: - name: containerdisk containerDisk: image: kubevirt/fedora-cloud-container-disk-demo - cloudInitNoCloud: userData: | #!/bin/bash echo "fedora" | passwd fedora --stdin name: cloudinitdisk status: {}
8.14.7. ゲストメモリーの管理
ゲストメモリー設定を特定のユースケースに合わせて調整する必要がある場合、ゲストの YAML 設定ファイルを編集してこれを実行できます。OpenShift Virtualization は、ゲストメモリーのオーバーコミットの設定と、ゲストメモリーのオーバーコミットアカウンティングの無効化を許可します。
以下の手順では、メモリー不足により仮想マシンのプロセスが強制終了される可能性を高めます。リスクを理解している場合にのみ続行してください。
8.14.7.1. ゲストメモリーのオーバーコミットの設定
仮想ワークロードに利用可能な量を上回るメモリーが必要な場合、メモリーのオーバーコミットを使用してホストのメモリーのすべてまたはそのほとんどを仮想マシンインスタンス (VMI) に割り当てることができます。メモリーのオーバーコミットを有効にすることは、通常ホストに予約されるリソースを最大化できることを意味します。
たとえば、ホストに 32 GB RAM がある場合、メモリーのオーバーコミットを使用してそれぞれ 4 GB RAM を持つ 8 つの仮想マシン (VM) に対応できます。これは、仮想マシンがそれらのメモリーのすべてを同時に使用しないという前提で機能します。
メモリーのオーバーコミットにより、メモリー不足 (OOM による強制終了) が原因で仮想マシンプロセスが強制終了される可能性が高くなります。
仮想マシンが OOM で強制終了される可能性は、特定の設定、ノードメモリー、利用可能な swap 領域、仮想マシンのメモリー消費、カーネルの same-page merging (KSM) の使用その他の要因によって変わります。
手順
仮想マシンインスタンスに対し、クラスターから要求された以上のメモリーが利用可能であることを明示的に示すために、仮想マシン設定ファイルを編集し、
spec.domain.memory.guest
をspec.domain.resources.requests.memory
よりも高い値に設定します。このプロセスはメモリーのオーバーコミットと呼ばれています。以下の例では、
1024M
がクラスターから要求されますが、仮想マシンインスタンスには2048M
が利用可能であると通知されます。ノードに利用可能な空のメモリーが十分にある限り、仮想マシンインスタンスは最大 2048M を消費します。kind: VirtualMachine spec: template: domain: resources: requests: memory: 1024M memory: guest: 2048M
注記ノードがメモリー不足の状態になると、Pod のエビクションルールと同じルールが仮想マシンインスタンスに適用されます。
仮想マシンを作成します。
$ oc create -f <file_name>.yaml
8.14.7.2. ゲストメモリーオーバーヘッドアカウンティングの無効化
要求する量に加えて、少量のメモリーが各仮想マシンインスタンスによって要求されます。追加のメモリーは、それぞれの VirtualMachineInstance
プロセスをラップするインフラストラクチャーに使用されます。
通常は推奨される方法ではありませんが、ゲストメモリーオーバーヘッドアカウンティングを無効にすることでノード上の仮想マシンインスタンスの密度を増やすことは可能です。
ゲストメモリーのオーバーヘッドアカウンティングを無効にすると、メモリー不足 (OOM による強制終了) による仮想マシンプロセスが強制終了の可能性が高くなります。
仮想マシンが OOM で強制終了される可能性は、特定の設定、ノードメモリー、利用可能な swap 領域、仮想マシンのメモリー消費、カーネルの same-page merging (KSM) の使用その他の要因によって変わります。
手順
ゲストメモリーオーバーヘッドアカウンティングを無効にするには、YAML 設定ファイルを編集し、
overcommitGuestOverhead
の値をtrue
に設定します。このパラメーターはデフォルトで無効にされています。kind: VirtualMachine spec: template: domain: resources: overcommitGuestOverhead: true requests: memory: 1024M
注記overcommitGuestOverhead
が有効にされている場合、これはゲストのオーバーヘッドをメモリー制限 (ある場合) に追加します。仮想マシンを作成します。
$ oc create -f <file_name>.yaml
8.14.8. 仮想マシンでの Huge Page の使用
Huge Page は、クラスター内の仮想マシンのバッキングメモリーとして使用できます。
8.14.8.1. 前提条件
8.14.8.2. Huge Page の機能
メモリーは Page と呼ばれるブロックで管理されます。多くのシステムでは、1 ページは 4Ki です。メモリー 1Mi は 256 ページに、メモリー 1Gi は 256,000 ページに相当します。CPU には、内蔵のメモリー管理ユニットがあり、ハードウェアでこのようなページリストを管理します。トランスレーションルックアサイドバッファー (TLB: Translation Lookaside Buffer) は、仮想から物理へのページマッピングの小規模なハードウェアキャッシュのことです。ハードウェアの指示で渡された仮想アドレスが TLB にあれば、マッピングをすばやく決定できます。そうでない場合には、TLB ミスが発生し、システムは速度が遅く、ソフトウェアベースのアドレス変換にフォールバックされ、パフォーマンスの問題が発生します。TLB のサイズは固定されているので、TLB ミスの発生率を減らすには Page サイズを大きくする必要があります。
Huge Page とは、4Ki より大きいメモリーページのことです。x86_64 アーキテクチャーでは、2Mi と 1Gi の 2 つが一般的な Huge Page サイズです。別のアーキテクチャーではサイズは異なります。Huge Page を使用するには、アプリケーションが認識できるようにコードを書き込む必要があります。Transparent Huge Pages (THP) は、アプリケーションによる認識なしに、Huge Page の管理を自動化しようとしますが、制約があります。特に、ページサイズは 2Mi に制限されます。THP では、THP のデフラグが原因で、メモリー使用率が高くなり、断片化が起こり、パフォーマンスの低下につながり、メモリーページがロックされてしまう可能性があります。このような理由から、アプリケーションは THP ではなく、事前割り当て済みの Huge Page を使用するように設計 (また推奨) される場合があります。
OpenShift Virtualization では、事前に割り当てられた Huge Page を使用できるように仮想マシンを設定できます。
8.14.8.3. 仮想マシンの Huge Page の設定
memory.hugepages.pageSize
および resources.requests.memory
パラメーターを仮想マシン設定に組み込み、仮想マシンを事前に割り当てられた Huge Page を使用するように設定できます。
メモリー要求はページサイズ別に分ける必要があります。たとえば、ページサイズ 1Gi
の場合に 500Mi
メモリーを要求することはできません。
ホストおよびゲスト OS のメモリーレイアウトには関連性がありません。仮想マシンマニフェストで要求される Huge Page が QEMU に適用されます。ゲスト内の Huge Page は、仮想マシンインスタンスの利用可能なメモリー量に基づいてのみ設定できます。
実行中の仮想マシンを編集する場合は、変更を有効にするために仮想マシンを再起動する必要があります。
前提条件
- ノードには、事前に割り当てられた Huge Page が設定されている必要がある。
手順
仮想マシン設定で、
resources.requests.memory
およびmemory.hugepages.pageSize
パラメーターをspec.domain
に追加します。以下の設定スニペットは、ページサイズが1Gi
の合計4Gi
メモリーを要求する仮想マシンについてのものです。kind: VirtualMachine ... spec: domain: resources: requests: memory: "4Gi" 1 memory: hugepages: pageSize: "1Gi" 2 ...
仮想マシン設定を適用します。
$ oc apply -f <virtual_machine>.yaml
8.14.9. 仮想マシン用の専用リソースの有効化
パフォーマンスを向上させるために、CPU などのノードリソースを仮想マシン専用に確保できます。
8.14.9.1. 専用リソースについて
仮想マシンの専用リソースを有効にする場合、仮想マシンのワークロードは他のプロセスで使用されない CPU でスケジュールされます。専用リソースを使用することで、仮想マシンのパフォーマンスとレイテンシーの予測の精度を向上させることができます。
8.14.9.2. 前提条件
-
CPU マネージャー はノードに設定される必要があります。仮想マシンのワークロードをスケジュールする前に、ノードに
cpumanager = true
ラベルが設定されていることを確認します。 - 仮想マシンの電源がオフになっていること。
8.14.9.3. 仮想マシンの専用リソースの有効化
Details タブで仮想マシンの専用リソースを有効にすることができます。Red Hat テンプレートまたはウィザードを使用して作成された仮想マシンは、専用のリソースで有効にできます。
手順
-
サイドメニューから Workloads
Virtual Machines をクリックします。 - 仮想マシンを選択して、Virtual Machine タブを開きます。
- Details タブをクリックします。
- Dedicated Resources フィールドの右側にある鉛筆アイコンをクリックして、Dedicated Resources ウィンドウを開きます。
- Schedule this workload with dedicated resources (guaranteed policy) を選択します。
- Save をクリックします。
8.14.10. 仮想マシンのスケジュール
仮想マシンの CPU モデルとポリシー属性が、ノードがサポートする CPU モデルおよびポリシー属性との互換性について一致することを確認して、ノードで仮想マシン (VM) をスケジュールできます。
8.14.10.1. ポリシー属性について
仮想マシン (VM) をスケジュールするには、ポリシー属性と、仮想マシンがノードでスケジュールされる際の互換性について一致する CPU 機能を指定します。仮想マシンに指定されるポリシー属性は、その仮想マシンをノードにスケジュールする方法を決定します。
ポリシー属性 | 説明 |
---|---|
force | 仮想マシンは強制的にノードでスケジュールされます。これは、ホストの CPU が仮想マシンの CPU に対応していない場合でも該当します。 |
require | 仮想マシンが特定の CPU モデルおよび機能仕様で設定されていない場合に仮想マシンに適用されるデフォルトのポリシー。このデフォルトポリシー属性または他のポリシー属性のいずれかを持つ CPU ノードの検出をサポートするようにノードが設定されていない場合、仮想マシンはそのノードでスケジュールされません。ホストの CPU が仮想マシンの CPU をサポートしているか、ハイパーバイザーが対応している CPU モデルをエミュレートできる必要があります。 |
optional | 仮想マシンがホストの物理マシンの CPU でサポートされている場合は、仮想マシンがノードに追加されます。 |
disable | 仮想マシンは CPU ノードの検出機能と共にスケジュールすることはできません。 |
forbid | この機能がホストの CPU でサポートされ、CPU ノード検出が有効になっている場合でも、仮想マシンはスケジュールされません。 |
8.14.10.2. ポリシー属性および CPU 機能の設定
それぞれの仮想マシン (VM) にポリシー属性および CPU 機能を設定して、これがポリシーおよび機能に従ってノードでスケジュールされるようにすることができます。設定する CPU 機能は、ホストの CPU によってサポートされ、またはハイパーバイザーがエミュレートされることを確認するために検証されます。
8.14.10.3. サポートされている CPU モデルでの仮想マシンのスケジューリング
仮想マシン (VM) の CPU モデルまたは仮想マシンインスタンス (VMI) を設定して、CPU モデルがサポートされているノードにこれをスケジュールできます。
手順
仮想マシン設定ファイルの
domain
仕様を編集します。以下の例は、VMI 向けに定義された特定の CPU モデルを示しています。apiVersion: kubevirt.io/v1 kind: VirtualMachineInstance metadata: name: myvmi spec: domain: cpu: model: Conroe 1
- 1
- VMI の CPU モデル。
8.14.10.4. ホストモデルでの仮想マシンのスケジューリング
仮想マシン (VM) の CPU モデルが host-model
に設定されている場合、仮想マシンはスケジュールされているノードの CPU モデルを継承します。
手順
仮想マシン設定ファイルの
domain
仕様を編集します。以下の例は、仮想マシンインスタンス (VMI) に指定されるhost-model
を示しています。apiVersion: kubevirt/v1alpha3 kind: VirtualMachineInstance metadata: name: myvmi spec: domain: cpu: model: host-model 1
- 1
- スケジュールされるノードの CPU モデルを継承する仮想マシンまたは仮想マシンインスタンス (VMI)。
8.14.11. PCI パススルーの設定
PCI (Peripheral Component Interconnect) パススルー機能を使用すると、仮想マシンからハードウェアデバイスにアクセスし、管理できます。PCI パススルーが設定されると、PCI デバイスはゲストオペレーティングシステムに物理的に接続されているかのように機能します。
クラスター管理者は、oc
コマンドラインインターフェイス (CLI) を使用して、クラスターでの使用が許可されているホストデバイスを公開および管理できます。
8.14.11.1. PCI パススルー用ホストデバイスの準備について
CLI を使用して PCI パススルー用にホストデバイスを準備するには、MachineConfig
オブジェクトを作成し、カーネル引数を追加して、Input-Output Memory Management Unit (IOMMU) を有効にします。PCI デバイスを Virtual Function I/O (VFIO) ドライバーにバインドしてから、HyperConverged
カスタムリソース (CR) の permittedHostDevices
フィールドを編集してクラスター内で公開します。OpenShift Virtualization Operator を最初にインストールする場合、permittedHostDevices
の一覧は空になります。
CLI を使用してクラスターから PCI ホストデバイスを削除するには、HyperConverged
CR から PCI デバイス情報を削除します。
8.14.11.1.1. IOMMU ドライバーを有効にするためのカーネル引数の追加
カーネルの IOMMU (Input-Output Memory Management Unit) ドライバーを有効にするには、MachineConfig
オブジェクトを作成し、カーネル引数を追加します。
前提条件
- 作業用の OpenShift Container Platform クラスターに対する管理者権限が必要です。
- Intel または AMD CPU ハードウェア。
- Intel Virtualization Technology for Directed I/O 拡張または BIOS (Basic Input/Output System) の AMD IOMMU が有効にされている。
手順
カーネル引数を識別する
MachineConfig
オブジェクトを作成します。以下の例は、Intel CPU のカーネル引数を示しています。apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: labels: machineconfiguration.openshift.io/role: worker 1 name: 100-worker-iommu 2 spec: config: ignition: version: 3.2.0 kernelArguments: - intel_iommu=on 3 ...
新規
MachineConfig
オブジェクトを作成します。$ oc create -f 100-worker-kernel-arg-iommu.yaml
検証
新規
MachineConfig
オブジェクトが追加されていることを確認します。$ oc get MachineConfig
8.14.11.1.2. PCI デバイスの VFIO ドライバーへのバインディング
PCI デバイスを VFIO (Virtual Function I/O) ドライバーにバインドするには、各デバイスから vendor-ID
および device-ID
の値を取得し、これらの値で一覧を作成します。一覧を MachineConfig
オブジェクトに追加します。MachineConfig
Operator は、PCI デバイスを持つノードで /etc/modprobe.d/vfio.conf
を生成し、PCI デバイスを VFIO ドライバーにバインドします。
前提条件
- カーネル引数を CPU の IOMMU を有効にするために追加している。
手順
lspci
コマンドを実行して、PCI デバイスのvendor-ID
およびdevice-ID
を取得します。$ lspci -nnv | grep -i nvidia
出力例
02:01.0 3D controller [0302]: NVIDIA Corporation GV100GL [Tesla V100 PCIe 32GB] [10de:1eb8] (rev a1)
Butane 設定ファイル
100-worker-vfiopci.bu
を作成し、PCI デバイスを VFIO ドライバーにバインドします。注記Butane の詳細は、Butane を使用したマシン設定の作成を参照してください。
例
variant: openshift version: 4.8.0 metadata: name: 100-worker-vfiopci labels: machineconfiguration.openshift.io/role: worker 1 storage: files: - path: /etc/modprobe.d/vfio.conf mode: 0644 overwrite: true contents: inline: | options vfio-pci ids=10de:1eb8 2 - path: /etc/modules-load.d/vfio-pci.conf 3 mode: 0644 overwrite: true contents: inline: vfio-pci
Butane を使用して、ワーカーノードに配信される設定を含む
MachineConfig
オブジェクトファイル (100-worker-vfiopci.yaml
) を生成します。$ butane 100-worker-vfiopci.bu -o 100-worker-vfiopci.yaml
MachineConfig
オブジェクトをワーカーノードに適用します。$ oc apply -f 100-worker-vfiopci.yaml
MachineConfig
オブジェクトが追加されていることを確認します。$ oc get MachineConfig
出力例
NAME GENERATEDBYCONTROLLER IGNITIONVERSION AGE 00-master d3da910bfa9f4b599af4ed7f5ac270d55950a3a1 3.2.0 25h 00-worker d3da910bfa9f4b599af4ed7f5ac270d55950a3a1 3.2.0 25h 01-master-container-runtime d3da910bfa9f4b599af4ed7f5ac270d55950a3a1 3.2.0 25h 01-master-kubelet d3da910bfa9f4b599af4ed7f5ac270d55950a3a1 3.2.0 25h 01-worker-container-runtime d3da910bfa9f4b599af4ed7f5ac270d55950a3a1 3.2.0 25h 01-worker-kubelet d3da910bfa9f4b599af4ed7f5ac270d55950a3a1 3.2.0 25h 100-worker-iommu 3.2.0 30s 100-worker-vfiopci-configuration 3.2.0 30s
検証
VFIO ドライバーがロードされていることを確認します。
$ lspci -nnk -d 10de:
この出力では、VFIO ドライバーが使用されていることを確認します。
出力例
04:00.0 3D controller [0302]: NVIDIA Corporation GP102GL [Tesla P40] [10de:1eb8] (rev a1) Subsystem: NVIDIA Corporation Device [10de:1eb8] Kernel driver in use: vfio-pci Kernel modules: nouveau
8.14.11.1.3. CLI を使用したクラスターでの PCI ホストデバイスの公開
クラスターで PCI ホストデバイスを公開するには、PCI デバイスの詳細を HyperConverged
カスタムリソース (CR) の spec.permittedHostDevices.pciHostDevices
配列に追加します。
手順
以下のコマンドを実行して、デフォルトエディターで
HyperConverged
CR を編集します。$ oc edit hyperconverged kubevirt-hyperconverged -n openshift-cnv
PCI デバイス情報を
spec.permittedHostDevices.pciHostDevices
配列に追加します。以下に例を示します。設定ファイルのサンプル
apiVersion: hco.kubevirt.io/v1 kind: HyperConverged metadata: name: kubevirt-hyperconverged namespace: openshift-cnv spec: permittedHostDevices: 1 pciHostDevices: 2 - pciDeviceSelector: "10DE:1DB6" 3 resourceName: "nvidia.com/GV100GL_Tesla_V100" 4 - pciDeviceSelector: "10DE:1EB8" resourceName: "nvidia.com/TU104GL_Tesla_T4" - pciDeviceSelector: "8086:6F54" resourceName: "intel.com/qat" externalResourceProvider: true 5 ...
注記上記のスニペットの例は、
nvidia.com/GV100GL_Tesla_V100
およびnvidia.com/TU104GL_Tesla_T4
という名前の 2 つの PCI ホストデバイスが、HyperConverged
CR の許可されたホストデバイスの一覧に追加されたことを示しています。これらのデバイスは、OpenShift Virtualization と動作することがテストおよび検証されています。- 変更を保存し、エディターを終了します。
検証
以下のコマンドを実行して、PCI ホストデバイスがノードに追加されたことを確認します。この出力例は、各デバイスが
nvidia.com/GV100GL_Tesla_V100
、nvidia.com/TU104GL_Tesla_T4
、およびintel.com/qat
のリソース名にそれぞれ関連付けられたデバイスが 1 つあることを示しています。$ oc describe node <node_name>
出力例
Capacity: cpu: 64 devices.kubevirt.io/kvm: 110 devices.kubevirt.io/tun: 110 devices.kubevirt.io/vhost-net: 110 ephemeral-storage: 915128Mi hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 131395264Ki nvidia.com/GV100GL_Tesla_V100 1 nvidia.com/TU104GL_Tesla_T4 1 intel.com/qat: 1 pods: 250 Allocatable: cpu: 63500m devices.kubevirt.io/kvm: 110 devices.kubevirt.io/tun: 110 devices.kubevirt.io/vhost-net: 110 ephemeral-storage: 863623130526 hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 130244288Ki nvidia.com/GV100GL_Tesla_V100 1 nvidia.com/TU104GL_Tesla_T4 1 intel.com/qat: 1 pods: 250
8.14.11.1.4. CLI を使用したクラスターからの PCI ホストデバイスの削除
クラスターから PCI ホストデバイスを削除するには、HyperConverged
カスタムリソース (CR) からそのデバイスの情報を削除します。
手順
以下のコマンドを実行して、デフォルトエディターで
HyperConverged
CR を編集します。$ oc edit hyperconverged kubevirt-hyperconverged -n openshift-cnv
適切なデバイスの
pciDeviceSelector
、resourceName
、およびexternalResourceProvider
(該当する場合) のフィールドを削除して、spec.permittedHostDevices.pciHostDevices
配列から PCI デバイス情報を削除します。この例では、intel.com/qat
リソースが削除されました。設定ファイルのサンプル
apiVersion: hco.kubevirt.io/v1 kind: HyperConverged metadata: name: kubevirt-hyperconverged namespace: openshift-cnv spec: permittedHostDevices: pciHostDevices: - pciDeviceSelector: "10DE:1DB6" resourceName: "nvidia.com/GV100GL_Tesla_V100" - pciDeviceSelector: "10DE:1EB8" resourceName: "nvidia.com/TU104GL_Tesla_T4" ...
- 変更を保存し、エディターを終了します。
検証
以下のコマンドを実行して、PCI ホストデバイスがノードから削除されたことを確認します。この出力例は、
intel.com/qat
リソース名に関連付けられているデバイスがゼロであることを示しています。$ oc describe node <node_name>
出力例
Capacity: cpu: 64 devices.kubevirt.io/kvm: 110 devices.kubevirt.io/tun: 110 devices.kubevirt.io/vhost-net: 110 ephemeral-storage: 915128Mi hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 131395264Ki nvidia.com/GV100GL_Tesla_V100 1 nvidia.com/TU104GL_Tesla_T4 1 intel.com/qat: 0 pods: 250 Allocatable: cpu: 63500m devices.kubevirt.io/kvm: 110 devices.kubevirt.io/tun: 110 devices.kubevirt.io/vhost-net: 110 ephemeral-storage: 863623130526 hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 130244288Ki nvidia.com/GV100GL_Tesla_V100 1 nvidia.com/TU104GL_Tesla_T4 1 intel.com/qat: 0 pods: 250
8.14.11.2. PCI パススルー用の仮想マシンの設定
PCI デバイスがクラスターに追加された後に、それらを仮想マシンに割り当てることができます。PCI デバイスが仮想マシンに物理的に接続されているかのような状態で利用できるようになりました。
8.14.11.2.1. PCI デバイスの仮想マシンへの割り当て
PCI デバイスがクラスターで利用可能な場合、これを仮想マシンに割り当て、PCI パススルーを有効にすることができます。
手順
PCI デバイスをホストデバイスとして仮想マシンに割り当てます。
例
apiVersion: kubevirt.io/v1 kind: VirtualMachine spec: domain: devices: hostDevices: - deviceName: nvidia.com/TU104GL_Tesla_T4 1 name: hostdevices1
- 1
- クラスターでホストデバイスとして許可される PCI デバイスの名前。仮想マシンがこのホストデバイスにアクセスできます。
検証
以下のコマンドを使用して、ホストデバイスが仮想マシンから利用可能であることを確認します。
$ lspci -nnk | grep NVIDIA
出力例
$ 02:01.0 3D controller [0302]: NVIDIA Corporation GV100GL [Tesla V100 PCIe 32GB] [10de:1eb8] (rev a1)
8.14.11.3. 関連情報
8.14.12. ウォッチドッグの設定
ウォッチドッグデバイスに仮想マシン (VM) を設定し、ウォッチドッグをインストールして、ウォッチドッグサービスを開始することで、ウォッチドッグを公開します。
8.14.12.1. 前提条件
-
仮想マシンで
i6300esb
ウォッチドッグデバイスのカーネルサポートが含まれている。Red Hat Enterprise Linux(RHEL) イメージが、i6300esb
をサポートしている。
8.14.12.2. ウォッチドッグデバイスの定義
オペレーティングシステム (OS) が応答しなくなるときにウォッチドッグがどのように進行するかを定義します。
表8.3 利用可能なアクション
|
仮想マシン (VM) の電源がすぐにオフになります。 |
| VM はその場で再起動し、ゲスト OS は反応できません。ゲスト OS の再起動に必要な時間の長さにより liveness プローブのタイムアウトが生じる可能性があるため、このオプションの使用は推奨されません。このタイムアウトにより、クラスターレベルの保護が liveness プローブの失敗に気づき、強制的に再スケジュールした場合に、VM の再起動にかかる時間が長くなる可能性があります。 |
| VM は、すべてのサービスを停止することにより、正常に電源を切ります。 |
手順
以下の内容を含む YAML ファイルを作成します。
apiVersion: kubevirt.io/v1 kind: VirtualMachine metadata: labels: kubevirt.io/vm: vm2-rhel84-watchdog name: <vm-name> spec: running: false template: metadata: labels: kubevirt.io/vm: vm2-rhel84-watchdog spec: domain: devices: watchdog: name: <watchdog> i6300esb: action: "poweroff" 1 ...
- 1
watchdog
アクション (poweroff
、reset
、またはshutdown
) を指定します。
上記の例では、電源オフアクションを使用して、RHEL8 VM で
i6300esb
ウォッチドッグデバイスを設定し、デバイスを/dev/watchdog
として公開します。このデバイスは、ウォッチドッグバイナリーで使用できるようになりました。
以下のコマンドを実行して、YAML ファイルをクラスターに適用します。
$ oc apply -f <file_name>.yaml
この手順は、ウォッチドッグ機能をテストするためにのみ提供されており、実稼働マシンでは実行しないでください。
以下のコマンドを実行して、VM がウォッチドッグデバイスに接続されていることを確認します。
$ lspci | grep watchdog -i
以下のコマンドのいずれかを実行して、ウォッチドッグがアクティブであることを確認します。
カーネルパニックをトリガーします。
# echo c > /proc/sysrq-trigger
ウォッチドッグサービスを終了します。
# pkill -9 watchdog
8.14.12.3. ウォッチドッグデバイスのインストール
仮想マシンに watchdog
パッケージをインストールして、ウォッチドッグサービスを起動します。
手順
root ユーザーとして、
watchdog
パッケージおよび依存関係をインストールします。# yum install watchdog
/etc/watchdog.conf
ファイルの以下の行のコメントを解除して、変更を保存します。#watchdog-device = /dev/watchdog
ウォッチドッグサービスが起動時に開始できるように有効化します。
# systemctl enable --now watchdog.service