1117 字
6 分钟
K8S容器资源Python运维开发

K8S 容器资源 Python 运维开发#

速查表#

资源类型API 路径SDK 类说明
Pod/api/v1/namespaces/{ns}/podsCoreV1ApiPod CRUD
Service/api/v1/namespaces/{ns}/servicesCoreV1Api服务发现
Deployment/apis/apps/v1/namespaces/{ns}/deploymentsAppsV1Api无状态应用
Job/apis/batch/v1/namespaces/{ns}/jobsBatchV1Api一次性任务
Node/api/v1/nodesCoreV1Api节点管理

选择建议:日常运维用 SDK(类型安全、自动序列化);需要精细控制 HTTP 头或对接非标准 API 时用 RESTful API。


1. SDK 管理 Pod#

使用 kubernetes Python SDK 创建、查询、删除 Pod。

import json, time, yaml
from kubernetes.client import CoreV1Api
from 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 读取配置并创建 Pod
with 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}")
# 查询 Pod
get = api.read_namespaced_pod(name='nginx-pod', namespace='default')
print(f"状态: {get.status.phase}")
# 保存结果为 JSON
with open("pod_sdk_dev.json", "w") as f:
json.dump(get.to_dict(), f, default=str, indent=4)

2. SDK 管理 Deployment#

import json, yaml, time
from kubernetes.client import AppsV1Api
from kubernetes.config import load_kube_config
load_kube_config()
api = AppsV1Api()
# 删除同名 Deployment
try:
api.delete_namespaced_deployment(name='nginx-deployment', namespace='default')
print('同名删除')
except Exception:
pass
time.sleep(5)
# 从 YAML 创建 Deployment
with 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}")
# 查询 Deployment
get = api.read_namespaced_deployment(name="nginx-deployment", namespace="default")
print(f"副本数: {get.spec.replicas}, 就绪: {get.status.ready_replicas}")
# 保存为 JSON
with open("deployment_sdk_dev.json", "w") as f:
json.dump(get.to_dict(), f, default=str, indent=4)

3. SDK 管理 Job#

import time, yaml
from kubernetes import client, config
config.load_kube_config()
api = client.BatchV1Api()
# 删除同名 Job
try:
api.delete_namespaced_job(name='pi', namespace='default')
print("删除同名 Job")
except Exception:
pass
time.sleep(10)
# 从 YAML 创建 Job
with 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}")
# 查询 Job
get = 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-Type
header_patch = {
"Content-Type": "application/strategic-merge-patch+json",
"Authorization": token
}
# 查询并删除同名 Service
resp = 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("同名删除完成")
# 创建 Service
with 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).text
print(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 random
from 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, yaml
from 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, threading
from 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: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

nginx-deployment.yaml#

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.15.4
ports:
- containerPort: 80

service.yaml#

apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30888
type: NodePort

service_update.yaml#

spec:
ports:
- port: 80
targetPort: 8089

job.yaml#

apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
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/
作者
Xeu
发布于
2025-03-03
许可协议
CC BY-NC-SA 4.0