Once migration plans are created, you often need to modify their configuration as migration requirements evolve. This chapter covers comprehensive plan modification techniques using kubectl-mtv patching capabilities, enabling dynamic updates without recreating plans.
Overview: Dynamic Plan Modification
Why Plan Patching?
Migration plans require updates throughout their lifecycle:
Environment Changes: Updated network configurations, storage requirements, or target namespaces
Migration Strategy Evolution: Switching between cold, warm, and live migration types
VM-Specific Customization: Individual VM requirements that emerge during planning
Hook Integration: Adding custom automation after initial plan creation
Performance Optimization: Adjusting convertor pod scheduling for better performance
Patching Capabilities
kubectl-mtv provides two primary patching mechanisms:
Plan-Level Patching (patch plan): Modify plan-wide settings affecting all VMs
VM-Level Patching (patch planvm): Customize individual VMs within the plan
Both approaches support comprehensive configuration updates verified from the command implementation.
Patching vs. Recreation
When to Patch:
Plan exists and contains complex VM selections
Need to preserve existing plan metadata and references
Making incremental configuration changes
Plan is referenced by other resources or automation
When to Recreate:
Fundamental changes to source/target providers
Major VM list modifications
Complete migration strategy overhaul
How-To: Patching Plan Settings
Basic Plan Configuration Updates
Migration Type Changes
Change migration strategies dynamically based on requirements:
1
2
3
4
5
6
7
8
9
10
11
# Switch from cold to warm migration
kubectl mtv patch plan --plan-name production-migration \--migration-type warm
# Enable live migration (KubeVirt sources only)
kubectl mtv patch plan --plan-name k8s-to-k8s-migration \--migration-type live
# Switch to cold migration for maximum reliability
kubectl mtv patch plan --plan-name critical-systems \--migration-type cold
Network and Storage Configuration
Update network settings and target configurations:
1
2
3
4
5
6
7
8
9
10
11
# Change transfer network for better performance
kubectl mtv patch plan --plan-name large-vm-migration \--transfer-network migration-network/high-bandwidth-net
# Update target namespace
kubectl mtv patch plan --plan-name dev-environment \--target-namespace development-new
# Modify description for better documentation
kubectl mtv patch plan --plan-name quarterly-migration \--description"Q4 2024 production workload migration to OpenShift 4.16"
Advanced Plan Configuration
Target VM Placement Updates
Modify where target VMs will be scheduled using various placement strategies:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Add labels to all target VMs
kubectl mtv patch plan --plan-name production-apps \--target-labels"environment=production,migration-batch=2024-q4"# Update node selector for hardware requirements
kubectl mtv patch plan --plan-name gpu-workloads \--target-node-selector"accelerator=nvidia-tesla-v100,node-type=compute"# Apply advanced affinity rules using KARL (see Chapter 28 for syntax reference)
kubectl mtv patch plan --plan-name database-cluster \--target-affinity"REQUIRE nodes(node-role.kubernetes.io/database=true) on node"# Set power state for all VMs after migration
kubectl mtv patch plan --plan-name maintenance-migration \--target-power-state off
Convertor Pod Optimization Updates
Update convertor pod scheduling for optimal migration performance:
1
2
3
4
5
6
7
8
9
10
11
# Move convertors to high-performance nodes
kubectl mtv patch plan --plan-name data-intensive-migration \--convertor-node-selector"node-type=high-io,storage-class=nvme"# Apply convertor affinity for storage proximity
kubectl mtv patch plan --plan-name storage-migration \--convertor-affinity"REQUIRE pods(app=ceph-osd) on node"# Add labels to convertor pods for monitoring
kubectl mtv patch plan --plan-name monitored-migration \--convertor-labels"monitoring=enabled,migration-type=production"
Template and Naming Configuration
Update naming templates for better resource organization:
1
2
3
4
5
6
7
8
9
10
11
# Update PVC naming template
kubectl mtv patch plan --plan-name organized-migration \--pvc-name-template"{{.PlanName}}-{{.TargetVmName}}-disk-{{.DiskIndex}}"# Set volume naming template
kubectl mtv patch plan --plan-name structured-storage \--volume-name-template"vol-{{.PVCName}}-{{.VolumeIndex}}"# Configure network interface naming
kubectl mtv patch plan --plan-name network-organized \--network-name-template"{{.TargetVmName}}-{{.NetworkType}}-{{.NetworkIndex}}"
# Enable static IP preservation for vSphere VMs
kubectl mtv patch plan --plan-name vsphere-production \--preserve-static-ips=true# Configure shared disk migration
kubectl mtv patch plan --plan-name cluster-workloads \--migrate-shared-disks=true# Enable compatibility mode for older systems
kubectl mtv patch plan --plan-name legacy-systems \--use-compatibility-mode=true# Configure cleanup behavior
kubectl mtv patch plan --plan-name test-migration \--delete-guest-conversion-pod=true\--delete-vm-on-fail-migration=true# Skip guest conversion for specific use cases
kubectl mtv patch plan --plan-name raw-disk-migration \--skip-guest-conversion=true# Disable preflight inspection for faster warm migrations
kubectl mtv patch plan --plan-name urgent-migration \--run-preflight-inspection=false
Conversion and Guest Conversion Configuration
Configure temporary storage, custom scripts, and virt-v2v image for guest conversion:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Set temporary storage for large VM conversion scratch space
kubectl mtv patch plan --plan-name large-migration \--conversion-temp-storage-class fast-scratch \--conversion-temp-storage-size 500Gi
# Add customization scripts ConfigMap for guest conversion
kubectl mtv patch plan --plan-name windows-migration \--customization-scripts migration-scripts/windows-customizations
# Override virt-v2v image for specific migration scenario
kubectl mtv patch plan --plan-name custom-v2v-migration \--virt-v2v-image registry.example.com/custom-virt-v2v:latest
# Skip zone node selector for EC2 migrations (EC2 only)
kubectl mtv patch plan --plan-name ec2-migration \--skip-zone-node-selector=true
Comprehensive Plan Update Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Complete plan reconfiguration for production migration
kubectl mtv patch plan --plan-name enterprise-migration \--description"Enterprise production migration - Phase 2"\--migration-type warm \--target-namespace production-v2 \--transfer-network production/high-speed-migration \--target-labels"environment=production,phase=2,team=platform"\--target-node-selector"node-role.kubernetes.io/compute=true"\--target-affinity"PREFER nodes(topology.kubernetes.io/zone=us-east-1a) on zone"\--target-power-state auto \--convertor-labels"migration=production,performance=optimized"\--convertor-node-selector"node-type=high-io,network=10gbe"\--convertor-affinity"REQUIRE nodes(storage-tier=premium) on node"\--preserve-static-ips=true\--preserve-cluster-cpu-model=true\--pvc-name-template"prod-{{.TargetVmName}}-{{.DiskIndex}}"\--delete-guest-conversion-pod=true\--run-preflight-inspection=true
How-To: Patching Individual VMs
VM Identity and Configuration
Modify individual VM settings within a plan:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Change target VM name
kubectl mtv patch planvm --plan-name production-migration --vm-name web-server-01 \--target-name web-prod-primary
# Set specific instance type for a VM
kubectl mtv patch planvm --plan-name enterprise-migration --vm-name database-main \--instance-type large-memory
# Specify root disk for VMs with multiple disks
kubectl mtv patch planvm --plan-name complex-migration --vm-name multi-disk-vm \--root-disk"Hard disk 1"# Set power state for specific VM
kubectl mtv patch planvm --plan-name maintenance-migration --vm-name critical-db \--target-power-state on
VM-Specific Naming Templates
Apply custom naming templates to individual VMs:
1
2
3
4
5
6
7
8
9
10
11
# Custom PVC naming for high-storage VM
kubectl mtv patch planvm --plan-name data-migration --vm-name large-database \--pvc-name-template"{{.TargetVmName}}-data-{{.WinDriveLetter}}-{{.DiskIndex}}"# Custom volume naming for multi-tier application
kubectl mtv patch planvm --plan-name app-migration --vm-name web-tier \--volume-name-template"{{.TargetVmName}}-vol-{{.VolumeIndex}}"# Custom network naming for multi-homed VMs
kubectl mtv patch planvm --plan-name network-migration --vm-name firewall-vm \--network-name-template"{{.TargetVmName}}-{{.NetworkType}}-{{.NetworkIndex}}"
Security Configuration
Configure VM-specific security settings:
1
2
3
4
5
6
7
8
9
10
11
# Add LUKS decryption secret for encrypted VM
kubectl mtv patch planvm --plan-name secure-migration --vm-name encrypted-database \--luks-secret db-encryption-keys
# Enable NBDE/Clevis passphrase-less disk unlocking via TANG server
kubectl mtv patch planvm --plan-name secure-migration --vm-name nbde-encrypted-vm \--nbde-clevis=true# Override plan-level deletion policy for specific VM
kubectl mtv patch planvm --plan-name test-migration --vm-name experimental-vm \--delete-vm-on-fail-migration=true
Adding and Managing Hooks
Attach custom automation to specific VMs:
Adding Hooks
1
2
3
4
5
6
7
8
9
10
11
12
# Add pre-migration hook to database VM
kubectl mtv patch planvm --plan-name production-migration --vm-name database-primary \--add-pre-hook database-backup-hook
# Add post-migration hook to web server
kubectl mtv patch planvm --plan-name production-migration --vm-name web-server-01 \--add-post-hook health-check-hook
# Add both pre and post hooks to critical application
kubectl mtv patch planvm --plan-name critical-migration --vm-name app-server-main \--add-pre-hook app-quiesce-hook \--add-post-hook app-validation-hook
Managing Existing Hooks
1
2
3
4
5
6
7
8
9
10
11
12
13
# Remove specific hook from VM
kubectl mtv patch planvm --plan-name production-migration --vm-name web-server-01 \--remove-hook old-health-check
# Clear all hooks from VM
kubectl mtv patch planvm --plan-name production-migration --vm-name test-vm \--clear-hooks# Replace hook by removing old and adding new
kubectl mtv patch planvm --plan-name production-migration --vm-name database-secondary \--remove-hook old-backup-hook
kubectl mtv patch planvm --plan-name production-migration --vm-name database-secondary \--add-pre-hook new-enhanced-backup-hook
Comprehensive VM Update Example
1
2
3
4
5
6
7
8
9
10
11
12
13
# Complete VM customization within plan
kubectl mtv patch planvm --plan-name enterprise-migration --vm-name critical-database \--target-name db-prod-primary \--instance-type extra-large \--root-disk"SCSI disk 1"\--target-power-state on \--pvc-name-template"{{.TargetVmName}}-{{.WinDriveLetter}}-{{.DiskIndex}}"\--volume-name-template"{{.TargetVmName}}-storage-{{.VolumeIndex}}"\--network-name-template"{{.TargetVmName}}-net-{{.NetworkIndex}}"\--luks-secret database-encryption-secret \--delete-vm-on-fail-migration=false\--add-pre-hook database-cluster-quiesce \--add-post-hook database-cluster-validate
# Initial plan with basic cold migration
kubectl mtv create plan --name evolving-migration \--source vsphere-prod --target openshift-prod \--vms"app-server-01,app-server-02,database-01"# Evolve to warm migration after testing
kubectl mtv patch plan --plan-name evolving-migration \--migration-type warm \--run-preflight-inspection=true# Add convertor optimization for warm migration
kubectl mtv patch plan --plan-name evolving-migration \--convertor-node-selector"node-type=high-io"\--convertor-affinity"REQUIRE nodes(network-speed=10gbe) on node"# Configure individual database VM for special handling
kubectl mtv patch planvm --plan-name evolving-migration --vm-name database-01 \--target-name database-primary \--instance-type large-memory \--add-pre-hook database-backup-hook \--add-post-hook database-validation-hook
Scenario 2: Performance Optimization Through Patching
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Start with basic plan
kubectl mtv create plan --name performance-migration \--source vsphere-datacenter --target openshift-cluster \--vms"where tags.category='performance-critical'"# Add performance optimizations
kubectl mtv patch plan --plan-name performance-migration \--transfer-network performance/dedicated-migration-net \--convertor-node-selector"node-type=high-performance,storage=nvme"\--convertor-labels"priority=high,performance=optimized"\--convertor-affinity"REQUIRE nodes(cpu-type=intel-skylake) on node"# Optimize target placement
kubectl mtv patch plan --plan-name performance-migration \--target-node-selector"node-role.kubernetes.io/compute=true,performance-tier=premium"\--target-affinity"PREFER nodes(topology.kubernetes.io/zone=performance-zone) on zone"\--target-labels"performance=critical,monitoring=enhanced"
# Basic plan without hooks
kubectl mtv create plan --name progressive-automation \--source vmware-test --target k8s-test \--vms database-test,web-test,cache-test
# Add database-specific automation
kubectl mtv patch planvm --plan-name progressive-automation --vm-name database-test \--add-pre-hook database-quiesce \--add-post-hook database-health-check
# Add web server automation
kubectl mtv patch planvm --plan-name progressive-automation --vm-name web-test \--add-pre-hook lb-drain-connections \--add-post-hook web-health-validation
# Add cache server automation
kubectl mtv patch planvm --plan-name progressive-automation --vm-name cache-test \--add-post-hook cache-warmup-hook
# Add plan-level notification# Note: Plan-level hooks require adding to all VMs individuallyfor vm in database-test web-test cache-test;do
kubectl mtv patch planvm --plan-name progressive-automation --vm-name$vm\--add-post-hook migration-notification
done
Scenario 4: Environment-Specific Customization
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Development environment configuration
kubectl mtv patch plan --plan-name dev-migration \--target-namespace development \--target-labels"environment=dev,auto-shutdown=true"\--target-power-state off \--delete-vm-on-fail-migration=true\--delete-guest-conversion-pod=true# Production environment configuration
kubectl mtv patch plan --plan-name prod-migration \--target-namespace production \--target-labels"environment=prod,backup=required,monitoring=critical"\--target-node-selector"node-role.kubernetes.io/production=true"\--target-affinity"REQUIRE nodes(reliability-tier=high) on node"\--preserve-static-ips=true\--preserve-cluster-cpu-model=true\--delete-vm-on-fail-migration=false
Patching with Provider Updates
While less common, provider configurations can also be updated:
Template Updates: Naming templates should be consistent across VMs
Use VM-Level Patching When:
Individual Customization: Specific VMs need unique configurations
Selective Hooks: Only certain VMs require automation
Security Requirements: LUKS secrets or power states vary per VM
Instance Types: VMs have different resource requirements
Target Names: Custom naming for specific VMs
Strategic Patching Approach
1. Plan First, Then Customize
1
2
3
4
5
6
7
8
9
10
# Start with plan-wide optimizations
kubectl mtv patch plan --plan-name enterprise-migration \--migration-type warm \--target-namespace production \--convertor-node-selector"node-type=high-io"# Then customize specific VMs
kubectl mtv patch planvm --plan-name enterprise-migration --vm-name database-cluster \--instance-type extra-large \--add-pre-hook cluster-backup
2. Group Similar VMs
1
2
3
4
5
6
7
8
9
10
11
12
13
# Apply similar configurations to VM groupsfor vm in web-01 web-02 web-03;do
kubectl mtv patch planvm --plan-name web-migration --vm-name$vm\--target-labels"tier=web,load-balancer=true"\--add-post-hook web-health-check
done
for vm in db-primary db-secondary;do
kubectl mtv patch planvm --plan-name db-migration --vm-name$vm\--instance-type large-memory \--add-pre-hook database-backup \--add-post-hook database-validation
done
3. Iterative Refinement
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Initial basic configuration
kubectl mtv patch plan --plan-name iterative-migration \--migration-type cold \--target-namespace staging
# Test and refine
kubectl mtv patch plan --plan-name iterative-migration \--migration-type warm \--convertor-node-selector"storage=ssd"# Final production configuration
kubectl mtv patch plan --plan-name iterative-migration \--target-namespace production \--target-affinity"REQUIRE nodes(reliability=high) on node"
Validation and Verification
Verify Plan Changes
1
2
3
4
5
6
7
8
# Check plan configuration after patching
kubectl get plan production-migration -o yaml
# Verify specific fields
kubectl get plan production-migration -ojsonpath='{.spec.targetNamespace}'# Check VM configurations
kubectl get plan production-migration -ojsonpath='{.spec.vms[*].name}'
Monitor Patch Results
1
2
3
4
5
6
7
8
# Watch plan status after patching
kubectl get plan production-migration -w# Check plan conditions
kubectl describe plan production-migration | grep-A 5 Conditions
# Verify VM-specific changes
kubectl get plan production-migration -ojsonpath='{.spec.vms[?(@.name=="database-01")].hooks}'
Common Patching Scenarios and Solutions
Problem: Migration Too Slow
Solution: Optimize with Patching
1
2
3
4
5
6
7
8
# Add high-performance convertor scheduling
kubectl mtv patch plan --plan-name slow-migration \--convertor-node-selector"node-type=high-io,network=10gbe"\--convertor-affinity"REQUIRE nodes(storage-tier=premium) on node"# Switch to warm migration for reduced downtime
kubectl mtv patch plan --plan-name slow-migration \--migration-type warm
Problem: VM Naming Conflicts
Solution: Update Naming Templates
1
2
3
4
5
6
7
# Fix naming conflicts with better templates
kubectl mtv patch plan --plan-name naming-conflict \--pvc-name-template"{{.PlanName}}-{{.TargetVmName}}-{{.DiskIndex}}"# Individual VM name fixes
kubectl mtv patch planvm --plan-name naming-conflict --vm-name conflicting-vm \--target-name unique-vm-name-prod
Problem: Missing Automation
Solution: Add Hooks Incrementally
1
2
3
4
# Add hooks to specific VMs needing automation
kubectl mtv patch planvm --plan-name manual-migration --vm-name database-server \--add-pre-hook backup-automation \--add-post-hook validation-automation
Problem: Security Compliance
Solution: Add Security Configurations
1
2
3
4
5
6
7
# Add LUKS support for encrypted VMs
kubectl mtv patch planvm --plan-name secure-migration --vm-name encrypted-vm \--luks-secret encryption-keys-secret
# Configure secure target placement
kubectl mtv patch plan --plan-name secure-migration \--target-node-selector"security-level=high,compliance=pci-dss"