网站运营单位是什么意思,天津个人专业做网站,免费发布信息的平台,温州建设网站文章目录 一、基本了解1.1 操作k8s API1.2 基本使用 二、数据表格展示K8s常见资源2.1 Namespace2.2 Node2.3 PV2.4 Deployment2.5 DaemonSet2.6 StatefulSet2.7 Pod2.8 Service2.9 Ingress2.10 PVC2.11 ConfigMap2.12 Secret2.13 优化 一、基本了解 操作K8s资源api方式#xf… 文章目录 一、基本了解1.1 操作k8s API1.2 基本使用 二、数据表格展示K8s常见资源2.1 Namespace2.2 Node2.3 PV2.4 Deployment2.5 DaemonSet2.6 StatefulSet2.7 Pod2.8 Service2.9 Ingress2.10 PVC2.11 ConfigMap2.12 Secret2.13 优化 一、基本了解 操作K8s资源api方式 原生api客户端库python客户端库 K8s支持三种客户端身份认证 HTTPS 证书认证基于CA证书签名的数字证书认证kubeconfig文件默认路径~/.kube/configHTTP Token认证通过一个Token来识别用户ServiceAccountHTTP Base认证用户名密码的方式认证1.19已经弃用 1.1 操作k8s API
1.安装Kubernetes客户端库。
pip install kubernetes -i https://pypi.tuna.tsinghua.edu.cn/simple2.基于HTTPS证书认证kubeconfig操作k8s API。
常用资源接口类实例化资源core_api client.CoreV1Api()namespace,pod,service,pv,pvcapps_api client.AppsV1Api()deployment,statefulset,daemonsetnetworking_api client.NetworkingV1beta1Api()ingressstorage_api client.StorageV1Api()storage_class
from kubernetes import client,config
import os
print(os.getcwd())kubeconfig os.path.join(os.getcwd(),kubeconfig.yaml) ##拿到k8s的~.kube/config文件内容。
config.load_kube_config(kubeconfig) ##指定kubeconfig配置文件/root/.kube/config
apps_api client.AppsV1Api() # 资源接口类实例化根据要操作的资源实例化不同的组。
# print(apps_api.list_deployment_for_all_namespaces())for dp in apps_api.list_deployment_for_all_namespaces().items:# print(dp) # 打印Deployment对象详细信息print(dp.metadata.labels)print(dp.metadata.name)3.基于HTTP Token认证ServiceAccount操作K8s API。
#############################################################
##获取Token字符串创建service account并绑定默认cluster-admin管理员集群角色。
# 创建用户
kubectl create serviceaccount dashboard-admin -n kube-system
# 用户授权
kubectl create clusterrolebinding dashboard-admin --clusterrolecluster-admin --serviceaccountkube-system:dashboard-admin
# 获取用户Token1.24版本之前
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk /dashboard-admin/{print $1})
# 获取用户Token1.24版本之后
kubectl create token dashboard-admin -n kube-system
#############################################################
from kubernetes import client,config
import os
configuration client.Configuration()
configuration.host https://192.168.161.120:6443 # APISERVER地址
ca_file os.path.join(os.getcwd(),ca.crt) # K8s集群CA证书/etc/kubernetes/pki/ca.crt
configuration.ssl_ca_cert ca_file
configuration.verify_ssl True
##启用证书验证。
token eyJhbGciOiJSUzI1NiIsImtpZCI6InhBd1JkOFFocE1oX0VsRnlDcmFwQUN4ajQzblNta2FnVW1ITmk1VU12ZUEifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjk0MDQ3ODI5LCJpYXQiOjE2OTQwNDQyMjksImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJkYXNoYm9hcmQtYWRtaW4iLCJ1aWQiOiI2Zjg0ZTFjMC0wYTY0LTQ4NTQtYThlMy03MDZkOWYxZThkZGMifX0sIm5iZiI6MTY5NDA0NDIyOSwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.GXwDKDNcCPjU23R-kYbs1Sl-73hG2p7RJShB0I8BU7cpifUhBaEKJjymx5IL_CYTl5LHRdlP0uo_sqXqrUBRBYrW5vctVq8MXLFNShSAKKLmxdIxxo4fHrWHMaRv8TU_wtKkATiXAO15q3n9YD7vN443FWK3sRuWpzh6Hvlr4dljnK_37YKiOd8eS8_dDC4BkeLo38EadnO39BwvC5lommz2LkCYMawunWkOxsI_eclPqXJ3ZkSCgEZUPD4_0CNv7D_X6S_gyMkdsCVxwFuL3EjI9ENh4GV2yKBVY69wuChlXB6vHGcYtiWzhTDdibv4l-5jIWhbwR_5CgaskKtmTQ #指定Token字符串下面方式获取
configuration.api_key {authorization: Bearer token} ##固定格式。
client.Configuration.set_default(configuration)
apps_api client.AppsV1Api()for dp in apps_api.list_deployment_for_all_namespaces().items:# print(dp) # 打印Deployment对象详细信息print(dp.metadata.labels)1.2 基本使用
1.创建一个deployment资源名为qingjun3个副本数使用nginx镜像。
from kubernetes import client,config
import osconfiguration client.Configuration()
configuration.host https://192.168.161.120:6443 # APISERVER地址
ca_file os.path.join(os.getcwd(),ca.crt) # K8s集群CA证书/etc/kubernetes/pki/ca.crt
configuration.ssl_ca_cert ca_file
configuration.verify_ssl True
# 启用证书验证
token eyJhbGciOiJSUzI1NiIsImtpZCI6InhBd1JkOFFocE1oX0VsRnlDcmFwQUN4ajQzblNta2FnVW1ITmk1VU12ZUEifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjk0MDQ3ODI5LCJpYXQiOjE2OTQwNDQyMjksImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJkYXNoYm9hcmQtYWRtaW4iLCJ1aWQiOiI2Zjg0ZTFjMC0wYTY0LTQ4NTQtYThlMy03MDZkOWYxZThkZGMifX0sIm5iZiI6MTY5NDA0NDIyOSwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.GXwDKDNcCPjU23R-kYbs1Sl-73hG2p7RJShB0I8BU7cpifUhBaEKJjymx5IL_CYTl5LHRdlP0uo_sqXqrUBRBYrW5vctVq8MXLFNShSAKKLmxdIxxo4fHrWHMaRv8TU_wtKkATiXAO15q3n9YD7vN443FWK3sRuWpzh6Hvlr4dljnK_37YKiOd8eS8_dDC4BkeLo38EadnO39BwvC5lommz2LkCYMawunWkOxsI_eclPqXJ3ZkSCgEZUPD4_0CNv7D_X6S_gyMkdsCVxwFuL3EjI9ENh4GV2yKBVY69wuChlXB6vHGcYtiWzhTDdibv4l-5jIWhbwR_5CgaskKtmTQ #指定Token字符串下面方式获取
configuration.api_key {authorization: Bearer token} ##固定格式。
client.Configuration.set_default(configuration)
apps_api client.AppsV1Api()namespace default
name qingjun
replicas 3
labels {a:1, b:2} # 不区分数据类型都要加引号
image nginx
body client.V1Deployment(api_versionapps/v1,kindDeployment,metadataclient.V1ObjectMeta(namename),specclient.V1DeploymentSpec(replicasreplicas,selector{matchLabels: labels},templateclient.V1PodTemplateSpec(metadataclient.V1ObjectMeta(labelslabels),specclient.V1PodSpec(containers[client.V1Container(nameweb,imageimage)])),))
try:apps_api.create_namespaced_deployment(namespacenamespace, bodybody) ##创建命令。
except Exception as e:status getattr(e, status) ##获取状态码。if status 400: # 400 格式错误409 资源存在403 没权限。print(e)print(格式错误)elif status 409:print(deployment资源存在)elif status 403:print(没权限)2.创建一个service资源。
core_api client.CoreV1Api()
namespace default
name qingjun
selector {a:1, b:2} # 不区分数据类型都要加引号
port 80
target_port 80
type NodePort
body client.V1Service(api_versionv1,kindService,metadataclient.V1ObjectMeta(namename),specclient.V1ServiceSpec(selectorselector,ports[client.V1ServicePort(portport,target_porttarget_port)],typetype)
)
try:core_api.create_namespaced_service(namespacenamespace, bodybody)
except Exception as e:status getattr(e, status)if status 400: # 400 格式错误409 资源存在403 没权限。print(e)print(格式错误)elif status 409:print(service资源存在)elif status 403:print(没权限)二、数据表格展示K8s常见资源 大致思路 使用Layui从接口获取JSON数据动态渲染表格。Django准备接口以JSON格式返回。接口类实例化遍历获取接口数据取对应字段值组成一个字典。 资源增删改查采用不同HTTP方法 HTTP方法数据处理说明POST新增新增一个资源GET获取取得一个资源PUT更新更新一个资源DELETE删除删除一个资源
2.1 Namespace
1.查询资源。
##items返回一个对象类LIST[{命名空间属性},{命名空间属性}] 每个元素是一个类字典命名空间属性操作类字典
for ns in core_api.list_namespace().items:name ns.metadata.name ##名称。labels ns.metadata.labels ##标签。create_time ns.metadata.creation_timestamp ##创建时间。namespace {name: name, labels: labels, create_time: create_time}2.删除资源。
core_api.delete_namespace(namename)3.创建资源。
body client.V1Namespace(api_versionv1,kindNamespace,metadataclient.V1ObjectMeta(namens_name)
)
core_api.create_namespace(bodybody)4.使用数据表格显示资源。 table.render({elem: #test,url:{% url namespace_api %},toolbar: #toolbarDemo //开启头部工具栏并为其绑定左侧模板,defaultToolbar: [filter, exports, print, { //自定义头部工具栏右侧图标。如无需自定义去除该参数即可title: 提示,layEvent: LAYTABLE_TIPS,icon: layui-icon-tips}],cols: [[{field: name, title: 名称, sort: true},{field: labels, title: 标签,templet: labelsFormat},{field: create_time, title: 创建时间},{fixed: right, title:操作, toolbar: #barDemo, width:150}]],page: true});// 标签格式化是一个对象function labelsFormat(d){result ;if (d.labels null){return None} else {for (let key in d.labels) {result span styleborder: 1px solid #d6e5ec;border-radius: 8px key : d.labels[key] /spanbr}return result}}总结其他资源功能开发与命名空间一样拷贝后需要的修改位置 服务端新添加一个url函数视图服务端函数视图GET方法里修改for遍历的K8s API接口、对应字段DELETE方法里修改删除的K8s API接口前端面包屑前端table.renader修改连接的API接口对应表头删除接口及提示文字另外除了Namespace、Node、PV其他适配加命名空间 2.2 Node
1.查询。
for node in core_api.list_node_with_http_info()[0].items:name node.metadata.name ##名称。labels node.metadata.labels ##标签。status node.status.conditions[-1].status ##准备就绪状态。scheduler (是 if node.spec.unschedulable is None else 否) ##是否可调度。cpu node.status.capacity[cpu] ##cpui资源memory node.status.capacity[memory] ##内存资源kebelet_version node.status.node_info.kubelet_version ##kubelet版本cri_version node.status.node_info.container_runtime_version ##CRI版本create_time node.metadata.creation_timestamp ##创建时间node {name: name, labels: labels, status:status,scheduler:scheduler , cpu:cpu, memory:memory,kebelet_version:kebelet_version, cri_version:cri_version,create_time: create_time}2.数据表格。 table.render({elem: #test,url:{% url node_api %},toolbar: #toolbarDemo //开启头部工具栏并为其绑定左侧模板,defaultToolbar: [filter, exports, print, { //自定义头部工具栏右侧图标。如无需自定义去除该参数即可title: 提示,layEvent: LAYTABLE_TIPS,icon: layui-icon-tips}],cols: [[{field: name, title: 名称, sort: true},{field: labels, title: 标签,templet: labelsFormat},{field: status, title: 准备就绪},{field: scheduler, title: 可调度},{field: cpu, title: CPU},{field: memory, title: 内存},{field: kebelet_version, title: kubelet版本},{field: cri_version, title: CRI版本},{field: create_time, title: 创建时间},{fixed: right, title:操作, toolbar: #barDemo, width:150}]],page: true});// 标签格式化是一个对象function labelsFormat(d){result ;if (d.labels null){return None} else {for (let key in d.labels) {result span styleborder: 1px solid #d6e5ec;border-radius: 8px key : d.labels[key] /spanbr}return result}}2.3 PV 数据存储Pod-PVC-PV-外部存储例如NFS、Ceph 1.查询。 字段名称、容量、访问模式、回收策略、状态、卷申请PVC/命名空间、存储类、创建时间 for pv in core_api.list_persistent_volume().items:name pv.metadata.namecapacity pv.spec.capacity[storage]access_modes pv.spec.access_modesreclaim_policy pv.spec.persistent_volume_reclaim_policystatus pv.status.phaseif pv.spec.claim_ref is not None:pvc_ns pv.spec.claim_ref.namespacepvc_name pv.spec.claim_ref.namepvc %s / %s % (pvc_ns, pvc_name)else:pvc 未绑定storage_class pv.spec.storage_class_namecreate_time pv.metadata.creation_timestamppv {name: name, capacity: capacity, access_modes:access_modes,reclaim_policy:reclaim_policy , status:status, pvc:pvc,storage_class:storage_class,create_time: create_time}2.创建。 name request.POST.get(name, None)capacity request.POST.get(capacity, None)access_mode request.POST.get(access_mode, None)storage_type request.POST.get(storage_type, None)server_ip request.POST.get(server_ip, None)mount_path request.POST.get(mount_path, None)body client.V1PersistentVolume(api_versionv1,kindPersistentVolume,metadataclient.V1ObjectMeta(namename),specclient.V1PersistentVolumeSpec(capacity{storage:capacity},access_modes[access_mode],nfsclient.V1NFSVolumeSource(serverserver_ip,path/ifs/kubernetes/%s %mount_path)))core_api.create_persistent_volume(bodybody)3.删除。
core_api.delete_persistent_volume(namename)4.数据表格。
table.render({elem: #test,url:{% url pv_api %},toolbar: #toolbarDemo //开启头部工具栏并为其绑定左侧模板,defaultToolbar: [filter, exports, print, { //自定义头部工具栏右侧图标。如无需自定义去除该参数即可title: 提示,layEvent: LAYTABLE_TIPS,icon: layui-icon-tips}],cols: [[{field: name, title: 名称, sort: true},{field: capacity, title: 容量},{field: access_modes, title: 访问模式},{field: reclaim_policy, title: 回收策略},{field: status, title: 状态},{field: pvc, title: PVC(命名空间/名称)},{field: storage_class, title: 存储类},{field: create_time, title: 创建时间},{fixed: right, title:操作, toolbar: #barDemo, width:150}]],page: true,id: pvtb
});2.4 Deployment
1.查询。 字段名称、命名空间、预期副本数、可用副本数、Pod标签选择器、镜像/状态、创建时间 for dp in apps_api.list_namespaced_deployment(namespace).items:name dp.metadata.namenamespace dp.metadata.namespacereplicas dp.spec.replicasavailable_replicas ( 0 if dp.status.available_replicas is None else dp.status.available_replicas)labels dp.metadata.labelsselector dp.spec.selector.match_labelscontainers {}for c in dp.spec.template.spec.containers:containers[c.name] c.imagecreate_time dp.metadata.creation_timestampdp {name: name, namespace: namespace, replicas:replicas,available_replicas:available_replicas , labels:labels, selector:selector,containers:containers, create_time: create_time}2.创建。 name request.POST.get(name,None)namespace request.POST.get(namespace,None)image request.POST.get(image,None)replicas int(request.POST.get(replicas,None))# 处理标签labels {}try:for l in request.POST.get(labels,None).split(,):k l.split()[0]v l.split()[1]labels[k] vexcept Exception as e:res {code: 1, msg: 标签格式错误}return JsonResponse(res)resources request.POST.get(resources,None)health_liveness request.POST.get(health[liveness],None) # {health[liveness]: [on], health[readiness]: [on]}health_readiness request.POST.get(health[readiness],None)if resources 1c2g:resources client.V1ResourceRequirements(limits{cpu:1,memory:1Gi},requests{cpu:0.9,memory:0.9Gi})elif resources 2c4g:resources client.V1ResourceRequirements(limits{cpu: 2, memory: 4Gi},requests{cpu: 1.9, memory: 3.9Gi})elif resources 4c8g:resources client.V1ResourceRequirements(limits{cpu: 4, memory: 8Gi},requests{cpu: 3.9, memory: 7.9Gi})else:resources client.V1ResourceRequirements(limits{cpu:500m,memory:1Gi},requests{cpu:450m,memory:900Mi})liveness_probe if health_liveness on:liveness_probe client.V1Probe(http_get/,timeout_seconds30,initial_delay_seconds30)readiness_probe if health_readiness on:readiness_probe client.V1Probe(http_get/,timeout_seconds30,initial_delay_seconds30)for dp in apps_api.list_namespaced_deployment(namespacenamespace).items:if name dp.metadata.name:res {code: 1, msg: Deployment已经存在}return JsonResponse(res)body client.V1Deployment(api_versionapps/v1,kindDeployment,metadataclient.V1ObjectMeta(namename),specclient.V1DeploymentSpec(replicasreplicas,selector{matchLabels: labels},templateclient.V1PodTemplateSpec(metadataclient.V1ObjectMeta(labelslabels),specclient.V1PodSpec(containers[client.V1Container( # https://github.com/kubernetes-client/python/blob/master/kubernetes/docs/V1Container.mdnameweb,imageimage,env[{name: TEST, value: 123}, {name: DEV, value: 456}],ports[client.V1ContainerPort(container_port80)],# liveness_probeliveness_probe, # readiness_probereadiness_probe,resourcesresources,)])),))apps_api.create_namespaced_deployment(namespacenamespace, bodybody)3.删除。
apps_api.delete_namespaced_deployment(namespacenamespace, namename)4.数据表格。 table.render({elem: #test,url:{% url deployment_api %}?namespace namespace,toolbar: #toolbarDemo //开启头部工具栏并为其绑定左侧模板,defaultToolbar: [filter, exports, print, { //自定义头部工具栏右侧图标。如无需自定义去除该参数即可title: 提示,layEvent: LAYTABLE_TIPS,icon: layui-icon-tips}],cols: [[{field: name, title: 名称, sort: true},{field: namespace, title: 命名空间},{field: replicas, title: 预期副本数},{field: available_replicas, title: 可用副本数},{field: labels, title: 标签,templet: labelsFormat},{field: selector, title: Pod标签选择器,templet: selectorFormat},{field: containers, title: 容器, templet: containersFormat},{field: create_time, title: 创建时间},{fixed: right, title:操作, toolbar: #barDemo, width:150}]],page: true,id: dptb});// 标签格式化是一个对象function labelsFormat(d){result ;if(d.labels null){return None} else {for (let key in d.labels) {result span styleborder: 1px solid #d6e5ec;border-radius: 8px key : d.labels[key] /spanbr}return result}}function selectorFormat(d){result ;for(let key in d.selector) {result span styleborder: 1px solid #d6e5ec;border-radius: 8px key : d.selector[key] /spanbr}return result}function containersFormat(d) {result ;for(let key in d.containers) {result key d.containers[key] br}return result}2.5 DaemonSet
1.查询。 字段名称、命名空间、预期节点数、可用节点数、Pod标签选择器、镜像、创建时间 for ds in apps_api.list_namespaced_daemon_set(namespace).items:name ds.metadata.namenamespace ds.metadata.namespacedesired_number ds.status.desired_number_scheduledavailable_number ds.status.number_availablelabels ds.metadata.labelsselector ds.spec.selector.match_labelscontainers {}for c in ds.spec.template.spec.containers:containers[c.name] c.image create_time ds.metadata.creation_timestampds {name: name, namespace: namespace, labels: labels, desired_number: desired_number,available_number: available_number,selector: selector, containers: containers, create_time: create_time}2.创建。 name request.POST.get(name,None)namespace request.POST.get(namespace,None)image request.POST.get(image,None)# 处理标签labels {}try:for l in request.POST.get(labels,None).split(,):k l.split()[0]v l.split()[1]labels[k] vexcept Exception as e:res {code: 1, msg: 标签格式错误}return JsonResponse(res)resources request.POST.get(resources,None)health_liveness request.POST.get(health[liveness],None) # {health[liveness]: [on], health[readiness]: [on]}health_readiness request.POST.get(health[readiness],None)if resources 1c2g:resources client.V1ResourceRequirements(limits{cpu:1,memory:1Gi},requests{cpu:0.9,memory:0.9Gi})elif resources 2c4g:resources client.V1ResourceRequirements(limits{cpu: 2, memory: 4Gi},requests{cpu: 1.9, memory: 3.9Gi})elif resources 4c8g:resources client.V1ResourceRequirements(limits{cpu: 4, memory: 8Gi},requests{cpu: 3.9, memory: 7.9Gi})else:resources client.V1ResourceRequirements(limits{cpu:500m,memory:1Gi},requests{cpu:450m,memory:900Mi})liveness_probe if health_liveness on:liveness_probe client.V1Probe(http_get/,timeout_seconds30,initial_delay_seconds30)readiness_probe if health_readiness on:readiness_probe client.V1Probe(http_get/,timeout_seconds30,initial_delay_seconds30)for dp in apps_api.list_namespaced_daemon_set(namespacenamespace).items:if name dp.metadata.name:res {code: 1, msg: DaemonSet已经存在}return JsonResponse(res)body client.V1DaemonSet(api_versionapps/v1,kindDaemonSet,metadataclient.V1ObjectMeta(namename),specclient.V1DeploymentSpec(selector{matchLabels: labels},templateclient.V1PodTemplateSpec(metadataclient.V1ObjectMeta(labelslabels),specclient.V1PodSpec(containers[client.V1Container( # https://github.com/kubernetes-client/python/blob/master/kubernetes/docs/V1Container.mdnameweb,imageimage,env[{name: TEST, value: 123}, {name: DEV, value: 456}],ports[client.V1ContainerPort(container_port80)],# liveness_probeliveness_probe, # readiness_probereadiness_probe,resourcesresources,)])),))3.删除。
apps_api.delete_namespaced_daemon_set(namespacenamespace, namename)4.数据表格。 table.render({elem: #test,url:{% url daemonset_api %}?namespace namespace,toolbar: #toolbarDemo //开启头部工具栏并为其绑定左侧模板,defaultToolbar: [filter, exports, print, { //自定义头部工具栏右侧图标。如无需自定义去除该参数即可title: 提示,layEvent: LAYTABLE_TIPS,icon: layui-icon-tips}],cols: [[{field: name, title: 名称, sort: true},{field: namespace, title: 命名空间,sort: true},{field: desired_number, title: 预期节点数,width: 100},{field: available_number, title: 可用节点数,width: 100},{field: labels, title: 标签,templet: labelsFormat},{field: selector, title: Pod 标签选择器,templet: selecotrFormat},{field: containers, title: 容器, templet: containersFormat},{field: create_time, title: 创建时间,width: 200},{fixed: right, title:操作, toolbar: #barDemo,width: 150}]],page: true,id: dstb});// 标签格式化是一个对象function labelsFormat(d){result ;if(d.labels null){return None} else {for (let key in d.labels) {result span styleborder: 1px solid #d6e5ec;border-radius: 8px key : d.labels[key] /spanbr}return result}}function selecotrFormat(d){result ;for(let key in d.selector) {result span styleborder: 1px solid #d6e5ec;border-radius: 8px key : d.selector[key] /spanbr}return result}function containersFormat(d) {result ;for(let key in d.containers) {result key d.containers[key] br}return result}2.6 StatefulSet
1.查询。 字段名称、命名空间、Service名称、预期副本数、可用副本数、Pod标签选择器、镜像、创建时间 for sts in apps_api.list_namespaced_stateful_set(namespace).items:name sts.metadata.namenamespace sts.metadata.namespacelabels sts.metadata.labelsselector sts.spec.selector.match_labelsreplicas sts.spec.replicasready_replicas (0 if sts.status.ready_replicas is None else sts.status.ready_replicas)#current_replicas sts.status.current_replicasservice_name sts.spec.service_namecontainers {}for c in sts.spec.template.spec.containers:containers[c.name] c.image create_time sts.metadata.creation_timestampds {name: name, namespace: namespace, labels: labels, replicas: replicas,ready_replicas: ready_replicas, service_name: service_name,selector: selector, containers: containers, create_time: create_time}2.删除。
apps_api.delete_namespaced_stateful_set(namespacenamespace, namename)3.数据表格。 table.render({elem: #test,url:{% url statefulset_api %}?namespace namespace,toolbar: #toolbarDemo //开启头部工具栏并为其绑定左侧模板,defaultToolbar: [filter, exports, print, { //自定义头部工具栏右侧图标。如无需自定义去除该参数即可title: 提示,layEvent: LAYTABLE_TIPS,icon: layui-icon-tips}],cols: [[{field: name, title: 名称, sort: true},{field: namespace, title: 命名空间,sort: true},{field: service_name, title: Service名称},{field: replicas, title: 预期副本数,width: 100},{field: ready_replicas, title: 可用副本数,width: 100},{field: labels, title: 标签,templet: labelsFormat},{field: selector, title: Pod 标签选择器,templet: selecotrFormat},{field: containers, title: 容器, templet: containersFormat},{field: create_time, title: 创建时间,width: 200},{fixed: right, title:操作, toolbar: #barDemo,width: 150}]],page: true,id: ststb});// 标签格式化是一个对象function labelsFormat(d){result ;if(d.labels null){return None} else {for (let key in d.labels) {result span styleborder: 1px solid #d6e5ec;border-radius: 8px key : d.labels[key] /spanbr}return result}}function selecotrFormat(d){result ;for(let key in d.selector) {result span styleborder: 1px solid #d6e5ec;border-radius: 8px key : d.selector[key] /spanbr}return result}function containersFormat(d) {result ;for(let key in d.containers) {result key d.containers[key] br}return result}2.7 Pod
1.查询。 字段名称、命名空间、IP地址、标签、容器组、状态、创建时间 for po in core_api.list_namespaced_pod(namespace).items:name po.metadata.namenamespace po.metadata.namespacelabels po.metadata.labelspod_ip po.status.pod_ipcontainers [] # [{},{},{}]status None# 只为None说明Pod没有创建不能调度或者正在下载镜像if po.status.container_statuses is None:status po.status.conditions[-1].reasonelse:for c in po.status.container_statuses:c_name c.namec_image c.image# 获取重启次数restart_count c.restart_count# 获取容器状态c_status Noneif c.ready is True:c_status Runningelif c.ready is False:if c.state.waiting is not None:c_status c.state.waiting.reasonelif c.state.terminated is not None:c_status c.state.terminated.reasonelif c.state.last_state.terminated is not None:c_status c.last_state.terminated.reasonc {c_name: c_name,c_image:c_image ,restart_count: restart_count, c_status: c_status}containers.append(c)create_time po.metadata.creation_timestamppo {name: name, namespace: namespace, pod_ip: pod_ip,labels: labels, containers: containers, status: status,create_time: create_time}2.删除。
core_api.delete_namespaced_pod(namespacenamespace, namename)3.数据表格。
table.render({elem: #test,url:{% url pod_api %}?namespace namespace,toolbar: #toolbarDemo //开启头部工具栏并为其绑定左侧模板,defaultToolbar: [filter, exports, print, { //自定义头部工具栏右侧图标。如无需自定义去除该参数即可title: 提示,layEvent: LAYTABLE_TIPS,icon: layui-icon-tips}],cols: [[{field: name, title: 名称, sort: true},{field: namespace, title: 命名空间,sort: true},{field: pod_ip, title: IP地址},{field: labels, title: 标签, templet: labelsFormat},{field: containers, title: 容器组, templet: containersFormat},{field: status, title: 状态,sort: true, templet: statusFormat},{field: create_time, title: 创建时间},{fixed: right, title:操作, toolbar: #barDemo,width: 250}]],page: true,id: potb
});
// 标签格式化是一个对象
function labelsFormat(d){result ;if(d.labels null){return None} else {for (let key in d.labels) {result span styleborder: 1px solid #d6e5ec;border-radius: 8px key : d.labels[key] /spanbr}return result}
}
function containersFormat(d) {result ;if (d.containers) {for(let key in d.containers) {data d.containers[key];result key : data.c_name data.c_image br 重启次数: data.restart_count br 状态: data.c_status br}return result} else {return None}
}
// 如果status为None使用容器状态显示
function statusFormat(d){result ;if(d.status None){for(let key in d.containers) {result d.containers[key].c_status br}return result} else {return d.status}
}2.8 Service
1.查询。 字段名称、命名空间、类型、集群IP、端口信息、Pod标签选择器、后端Pod、创建时间 for svc in core_api.list_namespaced_service(namespacenamespace).items:name svc.metadata.namenamespace svc.metadata.namespacelabels svc.metadata.labelstype svc.spec.typecluster_ip svc.spec.cluster_ipports []for p in svc.spec.ports: # 不是序列不能直接返回port_name p.nameport p.porttarget_port p.target_portprotocol p.protocolnode_port if type NodePort:node_port br NodePort: %s % p.node_portport {port_name: port_name, port: port, protocol: protocol, target_port:target_port, node_port: node_port}ports.append(port)selector svc.spec.selectorcreate_time svc.metadata.creation_timestamp# 确认是否关联Podendpoint for ep in core_api.list_namespaced_endpoints(namespacenamespace).items:if ep.metadata.name name and ep.subsets is None:endpoint 未关联else:endpoint 已关联svc {name: name, namespace: namespace, type: type,cluster_ip: cluster_ip, ports: ports, labels: labels,selector: selector, endpoint: endpoint, create_time: create_time}2.创建。 name request.POST.get(name,None)namespace request.POST.get(namespace,None)port int(request.POST.get(port,None))target_port int(request.POST.get(target-port,None))labels {}try:for l in request.POST.get(labels,None).split(,):k l.split()[0]v l.split()[1]labels[k] vexcept Exception as e:res {code: 1, msg: 标签格式错误}return JsonResponse(res)type request.POST.get(type,)body client.V1Service(api_versionv1,kindService,metadataclient.V1ObjectMeta(namename),specclient.V1ServiceSpec(selectorlabels,ports[client.V1ServicePort(portport,target_porttarget_port,)],typetype))core_api.create_namespaced_service(namespacenamespace, bodybody)3.删除。
core_api.delete_namespaced_service(namespacenamespace, namename)4.数据表格。
table.render({elem: #test,url:{% url service_api %}?namespace namespace,toolbar: #toolbarDemo //开启头部工具栏并为其绑定左侧模板,defaultToolbar: [filter, exports, print, { //自定义头部工具栏右侧图标。如无需自定义去除该参数即可title: 提示,layEvent: LAYTABLE_TIPS,icon: layui-icon-tips}],cols: [[{field: name, title: 名称, sort: true, width: 150},{field: namespace, title: 命名空间,width: 150, sort: true},{field: type, title: 类型,width: 120, sort: true},{field: cluster_ip, title: 集群IP,width: 100},{field: ports, title: 端口信息,templet: portsFormat},{field: labels, title: 标签, templet: labelsFormat},{field: selector, title: Pod 标签选择器, templet: selecotrFormat},{field: endpoint, title: 后端 Pod},{field: create_time, title: 创建时间},{fixed: right, title:操作, toolbar: #barDemo,width: 150}]],page: true,id: svctb
});
// 标签格式化是一个对象
function labelsFormat(d){result ;if(d.labels null){return None} else {for (let key in d.labels) {result span styleborder: 1px solid #d6e5ec;border-radius: 8px key : d.labels[key] /spanbr}return result}
}
function selecotrFormat(d){result ;for(let key in d.selector) {result span styleborder: 1px solid #d6e5ec;border-radius: 8px key : d.selector[key] /spanbr}return result
}
function portsFormat(d) {result ;for(let key in d.ports) {data d.ports[key];result 名称: data.port_name br 端口: data.port br 协议: data.protocol br 容器端口: data.target_port br}return result
}2.9 Ingress
1.查询。 字段名称、命名空间、HTTP、HTTPS、关联Service、创建时间 for ing in networking_api.list_namespaced_ingress(namespacenamespace).items:name ing.metadata.namenamespace ing.metadata.namespacelabels ing.metadata.labelsservice Nonehttp_hosts Nonefor h in ing.spec.rules:host h.hostpath (/ if h.http.paths[0].path is None else h.http.paths[0].path)service_name h.http.paths[0].backend.service_nameservice_port h.http.paths[0].backend.service_porthttp_hosts {host: host, path: path, service_name: service_name, service_port: service_port}https_hosts Noneif ing.spec.tls is None:https_hosts ing.spec.tlselse:for tls in ing.spec.tls:host tls.hosts[0]secret_name tls.secret_namehttps_hosts {host: host, secret_name: secret_name}create_time ing.metadata.creation_timestamping {name: name, namespace: namespace,labels: labels ,http_hosts: http_hosts,https_hosts: https_hosts, service: service, create_time: create_time
2.创建。 name request.POST.get(name,None)namespace request.POST.get(namespace,None)host request.POST.get(host,None)path request.POST.get(path,/)svc_name request.POST.get(svc_name,None)svc_port int(request.POST.get(svc_port,None))body client.NetworkingV1beta1Ingress(api_versionnetworking.k8s.io/v1beta1,kindIngress,metadataclient.V1ObjectMeta(namename, annotations{nginx.ingress.kubernetes.io/rewrite-target: /}),specclient.NetworkingV1beta1IngressSpec(rules[client.NetworkingV1beta1IngressRule(hosthost,httpclient.NetworkingV1beta1HTTPIngressRuleValue(paths[client.NetworkingV1beta1HTTPIngressPath(pathpath,backendclient.NetworkingV1beta1IngressBackend(service_portsvc_port,service_namesvc_name))]))]))networking_api.create_namespaced_ingress(namespacenamespace, bodybody)3.删除。
networking_api.delete_namespaced_ingress(namespacenamespace, namename)4.数据表格。
table.render({elem: #test,url:{% url ingress_api %}?namespace namespace,toolbar: #toolbarDemo //开启头部工具栏并为其绑定左侧模板,defaultToolbar: [filter, exports, print, { //自定义头部工具栏右侧图标。如无需自定义去除该参数即可title: 提示,layEvent: LAYTABLE_TIPS,icon: layui-icon-tips}],cols: [[{field: name, title: 名称, sort: true, width: 300},{field: namespace, title: 命名空间,width: 200, sort: true},{field: http_hosts, title: HTTP,templet: httpFormat},{field: https_hosts, title: HTTPS,templet: httpsFormat},{field: service, title: 关联 Service, templet: serviceFormat},{field: create_time, title: 创建时间,width: 200},{fixed: right, title:操作, toolbar: #barDemo,width: 150}]],page: true,id: ingtb
});
// 标签格式化是一个对象
function httpFormat(d){return 域名: d.http_hosts.host br 路径: d.http_hosts.path br
}
function httpsFormat(d){if(d.https_hosts ! null){return 域名: d.https_hosts.host br 证书Secret名称: d.https_hosts.secret_name br;} else {return None}
}
function serviceFormat(d) {return 名称: d.http_hosts.service_name br 端口: d.http_hosts.service_port br;
}2.10 PVC
1.查询。 字段名称、命名空间、状态、卷名称、容量、访问模式、存储类、创建时间 for pvc in core_api.list_namespaced_persistent_volume_claim(namespacenamespace).items:name pvc.metadata.namenamespace pvc.metadata.namespacelabels pvc.metadata.labelsstorage_class_name pvc.spec.storage_class_nameaccess_modes pvc.spec.access_modescapacity (pvc.status.capacity if pvc.status.capacity is None else pvc.status.capacity[storage])volume_name pvc.spec.volume_namestatus pvc.status.phasecreate_time pvc.metadata.creation_timestamppvc {name: name, namespace: namespace, lables: labels,storage_class_name: storage_class_name, access_modes: access_modes, capacity: capacity,volume_name: volume_name, status: status, create_time: create_time}2.创建。 name request.POST.get(name, None)namespace request.POST.get(namespace, None)storage_class request.POST.get(storage_class, None)access_mode request.POST.get(access_mode, None)capacity request.POST.get(capacity, None)body client.V1PersistentVolumeClaim(api_versionv1,kindPersistentVolumeClaim,metadataclient.V1ObjectMeta(namename,namespacenamespace),specclient.V1PersistentVolumeClaimSpec(storage_class_namestorage_class, # 使用存储类创建PV如果不用可去掉access_modes[access_mode],resourcesclient.V1ResourceRequirements(requests{storage : capacity})))core_api.create_namespaced_persistent_volume_claim(namespacenamespace, bodybody)2.删除。
core_api.delete_namespaced_persistent_volume_claim(namespacenamespace, namename)3.数据表格。
layui.use(table, function(){var table layui.table;var $ layui.jquery;table.render({elem: #test,url:{% url pvc_api %}?namespace namespace,toolbar: #toolbarDemo //开启头部工具栏并为其绑定左侧模板,defaultToolbar: [filter, exports, print, { //自定义头部工具栏右侧图标。如无需自定义去除该参数即可title: 提示,layEvent: LAYTABLE_TIPS,icon: layui-icon-tips}],cols: [[{field: name, title: 名称, sort: true},{field: namespace, title: 命名空间,sort: true},{field: labels, title: 标签,templet: labelsFormat},{field: status, title: 状态,width: 130},{field: volume_name, title: 卷名称},{field: capacity, title: 容量,width: 130},{field: access_modes, title: 访问模式},{field: storage_class_name, title: 存储类},{field: create_time, title: 创建时间,width: 200},{fixed: right, title:操作, toolbar: #barDemo,width: 150}]],page: true,id: pvctb});// 标签格式化是一个对象function labelsFormat(d){result ;if(d.labels null){return None} else {for (let key in d.labels) {result span styleborder: 1px solid #d6e5ec;border-radius: 8px key : d.labels[key] /spanbr}return result}}2.11 ConfigMap
1.查询. 字段名称、命名空间、数据数量、创建时间 for cm in core_api.list_namespaced_config_map(namespacenamespace).items:name cm.metadata.namenamespace cm.metadata.namespacedata_length (0 if cm.data is None else len(cm.data))create_time cm.metadata.creation_timestampcm {name: name, namespace: namespace, data_length: data_length, create_time: create_time}2.删除。
core_api.delete_namespaced_config_map(namename,namespacenamespace)3.数据表格。
table.render({elem: #test,url:{% url configmap_api %}?namespace namespace,toolbar: #toolbarDemo //开启头部工具栏并为其绑定左侧模板,defaultToolbar: [filter, exports, print, { //自定义头部工具栏右侧图标。如无需自定义去除该参数即可title: 提示,layEvent: LAYTABLE_TIPS,icon: layui-icon-tips}],cols: [[{field: name, title: 名称, sort: true},{field: namespace, title: 命名空间,sort: true},{field: data_length, title: 数据数量},{field: create_time, title: 创建时间},{fixed: right, title:操作, toolbar: #barDemo,width: 150}]],page: true,id: cmtb
});
// 标签格式化是一个对象
function labelsFormat(d){result ;if(d.labels null){return None} else {for (let key in d.labels) {result span styleborder: 1px solid #d6e5ec;border-radius: 8px key : d.labels[key] /spanbr}return result}
}2.12 Secret
1.查询. 字段名称、命名空间、数据数量、创建时间 for secret in core_api.list_namespaced_secret(namespacenamespace).items:name secret.metadata.namenamespace secret.metadata.namespacedata_length (空 if secret.data is None else len(secret.data))create_time secret.metadata.creation_timestampse {name: name, namespace: namespace, data_length: data_length, create_time: create_time}2.删除。
core_api.delete_namespaced_secret(namespacenamespace, namename)3.数据表格.
table.render({elem: #test,url:{% url secret_api %}?namespace namespace,toolbar: #toolbarDemo //开启头部工具栏并为其绑定左侧模板,defaultToolbar: [filter, exports, print, { //自定义头部工具栏右侧图标。如无需自定义去除该参数即可title: 提示,layEvent: LAYTABLE_TIPS,icon: layui-icon-tips}],cols: [[{field: name, title: 名称, sort: true},{field: namespace, title: 命名空间},{field: data_length, title: 数据数量},{field: create_time, title: 创建时间},{fixed: right, title:操作, toolbar: #barDemo,width: 150}]],page: true,id: secrettb
});
// 标签格式化是一个对象
function labelsFormat(d){result ;if(d.labels null){return None} else {for (let key in d.labels) {result span styleborder: 1px solid #d6e5ec;border-radius: 8px key : d.labels[key] /spanbr}return result}
}2.13 优化
1.每个k8s资源都有一个时间默认是UTC进行格式化中国时区
def dt_format(dt):current_datetime dt timedelta(hours8)dt date.strftime(current_datetime, %Y-%m-%d %H:%M:%S)return dt