k8s Webhook 使用java springboot实现webhook 学习总结

k8s Webhook 使用java springboot实现webhook 学习总结

大纲

  • 基础概念
  • 准入控制器(Admission Controllers)
  • ValidatingWebhookConfiguration 与 MutatingWebhookConfiguration
  • 准入检查(AdmissionReview)
  • 使用Springboot实现k8s-Webhook
  • 证书创建
  • 创建MutatingWebhookConfiguration 资源
  • java代码编写
  • 测试部署Pod
  • 将Webhook部署在k8s集群内部

基础概念

Webhook就是一种HTTP回调,很多软件都支持webhook,例如 以前的文章中提到的graylog 也可以使用webhook进行通知。kubernetes也支持Webhook,例如istio就是通过 Mutating webhooks 来自动将Envoy这个 sidecar 容器注入到 Pod 中去的。

kubernetes利用webhook可以实现类似Java Web Filter的功能,拦截对资源的操作请求。 将操作增强或者拦截验证

例如
创建一个Pod,可以对这个操作添加额外的配置,比如添加标签,添加容器,添加挂载等,或者验证Pod操作是不是满足某些要求,不满足则不执行等

kubernetes实现Webhook主要是利用的 动态准入控制 实现

准入控制器

kubernetes 支持多种准入控制器例如:

  • LimitRanger
  • NamespaceExists
  • NodeRestriction
  • …略 详细见准入控制器
  • MutatingAdmissionWebhook
  • ValidatingAdmissionWebhook

准入控制过程分为两个阶段

  • 第一阶段,运行变更准入控制器。
  • 第二阶段,运行验证准入控制器。

注意:某些控制器既是变更准入控制器又是验证准入控制器。

利用 –enable-admission-plugins 可以添加准入控制器,多个控制器使用,号分开

在这里插入图片描述

--disable-admission-plugins 配置可以关闭控制器

MutatingAdmissionWebhook & ValidatingAdmissionWebhook 准入控制器

要实现kubernetes的webhook主要是 MutatingAdmissionWebhook 与 ValidatingAdmissionWebhook 这两个准入控制器

  • ValidatingAdmissionWebhook准入控制器 主要作用就是对操作做验证性质的准入

  • MutatingAdmissionWebhook准入控制器 主要作用就是对操作做修改性质的准入

    例如:
    想在操作资源之前进行修改(Mutating Webhook),比如增加Container或者修改部署的一些属性
    想在操作资源之前进行校验(Validating Webhook),不满足条件的资源直接拒绝并给出相应信息

整体的执行流程如下图

在这里插入图片描述

本次测试的k8s 集群版本1.17默认是开启了MutatingAdmissionWebhook 与 ValidatingAdmissionWebhook 准入控制器,如果未开启需要添加这两个控制

在master节点的 /etc/kubernetes/manifests文件夹下修改 kube-apiserver.yaml后 api-server会自动重启

在这里插入图片描述

ValidatingWebhookConfiguration 与 MutatingWebhookConfiguration

前面提到的MutatingAdmissionWebhook & ValidatingAdmissionWebhook 准入控制器作用是开启准入的webhook调用。但如何调用,哪些资源允许调用则是由ValidatingWebhookConfiguration 与 MutatingWebhookConfiguration来配置

以MutatingWebhookConfiguration为例,可以配置如下条件

  • 请求webhook服务的地址路径
  • 匹配的k8s资源类型
  • …略

以下是一个简单的MutatingWebhookConfiguration配置文件

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration #类型
metadata: 
  name: my-test-webhook1 #创建MutatingWebhookConfiguration 的名称
