OpenShift Virtualization (OCP-V) - Installation

### OpenShift Virtualization

Red Hat® OpenShift® Virtualization は Red Hat OpenShift に含まれる機能であり、組織が新規および既存の仮想マシン (VM) ワークロードを実行およびデプロイするための先進的なプラットフォームを提供します。このソリューションにより、従来の仮想マシンを、信頼できる、一貫した包括的なハイブリッドクラウド・アプリケーション・プラットフォームに簡単に移行できます。

OpenShift Virtualization は、VM の移行を単純化するとともに、クラウドネイティブ・アプリケーション・プラットフォームのシンプルさと速度を利用してインフラストラクチャのモダナイゼーションの道筋を提供します。また、先進的な管理の原則を取り入れつつ既存の仮想化への投資を維持することを目指しており、Red Hat の包括的な仮想化ソリューションの基盤となります。

https://www.redhat.com/ja/technologies/cloud-computing/openshift/virtualization

### Installation
ここでは、以下の手順を参考に OCP 4.17 Bare Metal 環境に OCP-V を導入してみます。

前提条件等

https://docs.redhat.com/en/documentation/openshift_container_platform/4.17/html/virtualization/installing#preparing-cluster-for-virt

導入手順

https://docs.redhat.com/en/documentation/openshift_container_platform/4.17/html/virtualization/installing

#### Install OCP-V Operator

OperatorHub から `OpenShift Virtualization` キーワードで OCP-V Operator を検索します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128125/ea798294-df81-44a8-a553-c304d9a7fdab.png)

マニュアルに記載のパラメータ設定で導入します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128125/5fad690e-7895-4916-82f1-ac6cb47ceeec.png)

以上で OCP-V の導入は完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128125/34962188-352b-4618-a9b5-b7e301303776.png)

#### Create HyperConverged CR

続いて、マニュアルの手順に従い `Create HyperConverged` から HyperConverged CR を作成します。

```shell
$ oc explain HyperConverged
GROUP:      hco.kubevirt.io
KIND:       HyperConverged
VERSION:    v1beta1

DESCRIPTION:
    HyperConverged is the Schema for the hyperconvergeds API

FIELDS:
  apiVersion    <string>
    APIVersion defines the versioned schema of this representation of an object.
    Servers should convert recognized schemas to the latest internal value, and
    may reject unrecognized values. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

  kind  <string>
    Kind is a string value representing the REST resource this object
    represents. Servers may infer this from the endpoint the client submits
    requests to. Cannot be updated. In CamelCase. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

  metadata      <ObjectMeta>
    Standard object's metadata. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

  spec  <Object>
    HyperConvergedSpec defines the desired state of HyperConverged

  status        <Object>
    HyperConvergedStatus defines the observed state of HyperConverged
```

<details><summary> HyperConverged.spec </summary>

