Academy/vSphere Foundation 9.0 Administrator (2V0-16.25)/Lab: Deploy Virtual Machine via VM Service (kubectl apply)
This lab targets VCF 9.0

Lab: Deploy Virtual Machine via VM Service (kubectl apply)

VCF 9.0Intermediateadminkubernetes⏱ 60 min

Requires Supervisor enabled (Lab 10). VM Service uses VirtualMachine CRD (vmoperator.vmware.com/v1alpha1).

Objectives

  • Configure VM classes and content library for VM Service
  • Create a VirtualMachine manifest (YAML) and deploy via kubectl
  • Verify VM creation in both kubectl and vCenter UI
  • Understand VM class types: best-effort vs guaranteed reservations
  • Manage VM lifecycle through Kubernetes API (power on/off, delete)

Prerequisites

Supervisor enabled on VVF cluster (Lab 10 completed). Namespace 'dev-team' exists with resource quotas.

Prior labs: vvf-admin-10

Required skills:

  • YAML syntax
  • kubectl basics (apply, get, describe, delete)
  • Content Library concepts

Lab Environment

Holodeck VVF pod with Supervisor running. HAProxy providing load balancing. Namespace 'dev-team' available.

Credentials

SystemUsernamePassword
vCenteradministrator@vsphere.localSet during VCSA deployment
Supervisoradministrator@vsphere.localSame as vCenter

Tasks

Task 1 Configure VM Classes and Content Library

manageability

VM classes define resource profiles (CPU/memory) that developers can request. Content library provides VM images. Both must be configured before VM Service can provision VMs.

Step 1
vCenter → Workload Management → VM Service → VM Classes. Review built-in classes:
  • best-effort-xsmall (2 vCPU, 2GB)
  • best-effort-small (2 vCPU, 4GB)
  • best-effort-medium (4 vCPU, 8GB)
  • guaranteed-small (2 vCPU, 4GB, 100% reservation)
  • guaranteed-medium (4 vCPU, 8GB, 100% reservation)
Step 2
Create a custom VM class: Click 'Create VM Class' → Name='lab-small', vCPUs=2, Memory=4096 MB, Reservation: CPU=0, Memory=0 (best-effort).
best-effort = no reservation (shared resources). guaranteed = 100% reservation (dedicated resources). Use best-effort for dev/test, guaranteed for production.
Step 3
Assign VM classes to namespace: Workload Management → Namespaces → 'dev-team' → VM Service → Add VM Class. Select 'best-effort-small' and 'lab-small'.
Step 4
Create Content Library with VM image: vCenter → Content Libraries → Create Library → Name='vm-service-images', Type=Local.
Step 5
Import VM image: In the content library, click 'Import Item' → select a VM image OVF (e.g., Photon OS 5.0 OVA or Ubuntu Server 22.04 cloud image).
For Holodeck lab, use Photon OS — it's lightweight (~800MB) and VMware-maintained. Download from https://github.com/vmware/photon/releases.
Step 6
Associate content library with namespace: Workload Management → Namespaces → 'dev-team' → VM Service → Add Content Library → select 'vm-service-images'.

Validation Gate

Check: Workload Management → Namespaces → dev-team → VM Service tab

Expected: VM Classes (best-effort-small, lab-small) and Content Library (vm-service-images) associated with namespace

Task 2 Deploy VM Using kubectl apply

manageability

This is the core VM Service workflow — infrastructure-as-code for VMs using Kubernetes API. Exam objective 4.4 explicitly tests this capability.

Step 1

Authenticate to Supervisor:
kubectl vsphere login --server=<supervisor-api-ip> --vsphere-username=administrator@vsphere.local --insecure-skip-tls-verify

Step 2

Switch to dev-team namespace:
kubectl config use-context dev-team

Step 3

Create VM manifest file (my-vm.yaml):

apiVersion: vmoperator.vmware.com/v1alpha1
kind: VirtualMachine
metadata:
name: test-vm-01
namespace: dev-team
spec:
className: best-effort-small
imageName: photon-5-server
storageClass: vsan-default-storage-policy
powerState: poweredOn
networkInterfaces:

  • networkType: vsphere-distributed
Step 4

Apply the manifest:
kubectl apply -f my-vm.yaml

virtualmachine.vmoperator.vmware.com/test-vm-01 created
Step 5

Monitor VM creation:
kubectl get virtualmachines -n dev-team -w

NAME POWERSTATE AGE test-vm-01 poweredOn 2m
Step 6

