---
title: Configuring KubeVirt Redfish for VM management
---

# Configuring KubeVirt Redfish for VM management {#virt-kubevirt-redfish}

KubeVirt Redfish exposes OpenShift Virtualization virtual machines (VMs) through a Redfish-compatible API. This enables external tools and orchestration systems to manage VM power states, query inventory, and attach virtual media using the industry-standard Redfish protocol.

Use KubeVirt Redfish when you need programmatic control over VMs using Redfish, such as deploying virtualized control planes or automating VM lifecycle management.

> [!IMPORTANT]
> KubeVirt Redfish is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.
>
> For more information about the support scope of Red Hat Technology Preview features, see [Technology Preview Features Support Scope](https://access.redhat.com/support/offerings/techpreview/).

## About KubeVirt Redfish {#con_virt-about-kubevirt-redfish_virt-kubevirt-redfish}

KubeVirt Redfish is a Redfish-compatible API that exposes virtual machines (VMs) managed by OpenShift Virtualization on OpenShift Container Platform.

You can use the same Redfish automation patterns you use for physical baseboard management controllers (BMCs) to manage VM power and inventory. The primary use case is deploying virtualized control plane clusters, where the control plane nodes run as VMs on an existing OpenShift Virtualization cluster.

## KubeVirt Redfish architecture {#con_virt-kubevirt-redfish-architecture_virt-kubevirt-redfish}

KubeVirt Redfish is deployed on the hosting cluster as a Deployment resource and is exposed using Service and Route resources. KubeVirt Redfish connects to the cluster API to list and control the KubeVirt VMs you expose through configuration.

Requests arrive at the KubeVirt Redfish endpoint, which is exposed as an OpenShift Container Platform Route. KubeVirt Redfish then translates supported Redfish operations into KubeVirt API calls to manage VM power state, inventory, and virtual media.

## How KubeVirt Redfish differs from physical BMC Redfish {#con_virt-kubevirt-redfish-vs-bmc_virt-kubevirt-redfish}

Redfish is commonly used with physical baseboard management controllers (BMCs) for bare metal deployments, where it manages hardware power state, boot configuration, and provisioning.

KubeVirt Redfish is different in some of the following ways:

- It targets VMs managed by OpenShift Virtualization, not physical servers.
- It runs as a service on your cluster, not on hardware BMCs.
- You can use it for virtualized control plane deployments where physical BMC Redfish supports bare metal deployments.

The two are complementary and can be used together in environments with mixed physical and virtual nodes.

## Install KubeVirt Redfish {#proc_virt-installing-kubevirt-redfish_virt-kubevirt-redfish}

Install KubeVirt Redfish on your OpenShift Virtualization cluster by applying a series of custom resources (CRs). These CRs create the namespace, permissions, configuration, and deployment required to expose VMs through the Redfish API.

**Prerequisites**

- You have a OpenShift Container Platform cluster with OpenShift Virtualization installed.
- You installed the OpenShift CLI (`oc`).
- You logged in to OpenShift Container Platform as a user with `cluster-admin` privileges.

**Procedure**

1. Create the `Namespace` CR for KubeVirt Redfish by creating a YAML file with content such as the following example:

   ```yaml
   apiVersion: v1
   kind: Namespace
   metadata:
     name: kubevirt-redfish
     labels:
       app.kubernetes.io/name: kubevirt-redfish
   ```
2. Apply the resource by running the following command:

   ```terminal
   $ oc apply -f namespace.yaml
   ```
3. Create the `ServiceAccount` CR by creating a YAML file with content such as the following example:

   ```yaml
   apiVersion: v1
   kind: ServiceAccount
   metadata:
     name: kubevirt-redfish
     namespace: kubevirt-redfish
     labels:
       app.kubernetes.io/name: kubevirt-redfish
       app.kubernetes.io/component: rbac
   ```
4. Apply the resource by running the following command:

   ```terminal
   $ oc apply -f serviceaccount.yaml
   ```
5. Create the `ClusterRole` CR with required permissions by creating a YAML file with content such as the following example:

   ```yaml
   apiVersion: rbac.authorization.k8s.io/v1
   kind: ClusterRole
   metadata:
     name: kubevirt-redfish-role
     labels:
       app.kubernetes.io/name: kubevirt-redfish
       app.kubernetes.io/component: rbac
   rules:
     - apiGroups: ["kubevirt.io"]
       resources: ["virtualmachines", "virtualmachineinstances"]
       verbs: ["get", "list", "watch", "update", "patch"]
     - apiGroups: ["kubevirt.io"]
       resources: ["virtualmachines/status", "virtualmachineinstances/status"]
       verbs: ["get", "list", "watch", "patch"]
     - apiGroups: ["kubevirt.io"]
       resources: ["virtualmachines/restart", "virtualmachines/start", "virtualmachines/stop"]
       verbs: ["create"]
     - apiGroups: ["subresources.kubevirt.io"]
       resources: ["virtualmachineinstances/pause", "virtualmachineinstances/unpause"]
       verbs: ["create", "update"]
     - apiGroups: [""]
       resources: ["pods", "services", "configmaps", "secrets"]
       verbs: ["get", "list", "watch", "create", "update", "delete"]
     - apiGroups: [""]
       resources: ["namespaces"]
       verbs: ["get", "list"]
     - apiGroups: ["cdi.kubevirt.io"]
       resources: ["datavolumes", "volumeimportsources"]
       verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
     - apiGroups: [""]
       resources: ["persistentvolumeclaims"]
       verbs: ["get", "list", "create", "update", "patch", "delete", "watch"]
     - apiGroups: ["storage.k8s.io"]
       resources: ["storageclasses"]
       verbs: ["get", "list"]
   ```
6. Apply the resource by running the following command:

   ```terminal
   $ oc apply -f clusterrole.yaml
   ```
7. Create the `ClusterRoleBinding` CR by creating a YAML file with content such as the following example:

   ```yaml
   apiVersion: rbac.authorization.k8s.io/v1
   kind: ClusterRoleBinding
   metadata:
     name: kubevirt-redfish-binding
     labels:
       app.kubernetes.io/name: kubevirt-redfish
       app.kubernetes.io/component: rbac
   roleRef:
     apiGroup: rbac.authorization.k8s.io
     kind: ClusterRole
     name: kubevirt-redfish-role
   subjects:
     - kind: ServiceAccount
       name: kubevirt-redfish
       namespace: kubevirt-redfish
   ```
8. Apply the resource by running the following command:

   ```terminal
   $ oc apply -f clusterrolebinding.yaml
   ```
9. Create a `Secret` CR to enable the Redfish API to manage specific VMs:

   1. Generate a `bcrypt` hashed password for the Redfish API by running the following command in a Linux terminal:

      ```terminal
      $ htpasswd -nbB "" '<password>' | cut -d: -f2
      ```

      - `<password>` is the password you want to use for the Redfish API.

        The output is a `bcrypt` hashed password beginning with `$2a$`, `$2b$`, or `$2y$`.

        > [!NOTE]
        > In earlier Technology Preview releases, plain text passwords were used. Use `bcrypt` hashed passwords for improved security.
   2. Create the `Secret` CR containing the configuration with content such as the following example. Edit the `config.yaml` section to match your environment:

      ```yaml
      apiVersion: v1
      kind: Secret
      metadata:
        name: kubevirt-redfish-secret
        namespace: kubevirt-redfish
        labels:
          app.kubernetes.io/name: kubevirt-redfish
          app.kubernetes.io/component: config
      type: Opaque
      stringData:
        config.yaml: |
          server:
            host: "0.0.0.0"
            port: 8443
            tls:
              enabled: false
          system_id_convention: "enhanced"
          chassis:
            - name: "<chassis_name>"
              namespace: "<vm_namespace>"
              service_account: "kubevirt-redfish"
              vm_selector:
                labels:
                  redfish-enabled: "true"
          authentication:
            users:
              - username: "admin"
                password:
                  hash: "<bcrypt_password>"
                chassis: ["<chassis_name>"]
          datavolume:
            storage_class: "<storage_class>"
            storage_size: "3Gi"
      ```

      where:

      `system_id_convention`
      :   Specifies the format for Redfish system IDs. The recommended setting is `enhanced` to use `<namespace>.<vm-name>` format. The `legacy` setting uses `<vm-name>` only.

      `chassis`
      :   Specifies the namespaces where VMs are deployed. Replace `<chassis_name>` with a name for this chassis configuration and `<vm_namespace>` with the namespace containing your VMs. The `vm_selector` labels identify which VMs in the namespace are exposed through Redfish. Only VMs with matching labels are visible. You can configure multiple chassis entries to expose different subsets of VMs in the same namespace, each with different authentication users.

      `authentication`
      :   Specifies the username and password required to validate requests to the Redfish API. Replace `<bcrypt_password>` with the `bcrypt` hashed password that you generated.

      `datavolume`
      :   Specifies storage for VirtualMedia operations. Replace `<storage_class>` with a storage class available on your cluster, such as `lvms-vg1` or `ocs-storagecluster-ceph-rbd-virtualization`. For more information about storage options, see *Storage requirements* in "Prerequisites for virtualized control planes".
10. Apply the resource by running the following command:

    ```terminal
    $ oc apply -f secret.yaml
    ```

    > [!WARNING]
    > The credentials defined in this `Secret` CR enable full management control over the VMs exposed through KubeVirt Redfish, independently of any OpenShift Container Platform privileges.
11. Create the `Deployment` CR by creating a YAML file with content such as the following example:

    ```yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: kubevirt-redfish
      namespace: kubevirt-redfish
      labels:
        app.kubernetes.io/name: kubevirt-redfish
        app.kubernetes.io/component: server
    spec:
      replicas: 1
      selector:
        matchLabels:
          app.kubernetes.io/name: kubevirt-redfish
          app.kubernetes.io/component: server
      template:
        metadata:
          labels:
            app.kubernetes.io/name: kubevirt-redfish
            app.kubernetes.io/component: server
        spec:
          serviceAccountName: kubevirt-redfish
          securityContext:
            runAsNonRoot: true
          containers:
            - name: kubevirt-redfish
              image: registry.redhat.io/container-native-virtualization/kubevirt-redfish-rhel9:v4.22
              imagePullPolicy: Always
              ports:
                - name: http
                  containerPort: 8443
                  protocol: TCP
              env:
                - name: CONFIG_PATH
                  value: "/app/config/config.yaml"
                - name: LOG_LEVEL
                  value: "info"
              resources:
                requests:
                  memory: "512Mi"
                  cpu: "100m"
                limits:
                  memory: "2Gi"
                  cpu: "500m"
              livenessProbe:
                httpGet:
                  path: /redfish/v1/
                  port: 8443
                  scheme: HTTP
                initialDelaySeconds: 30
                periodSeconds: 10
              readinessProbe:
                httpGet:
                  path: /redfish/v1/
                  port: 8443
                  scheme: HTTP
                initialDelaySeconds: 5
                periodSeconds: 5
              securityContext:
                runAsNonRoot: true
                allowPrivilegeEscalation: false
                capabilities:
                  drop:
                    - ALL
              volumeMounts:
                - name: config-volume
                  mountPath: /app/config
                  readOnly: true
          volumes:
            - name: config-volume
              secret:
                secretName: kubevirt-redfish-secret
    ```

    where:

    - The `image` field specifies the KubeVirt Redfish container image.
12. Apply the resource by running the following command:

    ```terminal
    $ oc apply -f deployment.yaml
    ```
13. Create the `Service` CR by creating a YAML file with content such as the following example:

    ```yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: kubevirt-redfish
      namespace: kubevirt-redfish
      labels:
        app.kubernetes.io/name: kubevirt-redfish
        app.kubernetes.io/component: server
    spec:
      type: ClusterIP
      ports:
        - name: http
          port: 8443
          targetPort: 8443
          protocol: TCP
      selector:
        app.kubernetes.io/name: kubevirt-redfish
        app.kubernetes.io/component: server
    ```
14. Apply the resource by running the following command:

    ```terminal
    $ oc apply -f service.yaml
    ```
15. Create the `Route` CR to expose the Redfish API externally by creating a YAML file with content such as the following example:

    ```yaml
    apiVersion: route.openshift.io/v1
    kind: Route
    metadata:
      name: kubevirt-redfish
      namespace: kubevirt-redfish
      labels:
        app.kubernetes.io/name: kubevirt-redfish
        app.kubernetes.io/component: server
    spec:
      port:
        targetPort: http
      to:
        kind: Service
        name: kubevirt-redfish
        weight: 100
      tls:
        termination: edge
        insecureEdgeTerminationPolicy: Redirect
    ```
16. Apply the resource by running the following command:

    ```terminal
    $ oc apply -f route.yaml
    ```

**Verification**

1. Verify that the pods are running by running the following command:

   ```terminal
   $ oc get pods -n kubevirt-redfish
   ```

   ```terminal {title="Example output"}
   NAME                                READY   STATUS    RESTARTS   AGE
   kubevirt-redfish-587cd94988-xthml   1/1     Running   0          2m
   ```
2. Get the route hostname by running the following command:

   ```terminal
   $ oc get route kubevirt-redfish -n kubevirt-redfish -o jsonpath='{.spec.host}'
   ```
3. Test the Redfish endpoint by running the following command:

   ```terminal
   $ curl -sk -u "admin:<password>" https://<route_hostname>/redfish/v1/
   ```

   A successful response returns JSON with the Redfish service root:

   ```json
   {
     "@odata.id": "/redfish/v1",
     "@odata.type": "#ServiceRoot.v1_0_0.ServiceRoot",
     "Id": "RootService",
     "Name": "Root Service",
     "Systems": {
       "@odata.id": "/redfish/v1/Systems"
     }
   }
   ```

## Supported Redfish API endpoints {#ref_virt-kubevirt-redfish-api-endpoints_virt-kubevirt-redfish}

KubeVirt Redfish implements a subset of the Redfish standard for managing virtual machines. The following table lists the supported API endpoints.

Access these endpoints using the full URL format `https://<route_hostname>/<endpoint_path>`, where `<route_hostname>` is the KubeVirt Redfish Route hostname.

> [!NOTE]
> In endpoint paths, `{system_id}` refers to the VM identifier. With the `enhanced` system ID convention, this is `<namespace>.<vm-name>`. With the `legacy` convention, this is `<vm-name>` only.

**Supported Redfish API endpoints**

| Method | Endpoint | Description |
| --- | --- | --- |
| GET | `/redfish/v1/` | Service root. Returns available resource collections. |
| GET | `/redfish/v1/Systems` | List all VMs exposed as Redfish systems. |
| GET | `/redfish/v1/Systems/{system_id}` | Get details for a specific VM, including power state and boot settings. |
| POST | `/redfish/v1/Systems/{system_id}/Actions/ComputerSystem.Reset` | Power operations. Supported `ResetType` values: `On`, `ForceOff`, `GracefulShutdown`. |
| GET | `/redfish/v1/Systems/{system_id}/VirtualMedia/Cd` | Get VirtualMedia status for the VM’s virtual CD drive. |
| POST | `/redfish/v1/Systems/{system_id}/VirtualMedia/Cd/Actions/VirtualMedia.InsertMedia` | Attach an ISO image to the VM. Requires `Image` URL parameter. |
| POST | `/redfish/v1/Systems/{system_id}/VirtualMedia/Cd/Actions/VirtualMedia.EjectMedia` | Detach the ISO image from the VM. |
| PATCH | `/redfish/v1/Systems/{system_id}` | Modify boot settings. Set `Boot.BootSourceOverrideTarget` (`Cd`, `Hdd`, `Pxe`) and `Boot.BootSourceOverrideEnabled` (`Once`, `Continuous`, `Disabled`). |

**Additional resources**
{._additional-resources}

- [BMC addressing for installer-provisioned infrastructure](/openshift-docs-markdown/installing/installing_bare_metal/ipi/ipi-install-installation-workflow#bmc-addressing_ipi-install-installation-workflow)
- [Deploying far edge sites with ZTP](/openshift-docs-markdown/edge_computing/ztp-deploying-far-edge-sites#ztp-deploying-far-edge-sites)
- [Redfish standard (DMTF)](https://www.dmtf.org/standards/redfish)
