k8s的python客户端库--kubernetes
简介
Kubernetes 是什么
Kubernetes 是一个全新的基于容器技术的分布式架构解决方案,是 Google 开源的一个容器集群管理系统,Kubernetes 简称 K8S。
Kubernetes 是一个一站式的完备的分布式系统开发和支撑平台,更是一个开放平台,对现有的编程语言、编程框架、中间件没有任何侵入性。
Kubernetes 提供了完善的管理工具,这些工具涵盖了开发、部署测试、运维监控在内的各个环节。
Kubernetes 具有完备的集群管理能力,包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制、内建智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制、多粒度的资源配额管理能力。
Kubernetes 特性
- 自我修复
在节点故障时,重新启动失败的容器,替换和重新部署,保证预期的副本数量;杀死健康检查失败的容器,并且在未准备好之前不会处理用户的请求,确保线上服务不中断。 - 弹性伸缩
使用命令、UI或者基于CPU使用情况自动快速扩容和缩容应用程序实例,保证应用业务高峰并发时的高可用性;业务低峰时回收资源,以最小成本运行服务。 - 自动部署和回滚
K8S采用滚动更新策略更新应用,一次更新一个Pod,而不是同时删除所有Pod,如果更新过程中出现问题,将回滚更改,确保升级不影响业务。 - 服务发现和负载均衡
K8S为多个容器提供一个统一访问入口(内部IP地址和一个DNS名称),并且负载均衡关联的所有容器,使得用户无需考虑容器IP问题。 - 机密和配置管理
管理机密数据和应用程序配置,而不需要把敏感数据暴露在镜像里,提高敏感数据安全性。并可以将一些常用的配置存储在K8S中,方便应用程序使用。 - 存储编排
挂载外部存储系统,无论是来自本地存储,公有云,还是网络存储,都作为集群资源的一部分使用,极大提高存储使用灵活性。 - 批处理
提供一次性任务,定时任务;满足批量数据处理和分析的场景。
k8s官网
官网:https://kubernetes.io/zh-cn/
文档:https://kubernetes.io/zh-cn/docs/home/
集群
k8s集群怎么安装可以看之前的博客,有讲怎么部署了,这里就不做赘述了
客户端
参考
客户端库:https://kubernetes.io/zh-cn/docs/reference/using-api/client-libraries/
python库:https://github.com/kubernetes-client/python/
版本要求
支持的客户端版本的兼容性列表
- client 9.y.z: Kubernetes 1.12 or below (+-), Kubernetes 1.13 (✓), Kubernetes 1.14 or above (+-)
- client 10.y.z: Kubernetes 1.13 or below (+-), Kubernetes 1.14 (✓), Kubernetes 1.14 or above (+-)
- client 11.y.z: Kubernetes 1.14 or below (+-), Kubernetes 1.15 (✓), Kubernetes 1.16 or above (+-)
- client 12.y.z: Kubernetes 1.15 or below (+-), Kubernetes 1.16 (✓), Kubernetes 1.17 or above (+-)
- client 17.y.z: Kubernetes 1.16 or below (+-), Kubernetes 1.17 (✓), Kubernetes 1.18 or above (+-)
- client 18.y.z: Kubernetes 1.17 or below (+-), Kubernetes 1.18 (✓), Kubernetes 1.19 or above (+-)
- client 19.y.z: Kubernetes 1.18 or below (+-), Kubernetes 1.19 (✓), Kubernetes 1.20 or above (+-)
- client 20.y.z: Kubernetes 1.19 or below (+-), Kubernetes 1.20 (✓), Kubernetes 1.21 or above (+-)
- client 21.y.z: Kubernetes 1.20 or below (+-), Kubernetes 1.21 (✓), Kubernetes 1.22 or above (+-)
- client 22.y.z: Kubernetes 1.21 or below (+-), Kubernetes 1.22 (✓), Kubernetes 1.23 or above (+-)
- client 23.y.z: Kubernetes 1.22 or below (+-), Kubernetes 1.23 (✓), Kubernetes 1.24 or above (+-)
- client 24.y.z: Kubernetes 1.23 or below (+-), Kubernetes 1.24 (✓), Kubernetes 1.25 or above (+-)
- client 25.y.z: Kubernetes 1.24 or below (+-), Kubernetes 1.25 (✓), Kubernetes 1.26 or above (+-)
- client 26.y.z: Kubernetes 1.25 or below (+-), Kubernetes 1.26 (✓), Kubernetes 1.27 or above (+-)
- client 27.y.z: Kubernetes 1.26 or below (+-), Kubernetes 1.27 (✓), Kubernetes 1.28 or above (+-)
- client 28.y.z: Kubernetes 1.27 or below (+-), Kubernetes 1.28 (✓), Kubernetes 1.29 or above (+-)
- client 29.y.z: Kubernetes 1.28 or below (+-), Kubernetes 1.29 (✓), Kubernetes 1.30 or above (+-)
- client 30.y.z: Kubernetes 1.29 or below (+-), Kubernetes 1.30 (✓), Kubernetes 1.31 or above (+-)
测试环境k8s版本
$ kubectl version
Client Version: v1.30.1
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.30.0
所以安装最新版本就可以
安装
pip install kubernetes
或者
poetry add kubernetes
连接
from kubernetes import client, config
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
# 如果在k8s的本机上,或者配置文件是~/.kube/config,则可以直接加载配置
# config.load_kube_config()
# 创建API对象
api_instance = client.CoreV1Api()
# 使用API对象执行操作,例如列出所有命名空间
namespace_list = api_instance.list_namespace()
for namespace in namespace_list.items:
print(namespace.metadata.name)
使用config.load_kube_config()
方法来连接k8s集群
配置文件的获取方式有两种
- 显式通过
config_file
参数来指定 - 不指定
config_file
参数,会先检查环境变量- 如果找到环境变量
KUBECONFIG
,那么就直接使用KUBECONFIG
的值 - 如果找不到环境变量,那就会找
~/.kube/config
- 如果找到环境变量
操作k8s
参考 https://github.com/kubernetes-client/python/tree/master/examples
获取POD相关信息
from prettytable import PrettyTable
from kubernetes import client, config
from common.k8s_format import get_age
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
# 创建API对象
api_instance = client.CoreV1Api()
# 列出所有pod
table = PrettyTable()
table.align = "l"
table.field_names = ["NAME", "NAMESPACE", "READY", "STATUS", "RESTARTS", "AGE", "IP", "NODE"]
table.title = "所有名称空间下的POD"
pod_list = api_instance.list_pod_for_all_namespaces()
for pod in pod_list.items:
ready = 0
restarts = 0
for s in pod.status.container_statuses:
if s.ready:
ready += 1
restarts += s.restart_count
table.add_row([pod.metadata.name, pod.metadata.namespace,
f"{ready}/{len(pod.status.container_statuses)}", pod.status.phase, restarts,
get_age(pod.status.start_time), pod.status.pod_ip, pod.spec.node_name])
print(table)
"""
+-----------------------------------------------------------------------------------------------------------------------+
| 所有名称空间下的POD |
+------------------------------------------+-------------+-------+---------+----------+--------+----------------+-------+
| NAME | NAMESPACE | READY | STATUS | RESTARTS | AGE | IP | NODE |
+------------------------------------------+-------------+-------+---------+----------+--------+----------------+-------+
| nginx-deployment-68c885dc79-6g8cr | default | 1/1 | Running | 0 | 2m19s | 10.244.166.178 | node1 |
| nginx-deployment-68c885dc79-k66gf | default | 1/1 | Running | 0 | 2m19s | 10.244.166.180 | node1 |
| nginx-deployment-68c885dc79-qtkvs | default | 1/1 | Running | 0 | 2m19s | 10.244.166.179 | node1 |
| calico-kube-controllers-776b58cfc5-dd8s4 | kube-system | 1/1 | Running | 2 | 18d23h | 10.244.166.139 | node1 |
| calico-node-8ssd6 | kube-system | 1/1 | Running | 2 | 18d23h | 192.168.140.76 | node1 |
| calico-node-nkckv | kube-system | 1/1 | Running | 2 | 18d23h | 192.168.140.75 | node |
| coredns-7b5944fdcf-qrm6v | kube-system | 1/1 | Running | 2 | 18d23h | 10.244.166.142 | node1 |
| coredns-7b5944fdcf-tm2gx | kube-system | 1/1 | Running | 2 | 18d23h | 10.244.166.141 | node1 |
| etcd-node | kube-system | 1/1 | Running | 2 | 18d22h | 192.168.140.75 | node |
| kube-apiserver-node | kube-system | 1/1 | Running | 2 | 18d22h | 192.168.140.75 | node |
| kube-controller-manager-node | kube-system | 1/1 | Running | 2 | 18d22h | 192.168.140.75 | node |
| kube-proxy-2cndq | kube-system | 1/1 | Running | 2 | 18d23h | 192.168.140.75 | node |
| kube-proxy-5mdhc | kube-system | 1/1 | Running | 2 | 18d23h | 192.168.140.76 | node1 |
| kube-scheduler-node | kube-system | 1/1 | Running | 2 | 18d22h | 192.168.140.75 | node |
+------------------------------------------+-------------+-------+---------+----------+--------+----------------+-------+
"""
# 列出指定名称空间下的所有pod
table = PrettyTable()
table.align = "l"
table.field_names = ["NAME", "NAMESPACE", "READY", "STATUS", "RESTARTS", "AGE", "IP", "NODE"]
namespace = "default"
table.title = "{}名称空间下的POD".format(namespace)
pod_list = api_instance.list_namespaced_pod(namespace=namespace)
for pod in pod_list.items:
ready = 0
restarts = 0
for s in pod.status.container_statuses:
if s.ready:
ready += 1
restarts += s.restart_count
table.add_row([pod.metadata.name, pod.metadata.namespace,
f"{ready}/{len(pod.status.container_statuses)}", pod.status.phase, restarts,
get_age(pod.status.start_time), pod.status.pod_ip, pod.spec.node_name])
print(table)
"""
+--------------------------------------------------------------------------------------------------------------+
| default名称空间下的POD |
+-----------------------------------+-----------+-------+---------+----------+--------+----------------+-------+
| NAME | NAMESPACE | READY | STATUS | RESTARTS | AGE | IP | NODE |
+-----------------------------------+-----------+-------+---------+----------+--------+----------------+-------+
| nginx-deployment-68c885dc79-6g8cr | default | 1/1 | Running | 0 | 23m46s | 10.244.166.178 | node1 |
| nginx-deployment-68c885dc79-k66gf | default | 1/1 | Running | 0 | 23m46s | 10.244.166.180 | node1 |
| nginx-deployment-68c885dc79-qtkvs | default | 1/1 | Running | 0 | 23m46s | 10.244.166.179 | node1 |
+-----------------------------------+-----------+-------+---------+----------+--------+----------------+-------+
"""
# 读取指定pod的信息
table = PrettyTable()
table.align = "l"
table.field_names = ["NAME", "NAMESPACE", "READY", "STATUS", "RESTARTS", "AGE", "IP", "NODE"]
namespace = "default"
name="nginx-deployment-68c885dc79-6g8cr"
pod = api_instance.read_namespaced_pod(name, namespace)
ready = 0
restarts = 0
for s in pod.status.container_statuses:
if s.ready:
ready += 1
restarts += s.restart_count
table.add_row([pod.metadata.name, pod.metadata.namespace,
f"{ready}/{len(pod.status.container_statuses)}", pod.status.phase, restarts,
get_age(pod.status.start_time), pod.status.pod_ip, pod.spec.node_name])
print(table)
"""
+-----------------------------------+-----------+-------+---------+----------+--------+----------------+-------+
| NAME | NAMESPACE | READY | STATUS | RESTARTS | AGE | IP | NODE |
+-----------------------------------+-----------+-------+---------+----------+--------+----------------+-------+
| nginx-deployment-68c885dc79-6g8cr | default | 1/1 | Running | 0 | 25m33s | 10.244.166.178 | node1 |
+-----------------------------------+-----------+-------+---------+----------+--------+----------------+-------+
"""
获取api-resources
from kubernetes import client, config
from prettytable import PrettyTable
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
t = PrettyTable()
# 设置表头
t.field_names = ["name", "short_names", "api_version", "namespaced", "kind"]
# 设置左对其
t.align = "l"
# 创建v1的API对象
# 列出v1所有资源
api_instance = client.CoreV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建admissionregistration.k8s.io/v1的API对象
# 列出admissionregistration.k8s.io/v1所有资源
api_instance = client.AdmissionregistrationV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建apiextensions.k8s.io/v1的API对象
# 列出apiextensions.k8s.io/v1所有资源
api_instance = client.ApiextensionsV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建apiregistration.k8s.io/v1的API对象
# 列出apiregistration.k8s.io/v1所有资源
api_instance = client.ApiregistrationV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建apps/v1的API对象
# 列出apps/v1所有资源
api_instance = client.AppsV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建authentication.k8s.io/v1的API对象
# 列出authentication.k8s.io/v1所有资源
api_instance = client.AuthenticationV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建authorization.k8s.io/v1的API对象
# 列出authorization.k8s.io/v1所有资源
api_instance = client.AuthorizationV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建autoscaling/v2的API对象
# 列出autoscaling/v2所有资源
api_instance = client.AutoscalingV2Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建batch/v1的API对象
# 列出batch/v1所有资源
api_instance = client.BatchV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建certificates.k8s.io/v1的API对象
# 列出certificates.k8s.io/v1所有资源
api_instance = client.CertificatesV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建coordination.k8s.io/v1的API对象
# 列出coordination.k8s.io/v1所有资源
api_instance = client.CoordinationV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建discovery.k8s.io/v1的API对象
# 列出discovery.k8s.io/v1所有资源
api_instance = client.DiscoveryV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建events.k8s.io/v1的API对象
# 列出events.k8s.io/v1所有资源
api_instance = client.EventsV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建flowcontrol.apiserver.k8s.io/v1的API对象
# 列出flowcontrol.apiserver.k8s.io/v1所有资源
api_instance = client.FlowcontrolApiserverV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建networking.k8s.io/v1的API对象
# 列出networking.k8s.io/v1所有资源
api_instance = client.NetworkingV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建node.k8s.io/v1的API对象
# 列出node.k8s.io/v1所有资源
api_instance = client.NodeV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建policy/v1的API对象
# 列出policy/v1所有资源
api_instance = client.PolicyV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建rbac.authorization.k8s.io/v1的API对象
# 列出rbac.authorization.k8s.io/v1所有资源
api_instance = client.RbacAuthorizationV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建scheduling.k8s.io/v1的API对象
# 列出scheduling.k8s.io/v1所有资源
api_instance = client.SchedulingV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
# 创建storage.k8s.io/v1的API对象
# 列出storage.k8s.io/v1所有资源
api_instance = client.StorageV1Api()
for resource in api_instance.get_api_resources().resources:
row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
t.add_row(row)
print(t)
"""
如命令行 kubectl api-resources 结果
+-------------------------------------+-------------+---------------------------------+------------+----------------------------------+
| name | short_names | api_version | namespaced | kind |
+-------------------------------------+-------------+---------------------------------+------------+----------------------------------+
| bindings | | v1 | True | Binding |
| componentstatuses | cs | v1 | False | ComponentStatus |
| configmaps | cm | v1 | True | ConfigMap |
| endpoints | ep | v1 | True | Endpoints |
| events | ev | v1 | True | Event |
| limitranges | limits | v1 | True | LimitRange |
| namespaces | ns | v1 | False | Namespace |
| namespaces/finalize | | v1 | False | Namespace |
| namespaces/status | | v1 | False | Namespace |
| nodes | no | v1 | False | Node |
| nodes/proxy | | v1 | False | NodeProxyOptions |
| nodes/status | | v1 | False | Node |
| persistentvolumeclaims | pvc | v1 | True | PersistentVolumeClaim |
| persistentvolumeclaims/status | | v1 | True | PersistentVolumeClaim |
| persistentvolumes | pv | v1 | False | PersistentVolume |
| persistentvolumes/status | | v1 | False | PersistentVolume |
| pods | po | v1 | True | Pod |
| pods/attach | | v1 | True | PodAttachOptions |
| pods/binding | | v1 | True | Binding |
| pods/ephemeralcontainers | | v1 | True | Pod |
| pods/eviction | | v1 | True | Eviction |
| pods/exec | | v1 | True | PodExecOptions |
| pods/log | | v1 | True | Pod |
| pods/portforward | | v1 | True | PodPortForwardOptions |
| pods/proxy | | v1 | True | PodProxyOptions |
| pods/status | | v1 | True | Pod |
| podtemplates | | v1 | True | PodTemplate |
| replicationcontrollers | rc | v1 | True | ReplicationController |
| replicationcontrollers/scale | | v1 | True | Scale |
| replicationcontrollers/status | | v1 | True | ReplicationController |
| resourcequotas | quota | v1 | True | ResourceQuota |
| resourcequotas/status | | v1 | True | ResourceQuota |
| secrets | | v1 | True | Secret |
| serviceaccounts | sa | v1 | True | ServiceAccount |
| serviceaccounts/token | | v1 | True | TokenRequest |
| services | svc | v1 | True | Service |
| services/proxy | | v1 | True | ServiceProxyOptions |
| services/status | | v1 | True | Service |
| mutatingwebhookconfigurations | | admissionregistration.k8s.io/v1 | False | MutatingWebhookConfiguration |
| validatingadmissionpolicies | | admissionregistration.k8s.io/v1 | False | ValidatingAdmissionPolicy |
| validatingadmissionpolicies/status | | admissionregistration.k8s.io/v1 | False | ValidatingAdmissionPolicy |
| validatingadmissionpolicybindings | | admissionregistration.k8s.io/v1 | False | ValidatingAdmissionPolicyBinding |
| validatingwebhookconfigurations | | admissionregistration.k8s.io/v1 | False | ValidatingWebhookConfiguration |
| customresourcedefinitions | crd,crds | apiextensions.k8s.io/v1 | False | CustomResourceDefinition |
| customresourcedefinitions/status | | apiextensions.k8s.io/v1 | False | CustomResourceDefinition |
| apiservices | | apiregistration.k8s.io/v1 | False | APIService |
| apiservices/status | | apiregistration.k8s.io/v1 | False | APIService |
| controllerrevisions | | apps/v1 | True | ControllerRevision |
| daemonsets | ds | apps/v1 | True | DaemonSet |
| daemonsets/status | | apps/v1 | True | DaemonSet |
| deployments | deploy | apps/v1 | True | Deployment |
| deployments/scale | | apps/v1 | True | Scale |
| deployments/status | | apps/v1 | True | Deployment |
| replicasets | rs | apps/v1 | True | ReplicaSet |
| replicasets/scale | | apps/v1 | True | Scale |
| replicasets/status | | apps/v1 | True | ReplicaSet |
| statefulsets | sts | apps/v1 | True | StatefulSet |
| statefulsets/scale | | apps/v1 | True | Scale |
| statefulsets/status | | apps/v1 | True | StatefulSet |
| selfsubjectreviews | | authentication.k8s.io/v1 | False | SelfSubjectReview |
| tokenreviews | | authentication.k8s.io/v1 | False | TokenReview |
| localsubjectaccessreviews | | authorization.k8s.io/v1 | True | LocalSubjectAccessReview |
| selfsubjectaccessreviews | | authorization.k8s.io/v1 | False | SelfSubjectAccessReview |
| selfsubjectrulesreviews | | authorization.k8s.io/v1 | False | SelfSubjectRulesReview |
| subjectaccessreviews | | authorization.k8s.io/v1 | False | SubjectAccessReview |
| horizontalpodautoscalers | hpa | autoscaling/v2 | True | HorizontalPodAutoscaler |
| horizontalpodautoscalers/status | | autoscaling/v2 | True | HorizontalPodAutoscaler |
| cronjobs | cj | batch/v1 | True | CronJob |
| cronjobs/status | | batch/v1 | True | CronJob |
| jobs | | batch/v1 | True | Job |
| jobs/status | | batch/v1 | True | Job |
| certificatesigningrequests | csr | certificates.k8s.io/v1 | False | CertificateSigningRequest |
| certificatesigningrequests/approval | | certificates.k8s.io/v1 | False | CertificateSigningRequest |
| certificatesigningrequests/status | | certificates.k8s.io/v1 | False | CertificateSigningRequest |
| leases | | coordination.k8s.io/v1 | True | Lease |
| endpointslices | | discovery.k8s.io/v1 | True | EndpointSlice |
| events | ev | events.k8s.io/v1 | True | Event |
| flowschemas | | flowcontrol.apiserver.k8s.io/v1 | False | FlowSchema |
| flowschemas/status | | flowcontrol.apiserver.k8s.io/v1 | False | FlowSchema |
| prioritylevelconfigurations | | flowcontrol.apiserver.k8s.io/v1 | False | PriorityLevelConfiguration |
| prioritylevelconfigurations/status | | flowcontrol.apiserver.k8s.io/v1 | False | PriorityLevelConfiguration |
| ingressclasses | | networking.k8s.io/v1 | False | IngressClass |
| ingresses | ing | networking.k8s.io/v1 | True | Ingress |
| ingresses/status | | networking.k8s.io/v1 | True | Ingress |
| networkpolicies | netpol | networking.k8s.io/v1 | True | NetworkPolicy |
| runtimeclasses | | node.k8s.io/v1 | False | RuntimeClass |
| poddisruptionbudgets | pdb | policy/v1 | True | PodDisruptionBudget |
| poddisruptionbudgets/status | | policy/v1 | True | PodDisruptionBudget |
| clusterrolebindings | | rbac.authorization.k8s.io/v1 | False | ClusterRoleBinding |
| clusterroles | | rbac.authorization.k8s.io/v1 | False | ClusterRole |
| rolebindings | | rbac.authorization.k8s.io/v1 | True | RoleBinding |
| roles | | rbac.authorization.k8s.io/v1 | True | Role |
| priorityclasses | pc | scheduling.k8s.io/v1 | False | PriorityClass |
| csidrivers | | storage.k8s.io/v1 | False | CSIDriver |
| csinodes | | storage.k8s.io/v1 | False | CSINode |
| csistoragecapacities | | storage.k8s.io/v1 | True | CSIStorageCapacity |
| storageclasses | sc | storage.k8s.io/v1 | False | StorageClass |
| volumeattachments | | storage.k8s.io/v1 | False | VolumeAttachment |
| volumeattachments/status | | storage.k8s.io/v1 | False | VolumeAttachment |
+-------------------------------------+-------------+---------------------------------+------------+----------------------------------+
"""
获取deploy相关信息
from kubernetes import client, config
from prettytable import PrettyTable
from common.k8s_format import get_age
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
# 创建API对象
api_instance = client.AppsV1Api()
# 获取所有Deployment
table = PrettyTable()
table.align = "l"
table.field_names = ["NAMESPACE", "NAME", "READY", "UP-TO-DATE", "AVAILABLE", "AGE", "CONTAINERS",
"SELECTOR"]
table.title = "所有名称空间下的Deployment"
deploy_list = api_instance.list_deployment_for_all_namespaces()
for deploy in deploy_list.items:
containers = []
for container in deploy.spec.template.spec.containers:
containers.append(container.name)
if len(containers) == 1:
containers = containers[0]
selector = None
if deploy.spec.selector.match_labels:
selector = deploy.spec.selector.match_labels
else:
selector = deploy.spec.selector.match_expressions
table.add_row([deploy.metadata.namespace, deploy.metadata.name,
f"{deploy.status.ready_replicas}/{deploy.status.replicas}",
deploy.status.updated_replicas, deploy.status.available_replicas,
get_age(deploy.metadata.creation_timestamp),
containers if containers else "<none>",
selector if selector else "<none>"])
print(table)
"""
+----------------------------------------------------------------------------------------------------------------------------------------------------+
| 所有名称空间下的Deployment |
+-------------+-------------------------+-------+------------+-----------+--------+-------------------------+----------------------------------------+
| NAMESPACE | NAME | READY | UP-TO-DATE | AVAILABLE | AGE | CONTAINERS | SELECTOR |
+-------------+-------------------------+-------+------------+-----------+--------+-------------------------+----------------------------------------+
| default | nginx-deployment | 3/3 | 3 | 3 | 30m12s | nginx-http | {'app': 'http-server'} |
| kube-system | calico-kube-controllers | 1/1 | 1 | 1 | 18d23h | calico-kube-controllers | {'k8s-app': 'calico-kube-controllers'} |
| kube-system | coredns | 2/2 | 2 | 2 | 19d0h | coredns | {'k8s-app': 'kube-dns'} |
+-------------+-------------------------+-------+------------+-----------+--------+-------------------------+----------------------------------------+
"""
# 获取指定命名空间下的Deployment
namespace = "default"
table = PrettyTable()
table.align = "l"
table.field_names = ["NAMESPACE", "NAME", "READY", "UP-TO-DATE", "AVAILABLE", "AGE", "CONTAINERS",
"SELECTOR"]
table.title = f"{namespace}名称空间下的Deployment"
deploy_list = api_instance.list_namespaced_deployment(namespace=namespace)
for deploy in deploy_list.items:
containers = []
for container in deploy.spec.template.spec.containers:
containers.append(container.name)
if len(containers) == 1:
containers = containers[0]
selector = None
if deploy.spec.selector.match_labels:
selector = deploy.spec.selector.match_labels
else:
selector = deploy.spec.selector.match_expressions
table.add_row([deploy.metadata.namespace, deploy.metadata.name,
f"{deploy.status.ready_replicas}/{deploy.status.replicas}",
deploy.status.updated_replicas, deploy.status.available_replicas,
get_age(deploy.metadata.creation_timestamp),
containers if containers else "<none>",
selector if selector else "<none>"])
print(table)
"""
+--------------------------------------------------------------------------------------------------------------+
| default名称空间下的Deployment |
+-----------+------------------+-------+------------+-----------+--------+------------+------------------------+
| NAMESPACE | NAME | READY | UP-TO-DATE | AVAILABLE | AGE | CONTAINERS | SELECTOR |
+-----------+------------------+-------+------------+-----------+--------+------------+------------------------+
| default | nginx-deployment | 3/3 | 3 | 3 | 33m59s | nginx-http | {'app': 'http-server'} |
+-----------+------------------+-------+------------+-----------+--------+------------+------------------------+
"""
# 获取指定deploy的相关信息
name = "nginx-deployment"
namespace = "default"
table = PrettyTable()
table.align = "l"
table.field_names = ["NAMESPACE", "NAME", "READY", "UP-TO-DATE", "AVAILABLE", "AGE", "CONTAINERS",
"SELECTOR"]
deploy = api_instance.read_namespaced_deployment(name=name, namespace=namespace)
containers = []
for container in deploy.spec.template.spec.containers:
containers.append(container.name)
if len(containers) == 1:
containers = containers[0]
selector = None
if deploy.spec.selector.match_labels:
selector = deploy.spec.selector.match_labels
else:
selector = deploy.spec.selector.match_expressions
table.add_row([deploy.metadata.namespace, deploy.metadata.name,
f"{deploy.status.ready_replicas}/{deploy.status.replicas}",
deploy.status.updated_replicas, deploy.status.available_replicas,
get_age(deploy.metadata.creation_timestamp),
containers if containers else "<none>",
selector if selector else "<none>"])
print(table)
"""
+-----------+------------------+-------+------------+-----------+--------+------------+------------------------+
| NAMESPACE | NAME | READY | UP-TO-DATE | AVAILABLE | AGE | CONTAINERS | SELECTOR |
+-----------+------------------+-------+------------+-----------+--------+------------+------------------------+
| default | nginx-deployment | 3/3 | 3 | 3 | 35m21s | nginx-http | {'app': 'http-server'} |
+-----------+------------------+-------+------------+-----------+--------+------------+------------------------+
"""
获取service的相关信息
from kubernetes import client, config
from prettytable import PrettyTable
from common.k8s_format import get_age
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
# 创建API对象
api_instance = client.CoreV1Api()
table = PrettyTable()
table.align = "l"
table.field_names = ["NAMESPACE", "NAME", "TYPE", "CLUSTER-IP", "EXTERNAL-IP", "PORT(S)", "AGE",
"SELECTOR"]
table.title = "所有名称空间下的Service"
svc_list = api_instance.list_service_for_all_namespaces()
for svc in svc_list.items:
table.add_row([svc.metadata.namespace, svc.metadata.name, svc.spec.type,
",".join(svc.spec.cluster_i_ps),
",".join(svc.spec.external_i_ps) if svc.spec.external_i_ps else "<none>",
",".join(map(lambda x: str(x.port) + "/" + x.protocol, svc.spec.ports)),
get_age(svc.metadata.creation_timestamp),
svc.spec.selector if svc.spec.selector else "<none>"])
print(table)
"""
+----------------------------------------------------------------------------------------------------------------------------+
| 所有名称空间下的Service |
+-------------+------------+-----------+------------+-------------+------------------------+-------+-------------------------+
| NAMESPACE | NAME | TYPE | CLUSTER-IP | EXTERNAL-IP | PORT(S) | AGE | SELECTOR |
+-------------+------------+-----------+------------+-------------+------------------------+-------+-------------------------+
| default | kubernetes | ClusterIP | 10.96.0.1 | <none> | 443/TCP | 19d0h | <none> |
| kube-system | kube-dns | ClusterIP | 10.96.0.10 | <none> | 53/UDP,53/TCP,9153/TCP | 19d0h | {'k8s-app': 'kube-dns'} |
+-------------+------------+-----------+------------+-------------+------------------------+-------+-------------------------+
"""
# 获取指定名称空间下的所有service
table = PrettyTable()
table.align = "l"
table.field_names = ["NAMESPACE", "NAME", "TYPE", "CLUSTER-IP", "EXTERNAL-IP", "PORT(S)", "AGE",
"SELECTOR"]
namespace = "default"
table.title = f"{namespace}名称空间下的Service"
svc_list = api_instance.list_namespaced_service(namespace=namespace)
for svc in svc_list.items:
table.add_row([svc.metadata.namespace, svc.metadata.name, svc.spec.type,
",".join(svc.spec.cluster_i_ps),
",".join(svc.spec.external_i_ps) if svc.spec.external_i_ps else "<none>",
",".join(map(lambda x: str(x.port) + "/" + x.protocol, svc.spec.ports)),
get_age(svc.metadata.creation_timestamp),
svc.spec.selector if svc.spec.selector else "<none>"])
print(table)
"""
+--------------------------------------------------------------------------------------------+
| default名称空间下的Service |
+-----------+------------+-----------+------------+-------------+---------+-------+----------+
| NAMESPACE | NAME | TYPE | CLUSTER-IP | EXTERNAL-IP | PORT(S) | AGE | SELECTOR |
+-----------+------------+-----------+------------+-------------+---------+-------+----------+
| default | kubernetes | ClusterIP | 10.96.0.1 | <none> | 443/TCP | 19d0h | <none> |
+-----------+------------+-----------+------------+-------------+---------+-------+----------+
"""
# 获取指定service的信息
table = PrettyTable()
table.align = "l"
table.field_names = ["NAMESPACE", "NAME", "TYPE", "CLUSTER-IP", "EXTERNAL-IP", "PORT(S)", "AGE",
"SELECTOR"]
namespace = "default"
name="kubernetes"
svc = api_instance.read_namespaced_service(name=name, namespace=namespace)
table.add_row([svc.metadata.namespace, svc.metadata.name, svc.spec.type,
",".join(svc.spec.cluster_i_ps),
",".join(svc.spec.external_i_ps) if svc.spec.external_i_ps else "<none>",
",".join(map(lambda x: str(x.port) + "/" + x.protocol, svc.spec.ports)),
get_age(svc.metadata.creation_timestamp),
svc.spec.selector if svc.spec.selector else "<none>"])
print(table)
"""
+-----------+------------+-----------+------------+-------------+---------+-------+----------+
| NAMESPACE | NAME | TYPE | CLUSTER-IP | EXTERNAL-IP | PORT(S) | AGE | SELECTOR |
+-----------+------------+-----------+------------+-------------+---------+-------+----------+
| default | kubernetes | ClusterIP | 10.96.0.1 | <none> | 443/TCP | 19d0h | <none> |
+-----------+------------+-----------+------------+-------------+---------+-------+----------+
"""
创建资源
大概分两类:
- 不需要指定什么类型的资源,根据给出的资源清单创建文件
- 创建什么资源就用什么特定的接口
通过yaml文件创建
yaml文件
# nginx.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: http-server
strategy:
type: Recreate
template:
metadata:
labels:
app: http-server
spec:
containers:
- name: nginx-http
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- protocol: TCP
containerPort: 80
创建
from kubernetes import client, config, utils
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
k8s_client = client.ApiClient()
utils.create_from_yaml(k8s_client, "examples/k8s/nginx/nginx.yaml",verbose=True)
通过文件夹创建资源
from kubernetes import client, config, utils
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
k8s_client = client.ApiClient()
utils.create_from_directory(k8s_client, yaml_dir="examples/k8s/nginx", verbose=True)
通过字典创建资源
from kubernetes import client, config, utils
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
k8s_client = client.ApiClient()
data = {
'apiVersion': 'apps/v1',
'kind' : 'Deployment',
'metadata' : { 'name': 'nginx-deployment' },
'spec' : {
'replicas': 3,
'selector': {
'matchLabels': { 'app': 'http-server' }
},
'strategy': { 'type': 'Recreate' },
'template': {
'metadata': {
'labels': {
'app': 'http-server'
}
},
'spec' : {
'containers': [
{
'name' : 'nginx-http',
'image' : 'nginx:latest',
'imagePullPolicy': 'IfNotPresent',
'ports' : [
{
'protocol' : 'TCP',
'containerPort': 80
}
]
}
]
}
}
}
}
utils.create_from_dict(k8s_client, data=data, verbose=True)
通过专门的接口来创建资源
这里以 创建deploy举例
from kubernetes import client, config, utils
from kubernetes.client import exceptions
import yaml
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
api_instance = client.AppsV1Api()
with open("examples/k8s/nginx/nginx.yaml") as f:
nginx = yaml.safe_load(f)
try:
res = api_instance.create_namespaced_deployment(namespace="default", body=nginx)
print(res)
except exceptions.ApiException as e:
print("状态码:", e.status)
print("错误信息:", e.body)
以上基本都是通过读取yaml文件或者类似的资源清单来创建的
其实也可以通过接口一步步新建一个资源,只是比较复杂而已
通过接口创建资源
from kubernetes import client, config
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
DEPLOYMENT_NAME = "nginx-deployment"
# 配置Pod容器
container = client.V1Container(
name="nginx",
image="nginx:latest",
ports=[client.V1ContainerPort(container_port=80)],
resources=client.V1ResourceRequirements(
requests={ "cpu": "100m", "memory": "200Mi" },
limits={ "cpu": "500m", "memory": "500Mi" },
),
)
# 创建容器模板
template = client.V1PodTemplateSpec(
metadata=client.V1ObjectMeta(labels={ "app": "nginx" }),
spec=client.V1PodSpec(containers=[container]),
)
# 创建spec
spec = client.V1DeploymentSpec(
replicas=3, template=template, selector={
"matchLabels":
{ "app": "nginx" } })
# 创建deploy对象
deployment = client.V1Deployment(
api_version="apps/v1",
kind="Deployment",
metadata=client.V1ObjectMeta(name=DEPLOYMENT_NAME),
spec=spec,
)
api = client.AppsV1Api()
# 运行部署
resp = api.create_namespaced_deployment(
body=deployment, namespace="default"
)
# 响应
print("\n[INFO] deployment `nginx-deployment` created.\n")
print("%s\t%s\t\t\t%s\t%s" % ("NAMESPACE", "NAME", "REVISION", "IMAGE"))
print(
"%s\t\t%s\t%s\t\t%s\n"
% (
resp.metadata.namespace,
resp.metadata.name,
resp.metadata.generation,
resp.spec.template.spec.containers[0].image,
)
)
对资源的CRUD
这里以deployment为例
创建
from kubernetes import client, config
import yaml
from kubernetes.client import exceptions
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
api_instance = client.AppsV1Api()
with open("examples/k8s/nginx/nginx.yaml") as f:
nginx = yaml.safe_load(f)
try:
res = api_instance.create_namespaced_deployment(body=nginx)
print(res)
except exceptions.ApiException as e:
print("状态码:", e.status)
print("错误信息:", e.body)
删除
from kubernetes import client, config
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
name = "nginx-deployment"
namespace = "default"
api_instance = client.AppsV1Api()
res = api_instance.delete_namespaced_deployment(namespace=ns, name=deploy_name)
print(res)
查询
from kubernetes import client, config
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
name = "nginx-deployment"
namespace = "default"
api_instance = client.AppsV1Api()
res = api_instance.read_namespaced_deployment(namespace=ns, name=deploy_name)
print(res)
修改
from kubernetes import client, config
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
# 先查找
name = "nginx-deployment"
namespace = "default"
api_instance = client.AppsV1Api()
deploy = api_instance.read_namespaced_deployment(namespace=namespace, name=name)
# 再修改
deploy.spec.replicas = 1
res = api_instance.patch_namespaced_deployment(
namespace=deploy.metadata.namespace,
name=deploy.metadata.name,
body=deploy
)
print(res)
重启deploy
from kubernetes import client, config
import datetime
import pytz
# 加载配置文件
config.load_kube_config(config_file="examples/k8s/admin.conf")
# 先查找
name = "nginx-deployment"
namespace = "default"
api_instance = client.AppsV1Api()
deploy = api_instance.read_namespaced_deployment(namespace=namespace, name=name)
# 再重启
# update `spec.template.metadata` section
# to add `kubectl.kubernetes.io/restartedAt` annotation
deploy.spec.template.metadata.annotations = {
"kubectl.kubernetes.io/restartedAt": datetime.datetime.now(tz=pytz.UTC)
.isoformat()
}
api_instance = client.AppsV1Api()
# patch the deployment
resp = api_instance.patch_namespaced_deployment(
name=name, namespace=namespace, body=deploy
)
print("\n[INFO] deployment `nginx-deployment` restarted.\n")
print("%s\t\t\t%s\t%s" % ("NAME", "REVISION", "RESTARTED-AT"))
print(
"%s\t%s\t\t%s\n"
% (
resp.metadata.name,
resp.metadata.generation,
resp.spec.template.metadata.annotations,
)
)
本文来自博客园,作者:厚礼蝎,转载请注明原文链接:https://www.cnblogs.com/guangdelw/p/18254549