```shell
$ oc explain HyperConverged.spec
GROUP:      hco.kubevirt.io
KIND:       HyperConverged
VERSION:    v1beta1

FIELD: spec <Object>


DESCRIPTION:
    HyperConvergedSpec defines the desired state of HyperConverged

FIELDS:
  applicationAwareConfig        <Object>
    ApplicationAwareConfig set the AAQ configurations

  certConfig    <Object>
    certConfig holds the rotation policy for internal, self-signed certificates

  commonBootImageNamespace      <string>
    CommonBootImageNamespace override the default namespace of the common boot
    images, in order to hide them.

    If not set, HCO won't set any namespace, letting SSP to use the default. If
    set, use the namespace to create the
    DataImportCronTemplates and the common image streams, with this namespace.
    This field is not set by default.

  commonTemplatesNamespace      <string>
    CommonTemplatesNamespace defines namespace in which common templates will
    be deployed. It overrides the default openshift namespace.

  dataImportCronTemplates       <[]Object>
    DataImportCronTemplates holds list of data import cron templates (golden
    images)

  defaultCPUModel       <string>
    DefaultCPUModel defines a cluster default for CPU model: default CPU model
    is set when VMI doesn't have any CPU model.
    When VMI has CPU model set, then VMI's CPU model is preferred.
    When default CPU model is not set and VMI's CPU model is not set too,
    host-model will be set.
    Default CPU model can be changed when kubevirt is running.

  defaultRuntimeClass   <string>
    DefaultRuntimeClass defines a cluster default for the RuntimeClass to be
    used for VMIs pods if not set there.
    Default RuntimeClass can be changed when kubevirt is running, existing VMIs
    are not impacted till
    the next restart/live-migration when they are eventually going to consume
    the new default RuntimeClass.

  evictionStrategy      <string>
  enum: None, LiveMigrate, LiveMigrateIfPossible, External
    EvictionStrategy defines at the cluster level if the VirtualMachineInstance
    should be
    migrated instead of shut-off in case of a node drain. If the
    VirtualMachineInstance specific
    field is set it overrides the cluster level one.
    Allowed values:
    - `None` no eviction strategy at cluster level.
    - `LiveMigrate` migrate the VM on eviction; a not live migratable VM with no
    specific strategy will block the drain of the node util manually evicted.
    - `LiveMigrateIfPossible` migrate the VM on eviction if live migration is
    possible, otherwise directly evict.
    - `External` block the drain, track eviction and notify an external
    controller.
    Defaults to LiveMigrate with multiple worker nodes, None on single worker
    clusters.

  featureGates  <Object>
    featureGates is a map of feature gate flags. Setting a flag to `true` will
    enable
    the feature. Setting `false` or removing the feature gate, disables the
    feature.

  filesystemOverhead    <Object>
    FilesystemOverhead describes the space reserved for overhead when using
    Filesystem volumes.
    A value is between 0 and 1, if not defined it is 0.055 (5.5 percent
    overhead)

  higherWorkloadDensity <Object>
    HigherWorkloadDensity holds configurataion aimed to increase virtual machine
    density

  infra <Object>
    infra HyperConvergedConfig influences the pod configuration (currently only
    placement)
    for all the infra components needed on the virtualization enabled cluster
    but not necessarily directly on each node running VMs/VMIs.

  ksmConfiguration      <Object>
    KSMConfiguration holds the information regarding
    the enabling the KSM in the nodes (if available).

  kubeSecondaryDNSNameServerIP  <string>
    KubeSecondaryDNSNameServerIP defines name server IP used by KubeSecondaryDNS

  liveMigrationConfig   <Object>
    Live migration limits and timeouts are applied so that migration processes
    do not
    overwhelm the cluster.

  localStorageClassName <string>
    Deprecated: LocalStorageClassName the name of the local storage class.

  logVerbosityConfig    <Object>
    LogVerbosityConfig configures the verbosity level of Kubevirt's different
    components. The higher
    the value - the higher the log verbosity.

  mediatedDevicesConfiguration  <Object>
    MediatedDevicesConfiguration holds information about MDEV types to be
    defined on nodes, if available

  networkBinding        <map[string]Object>
    NetworkBinding defines the network binding plugins.
    Those bindings can be used when defining virtual machine interfaces.

  obsoleteCPUs  <Object>
    ObsoleteCPUs allows avoiding scheduling of VMs for obsolete CPU models

  permittedHostDevices  <Object>
    PermittedHostDevices holds information about devices allowed for passthrough

  resourceRequirements  <Object>
    ResourceRequirements describes the resource requirements for the operand
    workloads.

  scratchSpaceStorageClass      <string>
    Override the storage class used for scratch space during transfer
    operations. The scratch space storage class
    is determined in the following order:
    value of scratchSpaceStorageClass, if that doesn't exist, use the default
    storage class, if there is no default
    storage class, use the storage class of the DataVolume, if no storage class
    specified, use no storage class for
    scratch space

  storageImport <Object>
    StorageImport contains configuration for importing containerized data

  tektonPipelinesNamespace      <string>
    TektonPipelinesNamespace defines namespace in which example pipelines will
    be deployed.
    If unset, then the default value is the operator namespace.
    Deprecated: This field is ignored.

  tektonTasksNamespace  <string>
    TektonTasksNamespace defines namespace in which tekton tasks will be
    deployed.
    If unset, then the default value is the operator namespace.
    Deprecated: This field is ignored.

  tlsSecurityProfile    <Object>
    TLSSecurityProfile specifies the settings for TLS connections to be
    propagated to all kubevirt-hyperconverged components.
    If unset, the hyperconverged cluster operator will consume the value set on
    the APIServer CR on OCP/OKD or Intermediate if on vanilla k8s.
    Note that only Old, Intermediate and Custom profiles are currently
    supported, and the maximum available
    MinTLSVersions is VersionTLS12.

  tuningPolicy  <string>
  enum: annotation, highBurst
    TuningPolicy allows to configure the mode in which the RateLimits of
    kubevirt are set.
    If TuningPolicy is not present the default kubevirt values are used.
    It can be set to `annotation` for fine-tuning the kubevirt queryPerSeconds
    (qps) and burst values.
    Qps and burst values are taken from the annotation
    hco.kubevirt.io/tuningPolicy

  uninstallStrategy     <string>
  enum: RemoveWorkloads, BlockUninstallIfWorkloadsExist
    UninstallStrategy defines how to proceed on uninstall when workloads
    (VirtualMachines, DataVolumes) still exist.
    BlockUninstallIfWorkloadsExist will prevent the CR from being removed when
    workloads still exist.
    BlockUninstallIfWorkloadsExist is the safest choice to protect your
    workloads from accidental data loss, so it's strongly advised.
    RemoveWorkloads will cause all the workloads to be cascading deleted on
    uninstallation.
    WARNING: please notice that RemoveWorkloads will cause your workloads to be
    deleted as soon as this CR will be, even accidentally, deleted.
    Please correctly consider the implications of this option before setting it.
    BlockUninstallIfWorkloadsExist is the default behaviour.

  vddkInitImage <string>
    VDDK Init Image eventually used to import VMs from external providers

    Deprecated: please use the Migration Toolkit for Virtualization

  virtualMachineOptions <Object>
    VirtualMachineOptions holds the cluster level information regarding the
    virtual machine.

  vmStateStorageClass   <string>
    VMStateStorageClass is the name of the storage class to use for the PVCs
    created to preserve VM state, like TPM.
    The storage class must support RWX in filesystem mode.

  workloadUpdateStrategy        <Object>
    WorkloadUpdateStrategy defines at the cluster level how to handle automated
    workload updates

  workloads     <Object>
    workloads HyperConvergedConfig influences the pod configuration (currently
    only placement) of components
    which need to be running on a node where virtualization workloads should be
    able to run.
    Changes to Workloads HyperConvergedConfig can be applied only without
    existing workload.
```
</details>