webhooks:
- admissionReviewVersions:  #指定可接受的 AdmissionReview 对象版本 这里支持v1beta1 v1
  - v1beta1
  - v1
  clientConfig:
    # CA根证书内容 需要base64编码
    caBundle: JBRUN3YR..
    # 只支持https请求
    # 配置k8s webhook准入器调用的 webhook服务地址(部署在k8s集群外部)
    url: "https://webhooktest.liuyijiang.com/mutate/v1"  #webhook web服务访问的地址
   
    # 注意 url和service不能同时存在
    # webhook服务部署在k8s集群内部可以使用service的方式访问
    # service请求域名为 <servicename>.<namespace>.svc
    service:
        namespace: my-namespace
        name: my-webhook
        path: /mutate/v1  #指定请求地址
        port: 443  #端口默认是443可以不配置
  failurePolicy: Fail
  matchPolicy: Exact #精确匹配
  name: webhooktest.liuyijiang.com #名称随意但是必须是域名格式
  namespaceSelector:
    matchLabels:
      my-web-inject: enabled  #必须匹配标签为my-web-inject=enabled的命名空间内的资源才会被拦截
  rules:
  - apiGroups:
    - ""
    apiVersions: #匹配的版本
    - v1
    operations:  #拦截CREATE操作
    - CREATE
    resources:  #拦截执行类型是pod
    - pods
    scope: '*'  #所有命名空间
  sideEffects: None  #配置是否有副作用,None表示调用 Webhook 没有副作用
  timeoutSeconds: 30 #请求超时时间

更多详细配置见Webhook 配置

注意:使用k8s的webhook功能需要提前配置ValidatingWebhookConfiguration 或 MutatingWebhookConfiguration

准入检查(AdmissionReview)

当配置好ValidatingWebhookConfiguration 或 MutatingWebhookConfiguration后,满足条件的kubernetes资源操作就会触发webhook动作。

k8s会对配置中的地址(url中配置的地址或者service配置的地址)发送POST请求。请求的Content-Type为application/json,内容则是一个AdmissionReview json字符串。

我们的程序需求对AdmissionReview json字符串中的内容做分析修改操作完成自己的业务

具体的AdmissionReview参数可以参考官方文档Webhook 请求与响应

一个整体的k8s webhook调用流程如下

在这里插入图片描述

使用springboot实现k8s-Webhook

Webhook只是一个k8s执行准入阶段后会调用的一个http地址而已,所以只要按照k8s-Webhook标准的输入和输出实现的一个web项目都可以作为一个Webhook

这里使用java语言来开发测试

web项目可以部署在k8s集群外部也可以部署在集群内部,但k8s访问Webhook必须是https的请求!

在配置动态准入的时候可以有如下两种方式

  • 在k8s集群内部

    以下配置使用service访问集群内部的webhook
    clientConfig:
    service:
    name: istiod
    namespace: istio-system
    path: /inject
    port: 443

  • 在k8s集群外部

    以下配置使用url地址访问集群外部的webhook
    clientConfig:
    url: “https://webhooktest.medcrab.com/mutate”

开发前准备:

  • 1 确保k8s集群启用 MutatingAdmissionWebhook控制器,通常是已经启用的
  • 2 确保启用了 admissionregistration.k8s.io/v1 API

本例子的k8s集群使用 1.17版本,默认已开启支持

在这里插入图片描述

此例子实现一个动态的修改Pod的标签的Webhook,并且webhook部署在集群外部,主要功能如下

当部署pod的时候自动的给pod添加一个新的标签,可以基于此例子扩展,例如动态的添加新的容器用于监控(类似istio的边车模式)

step1 证书创建

k8s访问Webhook必须是https的请求,所以我们需要先准备对应的证书让我们的springboot项目支持https访问

如果有权威机构(花钱买的)签署证书则可以直接使用此证书来部署程序,否则就需要自己制作自签名证书

先定义一个将使用的域名例如 webhooktest.liuyijiang.com 后续请求都使用这个域名访问,我们需要使用根证书对此域名签名

这里将使用cfssl工具来创建证书,关于证书的制作可以参考此文章 使用cfssl为程序添加https证书

准备根证书

首先使用cfssl 创建根证书,这个根证书后续会用在1 创建域名签名证书 2配置webhook的caBundle

