Guidelines for using virtual machines

Tenant account users can follow these guidelines to optimize resource usage, improve security, and maintain the reliability of virtual machines provisioned with the virtual machine service.

Resource management

Right-size your virtual machines
  • Start with minimal resources and scale up as needed.
  • Monitor CPU and memory usage in the Red Hat® OpenShift® console.
  • Use resource quotas to prevent over-provisioning.
Storage
  • Choose an appropriate disk size for your workload.
  • Use persistent volumes for data that must survive virtual machine restarts.
  • Clean up unused volumes to free cluster resources.
Image selection
  • Use official, maintained images from the virtual machine catalog.
  • Keep virtual machines updated with the latest security patches.
  • Use cloud-init for automated configuration where appropriate.

To verify your namespace resource quotas, run the following command:

oc describe quota -n <your-namespace>

Typical resource allocations for virtual machine sizes are described in the following table:

Table 1. Virtual machine resource allocations
Size vCPU Memory (GB RAM) Disk (GB)
Small 1–2 2–4 20–50
Medium 2–4 4–8 50–100
Large 4–8 8–16 100–200
X-Large 8+ 16+ 200+

Security

SSH key management
  • Always use SSH keys instead of passwords.
  • Rotate keys regularly.
  • Use different keys for different environments.
  • Never share private keys.
Network security
  • Use NetworkPolicies to restrict traffic between virtual machines and services.
  • Expose only the ports that are required for your workload.
  • Use transport layer security (TLS) or Secure Sockets Layer (SSL) for web services.
  • Implement firewall rules within the virtual machine operating system.
Access control
  • Follow the principle of least privilege when assigning permissions.
  • Use service accounts for automated or programmatic access.
  • Regularly audit access logs.
  • Disable root SSH access where possible.
Updates and patching
  • Keep the virtual machine operating system updated.
  • Enable automatic security updates where appropriate.
  • Test updates in non-production environments before applying to production.
  • Subscribe to security advisories for the operating system you use.

Performance optimization

CPU and memory
  • Use CPU pinning for latency-sensitive workloads.
  • Enable huge pages for memory-intensive applications.
  • Monitor resource utilization regularly and adjust allocations as needed.
Storage performance
  • Use the storage class that is appropriate for your workload type.
  • Consider local storage for high-performance input/output requirements.
  • Configure appropriate disk I/O scheduling within the guest operating system.
Network performance
  • Use single-root I/O virtualization (SR-IOV) for high-throughput networking, if available in your cluster.
  • Configure appropriate maximum transmission unit (MTU) sizes for your network.
  • Monitor network latency and throughput using Red Hat® OpenShift® monitoring tools.

Lifecycle management

Backup and recovery
  • Regularly snapshot your virtual machines.
  • Test restore procedures to confirm backups are valid.
  • Document recovery procedures and store them in an accessible location.
  • Store backups in separate storage locations from the primary virtual machine.
Monitoring
  • Set up alerts for CPU, memory, and disk usage thresholds.
  • Monitor virtual machine health and availability through the Red Hat® OpenShift® console.
  • Track application-level metrics in addition to infrastructure metrics.
  • Use Red Hat® OpenShift® monitoring tools to centralize observability.
Maintenance windows
  • Plan and schedule regular maintenance windows for patching and updates.
  • Communicate planned downtime to stakeholders before maintenance begins.
  • Test changes in a non-production environment before applying to production.
  • Prepare and validate rollback procedures before each maintenance window.

Common workflows

The following examples illustrate typical usage patterns for the Virtual machine service. Each workflow combines provisioning, connectivity, and networking steps.

Deploy a web application
  1. Provision a virtual machine from the catalog with resources appropriate for your web server workload.
  2. Connect by using SSH and install your web server. For example, to install and start nginx:
    sudo dnf install -y nginx
    sudo systemctl enable --now nginx
  3. Create a LoadBalancer service to expose port 80.:
    cat <<EOF | oc apply -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: <your-load-balancer-name>
      namespace: <your-namespace>
    spec:
      type: LoadBalancer
      selector:
        kubevirt.io/vm: <your-vm-name>
      ports:
        - name: http
          protocol: TCP
          port: 80
          targetPort: 80
    EOF
  4. Retrieve the assigned external IP address and verify the application is reachable:
    oc get svc <your-load-balancer-name> -n <your-namespace>
Set up a database server
  1. Provision a virtual machine with sufficient memory and storage for your database workload.
  2. Attach a persistent volume for database files to ensure data survives virtual machine restarts.
  3. Connect by using SSH and install your database software, such as PostgreSQL or MySQL.
  4. Create a ClusterIP service for internal cluster access. For example, for PostgreSQL on port 5432:
    oc create service clusterip <my-vm-name> --tcp=5432:5432
  5. Configure snapshots or external tools for regular backups.
  6. Configure firewall rules within the virtual machine operating system to restrict database access.
Set up a development environment
  1. Provision a virtual machine with your required development tools and operating system image.
  2. Add your development SSH key during provisioning to enable secure access.
  3. Connect by using SSH and install your editor, IDE, or development tools.
  4. Use port forwarding to access development servers running on the virtual machine from your local workstation. For example, to forward ports 8080 and 3000:
    virtctl port-forward <your-vm-name> 8080:8080 3000:3000 -n <your-namespace>
  5. Use virtctl console for direct terminal access when SSH is unavailable.
Run batch processing jobs
  1. Provision a virtual machine with high CPU and memory allocation appropriate for your processing workload.
  2. Upload input data to the virtual machine by using secure copy protocol (SCP) or by mounting a shared volume.
  3. Connect by using SSH and run your processing jobs, or schedule them as system tasks.
  4. Monitor job progress through the Red Hat® OpenShift® console or by reviewing logs over SSH.
  5. Retrieve output results and deprovision the virtual machine when processing is complete.
Integrate with a continuous integration and continuous delivery pipeline
  1. Create a virtual machine template that captures your test environment configuration.
  2. Automate virtual machine provisioning by using the Red Hat® OpenShift® API or CLI in your pipeline scripts.
  3. Run automated tests against the provisioned virtual machine.
  4. Collect test results and logs on completion.
  5. Deprovision the virtual machine after tests complete to release cluster resources.
  6. Integrate the provisioning and deprovisioning steps with your CI/CD tooling, such as Jenkins or GitLab CI.

Quick reference commands

The following commands are commonly used to manage virtual machines on the Red Hat® OpenShift® cluster. Replace your-namespace and your-vm-name with your namespace and virtual machine name.

List virtual machines
oc get vm -n <your-namespace>
Get virtual machine details
oc describe vm <your-vm-name> -n <your-namespace>
Start a virtual machine
virtctl start <your-vm-name> -n <your-namespace>
Stop a virtual machine
virtctl stop <your-vm-name> -n <your-namespace>
Restart a virtual machine
virtctl restart <your-vm-name> -n <your-namespace>
Connect to the serial console
virtctl console <your-vm-name> -n <your-namespace>
Forward a port from the virtual machine to a local port
virtctl port-forward <your-vm-name> 8080:80 -n <your-namespace>
Get the virtual machine IP address
oc get vmi <your-vm-name> -n <your-namespace> -o jsonpath='{.status.interfaces[0].ipAddress}'
View events for a virtual machine
oc get events -n <your-namespace> --field-selector involvedObject.name=<your-vm-name>
Delete a virtual machine
oc delete vm <your-vm-name> -n <your-namespace>

Learn more

For more information, refer to the following additional resources: