kubectl + Python 脚本是轻量可靠起点,优先用 JSON 输出解析、避免表格陷阱,轮询用生成器+超时控制,重启用 delete 通用方案,权限与异常判断需按业务定制。

用 kubectl 命令行配合 Python 脚本是最轻量可靠的起点
直接调用系统 kubectl 比引入 kubernetes-client 更快上手,尤其当脚本只做状态轮询、重启或日志抓取这类简单操作时。前提是目标机器已配置好 kubeconfig 且 kubectl 可执行。
常见错误现象:subprocess.CalledProcessError: Command 'kubectl get pods' returned non-zero exit status 1——多数是权限或上下文问题,不是代码写错了。
- 确保执行脚本的用户能正常运行
kubectl get pods -n default手动验证 - 用
subprocess.run(..., capture_output=True, text=True)获取结构化输出,避免解析二进制乱码 - 不要硬编码命名空间,用
--namespace参数或环境变量KUBE_NAMESPACE控制作用域 - 如果集群启用了 RBAC,脚本账户至少要有
get和patch权限(如需重启)
解析 kubectl get pods -o wide 输出要避开列宽陷阱
kubectl 默认输出是表格格式,列对齐靠空格,但字段含空格(如 Running 状态后的容器名)会导致 str.split() 错位。别用空格切分。
正确做法是强制 JSON 输出:kubectl get pods -o json,再用 json.loads() 解析。虽然体积大些,但字段稳定、无歧义。
立即学习“Python免费学习笔记(深入)”;
- 示例命令:
kubectl get pods -n monitoring -o json - 关键字段路径:
items[].status.phase(Running/Pending/Failed),items[].status.containerStatuses[].ready - 注意
items[]可能为空(没 Pod),需加if not data.get("items"):防报错 - 若必须用表格格式(如调试时快速看),改用
-o custom-columns=...定制纯文本列,例如:kubectl get pods -o "custom-columns=NAME:.metadata.name,STATUS:.status.phase,READY:.status.containerStatuses[0].ready"
用 watch 模式轮询 Pod 状态时别卡死进程
频繁调用 kubectl get 查状态很容易写成 while True + time.sleep(),但这样无法响应中断(Ctrl+C 不生效)、不支持超时退出、也难加告警逻辑。
更可控的方式是封装为生成器函数,每次 yield 一个状态快照,并由外层控制循环条件和生命周期。
- 给
subprocess.run()加timeout=10,防kubectl卡住(比如 API Server 临时不可达) - 捕获
subprocess.TimeoutExpired和json.JSONDecodeError,记录日志后继续下一轮,别让单次失败崩掉整个脚本 - 轮询间隔建议 ≥5 秒;低于 2 秒可能触发 API Server 的速率限制(特别是多副本并行跑)
- 如果只是等某个 Pod 就绪,优先用
kubectl wait --for=condition=Ready pod/name,比自己轮询更精准
需要重启 Pod 时,delete 比 rollout restart 更通用
kubectl rollout restart deployment/xxx 看起来方便,但它依赖 Deployment 控制器存在。而很多测试或调试场景中 Pod 是直接用 kubectl run 或 Job 启的,没有 Deployment。
真正通用的做法是删 Pod,让控制器(Deployment/StatefulSet/ReplicaSet)自动重建它。这是 K8s 的设计契约,所有控制器都遵守。
- 命令示例:
kubectl delete pod my-app-7f8d4c9b6-xyz12 - 加
--grace-period=0 --force强制立即删除(仅限调试,生产慎用) - 删除前务必确认 Pod 是否属于控制器管理——查
ownerReferences字段,避免误删独立 Pod 导致服务中断 - 别在脚本里拼接
shell=True执行带变量的命令,用subprocess.run(["kubectl", "delete", "pod", pod_name])避免 shell 注入风险
真正麻烦的从来不是怎么发命令,而是判断“什么才算异常”:是 CrashLoopBackOff 连续出现三次?还是 Ready=False 超过 90 秒?这些业务规则得根据具体应用来定,没法套模板。


