ca-csr.json 内容如下

{
    "CN": "LYJCA", 
    "key": {
        "algo": "rsa", 
        "size": 2048  
    },
    "names": [
        {
             "C": "CN", 
             "L": "Chengdu", 
             "ST": "Sichuan", 
             "O": "liuyjCA", 
             "OU": "System" 
        }
    ]
}

使用命令 cfssl gencert -initca ca-csr.json | cfssljson -bare ca 创建CA根证书
在这里插入图片描述

得到ca.pem(根证书) ca-key.pem(根证书私钥)

用根证书给域名签发

使用生成的ca.pem ca-key.pem 对webhooktest.liuyijiang.com域名签名

ca-config.json 与 webhooktest.liuyijiang.com-csr.json  内容如下

ca-config.json

{
    "signing":{
        "default":{
            "expiry":"8760h" //指定了证书的有效期
        },
        "profiles":{//配置策略
            "mytest":{ //配置一个名称为mytest的策略
                "expiry":"8760h", //指定了证书的有效期
                "usages":[
                    "signing",   //表示该证书可用于签名其它证书
                    "key encipherment",
                    "server auth",  //  client端(客户端) 可以用该 CA 对 server 提供的证书进行验证
                    "client auth"   //  server端(服务端) 可以用该 CA 对 client 提供的证书进行验证
                ]
            }
        }
    }
}

webhooktest.liuyijiang.com-csr.json

{
 "CN":"liuyijiang.com",
 "hosts":[
   "webhooktest.liuyijiang.com"
 ],
 "key":{
    "algo":"rsa",
     "size":2048
  },
  "names":[
    {
      "C": "CN",
      "L": "Chengdu",
      "ST": "Sichuan",
      "O": "liuyijiang.com",
      "OU": "System"
    }
  ]
}

使用命令 cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=mytest webhooktest.liuyijiang.com-csr.json | cfssljson -bare webhooktest.liuyijiang.com

在这里插入图片描述

得到webhooktest.liuyijiang.com.pem(证书) webhooktest.liuyijiang.com-key.pem(证书私钥)

springboot项目开启https

springboot目前是不支持.pem证书的,需要把刚才创建的.pem证书转换为p12

使用 openssl命令进行证书转换

命令格式
openssl pkcs12 -export -in "待转换的证书文件" -inkey "待转换的私钥文件" -out "指定生成的p12证书文件"

使用命令 openssl pkcs12 -export -in webhooktest.liuyijiang.com.pem -inkey webhooktest.liuyijiang.com-key.pem -out key.p12 注意输入自定义密码(例如123456)

在这里插入图片描述

得到key.p12 证书

将key.p12证书放入到项目的src/main/resources文件夹下,这样只需要修改项目的application.properties文件加入配置即可开启https

server.port=443
server.ssl.protocol=TLS
server.ssl.key-store=classpath:key.p12
server.ssl.key-store-password=123456
server.ssl.key-store-type=PKCS12

在这里插入图片描述

验证证书生效

启动springboot项目,修改host文件将 webhooktest.liuyijiang.com 域名映射到127.0.0.1

在这里插入图片描述

参考 使用cfssl为程序添加https证书 将刚才的CA根证书放到浏览器的受信根证书里重启浏览器后访问

在这里插入图片描述

证书验证成功

到此证书的配置完成

step2 创建MutatingWebhookConfiguration 资源

因为需要在准入阶段动态的修改 Pod配置,所以需要使用MutatingWebhookConfiguration

MutatingWebhookConfiguration配置文件webhook1.yaml内容如下

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata: 
  name: my-test-webhook1 #创建MutatingWebhookConfiguration 的名称
