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- v1clientConfig:# 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>.svcservice:namespace: my-namespacename: my-webhookpath: /mutate/v1 #指定请求地址port: 443 #端口默认是443可以不配置failurePolicy: FailmatchPolicy: Exact #精确匹配name: webhooktest.liuyijiang.com #名称随意但是必须是域名格式namespaceSelector:matchLabels:my-web-inject: enabled #必须匹配标签为my-web-inject=enabled的命名空间内的资源才会被拦截rules:- apiGroups:- ""apiVersions: #匹配的版本- v1operations: #拦截CREATE操作- CREATEresources: #拦截执行类型是pod- podsscope: '*' #所有命名空间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- v1clientConfig:# CA根证书内容caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tL省略 # 只支持https请求url: "https://webhooktest.liuyijiang.com/mutate/v1" #webhook web服务访问的地址failurePolicy: FailmatchPolicy: Exact #精确匹配name: webhooktest.liuyijiang.com #名称随意但是必须是域名格式namespaceSelector:matchLabels:my-web-inject: enabled #必须匹配标签为my-web-inject=enabled的命名空间内的资源才会被拦截rules:- apiGroups:- ""apiVersions:- v1operations: #拦截CREATE操作- CREATEresources: #拦截执行类型是pod- podsscope: '*' #所有命名空间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); //创建一个UUIDresponse.put("allowed", true); //准入response.put("patchType", "JSONPatch"); //类型是JSONPatchresponse.put("patch", patch); //base64后的patchadmissionReview.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-testnamespace: webhook-ns
spec: # 容器配置 containers: - image: registry.cn-hangzhou.aliyuncs.com/jimliu/user-service:v3imagePullPolicy: IfNotPresent #Alwaysname: user-serviceports: - containerPort: 5555name: httpprotocol: 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-deploynamespace: my-in-webhook
spec:replicas: 1selector:matchLabels: app: webhook-pod template:metadata:labels:app: webhook-pod spec: imagePullSecrets:- name: myaliyunsecretcontainers:- name: webhook-run-containerimage: registry.cn-hangzhou.aliyuncs.com/jimliu/webhook:v1imagePullPolicy: IfNotPresent #Alwaysports: - containerPort: 443 protocol: TCP name: http ---apiVersion: v1
kind: Service
metadata:name: my-service-webhooknamespace: my-in-webhook
spec:ports:- protocol: TCPport: 443targetPort: 443name: httpselector: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- v1clientConfig:# CA根证书内容caBundle: LS0tLS1CRUdJTiBDRVJUS略..# 只支持https请求service:name: my-service-webhook # service的名称namespace: my-in-webhook #service所在的命名空间path: /mutate/v1 #指定请求地址port: 443 #端口默认是443可以不配置failurePolicy: FailmatchPolicy: Exact #精确匹配name: my-service-webhook.my-in-webhook.svc #名称随意但是必须是域名格式namespaceSelector:matchLabels:my-web-inject: enabled #必须匹配标签为my-web-inject=enabled的命名空间内的资源才会被拦截rules:- apiGroups:- ""apiVersions: #匹配的版本- v1operations: #拦截CREATE操作- CREATEresources: #拦截执行类型是pod- podsscope: '*' #所有命名空间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
相关文章:

k8s Webhook 使用java springboot实现webhook 学习总结
k8s Webhook 使用java springboot实现webhook 学习总结 大纲 基础概念准入控制器(Admission Controllers)ValidatingWebhookConfiguration 与 MutatingWebhookConfiguration准入检查(AdmissionReview)使用Springboot实现k8s-Web…...

JS逆向之猿人学爬虫第20题-wasm
文章目录 题目地址sign参数分析python算法还原往期逆向文章推荐题目地址 https://match.yuanrenxue.cn/match/20第20题被置顶到了第1页,题目难度 写的是中等 算法很简单,就一个标准的md5算法,主要是盐值不确定, 而盐值就在wasm里面,可以说难点就在于wasm分析 sign参数分…...

【双指针优化DP】The 2022 Hangzhou Normal U Summer Trials H
Problem - H - Codeforces 题意: 思路: 首先很明显是DP 因为只有1e6个站点,因此可以以站点作为阶段 注意到K很小,因此可以尝试把这个当作第二维 设dp[i][j]为到达第i个站点,已经花了j元钱的最小步数 然后就想了一…...
[论文笔记] LLM数据集——金融数据集
一、chatglm_金融 ModelScope 魔搭社区 请将modelscope sdk升级到v1.7.2rc0,执行: pip3 install "modelscope1.7.2rc0" -f https://modelscope.oss-cn-beijing.aliyuncs.com/releases/repo.html # 方式1 git clone http://www.modelscope…...

在亚马逊平台,如何有效举报违规行为?
众所周知,在每个行业都有一些违规现象,甚至这些违规现象还会给自己带来利益方面的损失,一旦触犯到自己的利益的话,那自己是需要想办法解决的,想办法规避。 就拿开亚马逊店铺来说,比较容易遇到的就是产品侵…...

