Skip to content

Commit 8cf5704

Browse files
committed
Build: (735c738) Merge pull request #300 from sradco/add_runbook_for_vm_stuck_in_status_alerts
Add VM in unhealthy state alerts runbooks
1 parent 54858d1 commit 8cf5704

3 files changed

Lines changed: 620 additions & 0 deletions

File tree

Lines changed: 309 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
# VirtualMachineStuckInUnhealthyState
2+
3+
## Meaning
4+
5+
This alert fires when a VirtualMachine has been stuck in an unhealthy state
6+
for more than 10 minutes and does not have an associated VMI
7+
(VirtualMachineInstance).
8+
9+
The alert indicates that a VirtualMachine is experiencing early-stage
10+
lifecycle issues before a VMI can be successfully created.
11+
This typically occurs during the initial phases of VM startup when KubeVirt
12+
is trying to provision resources, pull images, or schedule the workload.
13+
14+
**Affected States:**
15+
- `Provisioning` - Resources (DataVolumes, PVCs) are being prepared
16+
- `Starting` - VM is attempting to start but no VMI exists yet
17+
- `Terminating` - VM is being deleted but without an active VMI
18+
- `Error` states - Various scheduling, image, or resource allocation errors
19+
20+
## Impact
21+
22+
- **Severity:** Warning
23+
- **User Impact:** VMs cannot start or are stuck in error states
24+
- **Business Impact:** Workloads cannot be deployed, affecting application
25+
availability
26+
27+
## Possible Causes
28+
29+
### Resource-Related Issues
30+
- **Insufficient cluster resources** (CPU, memory, storage)
31+
- **Missing or misconfigured storage classes**
32+
- **PVC provisioning failures**
33+
- **DataVolume creation/import failures**
34+
35+
### Image and Registry Issues
36+
- **Container image pull failures** for containerDisk volumes
37+
- **Registry authentication problems**
38+
- **Network connectivity issues to image registries**
39+
- **Missing or corrupted VM disk images**
40+
41+
### Scheduling and Node Issues
42+
- **No schedulable nodes available** (all nodes cordoned/unschedulable)
43+
- **Insufficient resources** like KVM/GPU on available nodes or a
44+
mismatch between requested and available CPU models
45+
- **Node selector constraints** cannot be satisfied
46+
- **Taints and tolerations** preventing scheduling
47+
48+
### Configuration Issues
49+
- **Invalid VM specifications** (malformed YAML, unsupported
50+
features)
51+
- **Missing required Secrets or ConfigMaps**
52+
- **Incorrect resource requests/limits**
53+
- **Network configuration errors**
54+
55+
## Diagnosis
56+
57+
### 1. Check VM Status and Events
58+
```bash
59+
# Get VM details and status
60+
kubectl get vm <vm-name> -n <namespace> -o yaml
61+
62+
# Check VM events for error messages
63+
kubectl describe vm <vm-name> -n <namespace>
64+
65+
# Look for related events in the namespace
66+
kubectl get events -n <namespace> --sort-by='.lastTimestamp'
67+
```
68+
69+
### 2. Verify Resource Availability
70+
```bash
71+
# Check node resources and schedulability
72+
kubectl get nodes -o wide
73+
kubectl describe nodes
74+
75+
# Check storage classes and provisioners
76+
kubectl get storageclass
77+
kubectl get pv,pvc -n <namespace>
78+
79+
# For DataVolumes (if using)
80+
kubectl get datavolume -n <namespace>
81+
kubectl describe datavolume <dv-name> -n <namespace>
82+
```
83+
84+
### 3. Check Image Availability (for containerDisk)
85+
```bash
86+
# If using containerDisk, verify image accessibility from the affected node
87+
# Start a debug session on the node hosting the VM (or a representative node)
88+
kubectl debug node/<node-name> -it --image=busybox
89+
90+
# Inside the debug pod, check which container runtime is used
91+
ps aux | grep -E "(containerd|dockerd|crio)"
92+
93+
# For CRI-O/containerd clusters use crictl to pull the image
94+
crictl pull <vm-disk-image>
95+
96+
# For Docker-based clusters (less common)
97+
docker pull <vm-disk-image>
98+
99+
# Exit the debug session when done
100+
exit
101+
102+
# Check image pull secrets if required
103+
kubectl get secrets -n <namespace>
104+
```
105+
106+
### 4. Verify KubeVirt Configuration
107+
```bash
108+
# Discover the KubeVirt installation namespace
109+
export NAMESPACE="$(kubectl get kubevirt -A -o custom-columns="":.metadata.namespace)"
110+
111+
# Check KubeVirt CR conditions (expect Available=True)
112+
kubectl get kubevirt -n "$NAMESPACE" \
113+
-o jsonpath='{range .items[*].status.conditions[*]}{.type}={.status}{"\n"}{end}'
114+
115+
# Or check a single CR named 'kubevirt'
116+
kubectl get kubevirt kubevirt -n "$NAMESPACE" \
117+
-o jsonpath='{.status.conditions[?(@.type=="Available")].status}'
118+
119+
# Verify virt-controller is running
120+
kubectl get pods -n "$NAMESPACE" \
121+
-l kubevirt.io=virt-controller
122+
123+
# Check virt-controller logs for errors
124+
# Replace <virt-controller-pod> with a pod name from the list above
125+
kubectl logs -n "$NAMESPACE" <virt-controller-pod>
126+
127+
# Verify virt-handler is running
128+
kubectl get pods -n "$NAMESPACE" \
129+
-l kubevirt.io=virt-handler -o wide
130+
131+
# Check virt-handler logs for errors (daemonset uses per-node pods)
132+
# Replace <virt-handler-pod> with a pod name from the list above
133+
kubectl logs -n "$NAMESPACE" <virt-handler-pod>
134+
```
135+
136+
### 5. Review VM Specification
137+
Inspect the following details in the VM's spec to catch common
138+
misconfigurations:
139+
140+
- Disks and volumes (in spec.template.spec.domain.devices and volumes):
141+
- A bootable disk is defined using bootOrder: 1
142+
- Each disk name matches a volume name
143+
- Volume sources are valid: PVC, DataVolume, containerDisk, secret, or
144+
configMap
145+
146+
- Resources (in spec.template.spec.domain.resources):
147+
- Resource requests and limits are set and do not exceed node capacity
148+
149+
- Scheduling (in spec.template.spec):
150+
- nodeSelector, affinity, and tolerations are not overly restrictive
151+
152+
- Image pull configuration (in spec.template.spec.imagePullSecrets):
153+
- imagePullSecrets are configured if using a private image registry
154+
155+
- Power strategy (in spec.runStrategy or spec.running):
156+
- Only one of spec.runStrategy or spec.running is set, and it matches the
157+
desired behavior
158+
159+
## Mitigation
160+
161+
### Resource Issues
162+
1. **Scale cluster** if insufficient resources
163+
2. **Create missing storage classes** or configure default storage
164+
3. **Resolve PVC/DataVolume failures**:
165+
```bash
166+
kubectl get pvc -n <namespace>
167+
kubectl describe pvc <pvc-name> -n <namespace>
168+
```
169+
170+
### Image Issues
171+
1. **Verify image accessibility**:
172+
```bash
173+
# Validate from the node
174+
kubectl debug node/<node-name> -it --image=busybox
175+
176+
# Inside the debug pod, detect runtime and pull
177+
ps aux | grep -E "(containerd|dockerd|crio)"
178+
179+
# For CRI-O/containerd clusters:
180+
crictl pull <image-name>
181+
182+
# For Docker-based clusters (less common):
183+
docker pull <image-name>
184+
185+
exit
186+
```
187+
2. **Configure image pull secrets** if needed:
188+
```bash
189+
kubectl create secret docker-registry <secret-name> \
190+
--docker-server=<registry-url> \
191+
--docker-username=<username> \
192+
--docker-password=<password>
193+
```
194+
195+
### Scheduling Issues
196+
1. **Review VM scheduling constraints** and relax if too restrictive:
197+
- nodeSelector, affinity, and tolerations
198+
- Required CPU model, host devices, or features
199+
200+
2. **Verify node taints and tolerations** allow scheduling:
201+
- Ensure the VM tolerates node taints that apply to target nodes
202+
203+
3. **Ensure nodes have required capabilities**:
204+
- KVM availability, CPU features, GPU, SR-IOV, or storage access
205+
206+
4. If nodes were intentionally cordoned for maintenance, **uncordon** when
207+
appropriate:
208+
```bash
209+
kubectl uncordon <node-name>
210+
```
211+
212+
### Configuration Issues Resolution
213+
1. **Fix VM specification errors** based on kubectl describe output:
214+
```bash
215+
# Edit VM specification directly
216+
kubectl edit vm <vm-name> -n <namespace>
217+
218+
# Or patch specific fields
219+
kubectl patch vm <vm-name> -n <namespace> --type='merge' \
220+
-p='{"spec":{"template":{"spec":{"domain":{"resources": \
221+
{"requests":{"memory":"2Gi"}}}}}}}'
222+
```
223+
2. **Create missing secrets/configmaps**:
224+
```bash
225+
kubectl create secret generic <secret-name> \
226+
--from-literal=key=value
227+
```
228+
3. **Adjust resource requests** if they exceed node capacity
229+
230+
### Emergency Workarounds
231+
- **Restart the VM** to apply specification changes:
232+
```bash
233+
# Restart the VM to pick up spec changes
234+
virtctl restart <vm-name> -n <namespace>
235+
```
236+
- **Scale down non-critical workloads** temporarily if resource
237+
constraints exist
238+
- **Change storage class** if PVC provisioning fails:
239+
```bash
240+
# Check current storage class status
241+
kubectl get storageclass
242+
kubectl describe storageclass <current-storage-class>
243+
244+
# Look for PVC provisioning errors
245+
kubectl describe pvc <pvc-name> -n <namespace>
246+
247+
# If seeing "no volume provisioner" or similar errors,
248+
# specify a working storage class in VM spec:
249+
# spec.dataVolumeTemplates[].spec.pvc.storageClassName:
250+
# <working-class>
251+
```
252+
253+
## Prevention
254+
255+
1. **Resource Planning:**
256+
- Monitor cluster resource utilization
257+
- Set appropriate VM guest resources in the VM domain guest spec.
258+
- Plan storage capacity and provisioning
259+
260+
2. **Image Management:**
261+
- Use local image registries where possible to reduce
262+
latency
263+
- Configure DataVolume import methods appropriately:
264+
* **Pod import method**: Images pulled to temporary pods (default)
265+
* **Node import method**: Images pulled directly to nodes
266+
(requires pre-pulling)
267+
- Pre-pull critical containerDisk images to nodes only if
268+
using node import method
269+
270+
3. **Monitoring:**
271+
- Set up alerts for cluster resource exhaustion
272+
- Monitor storage provisioner health
273+
- Track VM startup success rates
274+
275+
4. **Testing:**
276+
- Validate VM templates in development environments
277+
- Test VM deployments after cluster changes
278+
- Regularly verify image accessibility
279+
280+
## Escalation
281+
282+
Escalate to the cluster administrator if:
283+
- Multiple VMs affected simultaneously (possible cluster-wide
284+
issue)
285+
- Issue persists after following resolution steps
286+
- Suspected KubeVirt component malfunction
287+
- Unable to access system logs for further diagnosis
288+
- You don't have enough permissions to run the diagnosis and/or
289+
mitigation steps.
290+
291+
## Related Alerts
292+
293+
- `VirtControllerDown` - May indicate controller issues preventing
294+
VM processing
295+
- `LowKVMNodesCount` - Related to insufficient KVM-capable nodes
296+
- `KubeVirtNoAvailableNodesToRunVMs` - Indicates no nodes available
297+
for VM scheduling
298+
299+
<!--DS: If you cannot resolve the issue, log in to the
300+
link:https://access.redhat.com[Customer Portal] and open a support
301+
case, attaching the artifacts gathered during the diagnosis
302+
procedure.-->
303+
<!--USstart-->
304+
If you cannot resolve the issue, see the following resources:
305+
306+
- [OKD Help](https://okd.io/docs/community/help/)
307+
- [#virtualization Slack channel](
308+
https://kubernetes.slack.com/channels/virtualization)
309+
<!--USend-->

0 commit comments

Comments
 (0)