webhooks:
- admissionReviewVersions:  #指定可接受的 AdmissionReview 对象版本 这里支持v1beta1 v1
  - v1beta1
  - v1
  clientConfig:
    # CA根证书内容
    caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tL省略  
    # 只支持https请求
    url: "https://webhooktest.liuyijiang.com/mutate/v1" #webhook web服务访问的地址
  failurePolicy: Fail
  matchPolicy: Exact #精确匹配
  name: webhooktest.liuyijiang.com #名称随意但是必须是域名格式
  namespaceSelector:
    matchLabels:
      my-web-inject: enabled  #必须匹配标签为my-web-inject=enabled的命名空间内的资源才会被拦截
  rules:
  - apiGroups:
    - ""
    apiVersions:
    - v1
    operations:  #拦截CREATE操作
    - CREATE
    resources:  #拦截执行类型是pod
    - pods
    scope: '*'  #所有命名空间
  sideEffects: None  #配置是否有副作用,None表示调用 Webhook 没有副作用
  timeoutSeconds: 30 #请求超时时间

注意:caBundle 内容是一个用 PEM 编码的 CA 证书,用于校验 Webhook 的服务器证书

这里就是使用开始创建的CA证书,可以把k8s-apiserver理解成一个浏览器,当访问webhooktest.liuyijiang.com时需要戴上一个根证书来确保webhook服务的证书正确	
注意:如果webhook服务的证书是自签名证书则需要配置caBundle指定为CA根证书,如果webhook服务的证书是权威机构(花钱买的)签署证书则可以不用配置caBundle

使用cat ca.pem | base64 -w 0 将根证书base64编码

在这里插入图片描述

注意:webhooktest.liuyijiang.com是一个自建的一个域名,需要在k8s master节点上配置域名映射

192.168.0.204为我本机ip地址

在这里插入图片描述

域名能够ping通

在这里插入图片描述

curl  --cacert ca.pem https://webhooktest.liuyijiang.com/echo  带证书访问正常

部署MutatingWebhookConfiguration资源

kubectl apply -f webhook1.yaml
kubectl get MutatingWebhookConfiguration

在这里插入图片描述

到此MutatingWebhookConfiguration的配置完成

step3 java代码编写

当K8S请求webhook时会发送 POST请求时,请求的Content-Type为application/json ,内容是一个AdmissionReview 对象的JSON序列化字符串

AdmissionReview的内容可以参考 https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers/#webhook-request-and-response

可以根据AdmissionReview request的kind实现自己的业务逻辑

代码编写很简单需要注意以下关键点

  • 1 controller中的mapping必须支持POST请求
  • 2 注意JSONPatch对字段的操作,需要base64 JSONPatch的操作方式
  • 3 响应也必须是一个Content-Type为application/json并且一个包含 AdmissionReview 对象的 JSON 序列化格式字符串
  • 4 响应中必须要有response字段并且已被有效填充。uid与allowed字符段必须有值

这里贴出一个极简的代码

     /**
      * 实现修改性质的准入 Webhook (Mutating Admission Webhook)	
      */
	@RequestMapping("/mutate/v1")
	public String mutateV1(HttpServletRequest req) throws Exception {
		InputStream in = req.getInputStream();
		/**
		 * 将输入流转成一个字符串  得到一个AdmissionReview(准入审查json字符串) 
		 */
		BufferedInputStream bis = new BufferedInputStream(in);
		byte[] b =  new byte[1024];
		int len = 0;
		StringBuilder sb = new StringBuilder();
		while ((len = bis.read(b)) != -1) {
			sb.append(new String(b, 0, len));
		 }
		System.out.println(sb); 
		/**
		 * 使用fastjson进行字符串转jsonobject
		 * 转换为一个AdmissionReview jsonobject
		 */
		JSONObject admissionReview = JSON.parseObject(sb.toString());
		/**
		 * 
		 * 给pod加一个标签 这是一个jsonpatch 操作
		 * op 代表操作类型
		 * path 代表操作的json路径
		 * value 代表修改的值
		 * 需要把字符串转换为base64编码
		 */
		String patchStr = "[{ \"op\": \"add\", \"path\": \"/metadata/labels\", \"value\": {\"new-label\":\"webhooktest\"} }]";
		Base64 base64= new Base64();  
		String patch = new String(base64.encode(patchStr.getBytes()));
		 
		/**
		 * uid,从发送到 Webhook 的 request.uid 中复制而来
		 */
		String uid = admissionReview.getJSONObject("request").getString("uid");
		
		/**
		 * 创建返回值
		 */
		Map<String,Object> response = new HashMap<>();
		response.put("uid", uid); //创建一个UUID
		response.put("allowed", true); //准入
		response.put("patchType", "JSONPatch"); //类型是JSONPatch
		response.put("patch", patch); //base64后的patch
		
		admissionReview.put("response", response);
		String data = admissionReview.toJSONString();
		System.out.println(data);
		return data;
	}

