当前位置: 首页 > news >正文

python开发基础篇1——后端操作K8s API方式

文章目录

  • 一、基本了解
    • 1.1 操作k8s API
    • 1.2 基本使用
  • 二、数据表格展示K8s常见资源
    • 2.1 Namespace
    • 2.2 Node
    • 2.3 PV
    • 2.4 Deployment
    • 2.5 DaemonSet
    • 2.6 StatefulSet
    • 2.7 Pod
    • 2.8 Service
    • 2.9 Ingress
    • 2.10 PVC
    • 2.11 ConfigMap
    • 2.12 Secret
    • 2.13 优化

一、基本了解

操作K8s资源api方式:

  • 原生api
  • 客户端库,python客户端库

K8s支持三种客户端身份认证:

  • HTTPS 证书认证:基于CA证书签名的数字证书认证(kubeconfig文件,默认路径~/.kube/config)
  • HTTP Token认证:通过一个Token来识别用户(ServiceAccount)
  • HTTP Base认证:用户名+密码的方式认证(1.19+已经弃用)

1.1 操作k8s API

1.安装Kubernetes客户端库。

pip install kubernetes -i https://pypi.tuna.tsinghua.edu.cn/simple

在这里插入图片描述

2.基于HTTPS证书认证(kubeconfig)操作k8s API。

常用资源接口类实例化资源
core_api = client.CoreV1Api()namespace,pod,service,pv,pvc
apps_api = client.AppsV1Api()deployment,statefulset,daemonset
networking_api = client.NetworkingV1beta1Api()ingress
storage_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 --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
# 获取用户Token(1.24版本之前)
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
# 获取用户Token(1.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资源,名为qingjun,3个副本数,使用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_version="apps/v1",kind="Deployment",metadata=client.V1ObjectMeta(name=name),spec=client.V1DeploymentSpec(replicas=replicas,selector={'matchLabels': labels},template=client.V1PodTemplateSpec(metadata=client.V1ObjectMeta(labels=labels),spec=client.V1PodSpec(containers=[client.V1Container(name="web",image=image)])),))
try:apps_api.create_namespaced_deployment(namespace=namespace, body=body)   ##创建命令。
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_version="v1",kind="Service",metadata=client.V1ObjectMeta(name=name),spec=client.V1ServiceSpec(selector=selector,ports=[client.V1ServicePort(port=port,target_port=target_port)],type=type)
)
try:core_api.create_namespaced_service(namespace=namespace, body=body)
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常见资源

大致思路:

  1. 使用Layui从接口获取JSON数据,动态渲染表格。
  2. Django准备接口,以JSON格式返回。
  3. 接口类实例化,遍历获取接口数据,取对应字段值,组成一个字典。
  • 资源增删改查采用不同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(name=name)

3.创建资源。

body = client.V1Namespace(api_version="v1",kind="Namespace",metadata=client.V1ObjectMeta(name=ns_name)
)
core_api.create_namespace(body=body)

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 style="border: 1px solid #d6e5ec;border-radius: 8px">' +key + ':' + d.labels[key] +'</span><br>'}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 style="border: 1px solid #d6e5ec;border-radius: 8px">' +key + ':' + d.labels[key] +'</span><br>'}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_version="v1",kind="PersistentVolume",metadata=client.V1ObjectMeta(name=name),spec=client.V1PersistentVolumeSpec(capacity={'storage':capacity},access_modes=[access_mode],nfs=client.V1NFSVolumeSource(server=server_ip,path="/ifs/kubernetes/%s" %mount_path)))core_api.create_persistent_volume(body=body)

3.删除。