深度学习入门教学——神经网络
深度学习就是训练神经网络。 1、神经网络 举个最简单的例子,以下是一个使用线性回归来预测房屋价格的函数。这样一个用于预测房屋价格的函数被称作是一单个神经元。大一点的神经网络,就是将这些单个神经元叠加起来。例如:神经网络根据多个相…...
阿里Java开发手册~OOP 规约
1. 【强制】避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成 本,直接用 类名 来访问即可。 2. 【强制】所有的覆写方法,必须加 Override 注解。 说明: getObject() 与 get 0 bject() 的问题。…...

【Mysql数据库面试01】内连接 左连接 右连接 全连接
【Mysql数据库】内连接 左连接 右连接 全连接 0.准备1.内连接1.1 SQL(不带where)1.2 SQL(带where)1.3总结 2.左连接2.1SQL(不带where)2.2SQL(带where)2.3总结 3.右连接3.1 SQL(不带where&#x…...

事务隔离:为什么你改了我还看不见
前提概要 你肯定不陌生,和数据库打交道的时候,我们总是会用到事务。最经典的例子就 是转账,你要给朋友小王转 100 块钱,而此时你的银行卡只有 100 块钱。 转账过程具体到程序里会有一系列的操作,比如查询余额、做加减法…...

吴恩达ChatGPT《LangChain Chat with Your Data》笔记
文章目录 1. Introduction2. Document Loading2.1 Retrieval Augmented Generation(RAG)2.2 Load PDFs2.3 Load YouTube2.4 Load URLs2.5 Load Notion 3. Document Splitting3.1 Splitter Flow3.2 Character Splitter3.3 Token Splitter3.4 Markdown Spl…...

https和http有什么区别
https和http有什么区别 简要 区别如下: https的端口是443.而http的端口是80,且二者连接方式不同;http传输时明文,而https是用ssl进行加密的,https的安全性更高;https是需要申请证书的,而h…...

振弦采集仪及在线监测系统完整链条的岩土工程隧道安全监测
振弦采集仪及在线监测系统完整链条的岩土工程隧道安全监测 近年来,随着城市化的不断推进和基础设施建设的不断发展,隧道建设也日益成为城市交通发展的必需品。然而,隧道建设中存在着一定的安全隐患,如地质灾害、地下水涌流等&…...

linux基础学习
1.day1 2.day2 1、VIM配置; 2、安装SSH,调用putty接入终端; 3、shell命令; *:匹配任意长度的字符 ?:匹配一个长度的字符 [...]:匹配其中指定的一个字符 [-]:匹配指定…...
android 前端常用布局文件升级总结(二)
问题一: android:name“android.support.v4.content.FileProvider” 报红 问题解决方案: 把xml布局文件里面: android.support.v4.content.FileProvider 更换成 androidx.core.content.FileProvider 问题二: android.support.design.wid…...

Linux复习——基础知识
作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页 1. 有关早期linux系统中 sysvin的init的7个级别描述正确的是( )[选择1项] A. init 1 关机状态 B. init 2 字符界面多用户模式 …...

【数据结构】实验三:链表
实验三链表 一、实验目的与要求 1)熟悉链表的类型定义; 2)熟悉链表的基本操作; 3)灵活应用链表解决具体应用问题。 二、实验内容 1)请设计一个单链表的存储结构,并实现单链表中基本运算算…...
第4集丨webpack 江湖 —— loader的安装和使用
目录 一、loader简介1.1 使用 loader1.1.1 配置文件方式1.1.2 内联方式 1.2 loader 特性1.3 解析 loader1.4 命名规范 二、css loader的安装和使用2.1 安装2.2 配置2.3 测试 三、 less-loader 的安装和使用3.1 安装3.2 配置3.3 测试3.4 附件3.4.1 webpack.config.js3.4.2 index…...

【Lua学习笔记】Lua进阶——协程
文章目录 协程协程的定义和调度StatusRunning 协程 协程是一种并发操作,相比于线程,线程在执行时往往是并行的,并且线程在创建销毁执行时极其消耗资源,并且过长的执行时间会造成主进程阻塞。而协程可以以并发时轮值时间片来执行&…...

亚马逊云科技纽约峰会,充分释放数据价值和生成式AI的潜力
生成式AI将深刻改变每个公司的运营方式,标志着人工智能技术发展的新转折点。亚马逊云科技昨日在纽约峰会上宣布,推出七项生成式AI新功能,进一步降低了生成式AI的使用门槛,让无论是业务用户还是开发者都能从中受益。借助这些新功能…...

什么是 web3?
在百度搜索引擎输入 “Web3”、“大厂”。跳出来基本都是这样的标题. 以及如今的互联网行业 “哀鸿遍野”,不仅内卷,还裁员。然后掀起一阵风,猛吹 Web3 的好,数据回归用户……最后再 “威逼利诱” 一下,Web3 就是 20 年…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...

Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...