也可以使用java k8s client库 io.fabric8,该库对k8s各种资源操作做了很好的封装

<dependency>
	    <groupId>io.fabric8</groupId>
	    <artifactId>kubernetes-client</artifactId>
	     <version>6.4.1</version>
	</dependency>

以下代码使用 client库实现

在这里插入图片描述

step4 测试部署Pod

部署Pod之前需要准备一个两个部署文件

  • 1 创建命名空间
  • 2 创建Pod

注意:命名空间需要带有MutatingWebhookConfiguration 中 namespaceSelector匹配的标签

namespace.yaml配置文件如下

apiVersion: v1
kind: Namespace  #类型 指定为Namespace
metadata:
  name: webhook-ns  #namespace的名称 注意只能是英文小写和数字 
  labels: 
    my-web-inject: enabled #注意: 命名空间需要带有namespaceSelector中匹配的标签

Pod部署文件指定命名空间是刚才创建的命名空间(webhook-ns),注意没有配置Pod的标签

pod.yaml配置文件如下

apiVersion: v1
kind: Pod
metadata: 
   name: user-service-webhook-test
   namespace: webhook-ns
spec: 
   # 容器配置       
   containers: 
      - image: registry.cn-hangzhou.aliyuncs.com/jimliu/user-service:v3
        imagePullPolicy: IfNotPresent  #Always
        name: user-service
        ports: 
          - containerPort:  5555
            name: http
            protocol: TCP

测试部署

kubectl apply -f namespace.yaml
kubectl apply -f pod.yaml

在这里插入图片描述

此时本机的eclipse中已经打印出k8s的请求日志

在这里插入图片描述

查看刚才部署的pod,发现已经动态的添加了标签了
kubectl -n webhook-ns get pods -o wide --show-labels

在这里插入图片描述

将Webhook部署在k8s集群内部

刚才的例子是将webhook部署在集群外部的方式,下面将测试把将Webhook部署在k8s集群内部,k8s访问内部Webhook使用的是service域名

step1 配置域名

k8s中service的域名默认格式是

<servicename>.<namespace>.svc.<clusterdomain>

使用my-service-webhook作为service的名称,此service后面将部署在my-in-webhook命名空间中!所以service的域名应该是

完整域名 my-service-webhook.my-in-webhook.svc.cluster.local 
简写域名 my-service-webhook.my-in-webhook.svc

k8s在请求webhook是会使用my-service-webhook.my-in-webhook.svc这个域名

step2 给Webhook服务配置证书

我们继续使用上面已经存在的CA根证书 创建Webhook服务的证书

service-csr.json内容如下

{
 "CN":"liuyijiang.com",
 "hosts":[
   "my-service-webhook.my-in-webhook.svc"
 ],
 "key":{
    "algo":"rsa",
     "size":2048
  },
  "names":[
    {
      "C": "CN",
      "L": "Chengdu",
      "ST": "Sichuan",
      "O": "liuyijiang.com",
      "OU": "System"
    }
  ]
}

注意hosts中的域名为my-service-webhook.my-in-webhook.svc

使用命令 cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=mytest service-csr.json | cfssljson -bare service 签名域名证书

