Kubernetes python package
source link: https://www.chunyangwen.com/blog/python/kubernetes-python.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
在项目中使用比较多的 kubernetes。主要使用相应的 python kubernetes 库包来进行各种部署的管理。 国内很多讲解 kubernetes 原理,但是对于这个库各种使用看起来比较少。
Initialization
网上搜索得到比较多的是使用默认的 kubeconfig 来初始化。
import os
from kubernetes import client, config
config.load_kube_config(os.path.expanduser("~/.kube/config"))
core_v1_api = client.CoreV1Api()
apps_v1 = client.AppsV1Api()
batch_v1_api = client.BatchV1Api()
networking_v1_api = client.NetworkingV1Api()
如果我们要管理多个集群,这种方式就不行。因为是使用了默认的 api_client
。如何按需创建需要的
api_client
呢?
import os
from kubernetes import client, config
from kubernetes.client import ApiClient, Configuration
config_file = os.path.expanduser("~/.kube/config")
client_configuration = Configuration()
config.load_kube_config(
config_file=config_file,
client_configuration=client_configuration,
)
api_client = ApiClient(configuration=client_configuration)
core_v1_api = client.CoreV1Api(api_client)
我们就可以用这段代码去初始化不同的 api_client
,然后用 client
来获取对应的 API
操作对象。
Deployments
为了简化代码,后续所有的示例都采用默认的配置,而不是单独创建 api_client
的形式。
创建一个 deployment,使用的是 AppsV1Api.create_namespaced_deployment
apps_v1_api = client.AppsV1Api()
namespace = "test"
response = apps_v1_api.create_namespaced_deployment(body=yaml_content, namespace=namespace)
这里的yaml_content
是创建具体的 deployment 的内容。
\(image\) 请替换成真实的镜像名字
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: '1'
labels:
app: my-awesome-deployment
spec:
progressDeadlineSeconds: 600
backoffLimit: 5
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: my-awesome-deployment
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: my-awesome-deployment
spec:
containers:
- image: $$image$$
imagePullPolicy: Always
name: my-awesome-deployment
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 1
memory: 1Gi
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
Deployment 的其它接口
# 不需要修改 replica
apps_v1_api.patch_namespaced_deployment(
name, body=body, namespace=namespace
)
# 需要修改 replica
apps_v1_api.patch_namespaced_deployment_scale(
name, body=body, namespace=namespace
)
apps_v1_api.read_namespaced_deployment(name, namespace=namespace)
apps_v1_api.delete_namespaced_deployment(name, namespace)
重启 deployment (patch_xxx)
重启实际上是需要增加一个新的 annotations
import datetime
import pytz
# deployment 就是加载进来的 yaml_content
deployment["spec"]["template"]["metadata"]["annotations"] = {
"kubectl.kubernetes.io/restartedAt": datetime.datetime.utcnow()
.replace(tzinfo=pytz.UTC)
.isoformat()
}
Service and ingress
Service
Service 使用的是 CoreV1Api
core_v1_api = client.CoreV1Api()
core_v1_api.create_namespaced_service(body=yaml_content, namespace=namespace)
core_v1_api.delete_namespaced_service(name, namespace)
yaml_content
内容如下:
apiVersion: v1
kind: Service
metadata:
name: $$service_name$$
spec:
ports:
- port: $$service_port$$
targetPort: $$target_port$$
protocol: TCP
selector:
app: $$target_name$$
sessionAffinity: None
type: $$service_type$$
注意填充上上述对应 $$$$
中的内容。其中要注意的是 selector
是和
deployment 中对应配置是对上的。spec.template.metadata
中的 labels
。
Ingress
Ingress 使用的 NetworkingV1Api
networking_v1_api = client.NetworkingV1Api()
core_v1_api.create_namespaced_ingress(body=yaml_content, namespace=namespace)
networking_v1_api.delete_namespaced_ingress(name, namespace)
yaml_content
如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress-name
spec:
rules:
- host: my-host
http:
paths:
- backend:
service:
name: my-service-name
port:
number: my-service-port
path: my-path
pathType: Prefix # Exact
上述所有 my-
开头都希望用户自己填充实际的。其中 my-service-name
和创建的 service
名称对应上。
Job 使用的是 BatchV1Api
batch_v1_api = client.BatchV1Api()
batch_v1_api.create_namespaced_job(body=yaml_content, namespace=namespace)
batch_v1_api.read_namespaced_job(name, namespace)
batch_v1_api.delete_namespaced_job(name, namespace)
yaml_content
内容如下:
apiVersion: batch/v1
kind: Job
metadata:
labels:
app: $$ name $$
name: $$ name $$
spec:
ttlSecondsAfterFinished: 3600
template:
metadata:
labels:
app: $$ name $$
spec:
containers:
- name: $$ name $$
image: $$ image $$
resources:
requests:
cpu: 1
memory: 2Gi
command: $$ command|safe $$
restartPolicy: Never
backoffLimit: 0
请自行填充 $$ $$
中的内容。
Logs and Events
查看 POD 的日志和事件时,一般需要先知道有哪些 POD,然后遍历这些 POD 来获取对应的内容。
core_v1_api = client.CoreV1Api()
# 使用具体的 label_selector 来选择相应的 POD
all_pods = core_v1_api.list_namespaced_pod(namespace=namespace, label_selector="app=my-awesome-deployment")
# all_pods 有个接口 `to_dict()`,可以把它打印出来,然后看怎么找到 POD name
dict_response = all_pods.to_dict()
pod_names = [item["metadata"]["name"] for item in dict_response["items"]]
core_v1_api = client.CoreV1Api()
namespace = "test"
response = core_v1_api.read_namespaced_pod_log(
name=name, namespace=namespace, tail_lines=100
)
event
core_v1_api = client.CoreV1Api()
namespace = "test"
pod_name = "zhangsan"
core_v1_api.list_namespaced_event(
namespace=namespace,
pretty=True,
field_selector=f"involvedObject.name={pod_name}"
)
- Api 对应的函数有个
async_req=True
入参,可以发起异步调用,response.get()
拿到结果 - 结果一般会有一个
to_dict
函数,可以通过打印这个结果来判断怎么去提取对应的信息 - 建议 yaml + jinja2 来进行模板配置和模板的渲染,这样可以方便生成想要的
yaml_content
Reference
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK