Pod Migration and Recovery Plan
Problem Description
Whether a node experiences a normal shutdown or an abnormal crash, the virtual machine Pods running on that node will not automatically migrate to other healthy nodes.
Cause Analysis
The platform implements a virtual machine solution based on the open-source component KubeVirt. However, from KubeVirt’s perspective, it is unable to distinguish whether a virtual machine has actually crashed or if the connection failed due to network or other reasons. Arbitrarily migrating the virtual machine to another node might result in multiple instances of the virtual machine existing simultaneously.
Solution
When maintaining virtual machine nodes, manual operations are required according to this document. For both normal shutdown and abnormal crash scenarios, manual eviction or forced deletion of virtual machine Pods is necessary.
Note: The following commands must be executed on the Master node of the corresponding cluster.
Pod Migration under Normal Shutdown
-
In the CLI tool, execute the following command to get node information. The
NAMEfield in the output is theNode-Name.kubectl get nodesOutput:
NAME STATUS ROLES AGE VERSION 1.1.1.211 Ready control-plane,master 99d v1.28.8 -
(Optional) Execute the following command to view virtual machine instances under the node.
kubectl get vmis --all-namespaces -o wide | grep <Node-Name> # Replace <Node-Name> with the Node-Name obtained in Step 1Output:
test-test vm-t-export-clone 13d Running 1.1.1.1 1.1.1.211 True False -
Before a normal shutdown, execute the following command to evict all virtual machine Pods on the node to be shut down. The following output indicates successful eviction.
kubectl drain <Node-Name> --delete-local-data --ignore-daemonsets=true --force --pod-selector=kubevirt.io=virt-launcher # Replace <Node-Name> with the Node-Name of the node to be shut downOutput:
Flag --delete-local-data has been deprecated, This option is deprecated and will be deleted. Use --delete-emptydir-data. node/1.1.1.211 cordoned evicting pod test-test/virt-launcher-vm-t-export-clone-hmnkk pod/virt-launcher-vm-t-export-clone-hmnkk evicted node/1.1.1.211 drained -
After all virtual machines have started on other nodes, shut down the node.
-
After the node shuts down and restarts, execute the following command to mark the node as schedulable.
kubectl uncordon <Node-Name> # Replace <Node-Name> with the Node-Name of the node that was shut down and restartedOutput:
node/1.1.1.211 uncordoned -
At this point, the original virtual machine instances on that node have migrated to other healthy nodes, and the node is now allowing new Pod scheduling after reboot.
Recovery from Abnormal Crash
-
In the CLI tool, execute the following command to get node information. The
NAMEfield in the output is theNode-Name.kubectl get nodesOutput:
NAME STATUS ROLES AGE VERSION 1.1.1.211 Ready control-plane,master 99d v1.28.8 -
Execute the following command to forcibly delete all virtual machine Pods on the node.
kubectl get po -A -l kubevirt.io=virt-launcher -o wide | grep <Node-Name> | awk '{print "kubectl delete pod --force -n " $1, $2}' | bash # Replace <Node-Name> with the Node-Name of the node that crashed abnormally -
Execute the following command to delete the volumeattachment on the node.
kubectl get volumeattachments.storage.k8s.io | grep <Node-Name> | awk '{print $1}' | xargs kubectl delete volumeattachments.storage.k8s.io # Replace <Node-Name> with the Node-Name of the node that crashed abnormally -
Execute the following command to check if there are any Pods with the label kubevirt.io=virt-api on the node that crashed abnormally.
kubectl -n kubevirt get po -l kubevirt.io=virt-api -o wide | grep <Node-Name> # Replace <Node-Name> with the Node-Name of the node that crashed abnormallyIf they exist, execute the following command to delete the Pods.
kubectl -n kubevirt get po -l kubevirt.io=virt-api -o name | xargs kubectl -n kubevirt delete --force --grace-period=0 -
Execute the following command to check if there are any Pods with the label kubevirt.io=virt-controller on the node that crashed abnormally.
kubectl -n kubevirt get po -l kubevirt.io=virt-controller -o wide | grep <Node-Name> # Replace <Node-Name> with the Node-Name of the node that crashed abnormallyIf they exist, execute the following command to delete the Pods.
kubectl -n kubevirt get po -l kubevirt.io=virt-controller -o name | xargs kubectl -n kubevirt delete --force --grace-period=0 -
At this point, after an abnormal crash of the node, the virtual machine instances will migrate to other healthy nodes.