得到service.pem(证书) service-key.pem(证书私钥)

使用命令 openssl pkcs12 -export -in service.pem -inkey service-key.pem -out key2.p12

得到key2.p12

在这里插入图片描述

修改配置application.properties

server.port=443
server.ssl.protocol=TLS
server.ssl.key-store=classpath:key2.p12
server.ssl.key-store-password=123456
server.ssl.key-store-type=PKCS12

到此证书配置完成

step3 创建镜像并推送到私库

将项目打包成jar文件制作镜像

docker build -t webhook .
docker tag webhook registry.cn-hangzhou.aliyuncs.com/jimliu/webhook:v1
docker push registry.cn-hangzhou.aliyuncs.com/jimliu/webhook:v1

在这里插入图片描述

到此webhook镜像创建完成

step4 部署webhook到k8s集群

部署配置文件如下deploy.yaml

apiVersion: v1
kind: Namespace  #类型 指定为Namespace
metadata:
  name: my-in-webhook  #namespace的名称 注意只能是英文小写和数字 
  
---  

apiVersion: apps/v1
kind: Deployment
metadata:
   name: webhook-pod-deploy
   namespace: my-in-webhook
spec:
    replicas: 1
    selector:
       matchLabels: 
          app: webhook-pod 
    template:
       metadata:
           labels:
              app: webhook-pod 
       spec:     
            imagePullSecrets:
               - name: myaliyunsecret
            containers:
                - name: webhook-run-container
                  image: registry.cn-hangzhou.aliyuncs.com/jimliu/webhook:v1
                  imagePullPolicy: IfNotPresent  #Always
                  ports: 
                      - containerPort: 443 
                        protocol: TCP 
                        name: http 

---


apiVersion: v1
kind: Service
metadata:
  name: my-service-webhook
  namespace: my-in-webhook
spec:
  ports:
    - protocol: TCP
      port: 443
      targetPort: 443
      name: http
  selector:
    app: webhook-pod 
  type: ClusterIP  

部署webhook

kubectl apply -f deploy.yaml

在这里插入图片描述

pod service 成功部署运行

在这里插入图片描述

到此webhook相关Pod Service部署完成

step5 创建MutatingWebhookConfiguration 资源

与外部webhook不同,内部部署的webhook不使用url而是配置service 其他的都一致

webhook2.yaml内容如下

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata: 
  name: my-test-webhook2 #创建MutatingWebhookConfiguration 的名称
webhooks:
- admissionReviewVersions:  #指定可接受的 AdmissionReview 对象版本 这里支持v1beta1 v1
  - v1beta1
  - v1
  clientConfig:
    # CA根证书内容
    caBundle: LS0tLS1CRUdJTiBDRVJUS略..
    # 只支持https请求
    service:
      name: my-service-webhook # service的名称
      namespace: my-in-webhook  #service所在的命名空间
      path: /mutate/v1  #指定请求地址
      port: 443  #端口默认是443可以不配置
  failurePolicy: Fail
  matchPolicy: Exact #精确匹配
  name: my-service-webhook.my-in-webhook.svc #名称随意但是必须是域名格式
  namespaceSelector:
    matchLabels:
      my-web-inject: enabled  #必须匹配标签为my-web-inject=enabled的命名空间内的资源才会被拦截
  rules:
  - apiGroups:
    - ""
    apiVersions: #匹配的版本
    - v1
    operations:  #拦截CREATE操作
    - CREATE
    resources:  #拦截执行类型是pod
    - pods
    scope: '*'  #所有命名空间
  sideEffects: None  #配置是否有副作用,None表示调用 Webhook 没有副作用
  timeoutSeconds: 30 #请求超时时间

注意:caBundle 还是使用先前创建的CA根证书

部署MutatingWebhookConfiguration

在这里插入图片描述

到此MutatingWebhookConfiguration部署完成

step6 测试效果

kubectl apply -f namespace.yaml
kubectl apply -f pod.yaml