完了すると、OCP-V Operator の `OpenShift Virtualization Deployment` Tab から以下のように参照することが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128125/262222f6-36d0-4d21-8b91-128271503ff9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128125/78f274cf-7265-437a-854d-2cc4e59b35c2.png)

#### Verification

`openshift-cnv` Project で以下のような Pod が稼働します。
```shell
$ oc get pod -n openshift-cnv
NAME                                                   READY   STATUS                   RESTARTS      AGE
aaq-operator-77c9f6dff4-z4ng7                          1/1     Running                  1             2d
bridge-marker-29znk                                    1/1     Running                  1             2d
bridge-marker-zkt4b                                    1/1     Running                  1             2d
cdi-apiserver-6876967544-kmt29                         1/1     Running                  1             2d
cdi-deployment-68b7f8d567-qnbsq                        1/1     Running                  1             2d
cdi-operator-6b9767547-gw88c                           1/1     Running                  1             2d
cdi-uploadproxy-559574ff4d-n5jgp                       1/1     Running                  1             2d
cluster-network-addons-operator-657845d57d-jkrxb       2/2     Running                  1             2d
hco-operator-7bc6c684d8-r6nr2                          1/1     Running                  1             2d
hco-webhook-56d78867d5-9f8mb                           1/1     Running                  1             2d
hostpath-provisioner-operator-7746dbc8d8-brf5g         1/1     Running                  1             2d
hyperconverged-cluster-cli-download-58d5799f9f-fqr2p   1/1     Running                  1             2d
kube-cni-linux-bridge-plugin-bcfvv                     1/1     Running                  1             2d
kube-cni-linux-bridge-plugin-wl2qd                     1/1     Running                  1             2d
kubemacpool-cert-manager-5d5579ff84-m4b29              1/1     Running                  1             2d
kubemacpool-mac-controller-manager-777799c66c-62fjr    2/2     Running                  1             2d
kubevirt-apiserver-proxy-84769cd4d9-k4qgk              1/1     Running                  1             2d
kubevirt-apiserver-proxy-84769cd4d9-wb5cg              1/1     Running                  1             2d
kubevirt-console-plugin-9f9cd9d57-6spcx                1/1     Running                  1             2d
kubevirt-console-plugin-9f9cd9d57-mdcjl                1/1     Running                  1             2d
ssp-operator-677bbb8959-5trq5                          1/1     Running                  1             2d
virt-api-6c654d8b54-hps2l                              1/1     Running                  1             2d
virt-api-6c654d8b54-mztvh                              1/1     Running                  1             2d
virt-controller-557948f-bhphr                          1/1     Running                  1             2d
virt-controller-557948f-q54m4                          1/1     Running                  1             2d
virt-exportproxy-59fbfb8587-7vnhk                      1/1     Running                  1             2d
virt-exportproxy-59fbfb8587-twkxp                      1/1     Running                  1             2d
virt-handler-46qjh                                     1/1     Running                  1             2d
virt-handler-l8m4h                                     1/1     Running                  1             2d
virt-operator-9b4696ff-4v7pg                           1/1     Running                  1             2d
virt-operator-9b4696ff-nkjx6                           1/1     Running                  1             2d
virt-template-validator-7f4874d847-2g26f               1/1     Running                  1             2d
virt-template-validator-7f4874d847-x6p2z               1/1     Running                  1             2d
```

