跳转到内容

Python 连接 Kubernetes

概述

使用 Python 的 kubernetes 客户端库来管理和操作 Kubernetes 集群,实现自动化部署、监控和运维。

安装

bash
pip install kubernetes

# 或使用 uv
uv add kubernetes

认证配置

方式一:使用 kubeconfig 文件

最常用的方式,读取 ~/.kube/config 中的集群配置:

python
from kubernetes import client, config

# 加载 kubeconfig(默认路径 ~/.kube/config)
config.load_kube_config()

# 指定 kubeconfig 文件路径
config.load_kube_config(config_file='/path/to/kubeconfig')

# 指定 context
config.load_kube_config(context='my-context')

方式二:集群内运行(In-Cluster)

当 Python 程序运行在 K8s Pod 内部时使用:

python
from kubernetes import client, config

# 自动使用 Pod 的 ServiceAccount
config.load_incluster_config()

方式三:直接配置

手动指定 API Server 地址和 Token:

python
from kubernetes import client

configuration = client.Configuration()
configuration.host = "https://k8s-api-server:6443"
configuration.api_key = {"authorization": "Bearer <token>"}
configuration.verify_ssl = False  # 仅用于测试

client.Configuration.set_default(configuration)

常用操作

核心 API(Core V1)

python
from kubernetes import client, config

config.load_kube_config()
v1 = client.CoreV1Api()

列出所有 Namespace

python
namespaces = v1.list_namespace()
for ns in namespaces.items:
    print(ns.metadata.name)

列出 Pod

python
# 列出所有命名空间的 Pod
pods = v1.list_pod_for_all_namespaces()
for pod in pods.items:
    print(f"{pod.metadata.namespace}/{pod.metadata.name} - {pod.status.phase}")

# 列出指定命名空间的 Pod
pods = v1.list_namespaced_pod(namespace="default")
for pod in pods.items:
    print(f"{pod.metadata.name} - {pod.status.phase}")

获取 Pod 日志

python
logs = v1.read_namespaced_pod_log(
    name="my-pod",
    namespace="default"
)
print(logs)

# 获取指定容器的日志
logs = v1.read_namespaced_pod_log(
    name="my-pod",
    namespace="default",
    container="sidecar",
    tail_lines=100
)

列出 Service

python
services = v1.list_service_for_all_namespaces()
for svc in services.items:
    print(f"{svc.metadata.namespace}/{svc.metadata.name} - {svc.spec.type}")

列出 ConfigMap 和 Secret

python
# ConfigMap
configmaps = v1.list_namespaced_config_map(namespace="default")
for cm in configmaps.items:
    print(cm.metadata.name)

# Secret
secrets = v1.list_namespaced_secret(namespace="default")
for secret in secrets.items:
    print(secret.metadata.name)

Apps API(Apps V1)

python
apps_v1 = client.AppsV1Api()

列出 Deployment

python
deployments = apps_v1.list_deployment_for_all_namespaces()
for deploy in deployments.items:
    ready = deploy.status.ready_replicas or 0
    total = deploy.spec.replicas
    print(f"{deploy.metadata.namespace}/{deploy.metadata.name} - {ready}/{total}")

列出 StatefulSet

python
statefulsets = apps_v1.list_stateful_set_for_all_namespaces()
for sts in statefulsets.items:
    print(f"{sts.metadata.namespace}/{sts.metadata.name}")

列出 DaemonSet

python
daemonsets = apps_v1.list_daemon_set_for_all_namespaces()
for ds in daemonsets.items:
    print(f"{ds.metadata.namespace}/{ds.metadata.name}")

创建资源

创建 Namespace

python
from kubernetes import client, config

config.load_kube_config()
v1 = client.CoreV1Api()

namespace = client.V1Namespace(
    metadata=client.V1ObjectMeta(name="my-namespace")
)
v1.create_namespace(body=namespace)

创建 Deployment

python
from kubernetes import client, config

config.load_kube_config()
apps_v1 = client.AppsV1Api()

