As a DevOps engineer, you can provision a VM and its guest OS in a declarative manner by writing VM deployment specifications in a Kubernetes YAML file.
Prerequisites
- Verify that you have available resources to deploy a VM in your namespace. See View VM Resources Available on a Namespace in vSphere with Tanzu.
- If you use NVIDIA vGPU or other PCI devices for your VMs, the following considerations apply:
- Make sure to use appropriate VM class with PCI configuration. See Add PCI Devices to a VM Class in vSphere with Tanzu.
- VMs with vGPU devices require images that have boot mode set to EFI, such as CentOS. Make sure to have access to these images. For information about supported images, search for VM Service image on the VMware Cloud Marketplace web site.
- VMs with vGPU devices that are managed by VM Service are automatically powered off when an ESXi host enters maintenance mode. This might temporarily affect workloads running in the VMs. The VMs are automatically powered on after the host exists the maintenance mode.
Procedure
- Prepare the VM YAML file.
In the file, specify the following parameters:
Option |
Description |
apiVersion |
Specifies the version of the VM Service API. Such as vmoperator.vmware.com/v1alpha1. |
kind |
Specifies the type of Kubernetes resource to create. The only available value is VirtualMachine. |
spec.imageName |
Specifies the content library image the VM should use. For example, centos-stream-8-vmservice-v1alpha1-xxxxxxxxxxxxx. |
spec.storageClass |
Identifies the storage class to be used for storage of the persistent volumes. For example, wcpglobal-storage-profile. |
spec.className |
Specifies the name of the VM class that describes the virtual hardware settings to be used. For example, custom. |
spec.networkInterfaces |
Specifies network-related settings for the VM.
|
spec.vmMetadata |
Includes additional metadata to pass to the VM. You can use this key to customize the guest OS image and set such items as the hostname of the VM and user-data, including passwords, ssh keys, and so on. The example YAML below uses ConfigMap to store the metadata. |
Use the following as an example of a YAML file
vmsvc-centos-vm.yaml
.
apiVersion: vmoperator.vmware.com/v1alpha1
kind: VirtualMachine
metadata:
name: vmsvc-centos-vm
namespace: my-ns-centos
spec:
imageName: centos-stream-8-vmservice-v1alpha1-xxxxxxxxxxxxx
className: custom
powerState: poweredOn
storageClass: wcpglobal-storage-profile
networkInterfaces:
- networkName: primary
networkType: vsphere-distributed
vmMetadata:
configMapName: vmsvc-centos-nginx-cm
transport: OvfEnv
---
apiVersion: v1
kind: ConfigMap
metadata:
name: vmsvc-centos-nginx-cm
namespace: my-ns-centos
data:
user-data: >-
I2Nsb3VkLWNvbmZpZwoKcGFzc3dvcmQ6IFZNV0FSRQpzc2hfcHdhdXRoOiB0cnVlCgp1c2VyczoKICAtIG5hbWU6IHZtd2FyZQogICAgc3VkbzogQUxMPShBTEwpIE5PUEFTU1dEOkFMTAogICAgbG9ja19wYXNzd2Q6IGZhbHNlCiAgICAjIFBhc3N3b3JkIHNldCB0byBBZG1pbiEyMwogICAgcGFzc3dkOiAnJDEkc2FsdCRTT0MzM2ZWYkEvWnhlSXdENXl3MXUxJwogICAgc2hlbGw6IC9iaW4vYmFzaAoKd3JpdGVfZmlsZXM6CiAgLSBjb250ZW50OiB8CiAgICAgIFZNU1ZDIFNheXMgSGVsbG8gV29ybGQKICAgIHBhdGg6IC9oZWxsb3dvcmxkCg==
ConfigMap contains the cloud-config blob that specifies the username and password for the guest OS. In this example,
user-data in vmsvc-centos-nginx-cm ConfigMap represents the following snippet in base64 format:
#cloud-config
password: VMWARE
ssh_pwauth: true
users:
- name: vmware
sudo: ALL=(ALL) NOPASSWD:ALL
lock_passwd: false
passwd: '$1$salt$SOC33fVbA/ZxeIwD5yw1u1'
shell: /bin/bash
write_files:
- content: |
VMSVC Says Hello World
path: /helloworld
- Deploy the VM.
kubectl apply -f vmsvc-centos-vm.yaml
- Verify that the VM has been created.
kubectl get vm -n my-ns-centos
NAME AGE
vmsvc-centos-vm 28s
- Check the status of the VM and associated events.
kubectl describe virtualmachine vmsvc-centos-vm
The output is similar to the following. From the output, you can also obtain the IP address of the VM, which appears in the Vm Ip field.
Name: vmsvc-centos-vm
Namespace: my-ns-centos
Annotations: vmoperator.vmware.com/image-supported-check: disabled
API Version: vmoperator.vmware.com/v1alpha1
Kind: VirtualMachine
Metadata:
Creation Timestamp: 2021-03-23T19:07:36Z
Finalizers:
virtualmachine.vmoperator.vmware.com
Generation: 1
Managed Fields:
...
...
Spec:
Class Name: custom
Image Name: vmservice-centos-20-10-server-cloudimg-amd64
Network Interfaces:
Network Name: primary
Network Type: vsphere-distributed
Power State: poweredOn
Storage Class: wcpglobal-storage-profile
Vm Metadata:
Config Map Name: vmsvc-centos-nginx-cm
Transport: OvfEnv
Status:
Bios UUID: 4218ec42-aeb3-9491-fe22-19b6f954ce38
Change Block Tracking: false
Conditions:
Last Transition Time: 2021-03-23T19:08:59Z
Status: True
Type: VirtualMachinePrereqReady
Host: 10.185.240.10
Instance UUID: 50180b3a-86ee-870a-c3da-90ddbaffc950
Phase: Created
Power State: poweredOn
Unique ID: vm-73
Vm Ip: 10.161.75.162
Events: <none>
...
- Verify that the VM IP is reachable.
ping 10.161.75.162
PING 10.161.75.162 (10.161.75.162): 56 data bytes
64 bytes from 10.161.75.162: icmp_seq=0 ttl=59 time=43.528 ms
64 bytes from 10.161.75.162: icmp_seq=1 ttl=59 time=53.885 ms
64 bytes from 10.161.75.162: icmp_seq=2 ttl=59 time=31.581 ms
Results
A VM created through the VM Service can be managed only by DevOps from the Kubernetes namespace. Its life cycle cannot be managed from the
vSphere Client, but vSphere administrators can monitor the VM and its resources. For more information, see
Monitor Virtual Machines Available in vSphere with Tanzu.
What to do next
For additional details, see the
Introducing Virtual Machine Provisioning blog.
If the VM includes a PCI device configured for vGPU, install the NVIDIA display driver. See Install the NVIDIA Guest Driver in a VM in vSphere with Tanzu.