在这里插入图片描述

使用kubectl -n my-in-webhook logs -f webhook-pod-deploy-6bb498fbf6-4jkm9 查看日志

在这里插入图片描述

查看刚才部署的pod,发现已经动态的添加了标签了
kubectl -n webhook-ns get pods -o wide --show-labels

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/48405.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文谈谈Git

"And if forever lasts till now Alright" 为什么要有git&#xff1f; 想象一下&#xff0c;现如今你的老师同时叫你和张三&#xff0c;各自写一份下半年的学习计划交给他。 可是你的老师是一个极其"较真"的人&#xff0c;发现你俩写的学习计划太"水&…

深度剖析APP开发中的UI/UX设计

作为一个 UI/UX设计师&#xff0c;除了要关注 UI/UX设计之外&#xff0c;还要掌握移动开发知识&#xff0c;同时在日常工作中也需要对用户体验有一定的认知&#xff0c;在本次分享中&#xff0c;笔者就针对自己在工作中积累的一些经验来进行一个总结&#xff0c;希望能够帮助到…

软件兼容性测试中需注意的关键问题

在进行软件兼容性测试时&#xff0c;有一些关键问题需要特别注意&#xff0c;以确保测试的准确性和全面性。本文将介绍一些在软件兼容性测试中需注意的关键问题&#xff0c;帮助测试人员更好地进行兼容性测试工作。 首先&#xff0c;测试范围&#xff0c;测试人员需要明确测试的…

pycharm 远程连接服务器并且debug, 支持torch.distributed.launch debug

未经允许&#xff0c;本文不得转载&#xff0c;vx&#xff1a;837007389 文章目录 step1&#xff1a;下载专业版本的pycharmstep2 配置自动同步文件夹&#xff0c;即远程的工程文件和本地同步2.1 Tools -> Deployment -> configuration2.2 设置同步文件夹2.3 同步服务器…

火山引擎DataLeap的Data Catalog系统公有云实践 (下)

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 Data Catalog公有云遇到的挑战 Data Catalog经历了一个从0到1在火山引擎公有云部署并逐步优化和迭代发布10版本的过程&#xff0c;在这个过程中经历不少挑战&#…

SQL语句(三十二)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、SQL语句类型 二、数据库操作 ​三、数据表操作 1. 数据类型 2. 查看 3. 创建 4. 删除 5. 更改 5.1 表 5.2 列 四、数据操作 4.1 增 4.2 删 4.3 改 4.4 查…

HHDESK便捷功能介绍三

1 连接便捷显示 工作中&#xff0c;往往需要设置很多资源连接。而过多的连接设&#xff0c;往往很容易混淆。 在HHDESK中&#xff0c;当鼠标点击连接时&#xff0c;会在下方显示本连接的参数&#xff0c;方便用户查看。 2 日志查看 实际工作中&#xff0c;查看日志是一件很…

JavaSwing+MySQL的在线考试系统

点击以下链接获取源码&#xff1a; https://download.csdn.net/download/qq_64505944/88114390?spm1001.2014.3001.5503 JDK1.8 MySQL5.7 功能&#xff1a;开始做题&#xff0c;上一题&#xff0c;下一题&#xff0c;提交&#xff0c;每题都有时间限制

真实和虚拟相撞,构造的VR展厅特点和优势有哪些?

随着科技的不断发展&#xff0c;VR展厅成为了现代展览的一种全新展现方式&#xff0c;三维立体展厅的设计&#xff0c;让企业、画展、纪念展等可以创造出令人惊叹的虚拟展览空间效果&#xff0c;为用户带来丰富的体验。观众身临其境地感受实体展厅和展品&#xff0c;这种超越了…

【3】-使用@task设置测试用例执行的权重

多个测试链路压测使测试任务按预想的比例执行 locust的task装饰器提供了入参weight&#xff0c;locust执行测试任务时&#xff0c;会根据weight的比例进行分配用户数 from locust import task, HttpUserclass MyTestUser(HttpUser):# test_01 : test_02 3 : 1task(3)def wei…

