Kubernetes Python Client Automation¶
Overview¶
Load kubeconfig or in-cluster config, list core workloads with the official Python client, and build read-only health/inventory reports (mutate only with explicit flags later).
kubernetes Python client is a typed wrapper around the API server. Respect RBAC, never log Secret data, and default to get/list.
Complete Docker SDK Automation first. Diagrams use Excalidraw only.
This is a core tutorial in Module 18 · Kubernetes Automation of the REBASH Academy Python for Cloud & DevOps Engineers series — written for Cloud, DevOps, Platform, and SRE engineers.
Prerequisites¶
Required¶
- REST APIs concepts
- Optional: local cluster (kind/minikube/k3s) or fixture path
Learning Objectives¶
By the end of this tutorial, you will be able to:
- Load kubeconfig / in-cluster config
- List Pods and Deployments in a namespace
- Sketch Services, ConfigMaps, Jobs, Namespaces
- Treat Secrets as opaque (metadata only in reports)
- Handle ApiException status codes
Architecture¶
This topic’s control points and relationships are shown below.
Theory¶
What it is¶
The official kubernetes Python package is a generated client around the Kubernetes API server. Your script loads credentials, builds typed API objects (CoreV1Api, AppsV1Api, and so on), and issues the same verbs kubectl uses — get, list, create, patch, delete — over HTTPS. It is not a replacement for controllers or operators; it is the library you use for inventory, health reports, CI gates, and small automation that must speak Kubernetes fluently.
Why it matters¶
Platform and SRE teams live in clusters. Shelling out to kubectl works for one-off jobs, but Python clients give structured objects, pagination helpers, and testable code paths. Read-only inventory tools catch Pending Pods, broken Deployments, and missing Services before users do. Mutating tools (when you eventually add them) inherit Role-Based Access Control (RBAC) from a ServiceAccount — so least privilege is enforceable, not optional.
How it works¶
Out of cluster, config.load_kube_config() reads KUBECONFIG or ~/.kube/config. Inside a Pod, config.load_incluster_config() uses the mounted ServiceAccount token and CA. Clients then call namespaced or cluster-scoped list/get methods. Errors surface as ApiException with HTTP status codes: 401/403 for auth or RBAC, 404 for missing objects, 409 for conflicts. Prefer namespace-scoped lists for controllers and reports — cluster-wide scans are slower and need broader permissions.
from kubernetes import config
config.load_kube_config() # laptop / CI with kubeconfig
# config.load_incluster_config() # Pod ServiceAccount
Key concepts and comparisons¶
| Resource | Typical client | Automation use |
|---|---|---|
| Pods, Namespaces, ConfigMaps, Secrets, Services | CoreV1Api | Inventory, health, Service endpoints |
| Deployments | AppsV1Api | Ready vs desired replicas |
| Jobs / CronJobs | BatchV1Api | Batch completion checks |
| Mode | When | Risk |
|---|---|---|
| List / get | Health checkers, audits | Low if RBAC is list/get only |
| Create / patch / delete | Controllers, apply tools | High — require --apply, dry-run, tickets |
Treat Secrets as opaque: report name, namespace, and type — never decode or print data values in logs or JSON reports.
Common pitfalls¶
- Running with a cluster-admin kubeconfig “just for a script” and accidentally enabling write paths later.
- Logging full object dumps that include Secret payloads or tokens.
- Ignoring pagination / large namespaces and timing out CI.
- Treating 403 as “cluster down” instead of “RBAC denied.”
- Mutating without server-side dry-run or a clear
--applyflag.
Hands-on Lab¶
Focus: practise the core workflow for Kubernetes Python Client Automation
mkdir -p ~/rebash-python/module-18
cd ~/rebash-python/module-18
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install 'kubernetes==31.0.0'
Step 1 – Fixture pod inventory¶
cd ~/rebash-python/module-18
source .venv/bin/activate
mkdir -p fixtures
cat > fixtures/pods.json << 'EOF'
{
"items": [
{"metadata": {"name": "web-a", "namespace": "demo"}, "status": {"phase": "Running"}},
{"metadata": {"name": "web-b", "namespace": "demo"}, "status": {"phase": "Pending"}}
]
}
EOF
cat > k8s_pods.py << 'EOF'
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
def from_fixture(path: Path, namespace: str | None) -> list[dict]:
data = json.loads(path.read_text(encoding="utf-8"))
rows = []
for item in data.get("items", []):
ns = item["metadata"]["namespace"]
if namespace and ns != namespace:
continue
rows.append({
"name": item["metadata"]["name"],
"namespace": ns,
"phase": item.get("status", {}).get("phase"),
})
return rows
def from_cluster(namespace: str) -> list[dict]:
from kubernetes import client, config
config.load_kube_config()
v1 = client.CoreV1Api()
pod_list = v1.list_namespaced_pod(namespace)
return [
{
"name": p.metadata.name,
"namespace": p.metadata.namespace,
"phase": p.status.phase,
}
for p in pod_list.items
]
def main() -> int:
p = argparse.ArgumentParser(description="Pod inventory")
p.add_argument("--namespace", default="demo")
p.add_argument("--fixture", type=Path)
args = p.parse_args()
try:
rows = (
from_fixture(args.fixture, args.namespace)
if args.fixture
else from_cluster(args.namespace)
)
except Exception as exc: # noqa: BLE001
print(f"error: {exc}", file=sys.stderr)
print("hint: pass --fixture fixtures/pods.json", file=sys.stderr)
return 1
print(json.dumps(rows, indent=2))
bad = [r for r in rows if r["phase"] != "Running"]
return 1 if bad else 0
if __name__ == "__main__":
raise SystemExit(main())
EOF
python k8s_pods.py --fixture fixtures/pods.json; echo exit=$?
Step 2 – Deployment readiness sketch¶
python - <<'PY'
dep = {"name": "api", "ready": 2, "desired": 3}
print("healthy" if dep["ready"] == dep["desired"] else "degraded")
print("# live: AppsV1Api().list_namespaced_deployment")
PY
Step 3 – RBAC note¶
Document: ServiceAccount + Role get/list on pods only for a health checker.
Validation¶
- Lab commands run under
~/rebash-python/module-18/ - You can explain each Theory section in your own words
- You used modern tooling where it applies to this topic
- You can describe one production failure mode for this topic
Code Walkthrough¶
Production practice for Kubernetes Python Client Automation always combines:
- Inspect before you change (status, plan, logs, dry-run)
- Prefer reversible, documented changes (Git, IaC, drop-ins, version pins)
- Capture evidence (command output, pipeline logs) for handovers
- Prefer current tools and APIs over legacy shortcuts
- Least privilege — escalate credentials only when required
Keep runbooks short enough to follow under pressure. Automate checks; keep humans for judgement.
Security Considerations¶
- Treat credentials and tokens for python as privileged — never commit them
- Prefer short-lived auth (OIDC, roles, SSO) over long-lived keys
- Validate blast radius before apply/deploy/delete operations
- Restrict who can approve production changes
- Collect audit logs; limit who can read sensitive traces
Common Mistakes¶
Running with a cluster-admin kubeconfig “just for a script” and accidentally enabling writ
Validate assumptions against the Theory section and official docs before changing production.
Logging full object dumps that include Secret payloads or tokens.
Lab shortcuts (open security groups, admin roles, skip approvals) must not ship unchanged.
Changing production without a rollback path
Always know how to revert (previous artefact, prior release, state rollback, DNS failback).
Best Practices¶
- Encode Kubernetes Python Client Automation changes as code and review them in pull requests
- Pin versions (images, modules, actions, provider plugins)
- Separate environments with clear promotion gates
- Alert on symptoms with runbooks attached
- Destroy lab resources; tag everything with owner and expiry where possible
Troubleshooting¶
| Symptom | Likely cause | What to do |
|---|---|---|
| 403 Forbidden | RBAC | Grant least list/get |
| Config exception | No kubeconfig | Fixture or set KUBECONFIG |
| Slow list | Cluster-wide without need | Namespace-scope |
Summary¶
- Official client + kubeconfig/in-cluster
- Read-only inventory/health first
- Labs for health checker and deployment validator
Interview Questions¶
- How does Kubernetes Python Client Automation show up when operating Cloud or production platforms?
- What would you check first if this area misbehaves in production?
- Which modern tools or APIs replace older equivalents here?
- What security control should accompany this capability?
- How would you automate verification of this topic in CI?
Sample answer — question 2
Start with blast radius and recent changes, gather evidence (logs, status, plan/diff), then fix forward with a known rollback path — not guesswork.