OpenShift Virtualization

The HyperConverged Operator ("CNV"/HCO) turns one bare-metal OpenShift worker into a KVM host for both halves of the grid — RHEL 9 Symphony management VMs and Windows Server 2019 Symphony compute VMs. It is the layer the whole supportability claim rests on: a GA’d Red Hat product, not a custom operator, and the platform every VM-shaped component in this architecture schedules onto.

Purpose

CDI (Containerized Data Importer) rides along with HCO and owns the DataSource/DataVolume/StorageProfile objects both the golden-image pipeline (detail) and the compute pool (detail) depend on. Everything is installed once by GitOps and reconciled by Argo CD — no manual oc apply after bootstrap.

Placement

Property Value

Cluster

sym-aws (self-hosted OpenShift 4.20, us-east-1, IPI — D9 pivot from ROSA HCP)

Namespace

openshift-cnv

Compute

Single virt-metal MachineSet, m5zn.metal, replicas: 1, us-east-1a — cost-scoped by design (~$4/hr); do not scale without an explicit cost decision

MachineConfigPool

virt-metal, scoped to the metal node only — the CPU Manager KubeletConfig rollout does not force a reboot of the three non-metal worker nodes

Storage

gp3-csi (EBS), RWO — no live migration for VM disks on this storage class; masters and compute hosts are treated as non-migratable

Operator posture

installPlanApproval: Automatic on both the HCO and Pipelines subscriptions — accepted for a PoC/reference build; production would pin Manual and gate on changelog review

Guest VMs land on the single metal node via the node-role.symphonygrid/virt selector baked into KubeVirt instance-type scheduling. OperatorGroup is scoped to openshift-cnv only (targetNamespaces: [openshift-cnv]), not cluster-wide.

Interfaces

Peer Direction Port / Protocol Purpose

openshift-marketplace (redhat-operators)

inbound to OLM

HTTPS (cluster-internal)

Operator catalog source for kubevirt-hyperconverged and openshift-pipelines-operator-rh

virt-metal MachineSet to AWS EC2 API

outbound

HTTPS 443

Machine provisioning (m5zn.metal instance create/terminate)

KubeVirt virt-handler (per node)

inbound from API server

Kubernetes API (6443)

VM lifecycle reconciliation

Guest VMs (RHEL/Windows)

via l2bridge binding

grid UDN, layer2

VM network I/O — carries the full Symphony port matrix, see Symphony management

CDI DataVolume importer

outbound to installer-repo

HTTP

Golden-image / ISO import into gp3-csi-backed PVCs

Maturity

  • GA on self-hosted OpenShift 4.20 and on ROSA (Classic and HCP) — Red Hat’s own Cloud Experts CLI tutorial for OCP Virt on ROSA uses the same bare-metal machine-pool pattern used here, though that tutorial states plainly it is "not designed to be a production-ready deployment"; this build inherits that same PoC posture (RWO gp3-csi, no live migration configured).

  • Hard scheduling prerequisite, build-discovered (ADR 0013, commit 8a8a79f): KubeVirt’s d1. dedicated-CPU instance types — used by every Windows compute VM — hard-require the target node’s kubelet to run cpuManagerPolicy: static. Without the virt-metal-cpumanager.yaml KubeletConfig, every VM using a d1. instancetype is permanently ErrorUnschedulable while Argo shows the Application Synced/Healthy — a fact this build had to discover, undocumented anywhere in KubeVirt’s own instancetype docs.

  • CDI StorageProfile gap, build-discovered: CDI’s automatic inference for ebs.csi.aws.com only found {ReadWriteOnce, Block} — DataVolumes requesting the default Filesystem volume mode (what both the Windows ISO import and every golden-image clone need) failed admission with ErrClaimNotValid until a spec.claimPropertySets override was added.

  • Red Hat’s Example Architecture: 1000 Virtual Machines (Dec 2025, v1.0.0) sizes a bare-metal OCP-Virt cluster at 14 nodes total for 1000 VMs, one configuration in a table ranging 21-200 VMs/host depending on node size — this build’s single-metal-node footprint (2 mgmt + 2 compute VMs) is far below that scale and has not been load- or density-tested.

  • Live migration is not configured: gp3-csi (EBS, RWO) VM disks cannot live-migrate. Acceptable for compute hosts (cattle, rejoin on reboot) but a real operational constraint for the master — see Symphony management.

Verify

# 1. HyperConverged is Available (operator + all its components converged)
oc get hyperconverged kubevirt-hyperconverged -n openshift-cnv \
  -o jsonpath='{.status.conditions[?(@.type=="Available")].status}'

# 2. The virt-metal node is Ready and carries the grid label
oc get nodes -l node-role.symphonygrid/virt= -o wide

# 3. CPU Manager static policy actually landed on that node
oc get node -l node-role.symphonygrid/virt= \
  -o jsonpath='{.items[0].metadata.labels.cpumanager}'
# expect "true" -- "false" or absent means the KubeletConfig rollout hasn't converged yet

# 4. StorageProfile carries the Filesystem claimPropertySet override
oc get storageprofile gp3-csi -o jsonpath='{.spec.claimPropertySets}'

# 5. virtctl can start/reach a test VM (basic HCO smoke test)
virtctl version
oc get vmi -n symphony

Continue to Windows golden image pipeline, the component that turns this substrate into a Symphony-ready compute image.