deployment = client.V1Deployment(
    api_version="apps/v1",
    kind="Deployment",
    metadata=client.V1ObjectMeta(name="nginx-deployment"),
    spec=client.V1DeploymentSpec(
        replicas=3,
        selector=client.V1LabelSelector(
            match_labels={"app": "nginx"}
        ),
        template=client.V1PodTemplateSpec(
            metadata=client.V1ObjectMeta(
                labels={"app": "nginx"}
            ),
            spec=client.V1PodSpec(
                containers=[
                    client.V1Container(
                        name="nginx",
                        image="nginx:1.25",
                        ports=[client.V1ContainerPort(container_port=80)]
                    )
                ]
            )
        )
    )
)

apps_v1.create_namespaced_deployment(
    namespace="default",
    body=deployment
)

从 YAML 文件创建资源

更实用的方式,直接从 YAML 创建任意资源:

python
import yaml
from kubernetes import client, config, utils

config.load_kube_config()

with open("deployment.yaml") as f:
    dep = yaml.safe_load(f)

# 使用 utils 创建
k8s_client = client.ApiClient()
utils.create_from_yaml(k8s_client, "deployment.yaml")

删除资源

python
# 删除 Deployment
apps_v1.delete_namespaced_deployment(
    name="nginx-deployment",
    namespace="default"
)

# 删除 Namespace
v1.delete_namespace(name="my-namespace")

更新资源

python
# 更新 Deployment 副本数
deployment = apps_v1.read_namespaced_deployment(
    name="nginx-deployment",
    namespace="default"
)
deployment.spec.replicas = 5
apps_v1.patch_namespaced_deployment(
    name="nginx-deployment",
    namespace="default",
    body=deployment
)

Watch 机制

实时监控资源变化:

python
from kubernetes import client, config, watch

config.load_kube_config()
v1 = client.CoreV1Api()

w = watch.Watch()
for event in w.stream(v1.list_namespaced_pod, namespace="default"):
    pod = event['object']
    event_type = event['type']
    print(f"{event_type}: {pod.metadata.name} - {pod.status.phase}")

动态客户端

当需要操作 CRD(自定义资源)等非内置资源时:

python
from kubernetes import client, config
from kubernetes.dynamic import DynamicClient

config.load_kube_config()
k8s_client = client.ApiClient()
dyn_client = DynamicClient(k8s_client)

# 操作 CRD 资源
crd_api = dyn_client.resources.get(
    api_version="argoproj.io/v1alpha1",
    kind="Application"
)

# 列出 ArgoCD Application
apps = crd_api.get(namespace="argocd")
for item in apps.items:
    print(item.metadata.name)

异步客户端

高并发场景下使用异步客户端:

python
import asyncio
from kubernetes import client, config
from kubernetes.asyncio import client as async_client

async def main():
    await config.load_kube_config()
    v1 = async_client.CoreV1Api()

    pods = await v1.list_pod_for_all_namespaces()
    for pod in pods.items:
        print(pod.metadata.name)

    await v1.api_client.close()

asyncio.run(main())

实用脚本示例

集群资源概览

python
from kubernetes import client, config

config.load_kube_config()
v1 = client.CoreV1Api()
apps_v1 = client.AppsV1Api()

print("=== 集群概览 ===")

# Node 状态
nodes = v1.list_node()
print(f"Nodes: {len(nodes.items)}")

# Namespace 数量
namespaces = v1.list_namespace()
print(f"Namespaces: {len(namespaces.items)}")

# Pod 统计
pods = v1.list_pod_for_all_namespaces()
running = sum(1 for p in pods.items if p.status.phase == "Running")
print(f"Pods: {len(pods.items)} (Running: {running})")

# Deployment 统计
deployments = apps_v1.list_deployment_for_all_namespaces()
print(f"Deployments: {len(deployments.items)}")

批量清理 Completed Pod

python
from kubernetes import client, config

config.load_kube_config()
v1 = client.CoreV1Api()

pods = v1.list_pod_for_all_namespaces()
deleted = 0

for pod in pods.items:
    if pod.status.phase in ("Succeeded", "Failed"):
        v1.delete_namespaced_pod(
            name=pod.metadata.name,
            namespace=pod.metadata.namespace
        )
        deleted += 1
        print(f"Deleted: {pod.metadata.namespace}/{pod.metadata.name}")

print(f"\nTotal deleted: {deleted}")

参考资料

基于 MIT 许可发布