Get detailed VM status:
kubectl describe virtualmachine test-vm-01 -n dev-team

Shows VM details: className, imageName, IP address, powerState, storage details.
Step 7
Verify in vCenter: Navigate to cluster → VMs → find 'test-vm-01'. Confirm it appears as a regular VM managed by Supervisor.
VM visible in vCenter inventory under the dev-team namespace resource pool.

Validation Gate

Check: kubectl get virtualmachines -n dev-team && vCenter shows test-vm-01 in inventory

Expected: VM test-vm-01 in poweredOn state visible in both kubectl and vCenter

Common Errors

kubectl apply fails with 'no matches for kind VirtualMachine'
Cause: Not connected to Supervisor context or VirtualMachine CRD not registered
Fix: Re-login: kubectl vsphere login. Verify context: kubectl config current-context should show Supervisor cluster.
VM stuck in 'Creating' state
Cause: Content library image not available or storage class not found
Fix: kubectl describe vm test-vm-01 — check Events section for specific error. Verify imageName matches content library item name exactly.
VM created but no IP assigned
Cause: Workload network port group not configured or DHCP not available
Fix: VM Service VMs on vDS need either DHCP on workload VLAN or cloud-init with static IP. Verify workload port group VLAN is trunked on physical switch.

Task 3 Manage VM Lifecycle via kubectl

manageability

Day-2 VM operations through kubectl demonstrate the Kubernetes-native management model — the self-service experience developers get with VM Service.

Step 1

Power off VM:
kubectl patch virtualmachine test-vm-01 -n dev-team --type merge -p '{"spec":{"powerState":"poweredOff"}}'

virtualmachine.vmoperator.vmware.com/test-vm-01 patched
Step 2

Verify power state:
kubectl get vm test-vm-01 -n dev-team

POWERSTATE shows 'poweredOff'
Step 3

Power on:
kubectl patch virtualmachine test-vm-01 -n dev-team --type merge -p '{"spec":{"powerState":"poweredOn"}}'

Step 4

Delete VM:
kubectl delete vm test-vm-01 -n dev-team

virtualmachine.vmoperator.vmware.com "test-vm-01" deleted
Step 5

Verify deletion in vCenter: VM 'test-vm-01' no longer appears in inventory.

Deletion is permanent — no recycle bin. In production, Velero backup (Supervisor Service) should be configured for recovery.

Validation Gate

Check: kubectl get vm -n dev-team

Expected: No resources found in dev-team namespace (VM deleted)

Final Validation

VM classes and content library configured, VM deployed via kubectl, lifecycle operations (power on/off/delete) demonstrated.

✓ VM classes assigned to dev-team namespace → best-effort-small and lab-small visible

✓ Content library associated with dev-team namespace → vm-service-images library listed

✓ VM Service workflow complete: create → verify → power cycle → delete → All kubectl operations succeeded without errors

Cleanup / Restore

Snapshot: post-vm-service-lab

• Ensure test-vm-01 is deleted (kubectl delete vm test-vm-01 -n dev-team)

• Take snapshot 'post-vm-service-lab'

Design Reflection (VCDX)

Panelist: When should a customer use VM Service vs traditional VM provisioning? What guardrails prevent resource sprawl? How do you handle Windows VMs in VM Service (guest customization, licensing)?

Requirements

  • Developer self-service VM provisioning
  • Resource governance via quotas
  • Infrastructure-as-code for VMs
  • Integration with CI/CD pipelines

Constraints

  • VM images must be in content library (no ad-hoc ISO installs)
  • VM classes predefine allowed sizes (no arbitrary sizing)
  • vDS networking limits to VLAN-based isolation
  • No VM snapshot support through kubectl (vSphere-only feature)

Assumptions

  • Developers understand YAML and kubectl
  • Content library images are pre-hardened and approved
  • Namespace quotas prevent resource exhaustion

Risks

  • Uncontrolled VM sprawl if quotas not enforced
  • Image drift if content library not regularly updated
  • Developer confusion between kubectl VM and vCenter VM management

Self-Assessment Discussion Prompts

  1. How do VM Service VMs differ from traditional vCenter VMs in backup, monitoring, and lifecycle?
  2. What's the right VM class strategy — few standardized classes or many custom classes?
  3. How would you integrate VM Service with a GitOps workflow?

References

Was this page useful?
Type to search. ↑ ↓ to move, Enter to open, Esc to close.