仅供参考,学习测试使用
在提供的OpenStack 私有云平台上,使用 k8s-python-dev 镜像创建 1 台云主机,云主机类型使用 4vCPU/12G 内存/100G 硬盘。该主机中已经默认安装了所需的开发环境,登录默认账号密码为“root/1DaoYun@2022”。
使用Kubernetes Restful API 库,在/root 目录下,创建 api_deployment_manager.py 文件, 要求编写 python 代码,代码实现以下任务:
(1)编写 Python 程序实现 Deployment 资源的创建。Deployment 配置信息如下。如果同名Deployment 存在,先删除再创建。
(2)创建完成后,查询该Deployment 的详细信息,执行结果控制台输出,以yaml 格式展示。
创建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:
from kubernetes import client, config
# 加载 kubeconfig 配置文件
config.load_kube_config()
# 创建 Deployment 对象
deployment = client.AppsV1Api().create_namespaced_deployment(
body={
"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
}]
}]
}
}
}
},
namespace="default"
)
# 获取 Deployment 对象的详细信息
deployment_info = client.AppsV1Api().read_namespaced_deployment(
name="nginx-deployment",
namespace="default"
)
# 将 Deployment 对象信息以 yaml 格式打印输出
import yaml
deployment_info_yaml = yaml.dump(
client.ApiClient().sanitize_for_serialization(deployment_info)
)
print(deployment_info_yaml)
首先通过 config.load_kube_config() 加载 kubeconfig 配置文件,然后使用 client.AppsV1Api().create_namespaced_deployment() 方法创建 Deployment 对象,并使用 client.AppsV1Api().read_namespaced_deployment() 方法获取该对象的详细信息。最后,使用 yaml.dump() 方法将 Deployment 对象信息以 yaml 格式输出到控制台。
1.执行api_deployment_manager.py 脚本,成功创建 deployment 资源,计 1 分;
2.检查创建的 deployment 资源,配置信息无误计 1 分。
在前面已建好的 Kubernetes 开发环境云平台上。使用 Kubernetes python SDK 的“kubernetes”Python 库,在/root 目录下,创建 sdk_job_manager.py 文件,要求编写 python 代码,代码实现以下任务:
(1)编写 Python 程序实现 Job 资源的创建。Job 配置信息如下。如果同名 Job 存在, 先删除再创建。
(2)创建完成后,查询该 Job 的详细信息,执行结果控制台输出,以 json 格式展示。
Job 创建 yaml 的信息如下:
apiVersion: batch/v1 kind: Job
metadata: name: pi
spec:
template: spec:
containers:
from kubernetes import client, config
# 加载Kubernetes配置
config.load_kube_config()
# 创建Kubernetes API客户端对象
api_client = client.BatchV1Api()
# 定义Job资源的元数据信息
metadata = client.V1ObjectMeta(name="pi")
# 定义Job的Pod模板
pod_template = client.V1PodTemplateSpec(
spec=client.V1PodSpec(
restart_policy="Never",
containers=[
client.V1Container(
name="pi",
image="perl",
command=["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
)
]
)
)
# 定义Job的规格
job_spec = client.V1JobSpec(
template=pod_template,
backoff_limit=4
)
# 创建Job资源
try:
api_client.delete_namespaced_job(name="pi", namespace="default")
except:
pass
api_response = api_client.create_namespaced_job(
body=client.V1Job(
api_version="batch/v1",
kind="Job",
metadata=metadata,
spec=job_spec
),
namespace="default"
)
print("Job created. status='%s'" % str(api_response.status))
# 查询Job的详细信息
api_response = api_client.read_namespaced_job(name="pi", namespace="default")
print("Job details:")
print(api_response.to_json())
1.执行 sdk_job_manager.py 脚本,成功创建job 资源,计 0.5 分;
2.查询 job 资源,配置信息无误,计 0.5 分。
编写 Python 程序实现Pod 资源管理程序,将 Pod 资源管理的封装成Web 服务。
在/root 目录下创建pod_server.py 程序,实现Pod 的增删查改等Web 访问操作。http.server 的 host 为 localhost,端口 8889;程序内部实现Kubernetes 认证。
提示说明:Python 标准库http.server 模块,提供了HTTP Server 请求封装。需要实现的 Restful API 接口如下:
GET /pod/{name} ,查询指定名称{name}的 Pod;Response 的 Body 以 json 格式输出。
POST /pod/{yamlfilename} 创建 yaml 文件名称为{yamlfilename}的 Pod;Response 的
Body 以 json 格式。
编码完成后,“手工下载”文件服务器主目录所有*.yaml 文件到 root 目录下,“手动执行”所编写pod_server.py 程序,提交答案进行检测。
import http.server
import json
import os
import ssl
import subprocess
import urllib.parse
from kubernetes import client, config
from kubernetes.client.rest import ApiException
class PodServer(http.server.BaseHTTPRequestHandler):
def do_GET(self):
parsed_path = urllib.parse.urlparse(self.path)
path = parsed_path.path.split('/')
if path[1] == 'pod':
name = path[2]
try:
config.load_kube_config()
api_instance = client.CoreV1Api()
api_response = api_instance.read_namespaced_pod(name, 'default')
response = {'name': api_response.metadata.name,
'status': api_response.status.phase,
'host_ip': api_response.status.host_ip,
'pod_ip': api_response.status.pod_ip}
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps(response).encode())
except ApiException as e:
self.send_error(404, message=str(e))
else:
self.send_error(404)
def do_POST(self):
parsed_path = urllib.parse.urlparse(self.path)
path = parsed_path.path.split('/')
if path[1] == 'pod':
yaml_filename = path[2]
try:
config.load_kube_config()
with open(yaml_filename, 'r') as f:
pod_yaml = f.read()
api_instance = client.CoreV1Api()
api_response = api_instance.create_namespaced_pod(body=pod_yaml, namespace='default')
response = {'name': api_response.metadata.name,
'status': api_response.status.phase,
'host_ip':
保存为pod_server.py文件并运行
1.HTTP 服务成功启动,计 1 分;
2.发起指定参数的GET 查询 Pod 请求,成功查询指定名称的 pod 服务,计 1 分;
3.发起指定参数的 POST 创建 Pod 请求,成功创建 Pod 服务,计 1 分。
编写 Python 程序实现 Service 资源管理程序,将 Service 资源管理的封装成 Web 服务。在/root 目录下创建 service_server.py 程序,实现 Service 的增删查改等 Web 访问操作。
http.server 的 host 为 localhost,端口 8888;程序内部实现Kubernetes 认证。
提示说明:Python 标准库http.server 模块,提供了HTTP Server 请求封装。需要实现的 Restful API 接口如下:
GET /services/{name},查询指定名称{name}的 Service;Response 的 Body 以 json 格式输出。
POST /services/{yamlfilename} 创建yaml 文件名称为{yamlfilename}的 Service; Response 的Body 以 json 格式,(手工将文件服务器主目录所有*.yaml 文件下载到 root 目录下)。
DELETE /services/{name};删除指定名称的 Service;Response 的 Body 以 json 格式。编码完成后,自己手动执行提供 Web HTTP 服务的 service_server.py 程序,提交答案进
行检测。
import http.server
import json
import os
import subprocess
class ServiceHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
if self.path.startswith('/services/'):
service_name = self.path.split('/')[-1]
service_info = self.get_service_info(service_name)
if service_info is not None:
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps(service_info).encode())
else:
self.send_response(404)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(b'Service not found')
def do_POST(self):
if self.path.startswith('/services/'):
yaml_file_name = self.path.split('/')[-1]
yaml_file_path = os.path.join('/root', yaml_file_name)
if not os.path.isfile(yaml_file_path):
self.send_response(404)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(b'YAML file not found')
return
service_name = self.create_service_from_yaml(yaml_file_path)
service_info = self.get_service_info(service_name)
if service_info is not None:
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps(service_info).encode())
else:
self.send_response(500)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(b'Failed to create service')
def do_DELETE(self):
if self.path.startswith('/services/'):
service_name = self.path.split('/')[-1]
result = self.delete_service(service_name)
if result:
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({'result': 'success'}).encode())
else:
self.send_response(404)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(b'Service not found')
def get_service_info(self, service_name):
command = ['kubectl', 'get', 'service', service_name, '-o', 'json']
output = self.run_command(command)
if output is None:
return None
service_info = json.loads(output)['metadata']
return {
'name': service_info['name'],
'namespace': service_info['namespace'],
'creationTimestamp': service_info['creationTimestamp'],
'labels': service_info['labels'],
}
def create_service_from_yaml(self, yaml_file_path):
command = ['kubectl', 'apply', '-f', yaml_file_path]
output = self.run_command(command)
if output is None:
return None
service_name = output.strip().split(' ')[-1]
return service_name
def delete_service(self, service_name):
command = ['kubectl', 'delete', 'service', service_name]
output = self.run_command(command)
return output is not None
def run_command(self, command):
try:
output = subprocess.check_output(command, stderr=subprocess.STDOUT)
return output.decode()
except subprocess.CalledProcessError as e:
print(e.output.decode())
return None
if __name__ == '__main__':
server_address = ('localhost', 8888)
httpd = http.server.HTTPServer(server_address, ServiceHandler)
httpd.socket = ssl.wrap_socket(httpd
1.HTTP 服务成功启动,计 1 分;
2.发起指定参数的 POST 创建 service 请求,成功创建 service 资源,计 1 分;
3.发起指定参数的GET 查询 service 请求,成功查询指定名称的 Service,计 1 分;
4.发起指定参数的DELETE 删除 service 请求,成功删除指定名称的 Service,计 1 分