Cluster admins or operators often face unplanned node failures or planned maintenance. Kubernetes Eviction API offers a controlled path to terminate Pods while respecting policies. It uses the Eviction subresource to enforce PodDisruptionBudgets
and terminationGracePeriodSeconds
, ensuring safe, graceful Pod deletion. This article explains the Eviction API end to end, with examples.
TL;DR
- The API uses a subresource at
/pods/{name}/eviction
to delete Pods under policy control. - Eviction honors
PodDisruptionBudget
andterminationGracePeriodSeconds
to maintain application availability. - CLI and client-go support:
kubectl drain
andclient.CoreV1().Evictions()
. - Dry-run mode simulates eviction without actual deletion:
kubectl drain --dry-run
. - Event-driven eviction enables automated remediation on metrics alerts (e.g., memory pressure) via custom controllers.
Eviction API Overview
The API acts like a policy-controlled delete. Instead of ordinary DELETE /api/v1/pods/{name}
, clients POST an Eviction
object to /api/v1/namespaces/{ns}/pods/{pod}/eviction
. The server evaluates PodDisruptionBudgets
, then marks the Pod for graceful termination. The subresource prevents bypassing disruption budgets.
Eviction Object Structure
apiVersion: policy/v1
kind: Eviction
metadata:
name: my-pod
namespace: default
deleteOptions:
gracePeriodSeconds: 30
deleteOptions.gracePeriodSeconds
overrides the Pod’s terminationGracePeriodSeconds
. If omitted, the default period applies.
Eviction vs. Delete
Eviction blocks if PDB limits would break availability. A normal delete ignores PDB. Eviction returns HTTP 429
if .status.disruptedPods
exceeds .spec.maxUnavailable
in any PodDisruptionBudget
.
PodDisruptionBudget Integration
PDB defines minAvailable
or maxUnavailable
across matching Pods. Eviction API checks all PDBs that select the Pod. If eviction breaches any, the request fails with 429 Too Many Requests
until conditions free up.
kubectl and API Eviction
KUBECTL_PLUGINS_PATH=~/.kube/plugins
kubectl drain node1 \
--ignore-daemonsets \
--delete-emptydir-data \
--timeout=5m
kubectl drain
sequentially issues Eviction subresource calls for each Pod. It handles retry logic on 429
, waits until PDB permits eviction, then proceeds.
Client-Go Example for API Eviction
import (
"context"
policyv1 "k8s.io/api/policy/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)
func evictPod(clientset *kubernetes.Clientset, podName, ns string) error {
eviction := &policyv1.Eviction{
ObjectMeta: metav1.ObjectMeta{
Name: podName,
Namespace: ns,
},
}
return clientset.CoreV1().Pods(ns).
Evict(context.TODO(), eviction)
}
Dry-Run Evictions
Dry-run mode helps test PDB and eviction logic without actual Pod termination:
kubectl drain node1 --ignore-daemonsets --dry-run=client
Server side dry-run can use ?dryRun=All
query param on the HTTP request.
Example Eviction Use Case
Operators can build custom controllers to watch for metrics alerts (e.g., disk pressure). On threshold breach, the controller issues Eviction API calls to relocate Pods automatically:
- Monitor Node metrics via Prometheus.
- On disk pressure event, call Eviction API for selected Pods.
- ReplicaSet recreates Pods on healthy nodes.
Security Context and Access Controls
Permission to evict requires create
on policy/v1/evictions
subresource. RBAC example:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-evictor
rules:
- apiGroups: ["policy"]
resources: ["pods/eviction"]
verbs: ["create"]
Handling Concurrent Evictions
The API server serializes eviction requests per Pod subresource. Parallel eviction attempts for the same Pod result in one success and one HTTP 404
or 409
. Clients should handle retries and backoff.
References
Suggested Reading
PostHashID: 0f161d19344492245149b8045d3de330daa0811cac0a5988f5b8b089aa627e07