core_api.delete_persistent_volume(name=name)

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_seconds=30,initial_delay_seconds=30)readiness_probe = ""if health_readiness == "on":readiness_probe = client.V1Probe(http_get="/",timeout_seconds=30,initial_delay_seconds=30)for dp in apps_api.list_namespaced_deployment(namespace=namespace).items:if name == dp.metadata.name:res = {"code": 1, "msg": "Deployment已经存在!"}return JsonResponse(res)body = client.V1Deployment(api_version="apps/v1",kind="Deployment",metadata=client.V1ObjectMeta(name=name),spec=client.V1DeploymentSpec(replicas=replicas,selector={'matchLabels': labels},template=client.V1PodTemplateSpec(metadata=client.V1ObjectMeta(labels=labels),spec=client.V1PodSpec(containers=[client.V1Container(   # https://github.com/kubernetes-client/python/blob/master/kubernetes/docs/V1Container.mdname="web",image=image,env=[{"name": "TEST", "value": "123"}, {"name": "DEV", "value": "456"}],ports=[client.V1ContainerPort(container_port=80)],# liveness_probe=liveness_probe, # readiness_probe=readiness_probe,resources=resources,)])),))apps_api.create_namespaced_deployment(namespace=namespace, body=body)

3.删除。

apps_api.delete_namespaced_deployment(namespace=namespace, name=name)

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 style="border: 1px solid #d6e5ec;border-radius: 8px">' +key + ':' + d.labels[key] +'</span><br>'}return result}}function selectorFormat(d){result = "";for(let key in d.selector) {result += '<span style="border: 1px solid #d6e5ec;border-radius: 8px">' +key + ':' + d.selector[key] +'</span><br>'}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_seconds=30,initial_delay_seconds=30)readiness_probe = ""if health_readiness == "on":readiness_probe = client.V1Probe(http_get="/",timeout_seconds=30,initial_delay_seconds=30)for dp in apps_api.list_namespaced_daemon_set(namespace=namespace).items:if name == dp.metadata.name:res = {"code": 1, "msg": "DaemonSet已经存在!"}return JsonResponse(res)body = client.V1DaemonSet(api_version="apps/v1",kind="DaemonSet",metadata=client.V1ObjectMeta(name=name),spec=client.V1DeploymentSpec(selector={'matchLabels': labels},template=client.V1PodTemplateSpec(metadata=client.V1ObjectMeta(labels=labels),spec=client.V1PodSpec(containers=[client.V1Container(   # https://github.com/kubernetes-client/python/blob/master/kubernetes/docs/V1Container.mdname="web",image=image,env=[{"name": "TEST", "value": "123"}, {"name": "DEV", "value": "456"}],ports=[client.V1ContainerPort(container_port=80)],# liveness_probe=liveness_probe, # readiness_probe=readiness_probe,resources=resources,)])),))

3.删除。

apps_api.delete_namespaced_daemon_set(namespace=namespace, name=name)

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 style="border: 1px solid #d6e5ec;border-radius: 8px">' +key + ':' + d.labels[key] +'</span><br>'}return result}}function selecotrFormat(d){result = "";for(let key in d.selector) {result += '<span style="border: 1px solid #d6e5ec;border-radius: 8px">' +key + ':' + d.selector[key] +'</span><br>'}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(namespace=namespace, name=name)

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 style="border: 1px solid #d6e5ec;border-radius: 8px">' +key + ':' + d.labels[key] +'</span><br>'}return result}}function selecotrFormat(d){result = "";for(let key in d.selector) {result += '<span style="border: 1px solid #d6e5ec;border-radius: 8px">' +key + ':' + d.selector[key] +'</span><br>'}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 = "None"if c.ready is True:c_status = "Running"elif 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(namespace=namespace, name=name)

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 style="border: 1px solid #d6e5ec;border-radius: 8px">' +key + ':' + d.labels[key] +'</span><br>'}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(namespace=namespace).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(namespace=namespace).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_version="v1",kind="Service",metadata=client.V1ObjectMeta(name=name),spec=client.V1ServiceSpec(selector=labels,ports=[client.V1ServicePort(port=port,target_port=target_port,)],type=type))core_api.create_namespaced_service(namespace=namespace, body=body)

3.删除。

core_api.delete_namespaced_service(namespace=namespace, name=name)

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 style="border: 1px solid #d6e5ec;border-radius: 8px">' +key + ':' + d.labels[key] +'</span><br>'}return result}
}
function selecotrFormat(d){result = "";for(let key in d.selector) {result += '<span style="border: 1px solid #d6e5ec;border-radius: 8px">' +key + ':' + d.selector[key] +'</span><br>'}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(namespace=namespace).items:name = ing.metadata.namenamespace = ing.metadata.namespacelabels = ing.metadata.labelsservice = "None"http_hosts = "None"for 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 = "None"if 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_version="networking.k8s.io/v1beta1",kind="Ingress",metadata=client.V1ObjectMeta(name=name, annotations={"nginx.ingress.kubernetes.io/rewrite-target": "/"}),spec=client.NetworkingV1beta1IngressSpec(rules=[client.NetworkingV1beta1IngressRule(host=host,http=client.NetworkingV1beta1HTTPIngressRuleValue(paths=[client.NetworkingV1beta1HTTPIngressPath(path=path,backend=client.NetworkingV1beta1IngressBackend(service_port=svc_port,service_name=svc_name))]))]))networking_api.create_namespaced_ingress(namespace=namespace, body=body)

3.删除。

networking_api.delete_namespaced_ingress(namespace=namespace, name=name)

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(namespace=namespace).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_version="v1",kind="PersistentVolumeClaim",metadata=client.V1ObjectMeta(name=name,namespace=namespace),spec=client.V1PersistentVolumeClaimSpec(storage_class_name=storage_class,   # 使用存储类创建PV,如果不用可去掉access_modes=[access_mode],resources=client.V1ResourceRequirements(requests={"storage" : capacity})))core_api.create_namespaced_persistent_volume_claim(namespace=namespace, body=body)

2.删除。

core_api.delete_namespaced_persistent_volume_claim(namespace=namespace, name=name)

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 style="border: 1px solid #d6e5ec;border-radius: 8px">' +key + ':' + d.labels[key] +'</span><br>'}return result}}

2.11 ConfigMap

1.查询.

字段:名称、命名空间、数据数量、创建时间

for cm in core_api.list_namespaced_config_map(namespace=namespace).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(name=name,namespace=namespace)

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 style="border: 1px solid #d6e5ec;border-radius: 8px">' +key + ':' + d.labels[key] +'</span><br>'}return result}
}

2.12 Secret

1.查询.

字段:名称、命名空间、数据数量、创建时间

for secret in core_api.list_namespaced_secret(namespace=namespace).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(namespace=namespace, name=name)

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 style="border: 1px solid #d6e5ec;border-radius: 8px">' +key + ':' + d.labels[key] +'</span><br>'}return result}
}

2.13 优化

1.每个k8s资源都有一个时间,默认是UTC,进行格式化中国时区

def dt_format(dt):current_datetime = dt + timedelta(hours=8)dt = date.strftime(current_datetime, '%Y-%m-%d %H:%M:%S')return dt

相关文章:

python开发基础篇1——后端操作K8s API方式

文章目录 一、基本了解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…...

【实践篇】Redis最强Java客户端(一)之Redisson入门介绍

Redisson入门介绍 文章目录 Redisson入门介绍1.1 Redisson简介1.1.1 起源和历史1.1.2 优势和特点1.1.3 与其他Java Redis客户端的比较 1.2 使用和配置1.2.1 依赖和SDK1.2.2 配置文件解析1.2.3 连接池配置 1.3 优雅的让Hash的某个Field过期2. 参考资料3. 源码地址4. Redis从入门…...

掌握AI助手的魔法工具:解密`Prompt`(提示)在AIGC时代的应用(下篇)

前言&#xff1a;在前面的两篇文章中&#xff0c;我们深入探讨了AI助手中的魔法工具——Prompt&#xff08;提示&#xff09;的基本概念以及在AIGC&#xff08;Artificial Intelligence-Generated Content&#xff0c;人工智能生成内容&#xff09;时代的应用场景。在本篇中&am…...

十)Stable Diffussion使用教程:Lora

LoRA 的全称为 Low-Rank Adaptation(低秩适应),是一种在机器学习中使用的方法,用于解决一些特殊问题,尤其是在数据中存在不均匀性的情况下表现较好。 要理解 LoRA,我们首先需要理解两个概念:低秩和适应。 低秩(Low Rank):在数学中,秩(Rank)是一个描述矩阵信息量的…...

kafka学习-消费者

目录 1、消费者、消费组 2、心跳机制 3、消费者常见参数配置 4、订阅 5、反序列化 基本概念 自定义反序列化器 6、位移提交 6.1、自动提交 6.2、手动提交 同步提交 异步提交 7、再均衡 7.1、定义与基本概念 7.2、缺陷 7.3、如何避免再均衡 7.4、如何进行组内分…...

Alibaba(商品详情)API接口

为了进行电商平台 的API开发&#xff0c;首先我们需要做下面几件事情。 1&#xff09;开发者注册一个账号 2&#xff09;然后为每个alibaba应用注册一个应用程序键&#xff08;App Key) 。 3&#xff09;下载alibaba API的SDK并掌握基本的API基础知识和调用 4&#xff09;利…...

OLED透明屏触控:引领未来科技革命的创新力量

OLED透明屏触控技术作为一项颠覆性的创新&#xff0c;正在引领新一轮科技革命。它将OLED显示技术与触摸技术相结合&#xff0c;实现了透明度和触控功能的完美融合。 在这篇文章中&#xff0c;尼伽将通过引用最新的市场数据、报告和行业动态&#xff0c;详细介绍OLED透明屏触控…...

Ubuntu下QT操作Mysql数据库

本篇总结一下一下Ubuntu下QT操作Mysql数据库。 目录 1. 启动Mysql数据库服务器 2.查看QT支持的数据库驱动 3.连接数据库 4. 增加表和记录 5. 删除记录 6. 修改记录 7. 查询记录 8.完整代码和运行效果 常见错误总结&#xff1a; (1) 数据库服务没启动报错信息 (2) 有…...

sqli --【1--10】

Less-1&#xff08;联合查询&#xff09; 1.查看是否有回显 2.查看是否有报错 3.使用联合查询&#xff08;字符注入&#xff09; 3.1判断其列数 3.2 判断显示位置 3.3敏感信息查询 Less-2&#xff08;联合查询&#xff09; 1.查看是否有回显 2.查看是否有报错 3.使用…...

《自然语言处理(NLP)的最新进展:Transformers与GPT-4的浅析》

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

Wireshark 用命令行分析数据包

1&#xff0c;那些情况需要使用命令行 Wireshark一次性提供了太多的信息。使用命令行工具可以限制打印出的信息&#xff0c;最后只显示相关数据&#xff0c;比如用单独一行来显示IP地址。命令行工具适用于过滤数据包捕获文件&#xff0c;并提供结果给另一个支持UNIX管道的工具…...

LVS DR模式负载均衡群集部署

目录 1 LVS-DR 模式的特点 1.1 数据包流向分析 1.2 DR 模式的特点 2 DR模式 LVS负载均衡群集部署 2.1 配置负载调度器 2.1.1 配置虚拟 IP 地址 2.1.2 调整 proc 响应参数 2.1.3 配置负载分配策略 2.2 部署共享存储 2.3 配置节点服务器 2.3.1 配置虚拟 IP 地址 2.3.2…...

探讨前后端分离开发的优势、实践以及如何实现更好的用户体验?

随着互联网技术的迅猛发展&#xff0c;前后端分离开发已经成为现代软件开发的一种重要趋势。这种开发模式将前端和后端的开发工作分开&#xff0c;通过清晰的接口协议进行通信&#xff0c;旨在优化开发流程、提升团队协作效率&#xff0c;并最终改善用户体验。本文将深入探讨前…...

微博一面:JVM预热,你的方案是啥?

说在前面 在40岁老架构师 尼恩的读者社区(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如微博、阿里、汽车之家、极兔、有赞、希音、百度、网易、滴滴的面试资格&#xff0c;遇到一几个很重要的面试题&#xff1a; JVM预热&#xff0c;你的方案是啥&#xff1f;Springb…...

open与fopen的区别

1. 来源 从来源的角度看&#xff0c;两者能很好的区分开&#xff0c;这也是两者最显而易见的区别&#xff1a; open是UNIX系统调用函数&#xff08;包括LINUX等&#xff09;&#xff0c;返回的是文件描述符&#xff08;File Descriptor&#xff09;&#xff0c;它是文件在文件…...

Unity记录一些glsl和hlsl的着色器Shader逆向代码

以下内容一般基于 GLSL 300 之后 以下某些代码行&#xff0c;是“伪代码“&#xff0c;绝大部分是renderDoc 逆向产生标准代码 本人OpenlGL零基础&#xff0c;也不打算重头学 目录 Clip&#xff08;&#xff09; 剔除函数 discard; FS最终颜色输出 out 和最终颜色相加方程…...

基于Sentinel的微服务保护

前言 Sentinel是Alibaba开源的一款微服务流控组件&#xff0c;用于解决分布式应用场景下服务的稳定性问题。Sentinel具有丰富的应用场景&#xff0c;它基于流量提供一系列的服务保护措施&#xff0c;例如多线程秒杀情况下的系统承载&#xff0c;并发访问下的流量控制&#xff…...

Collectors类作用:

一、Collectors类&#xff1a; 1.1、Collectors介绍 Collectors类&#xff0c;是JDK1.8开始提供的一个的工具类&#xff0c;它专门用于对Stream操作流中的元素各种处理操作&#xff0c;Collectors类中提供了一些常用的方法&#xff0c;例如&#xff1a;toList()、toSet()、to…...

LASSO回归

LASSO回归 LASSO(Least Absolute Shrinkage and Selection Operator&#xff0c;最小绝对值收敛和选择算子算法)是一种回归分析技术&#xff0c;用于变量选择和正则化。它由Robert Tibshirani于1996年提出&#xff0c;作为传统最小二乘回归方法的替代品。 损失函数 1.线性回…...

机器学习中的 K-均值聚类算法及其优缺点。

K-均值聚类算法是一种常见的无监督学习算法&#xff0c;它可以将数据集分成 K 个簇&#xff0c;每个簇内部的数据点尽可能相似&#xff0c;而不同簇之间的数据点应尽可能不同。下面详细讲解 K-均值聚类算法的优缺点&#xff1a; 优点&#xff1a; 简单易用&#xff1a;K-均值…...

云计算与虚拟化

一、概念 什么是云计算&#xff1f; 云计算&#xff08;cloud computing&#xff09;是分布式计算的一种&#xff0c;指的是通过网络“云”将巨大的数据计算处理程序分解成无数个小程序&#xff0c;然后&#xff0c;通过多部服务器组成的系统进行处理和分析这些小程序得到结果…...

Linux常见进程类别

目录 常见进程类别 守护进程&精灵进程 任务管理 进程组 作业 作业 | 进程组 会话 w命令 守护进程 守护进程的创建 setsid()函数 daemon()函数 模拟实现daemon函数 前台进程 | 后台进程 僵尸进程 | 孤儿进程 僵尸进程的一些细节 守护进程 | 后台进程 守护…...

智能小车之蓝牙控制并测速小车、wife控制小车、4g控制小车、语音控制小车

目录 1. 蓝牙控制小车 2. 蓝牙控制并测速小车 3. wifi控制测速小车 4. 4g控制小车 5. 语音控制小车 1. 蓝牙控制小车 使用蓝牙模块&#xff0c;串口透传蓝牙模块&#xff0c;又叫做蓝牙串口模块 串口透传技术&#xff1a; 透传即透明传送&#xff0c;是指在数据的传输过…...

指针进阶(一)

指针进阶 1. 字符指针面试题 2. 指针数组3. 数组指针3.1 数组指针的定义3.2 &数组名VS数组名 3.3 数组指针的使用4. 数组传参和指针传参4.1 一维数组传参4.2 二维数组传参4.3 一级指针传参4.4 二级指针传参 前言 指针的主题&#xff0c;我们在初级阶段的《指针》章节已经接…...

c# sql 判断表中是否包含指定字段

你可以使用以下方法来判断一个 SQL 数据库中的表是否包含指定的字段。 首先&#xff0c;你需要连接到数据库&#xff0c;然后执行一条 SQL 查询语句来检查表结构。你可以使用 SELECT 语句和 INFORMATION_SCHEMA.COLUMNS 系统视图来获取表中的所有列信息。 下面是一个示例代码…...

08-JVM垃圾收集器详解

上一篇&#xff1a;07-垃圾收集算法详解 如果说收集算法是内存回收的方法论&#xff0c;那么垃圾收集器就是内存回收的具体实现。 虽然我们对各个收集器进行比较&#xff0c;但并非为了挑选出一个最好的收集器。因为直到现在为止还没有最好的垃圾收集器出现&#xff0c;更加没…...

sql_mode详解

文章目录 一、sql_mode作用二、查询sql_mode三、mysql8默认的mode配置&#xff08;6个默认配置&#xff09;四、常见mode详细解释mysql8默认配置了的mode&#xff08;6个&#xff09;需要自己配置的mode&#xff08;4个&#xff09; 五、设置sql_mode&#xff08;一旦设置了&am…...

Vue3的新特性总结

一、Vue3 里 script 的三种写法 首先&#xff0c;Vue3 新增了一个叫做组合式 api 的东西&#xff0c;英文名叫 Composition API。因此 Vue3 的 script 现在支持三种写法。 1、最基本的 Vue2 写法 <template><div>{{ count }}</div><button click"…...

【Node】Mac多版本Node切换

1、查看当前电脑是否安装node node -v或者查看当前电脑通过brew安装的node路径 ls /usr/local/Cellar/node*2、查看可安装的node brew search node3、安装其他版本node 下载需要安装的node版本 brew install node144、brew切换node版本 假设之前的版本是18&#xff0c;需…...

Apache POI

POI介绍 Apache POI是用Java编写的免费开源的跨平台的Java API&#xff0c; Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能&#xff0c; 其中使用最多的就是使用POI操作Excel文件。 maven坐标&#xff1a; <dependency><groupId>org.apa…...

济宁网站运营/网页模板网站

“Bug总归会有解决的那一天&#xff0c;但是女生真的搞不定啊&#xff01;” 每到5.20&#xff0c;怎么讨女友欢心就成了老大难的问题。也许是和代码相处太久&#xff0c;很多程序员常常调侃自己已经丧失了哄女孩的能力。 为了表达爱意&#xff0c;程序员们使尽浑身解数&#…...

淘宝官网首页入口手机/首页关键词优化价格

速度慢有很多种情况&#xff0c;比如 DNS解析CDN&#xff08;可能用了国外的cdn&#xff0c;也会导致很慢的&#xff09;服务器IO&#xff08;阿里云的io做的不是很好&#xff0c;频繁的操作io&#xff0c;可能很慢&#xff09;数据库当然跟访问用户的网络也有关系 可以仔细排…...

网站 手机网站/惠州百度关键词优化

微信小程序接入腾讯云IM即时通讯&#xff08;会话列表之未读消息&#xff0c;显示最新一条消息开发步骤&#xff09; 1.未读消息思路 首先&#xff0c;获取未读消息第一步就是要先能接收到对方发送的信息&#xff0c;也就是要在官方api中给的监听新消息事件做处理。先看下图需…...

wordpress首页图文轮播/seo平台有哪些

废话不多说&#xff0c;直接切入主题&#xff0c;百度网盘文件怎么核电脑文件同步&#xff1f;如果你还在复制粘贴的话&#xff0c;那也太浪费时间啦&#xff0c;今天给大家介绍一个简单的操作方式&#xff0c;可以实现百度网盘文件和电脑文件实时同步。 1.下载安装FileYee 首…...

湛江市建网站/微商软文大全

由于信道管理器在客户端和服务端所起的不同作用&#xff0c;分为信道监听器和信道工厂。和服务端的信道监听其相比&#xff0c;处于客户端的信道工厂显得简单。从名称就可以看得出来&#xff0c;信道工厂的作用就是单纯的创建用于消息发送的信道。我们先来看看与信道工厂相关的…...

网站建设 解决方案/最近三天的国内新闻

本文为大家分享了mysql 5.7.18 MSI安装教程&#xff0c;供大家参考&#xff0c;具体内容如下1.下载&#xff1a;官网地址可以看到note32位和64位下载是一样的2.双击下载的文件3.安装页面4选择安装类型(选择full后续检查需求有问题&#xff0c;可以直接选custom&#xff0c;注意…...