OCP Console に `Virtualization` Section が追加され、Overview 画面右上の `Download the virtctl command-line utility` から `virtctl` Command の Download も可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128125/a6053662-d7ef-4c95-a636-67a6ea4c608b.png)

```shell
$ virtctl version
Client Version: version.Info{GitVersion:"v1.3.1-177-gba5bdde115", GitCommit:"ba5bdde1155476fd28d210baf3186872c25a4c37", GitTreeState:"clean", BuildDate:"2025-01-22T22:13:16Z", GoVersion:"go1.22.9 (Red Hat 1.22.9-2.el9_5) X:strictfipsruntime", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{GitVersion:"v1.3.1-177-gba5bdde115", GitCommit:"ba5bdde1155476fd28d210baf3186872c25a4c37", GitTreeState:"clean", BuildDate:"2025-01-22T22:10:34Z", GoVersion:"go1.22.9 (Red Hat 1.22.9-2.el9_5) X:strictfipsruntime", Compiler:"gc", Platform:"linux/amd64"}

$ virtctl
Available Commands:
  addvolume         add a volume to a running VM
  adm               Administrate KubeVirt configuration.
  completion        Generate the autocompletion script for the specified shell
  console           Connect to a console of a virtual machine instance.
  create            Create a manifest for the specified Kind.
  credentials       Manipulate credentials on a virtual machine.
  expand            Return the VirtualMachine object with expanded instancetype and preference.
  expose            Expose a virtual machine instance, virtual machine, or virtual machine instance replica set as a new service.
  fslist            Return full list of filesystems available on the guest machine.
  guestfs           Start a shell into the libguestfs pod
  guestosinfo       Return guest agent info about operating system.
  help              Help about any command
  image-upload      Upload a VM image to a DataVolume/PersistentVolumeClaim.
  memory-dump       Dump the memory of a running VM to a pvc
  migrate           Migrate a virtual machine.
  migrate-cancel    Cancel migration of a virtual machine.
  pause             Pause a virtual machine
  permitted-devices List the permitted devices for vmis.
  port-forward      Forward local ports to a virtualmachine or virtualmachineinstance.
  removevolume      remove a volume from a running VM
  restart           Restart a virtual machine.
  scp               SCP files from/to a virtual machine instance.
  soft-reboot       Soft reboot a virtual machine instance
  ssh               Open a SSH connection to a virtual machine instance.
  start             Start a virtual machine.
  stop              Stop a virtual machine.
  unpause           Unpause a virtual machine
  usbredir          Redirect an USB device to a virtual machine instance.
  userlist          Return full list of logged in users on the guest machine.
  version           Print the client and server version information.
  vmexport          Export a VM volume.
  vnc               Open a vnc connection to a virtual machine instance.

Use "virtctl <command> --help" for more information about a given command.
Use "virtctl options" for a list of global command-line options (applies to all commands).
```