Skip to content

Eviction

The eviction subresource triggers graceful pod termination while respecting PodDisruptionBudgets. It is the mechanism behind kubectl drain and is preferred over calling api.delete() directly when you need disruption-budget-aware eviction.

Availability

Only resources with the Evictable marker interface expose api.eviction. In practice this means Pod.

from kubex.k8s.v1_35.core.v1.pod import Pod

pod_api.eviction.create(...)   # OK: Pod has Evictable

from kubex.k8s.v1_35.apps.v1.deployment import Deployment

deploy_api.eviction.create(...)  # type error + runtime NotImplementedError

Creating an eviction

api.eviction.create() submits an Eviction object to the API server. If the pod is protected by a PodDisruptionBudget that would be violated, the API server returns 429 Too Many Requests and you should retry after a delay.

from kubex.api import Api
from kubex.client import create_client
from kubex.core.exceptions import KubexApiError
from kubex.k8s.v1_35.core.v1.pod import Pod
from kubex_core.models.eviction import Eviction
from kubex_core.models.metadata import ObjectMetadata
from kubex_core.models.status import Status


async def evict_pod(pod_name: str, namespace: str) -> None:
    client = await create_client()
    async with client:
        api: Api[Pod] = Api(Pod, client=client, namespace=namespace)

        eviction = Eviction(
            metadata=ObjectMetadata(name=pod_name, namespace=namespace),
        )
        status: Status = await api.eviction.create(pod_name, eviction)
        print(f"Eviction status: {status.status}")

Handling PodDisruptionBudget violations

When a PDB blocks the eviction the API server responds with HTTP 429. Kubex surfaces this as a KubexApiError. Retry with an exponential back-off until the PDB allows the eviction:

import anyio

from kubex.core.exceptions import KubexApiError
from kubex_core.models.eviction import Eviction
from kubex_core.models.metadata import ObjectMetadata


async def evict_with_retry(api: Api[Pod], pod_name: str, namespace: str) -> None:
    eviction = Eviction(
        metadata=ObjectMetadata(name=pod_name, namespace=namespace),
    )
    for attempt in range(10):
        try:
            await api.eviction.create(pod_name, eviction)
            return
        except KubexApiError as exc:
            if exc.status.value == 429:
                await anyio.sleep(2**attempt)
            else:
                raise
    raise RuntimeError(f"Could not evict {pod_name} after 10 attempts")

Options

Option Type Description
dry_run DryRun | bool | None Validate without performing the eviction
field_manager str | None Field manager name
namespace str | None | ... Override the Api instance namespace
request_timeout Timeout | float | None | ... Override the client-level timeout

Eviction vs deletion

api.delete() api.eviction.create()
Respects PodDisruptionBudgets No Yes
Returns 429 when PDB blocks No Yes
Kubernetes mechanism DELETE on the pod POST to the eviction subresource
Typical use Force removal Graceful drain

Use api.delete() only when you need to forcibly remove a pod regardless of PDBs (for example, during cluster decommission). Use eviction for controlled workload migrations.