1117 字
6 分钟
K8S容器资源Python运维开发
K8S 容器资源 Python 运维开发
速查表
| 资源类型 | API 路径 | SDK 类 | 说明 |
|---|---|---|---|
| Pod | /api/v1/namespaces/{ns}/pods | CoreV1Api | Pod CRUD |
| Service | /api/v1/namespaces/{ns}/services | CoreV1Api | 服务发现 |
| Deployment | /apis/apps/v1/namespaces/{ns}/deployments | AppsV1Api | 无状态应用 |
| Job | /apis/batch/v1/namespaces/{ns}/jobs | BatchV1Api | 一次性任务 |
| Node | /api/v1/nodes | CoreV1Api | 节点管理 |
选择建议:日常运维用 SDK(类型安全、自动序列化);需要精细控制 HTTP 头或对接非标准 API 时用 RESTful API。
1. SDK 管理 Pod
使用 kubernetes Python SDK 创建、查询、删除 Pod。
import json, time, yamlfrom kubernetes.client import CoreV1Apifrom kubernetes.config import load_kube_config
load_kube_config()api = CoreV1Api()
# 删除同名 Pod(忽略不存在的情况)try: api.delete_namespaced_pod(name='nginx-pod', namespace='default') print("删除同名 Pod")except Exception: pass
time.sleep(5)
# 从 YAML 读取配置并创建 Podwith open("nginx-pod.yaml", encoding='utf-8') as f: data = yaml.safe_load(f)
create = api.create_namespaced_pod(body=data, namespace='default')print(f"创建成功: {create.metadata.name}")
# 查询 Podget = api.read_namespaced_pod(name='nginx-pod', namespace='default')print(f"状态: {get.status.phase}")
# 保存结果为 JSONwith open("pod_sdk_dev.json", "w") as f: json.dump(get.to_dict(), f, default=str, indent=4)2. SDK 管理 Deployment
import json, yaml, timefrom kubernetes.client import AppsV1Apifrom kubernetes.config import load_kube_config
load_kube_config()api = AppsV1Api()
# 删除同名 Deploymenttry: api.delete_namespaced_deployment(name='nginx-deployment', namespace='default') print('同名删除')except Exception: pass
time.sleep(5)
# 从 YAML 创建 Deploymentwith open('nginx-deployment.yaml', encoding='utf-8') as f: data = yaml.safe_load(f)
create = api.create_namespaced_deployment(body=data, namespace='default')print(f"创建成功: {create.metadata.name}")
# 查询 Deploymentget = api.read_namespaced_deployment(name="nginx-deployment", namespace="default")print(f"副本数: {get.spec.replicas}, 就绪: {get.status.ready_replicas}")
# 保存为 JSONwith open("deployment_sdk_dev.json", "w") as f: json.dump(get.to_dict(), f, default=str, indent=4)3. SDK 管理 Job
import time, yamlfrom kubernetes import client, config
config.load_kube_config()api = client.BatchV1Api()
# 删除同名 Jobtry: api.delete_namespaced_job(name='pi', namespace='default') print("删除同名 Job")except Exception: pass
time.sleep(10)
# 从 YAML 创建 Jobwith open('job.yaml', encoding='utf-8') as f: data = yaml.safe_load(f)
create = api.create_namespaced_job(body=data, namespace='default')print(f"创建成功: {create.metadata.name}")
# 查询 Jobget = api.read_namespaced_job(name='pi', namespace='default')print(f"状态: {get.status.conditions}")4. RESTful API 管理 Service
使用 requests 直接调用 K8S RESTful API,适用于需要自定义 Header 或 Patch 操作的场景。
import requests, yaml, json
token = 'bearer <your-token>'url = 'https://<master-ip>:6443/api/v1/namespaces/default/services'
header = { "Content-Type": "application/json", "Authorization": token}# Patch 操作需要不同的 Content-Typeheader_patch = { "Content-Type": "application/strategic-merge-patch+json", "Authorization": token}
# 查询并删除同名 Serviceresp = requests.get(f"{url}/nginx-svc", headers=header, verify=False)if resp.status_code == 200: requests.delete(f"{url}/nginx-svc", headers=header, verify=False) print("同名删除完成")
# 创建 Servicewith open('service.yaml', encoding='utf-8') as f: data = json.dumps(yaml.safe_load(f))create = requests.post(url, headers=header, data=data, verify=False).textprint(f"创建信息: {create}")
# 查询并保存get = requests.get(f"{url}/nginx-svc", headers=header, verify=False)with open('service_api_dev.json', 'w') as f: json.dump(get.json(), f, indent=4)
# 更新 Service(Patch)with open('service_update.yaml', encoding='utf-8') as f: update_data = json.dumps(yaml.safe_load(f))update = requests.patch(f"{url}/nginx-svc", headers=header_patch, data=update_data, verify=False)print(f"更新状态: {update.status_code}")5. 自定义调度器
实现自定义 Pod 调度逻辑:获取 Ready 节点 → 获取 Pending Pod → 随机选择节点绑定。
import randomfrom kubernetes import client, config
namespace = 'default'config.load_kube_config()api = client.CoreV1Api()
def get_ready_nodes(): """获取所有 Ready 状态的节点""" nodelist = api.list_node() ready_nodes = [] for node in nodelist.items: for condition in node.status.conditions: if condition.type == 'Ready' and condition.status == 'True': ready_nodes.append(node.metadata.name) break return ready_nodes
def get_pending_pods(): """获取所有 Pending 状态且未调度的 Pod""" podlist = api.list_namespaced_pod(namespace) pending_pods = [] for pod in podlist.items: if pod.status.phase == 'Pending' and pod.spec.node_name is None: pending_pods.append(pod.metadata.name) return pending_pods
def bind_pod_to_node(nodename, podname): """将 Pod 绑定到指定节点""" target = client.V1ObjectReference(kind='node', api_version='v1', name=nodename) meta = client.V1ObjectMeta(name=podname) body = client.V1Binding(target=target, metadata=meta) try: api.create_namespaced_binding(namespace, body) return True except client.exceptions.ApiException as e: print(f"绑定失败: {e.reason}") return False
def schedule_pods(nodes, pods): """随机选择节点调度所有 Pending Pod""" if not nodes or not pods: print("无可用节点或无待调度 Pod") return nodename = random.choice(nodes) print(f"选择节点: {nodename}") for podname in pods: scheduler = api.read_namespaced_pod(podname, namespace).spec.scheduler_name print(f"调度 Pod: {podname} (scheduler: {scheduler})") if bind_pod_to_node(nodename, podname): print(f" -> 绑定成功")
if __name__ == "__main__": nodes = get_ready_nodes() pods = get_pending_pods() schedule_pods(nodes, pods)6. Pod RESTful API HTTP 服务封装
将 K8S Pod API 封装为本地 HTTP 服务,方便其他系统调用。
import json, requests, yamlfrom http.server import HTTPServer, BaseHTTPRequestHandler
class PodHandler(BaseHTTPRequestHandler): api = "https://<master-ip>:6443/api/v1/namespaces/default/pods" auth = { 'verify': False, 'headers': { "Content-Type": "application/json", "Authorization": "Bearer <token>" } }
def _parse_name(self): return self.path.split('/')[-1]
def do_GET(self): """GET /pod/<name> - 查询 Pod""" if self.path.startswith('/pod/'): res = requests.get(f"{self.api}/{self._parse_name()}", **self.auth) self.send_response(200) self.end_headers() self.wfile.write(json.dumps(res.json()).encode())
def do_POST(self): """POST /pod/<yaml-file> - 从 YAML 文件创建 Pod""" if self.path.startswith('/pod/'): with open(f"/root/{self._parse_name()}") as f: body = json.dumps(yaml.safe_load(f)) res = requests.post(self.api, data=body, **self.auth) self.send_response(201) self.end_headers() self.wfile.write(json.dumps(res.json()).encode())
def do_DELETE(self): """DELETE /pod/<name> - 删除 Pod""" if self.path.startswith('/pod/'): requests.delete(f"{self.api}/{self._parse_name()}", **self.auth) self.send_response(204) self.end_headers()
if __name__ == "__main__": HTTPServer(('localhost', 8889), PodHandler).serve_forever()7. Service RESTful API HTTP 服务封装
import json, requests, yaml, threadingfrom http.server import HTTPServer, BaseHTTPRequestHandler
class ServiceHandler(BaseHTTPRequestHandler): api = "https://<master-ip>:6443/api/v1/namespaces/default/services" auth = { 'headers': { "Content-Type": "application/json", "Authorization": "Bearer <token>" }, 'verify': False }
def _parse_name(self): return self.path.split('/')[-1]
def do_GET(self): """GET /services/<name> - 查询 Service""" if self.path.startswith('/services/'): res = requests.get(f"{self.api}/{self._parse_name()}", **self.auth) self.send_response(200) self.end_headers() self.wfile.write(json.dumps(res.json()).encode())
def do_POST(self): """POST /services/<yaml-file> - 从 YAML 文件创建 Service""" if self.path.startswith('/services/'): with open(f"/root/{self._parse_name()}") as f: body = json.dumps(yaml.safe_load(f)) res = requests.post(self.api, data=body, **self.auth) self.send_response(201) self.end_headers() self.wfile.write(json.dumps(res.json()).encode())
def do_DELETE(self): """DELETE /services/<name> - 删除 Service""" if self.path.startswith('/services/'): requests.delete(f"{self.api}/{self._parse_name()}", **self.auth) self.send_response(204) self.end_headers()
if __name__ == "__main__": threading.Thread( target=lambda: HTTPServer(('localhost', 8888), ServiceHandler).serve_forever() ).start()8. 配套 YAML 文件
nginx-pod.yaml
apiVersion: v1kind: Podmetadata: name: nginx-pod labels: app: nginxspec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80nginx-deployment.yaml
apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deployment labels: app: nginxspec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.15.4 ports: - containerPort: 80service.yaml
apiVersion: v1kind: Servicemetadata: name: nginx-svcspec: selector: app: nginx ports: - port: 80 targetPort: 80 nodePort: 30888 type: NodePortservice_update.yaml
spec: ports: - port: 80 targetPort: 8089job.yaml
apiVersion: batch/v1kind: Jobmetadata: name: pispec: template: spec: containers: - name: pi image: perl command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] restartPolicy: Never backoffLimit: 4 K8S容器资源Python运维开发
https://blog.xeu.asia/posts/k8s-python-ops/