实景三维在智慧矿山中的应用

项目背景 智慧矿山是以矿山数字化、信息化为前提和基础&#xff0c;对矿山生产、职业健康与安全、技术支持与后勤保障等进行主动感知、自动分析、快速处理&#xff0c;建设智慧矿山&#xff0c;最终实现安全矿山、无人矿山、高效矿山、清洁矿山的建设。 智慧矿山的可视化管理…

postgresql四种逻辑复制的状态

准备 CreateCheckpoint&#xff0c;或者bgwriter启动时&#xff0c;或者创建logicalreplicationslot时都会调用LogStandbySnapshot 记录一个XLOG_RUNNING_XACTS类型的日志。日志中记录了所有提交的事务的xid(HistoricSnapshot) 启动&#xff08;SNAPBUILD_BUILDING_SNAPSHOT&…

linux下i2c调试神器i2c-tools安装及使用

i2c-tools介绍 在嵌入式linux开发中&#xff0c;有时候需要确认i2c硬件是否正常连接&#xff0c;设备是否正常工作&#xff0c;设备的地址是多少等等&#xff0c;这里我们就需要使用一个用于测试I2C总线的工具——i2c-tools。 i2c-tools是一个专门调试i2c的开源工具&#xff…

SpringCloudAlibaba微服务实战系列(三)Sentinel1.8.0+流控

SpringCloudAlibaba–Sentinel Sentinel被称为分布式系统的流量防卫兵&#xff0c;是阿里开源流量框架&#xff0c;从服务限流、降级、熔断等多个纬度保护服务。Sentinel同时提供了简洁易用的控制台&#xff0c;可以看到接入应用的秒级数据&#xff0c;并可以在控制台设置一些…

北航投资已投企业四象科技成功发射三颗卫星

1箭4星&#xff01;2023年7月23日10时50分&#xff0c;我国在太原卫星发射中心使用长征二号丁运载火箭&#xff0c;成功将四象科技“矿大南湖号”SAR遥感卫星、“虹口复兴号”光学遥感卫星、“中电农创号”热红外遥感卫星以及银河航天灵犀03星共4颗卫星发射升空&#xff0c;卫星…

C语言中的函数(超详细)

C语言中的函数&#xff08;超详细&#xff09; 一、函数概述二、C语言中函数的分类1.库函数2.自定义函数三、函数的参数1.实际参数&#xff08;实参&#xff09;2.形式参数&#xff08;形参&#xff09;四、函数的调用1.传值调用2.传址调用五、函数的嵌套调用和链式访问1.嵌套调…

人机交互与人机混合智能的区别

人机交互和人机融合智能是两个相关但不完全相同的概念&#xff1a; 人机交互是指人与计算机之间的信息交流和互动过程。它关注的是如何设计和实现用户友好的界面&#xff0c;以便人们能够方便、高效地与计算机进行沟通和操作。人机交互通常强调用户体验和界面设计&#xff0c;旨…

基于Java+SpringBoot+vue前后端分离新闻推荐系统设计实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

第五章 传输层

第五章 传输层 5.1 运输层的功能 运输层功能&#xff1a; 运输层为应用进程之间提供 端到端的逻辑通信&#xff08;但网络层是为主机之间提供逻辑通信&#xff09;。 运输层还要对收到的报文进行差错检测。 运输层提供面向连接和无连接的服务 ​ 从通信和信息处理的角度看…

linux V4L2子系统——v4l2架构(1)之整体架构

概述 V4L&#xff08;Video for Linux&#xff09;是Linux内核中关于视频设备的API接口&#xff0c;涉及视频设备的音频和视频信息采集及处理、视频设备的控制。V4L出现于Linux内核2.1版本&#xff0c;经过修改bug和添加功能&#xff0c;Linux内核2.5版本推出了V4L2&#xff08…