Day 66:【99天精通Python】Python 操作 Kubernetes (K8s) - 驾驭集群的舵手
前言
欢迎来到第66天!
在昨天的课程中,我们学会了用 Python 操作 Docker,管理单机上的容器。但当我们的业务规模扩大,有几百个容器分布在几十台服务器上时,单靠 Docker 就管理不过来了。
Kubernetes (K8s)是目前最主流的容器编排系统。它可以自动调度、扩展和管理容器应用。
虽然 K8s 通常使用 YAML 文件和kubectl命令来管理,但在自动化运维平台或 CI/CD 流水线中,我们经常需要用 Python 代码来控制集群。Python 官方客户端kubernetes库提供了强大的能力。
本节内容:
- K8s 核心概念 (Pod, Deployment, Service)
- 安装 Python K8s 客户端
- 连接集群 (Kubeconfig)
- 查看资源 (List Pods)
- 创建资源 (Create Deployment)
- 实战练习:自动扩缩容脚本
一、K8s 核心概念速览
在写代码前,先复习一下 K8s 的几个基本对象:
- Pod:K8s 的最小调度单位,一个 Pod 里可以跑一个或多个容器(通常是一个)。
- Deployment:管理 Pod 的控制器,负责定义"我要跑几个副本"、“用什么镜像”。
- Service:负责服务发现和负载均衡,给一组 Pod 提供一个固定的访问入口。
- Namespace:命名空间,用于隔离资源(默认是
default)。
二、环境与安装
2.1 准备 K8s 集群
你需要一个可访问的 K8s 集群。
- 本地学习:推荐安装Minikube或Kind。
- 云服务:阿里云 ACK / 腾讯云 TKE。
2.2 安装 Python 客户端
pipinstallkubernetes2.3 配置 Kubeconfig
Python 代码默认会去读取~/.kube/config文件来连接集群。请确保你的机器上可以通过kubectl访问集群。
三、连接集群与查看资源
3.1 建立连接
fromkubernetesimportclient,config# 1. 加载配置# 如果是在集群外部运行代码 (比如你的笔记本),用 load_kube_configconfig.load_kube_config()# 如果是在集群内部运行代码 (比如代码跑在 Pod 里),用 load_incluster_config# config.load_incluster_config()print("K8s 配置加载成功!")3.2 查看所有 Pod
# CoreV1Api 用于操作核心资源 (Pod, Service, Node)v1=client.CoreV1Api()print("正在列出 default 命名空间下的 Pods:")pods=v1.list_namespaced_pod(namespace="default")forpodinpods.items:print(f"Pod名:{pod.metadata.name}, 状态:{pod.status.phase}, IP:{pod.status.pod_ip}")3.3 查看所有 Node
print("\n正在列出集群节点:")nodes=v1.list_node()fornodeinnodes.items:print(f"节点名:{node.metadata.name}")四、创建资源:部署一个 Nginx
要在代码里创建资源,我们需要构建类似 YAML 的字典结构。
fromkubernetesimportclient,config config.load_kube_config()# AppsV1Api 用于操作 Deployment, StatefulSetapps_v1=client.AppsV1Api()defcreate_deployment():# 1. 定义容器container=client.V1Container(name="nginx",image="nginx:1.14.2",ports=[client.V1ContainerPort(container_port=80)])# 2. 定义 Pod 模板template=client.V1PodTemplateSpec(metadata=client.V1ObjectMeta(labels={"app":"nginx"}),spec=client.V1PodSpec(containers=[container]))# 3. 定义 Deployment 规范spec=client.V1DeploymentSpec(replicas=3,# 副本数selector=client.V1LabelSelector(match_labels={"app":"nginx"}),template=template)# 4. 定义 Deployment 对象deployment=client.V1Deployment(api_version="apps/v1",kind="Deployment",metadata=client.V1ObjectMeta(name="python-nginx-demo"),spec=spec)# 5. 调用 API 创建print("正在创建 Deployment...")apps_v1.create_namespaced_deployment(namespace="default",body=deployment)print("创建成功!")if__name__=="__main__":create_deployment()运行后,使用kubectl get deploy可以看到python-nginx-demo已经创建,并启动了 3 个 Pod。
五、实战练习:自动扩缩容 (Auto Scaling)
虽然 K8s 自带 HPA (Horizontal Pod Autoscaler),但有时我们需要更复杂的自定义逻辑(比如根据 MySQL 的 QPS 来扩容 Web 服务)。
下面的脚本演示了如何修改Deployment 的副本数。
defscale_deployment(name,replicas):"""调整副本数"""print(f"正在将{name}的副本数调整为{replicas}...")# patch 方法用于局部更新# body 只需要包含要修改的字段body={"spec":{"replicas":replicas}}apps_v1.patch_namespaced_deployment_scale(name=name,namespace="default",body=body)print("调整指令已下发。")# 模拟业务逻辑importtimeif__name__=="__main__":# 假设这是晚高峰,扩容到 5 个scale_deployment("python-nginx-demo",5)time.sleep(5)# 假设高峰期过了,缩容回 2 个scale_deployment("python-nginx-demo",2)六、删除资源
清理战场。
defdelete_deployment(name):print(f"正在删除{name}...")apps_v1.delete_namespaced_deployment(name=name,namespace="default")print("删除成功。")# delete_deployment("python-nginx-demo")七、常见问题
Q1:API 太多记不住怎么办?
K8s API 确实非常复杂。
CoreV1Api: 核心资源 (Pod, Service, ConfigMap, Secret)。AppsV1Api: 应用资源 (Deployment, DaemonSet, StatefulSet)。BatchV1Api: 批处理 (Job, CronJob)。
技巧:如果不确定参数怎么填,可以先写一个 YAML,然后对照 YAML 的结构去查 Python 对象的定义。
Q2:load_incluster_config报错?
这个方法只有在 Pod 内部运行时才有效。如果你在本地 IDE 运行,必须用load_kube_config。
Q3:如何监听资源变化 (Watch)?
K8s 提供了 Watch 机制,类似长连接推送。
fromkubernetesimportwatch w=watch.Watch()# 监听 Pod 变化foreventinw.stream(v1.list_namespaced_pod,namespace="default"):print(f"事件:{event['type']}- Pod:{event['object'].metadata.name}")八、小结
关键要点:
- Kubernetes 库让我们能用 Python 编程的方式管理集群。
- Deployment是管理应用的主力,通过
patch_scale可以轻松扩缩容。 - Watch机制可以让我们实时感知集群状态的变化。
九、课后作业
- Pod 重启器:编写一个脚本,查找所有状态为
Error或CrashLoopBackOff的 Pod,并将其删除(K8s 的控制器会自动重建它,相当于重启)。 - 资源统计:遍历集群中所有的 Node,统计总的 CPU 和 内存容量(
capacity字段)。 - 定时任务:结合 Day 41 (Schedule),编写一个脚本,每天晚上 20:00 将某个测试环境的 Deployment 副本数缩减为 0(省钱),早上 08:00 恢复为 1。
下节预告
Day 67:设计模式 (Design Patterns) 上篇- 为什么高手的代码看起来那么整洁?因为他们用了设计模式。明天我们学习单例模式和工厂模式,提升代码的内功修为!
系列导航:
- 上一篇:Day 65 - Python操作Docker
- 下一篇:Day 67 - 设计模式上(待更新)