OpenELB使用分析

前言

OpenELB 是由青云科技开源的云原生负载均衡器,可以在基于裸金属服务器、边缘以及虚拟化的 Kubernetes 环境中使用 LoadBalancer 类型的 Service 对外暴露服务。核心功能包括:

  • BGP 模式和二层网络模式下的负载均衡
  • 基于路由器 ECMP 的负载均衡
  • IP 地址池管理
  • 使用 CRD 进行 BGP 配置

工作原理

Layer2 模式

  • 图中有一个类型为 LoadBalancer 的 Service,其 VIP 为 192.168.0.91(和 k8s 的节点相同网段),后端有两个 pod(分别为 pod1 和 pod2)
  • 安装在 Kubernetes 集群中的 OpenELB 随机选择一个节点(图中为 worker 1)来处理 Service 请求。当局域网中出现 arp request 数据包来查询 192.168.0.91 的 mac 地址的时候,OpenELB 会进行回应(使用 worker 1 的 MAC 地址),此时路由器(也可能是交换机)将 Service 的 VIP 192.168.0.91 和 worker 1 的 MAC 地址绑定,之后所有请求到 192.168.0.91 的数据包都会被转发到 worker1 上
  • Service 流量到达 worker 1 后, worker 1 上的 kube-proxy 将流量转发到后端的两个 pod 进行负载均衡,这些 pod 不一定在 work1 上

主要的工作流程就如同上面描述的一般,但是还有几个需要额外注意的点:

  • 如果 worker 1 出现故障,OpenELB 会重新向路由器发送 APR/NDP 数据包,将 Service IP 地址映射到 worker 2 的 MAC 地址,Service 流量切换到 worker 2
  • 主备切换过程并不是瞬间完成的,中间会产生一定时间的服务中断(具体多久官方也没说,实际上应该是取决于检测到节点宕机的时间加上重新选主的时间)
  • 如果集群中已经部署了多个 openelb-manager 副本,OpenELB 使用 Kubernetes 的领导者选举特性算法来进行选主,从而确保只有一个副本响应 ARP/NDP 请求

BGP 模式(暂未实验,需要支持bgp的路由器)

OpenELB 的 BGP 模式使用的是gobgp实现的 BGP 协议,通过使用 BGP 协议和路由器建立 BGP 连接并实现 ECMP 负载均衡,从而实现高可用的 LoadBalancer。

我们还是借用官网的图来解释一下这个流程,注意 BGP 模式暂不支持 IPv6。

  • 图中有一个类型为 LoadBalancer 的 Service,其 VIP 为 172.22.0.2(和 k8s 的节点不同网段),后端有两个 pod(分别为 pod1 和 pod2)
  • 安装在 Kubernetes 集群中的 OpenELB 与 BGP 路由器建立 BGP 连接,并将去往 172.22.0.2 的路由发布到 BGP 路由器,在配置得当的情况下,路由器上面的路由表可以看到 172.22.0.2 这个 VIP 的下一条有多个节点(均为 k8s 的宿主机节点)
  • 当外部客户端机器尝试访问 Service 时,BGP 路由器根据从 OpenELB 获取的路由,在 master、worker 1 和 worker 2 节点之间进行流量负载均衡。Service 流量到达一个节点后,该节点上的 kube-proxy 将流量转发到后端的两个 pod 进行负载均衡,这些 pod 不一定在该节点上

因为 BGP 需要BGP路由器的支持,就暂时没有搭建,后续会考虑改用另外模式对外访问。

Layer2 Mode实验

配置 ARP 参数

在Layer2模式下,需要为kube-proxy启用strictARP,开启之后 k8s 集群中的 kube-proxy 会停止响应 kube-ipvs0 网卡之外的其他网卡的 arp 请求,让OpenELB处理ARP请求。

strict ARP 开启之后相当于把 将 arp_ignore 设置为 1 并将 arp_announce 设置为 2 启用严格的 ARP,这个原理和 LVS 中的 DR 模式对 RS 的配置一样,可以参考之前的文章中的解释[8]。

strict ARP configure arp_ignore and arp_announce to avoid answering ARP queries from kube-ipvs0 interface

# 查看kube-proxy中的strictARP配置
$ kubectl get configmap -n kube-system kube-proxy -o yaml | grep strictARPstrictARP: false# 手动修改strictARP配置为true
$ kubectl edit configmap -n kube-system kube-proxy
configmap/kube-proxy edited
# 使用命令直接修改并对比不同
$ kubectl get configmap kube-proxy -n kube-system -o yaml | sed -e "s/strictARP: false/strictARP: true/" | kubectl diff -f - -n kube-system
# 确认无误后使用命令直接修改并生效
$ kubectl get configmap kube-proxy -n kube-system -o yaml | sed -e "s/strictARP: false/strictARP: true/" | kubectl apply -f - -n kube-system
# 重启kube-proxy确保配置生效
$ kubectl rollout restart ds kube-proxy -n kube-system
# 确认配置生效
$ kubectl get configmap -n kube-system kube-proxy -o yaml | grep strictARPstrictARP: true
部署 openelb

这里我们还是使用 yaml 进行部署,官方把所有部署的资源整合到了一个文件中,我们还是老规矩先下载到本地再进行部署。

$ wget https://raw.githubusercontent.com/openelb/openelb/master/deploy/openelb.yaml
#已下载openelb源码包,进入deploy目录应用 https://github.com/openelb/openelb
$ cd /openelb-master/deploy
##镜像需要自己拉取,上传到haror
$ vi openelb.yamlimage: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.1.1修改为示例:image: 10.8.59.173:17443/cloud/eastcom.com/openelb/kube-webhook-certgen:v1.1.1
$ kubectl apply -f openelb.yaml
namespace/openelb-system created
customresourcedefinition.apiextensions.k8s.io/bgpconfs.network.kubesphere.io created
customresourcedefinition.apiextensions.k8s.io/bgppeers.network.kubesphere.io created
customresourcedefinition.apiextensions.k8s.io/eips.network.kubesphere.io created
serviceaccount/kube-keepalived-vip created
serviceaccount/openelb-admission created
role.rbac.authorization.k8s.io/leader-election-role created
role.rbac.authorization.k8s.io/openelb-admission created
clusterrole.rbac.authorization.k8s.io/kube-keepalived-vip created
clusterrole.rbac.authorization.k8s.io/openelb-admission created
clusterrole.rbac.authorization.k8s.io/openelb-manager-role created
rolebinding.rbac.authorization.k8s.io/leader-election-rolebinding created
rolebinding.rbac.authorization.k8s.io/openelb-admission created
clusterrolebinding.rbac.authorization.k8s.io/kube-keepalived-vip created
clusterrolebinding.rbac.authorization.k8s.io/openelb-admission created
clusterrolebinding.rbac.authorization.k8s.io/openelb-manager-rolebinding created
service/openelb-admission created
deployment.apps/openelb-manager created
job.batch/openelb-admission-create created
job.batch/openelb-admission-patch created
mutatingwebhookconfiguration.admissionregistration.k8s.io/openelb-admission created
validatingwebhookconfiguration.admissionregistration.k8s.io/openelb-admission created

接下来我们看看部署的CRD 资源,这几个 CRD 资源主要就是方便我们管理 openelb,这也是 OpenELB 相对 MetalLB 的优势。

$ kubectl get crd
NAME                             CREATED AT
bgpconfs.network.kubesphere.io   2022-05-19T06:37:19Z
bgppeers.network.kubesphere.io   2022-05-19T06:37:19Z
eips.network.kubesphere.io       2022-05-19T06:37:19Z
$ kubectl get ns openelb-system -o wide
NAME             STATUS   AGE
openelb-system   Active   2m27s

实际上主要工作的负载就是这两个 jobs.batch 和这一个 deployment

$ kubectl get pods -n openelb-system
root@cloud-173:/home/xuwt/openelb-master/deploy# kubectl get pods -n openelb-system
NAME                               READY   STATUS              RESTARTS   AGE
openelb-admission-create-755w5     0/1     ImagePullBackOff    0          116s
openelb-admission-patch-tkh8w      0/1     ErrImagePull        0          116s
openelb-manager-794999f796-pwlm5   0/1     ContainerCreating   0          116s
NAME                               READY   STATUS      RESTARTS   AGE
openelb-admission-create-57tzm     0/1     Completed   0          5m11s
openelb-admission-patch-j5pl4      0/1     Completed   0          5m11s
openelb-manager-5cdc8697f9-h2wd6   1/1     Running     0          5m11s
$ kubectl get deploy -n openelb-system
NAME              READY   UP-TO-DATE   AVAILABLE   AGE
openelb-manager   1/1     1            1           5m38s
$ kubectl get jobs.batch -n openelb-system
NAME                       COMPLETIONS   DURATION   AGE
openelb-admission-create   1/1           11s        11m
openelb-admission-patch    1/1           12s        11m
指定用于OpenELB的网卡

如果安装了OpenELB的节点有多个NIC,则需要在第2层模式下指定用于OpenELB的NIC。如果节点只有一个NIC,则可以跳过此步骤。

在本例中,安装了OpenELB的master 1节点有两个NIC(eno1 10.8.59.173和eno2 192.168.1.2),我们指定 eno1 用于OpenELB。

运行以下命令注释cloud-173以指定NIC:

kubectl annotate nodes master-1 layer2.openelb.kubesphere.io/v1alpha1="10.200.0.31"
kubectl annotate nodes master-2 layer2.openelb.kubesphere.io/v1alpha1="10.200.0.32"
kubectl annotate nodes master-3 layer2.openelb.kubesphere.io/v1alpha1="10.200.0.33"
创建 EIP(EXTERNAL-IP)

EXTERNAL-IP 就是可以在公网访问的 IP 。在局域网中使用EIP供集群外部访问。这里的EIP对象充当OpenELB的IP地址池,如果你有多个IP,则填写起始IP-结束IP,如果你只有一个IP,则填写一个就好。

接下来我们需要配置 loadbalancerIP 所在的网段资源,这里我们创建一个 Eip 对象来进行定义,后面对 IP 段的管理也是在这里进行。

apiVersion: network.kubesphere.io/v1alpha2
kind: Eip
metadata:# Eip 对象的名称。name: eip-layer2-pool
spec:# Eip 对象的地址池address: 10.200.0.231-10.200.0.232# openELB的运行模式,默认为bgpprotocol: layer2# OpenELB 在其上侦听 ARP/NDP 请求的网卡。该字段仅在protocol设置为时有效layer2。interface: bond0# 指定是否禁用 Eip 对象# false表示可以继续分配# true表示不再继续分配disable: false
status:# 指定 Eip 对象中的IP地址是否已用完。occupied: false# 指定 Eip 对象中有多少个 IP 地址已分配给服务。# 直接留空,系统会自动生成usage:  # Eip 对象中的 IP 地址总数。poolSize: 100# 指定使用的 IP 地址和使用 IP 地址的服务。服务以Namespace/Service name格式显示(例如,default/test-svc)。# 直接留空,系统会自动生成used:  # Eip 对象中的第一个 IP 地址。firstIP: 10.31.88.101# Eip 对象中的最后一个 IP 地址。lastIP: 10.31.88.200ready: true# 指定IP协议栈是否为 IPv4。目前,OpenELB 仅支持 IPv4,其值只能是true.v4: true

配置完成后我们直接部署即可

$ kubectl apply -f openelb/openelb-eip.yaml
eip.network.kubesphere.io/eip-layer2-pool created

部署完成后检查 eip 的状态

$ kubectl get eip
NAME              CIDR                        USAGE   TOTAL
eip-layer2-pool   10.31.88.101-10.31.88.200           100
创建测试服务

然后我们创建对应的服务

apiVersion: apps/v1
kind: Deployment
metadata:labels:name: nginx-31-openelbname: nginx-31-openelb
spec:replicas: 2selector:matchLabels:app: nginx-31-openelbtemplate:metadata:annotations:labels:app: nginx-31-openelbspec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- master-1containers:- name: nginx-openelb-containerimage: 10.200.0.31:17443/cloud/eastcom.com/nginx:latestports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: nginx-service-openelbannotations:lb.kubesphere.io/v1alpha1: openelbprotocol.openelb.kubesphere.io/v1alpha1: layer2eip.openelb.kubesphere.io/v1alpha2: eip-pool-231
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: nginx-31-openelbtype: LoadBalancer

然后我们检查部署状态:

$ kubectl apply -f nginx-fix173-openelb.yaml
deployment.apps/nginx-31-openelb configured
service/nginx-service-openelb unchanged

在集群节点的执行ip neigh命令,可以查看MAC地址表和IP邻居表中,10.200.0.231的mac地址如下:

同时在集群外,不同网段物理机(接入同一个交换机),使用arp广播实验,可以查找到mac地址:

Layer2 工作原理日志检查

我们查看 pod 的日志,可以看到更多的详细信息:

$ kubectl logs -f -n  openelb-system openelb-manager-5cdc8697f9-h2wd6
...省略一堆日志输出...
{"level":"info","ts":1705563860.7568872,"msg":"setup openelb service","service":"default/nginx-service-openelb"}
{"level":"info","ts":1705563860.7570846,"logger":"IPAM","msg":"unAssignIP","args":{"Key":"default/nginx-service-openelb","Addr":"","Eip":"eip-pool-231","Protocol":"layer2","Unalloc":false},"peek":true,"result":{"Addr":"10.200.0.231","Eip":"eip-pool-231","Protocol":"layer2","Sp":{}},"err":null}
{"level":"info","ts":1705563860.8391945,"logger":"arpSpeaker","msg":"map ingress ip","ingress":"10.200.0.231","nodeIP":"10.200.0.32","nodeMac":"ca:09:ad:fb:c7:aa"}
{"level":"info","ts":1705563860.839278,"logger":"arpSpeaker","msg":"send gratuitous arp packet","eip":"10.200.0.231","nodeIP":"10.200.0.32","hwAddr":"ca:09:ad:fb:c7:aa"}
{"level":"info","ts":1705563860.8393674,"logger":"arpSpeaker","msg":"send gratuitous arp packet","eip":"10.200.0.231","nodeIP":"10.200.0.32","hwAddr":"ca:09:ad:fb:c7:aa"}

可以看到 openelb-manager 会持续的监听局域网中的 ARP request 请求,当遇到请求的 IP 是自己 IP 池里面已经使用的 VIP 时会主动响应。如果 openelb-manager 存在多个副本的时候,它们会先使用 k8s 的选主算法来进行选主,然后再由选举出来的主节点进行 ARP 报文的响应。

In Layer 2 mode, OpenELB uses the leader election feature of Kubernetes to ensure that only one replica responds to ARP/NDP requests.

查看 arp 表来确定 MAC 地址从而确定 VIP 所在的节点,

root@master-1:/home/xuwt/openelb# kubectl get svc
NAME                    TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
kubernetes              ClusterIP      10.96.0.1      <none>         443/TCP        4h44m
nginx-service-openelb   LoadBalancer   10.97.40.158   10.200.0.231   80:30267/TCP   54m
root@master-1:/home/xuwt/openelb# ip neigh  | grep 10.200.0
10.200.0.231 dev bond0 lladdr ca:09:ad:fb:c7:aa STALE
OpenELB-manager 高可用

默认情况下,openelb-manager 只会部署一个副本,对于可用性要求较高的生产环境可能无法满足需求,官方也给出了部署多个副本[9]的教程。

官方教程的方式是推荐通过给节点添加 label 的方式来控制副本的部署数量和位置,这里我们将其配置为每个节点都运行一个服务(类似于 daemonset)。首先我们给需要部署的节点打上 labels。

# 我们给集群内的三个节点都打上label
$ kubectl label --overwrite nodes tiny-calico-master-88-1.k8s.tcinternal tiny-calico-worker-88-11.k8s.tcinternal tiny-calico-worker-88-12.k8s.tcinternal lb.kubesphere.io/v1alpha1=openelb
# 查看当前节点的labels
$ kubectl get nodes -o wide --show-labels=true | grep openelb
tiny-calico-master-88-1.k8s.tcinternal    Ready    control-plane,master   16d   v1.23.6   10.31.88.1    <none>        CentOS Linux 7 (Core)   3.10.0-1160.62.1.el7.x86_64   docker://20.10.14   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=tiny-calico-master-88-1.k8s.tcinternal,kubernetes.io/os=linux,lb.kubesphere.io/v1alpha1=openelb,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
tiny-calico-worker-88-11.k8s.tcinternal   Ready    <none>                 16d   v1.23.6   10.31.88.11   <none>        CentOS Linux 7 (Core)   3.10.0-1160.62.1.el7.x86_64   docker://20.10.14   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=tiny-calico-worker-88-11.k8s.tcinternal,kubernetes.io/os=linux,lb.kubesphere.io/v1alpha1=openelb
tiny-calico-worker-88-12.k8s.tcinternal   Ready    <none>                 16d   v1.23.6   10.31.88.12   <none>        CentOS Linux 7 (Core)   3.10.0-1160.62.1.el7.x86_64   docker://20.10.14   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=tiny-calico-worker-88-12.k8s.tcinternal,kubernetes.io/os=linux,lb.kubesphere.io/v1alpha1=openelb

然后我们先把副本的数量缩容到 0。

$ kubectl scale deployment openelb-manager --replicas=0 -n openelb-system

接着修改配置,在部署节点的 nodeSelector 字段中增加我们前面新加的 labels

复制

$ kubectl get deployment openelb-manager -n openelb-system -o yaml
...略去一堆输出...nodeSelector:kubernetes.io/os: linuxlb.kubesphere.io/v1alpha1: openelb
...略去一堆输出...

扩容副本数量到 3。

复制

$ kubectl scale deployment openelb-manager --replicas=3 -n openelb-system

检查 deployment 状态

$ kubectl get po -n openelb-system -o wide
NAME                               READY   STATUS      RESTARTS   AGE   IP            NODE                                      NOMINATED NODE   READINESS GATES
openelb-admission-create-fvfzk     0/1     Completed   0          78m   10.88.84.89   tiny-calico-worker-88-11.k8s.tcinternal   <none>           <none>
openelb-admission-patch-tlmns      0/1     Completed   1          78m   10.88.84.90   tiny-calico-worker-88-11.k8s.tcinternal   <none>           <none>
openelb-manager-6457bdd569-6n9zr   1/1     Running     0          62m   10.31.88.1    tiny-calico-master-88-1.k8s.tcinternal    <none>           <none>
openelb-manager-6457bdd569-c6qfd   1/1     Running     0          62m   10.31.88.12   tiny-calico-worker-88-12.k8s.tcinternal   <none>           <none>
openelb-manager-6457bdd569-gh995   1/1     Running     0          62m   10.31.88.11   tiny-calico-worker-88-11.k8s.tcinternal   <none>           <none>

至此就完成了 openelb-manager 的高可用部署改造。

参考资料:

​​https://tinychen.com/20220523-k8s-07-loadbalancer-openelb/​​

​​https://openelb.io/docs/overview/​​

​​https://blog.csdn.net/weixin_39246554/article/details/129386533​​

在删除 OpenELB 之前,必须确保​​openelb-system​​​命名空间下没有任何服务,特别是后面配置到eip时,必须先删除​​Eip​​​,再删除 OpenELB ,否则你会遇到无法删除​​Eip​​​的Bug,引用来源:​​https://kubesphere.com.cn/forum/d/2379-porter/8​​

​​https://blog.csdn.net/weixin_64334766/article/details/134794870​​

[root@k8s-master service]# cat service1.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:labels:name: my-nginxname: my-nginxnamespace: myns
spec:replicas: 3selector:matchLabels:name: my-nginx-deploytemplate:metadata:labels:name: my-nginx-deployspec:containers:- name: my-nginx-podimage: nginxports:- containerPort: 80---apiVersion: v1
kind: Service
metadata:name: my-nginx-servicenamespace: mynsannotations:   #这三行详情也要添加,尤为重要lb.kubesphere.io/v1alpha1: openelbprotocol.openelb.kubesphere.io/v1alpha1: layer2  eip.openelb.kubesphere.io/v1alpha2: my-eip-pool   #指定创建地址池时指定的名称
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: my-nginx-deploytype: LoadBalancer   #指定type为LoadBalancerLoadBalancerIP: number  这段执行错误    #是可以指定IP的

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Tuxera for Mac产品2024最新版本功能描述优化介绍

Tuxera for Mac产品描述优化 Tuxera for Mac&#xff0c;是Mac用户的专属读写神器。无论你是职场人士还是学生&#xff0c;只要你在Mac上工作、学习&#xff0c;需要频繁读写Windows格式的存储设备&#xff0c;Tuxera for Mac都将是你的不二之选。 Tuxera Ntfs For Mac 2024下…

密码算法概论

基本概念 什么是密码学&#xff1f; 简单来说&#xff0c;密码学就是研究编制密码和破译密码的技术科学 例题&#xff1a; 密码学的三个阶段 古代到1949年&#xff1a;具有艺术性的科学1949到1975年&#xff1a;IBM制定了加密标准DES1976至今&#xff1a;1976年开创了公钥密…

unbuntu mysql8.0新建用户及开启远程连接

MySQL更新到8.0以上版本后&#xff0c;在创建连接远程的用户的时候和之前5.x的版本有了很大的不同&#xff0c;不能使用原来同时创建用户和授权的命令。 以下是记录的MySQL8.0创建用户并授权的命令&#xff1a; 查看用户表&#xff1a; user mysql; select host,user,authen…

算法系列--递归,回溯,剪枝的综合应用(2)

&#x1f495;"对相爱的人来说&#xff0c;对方的心意&#xff0c;才是最好的房子。"&#x1f495; 作者&#xff1a;Lvzi 文章主要内容&#xff1a;算法系列–递归,回溯,剪枝的综合应用(2) 大家好,今天为大家带来的是算法系列--递归,回溯,剪枝的综合应用(2) 一.括号…

Java的IDEA的工程管理

模块和包的图标&#xff1a; 举个例子&#xff1a; IDEA中创建包&#xff1a; 如图所示&#xff0c;com.LBJ的意思是在com包中创建子包LBJ 参见&#xff1a; IDEA中项目、模块和包的关系_idea中模块和项目-CSDN博客

llama-index 结合chatglm3-6B 利用RAG 基于文档智能问答

简介 llamaindex结合chatglm3使用 import os import torch from llama_index.core import VectorStoreIndex, ServiceContext from llama_index.core.callbacks import CallbackManager from llama_index.core.llms.callbacks import llm_completion_callback from llama_ind…

使用STM32 MCU模拟实现PPS+TOD授时信号

简介 PPSTOD是授时信号的一种&#xff0c;用来传递准确的时间信息。 PPS&#xff0c;Pulse Per Second&#xff0c;是每秒一次的脉冲信号&#xff0c;其上升沿表示整秒的时刻。TOD&#xff0c;Time of Day&#xff0c;是时间信息。是跟随在每个PPS信号后的由串口发出的一句报…

HTML——4.表格、列表、区块

一、表格 HTML 表格是用于展示结构化数据的重要元素&#xff0c;它允许将数据以行和列的形式组织和显示。 基本结构和常见元素&#xff1a; 1. <table> 元素 <table> 元素是 HTML 表格的根元素&#xff0c;它用于定义整个表格的开始和结束。 2. <thead>、…

曼哈顿距离和切比雪夫距离

曼哈顿距 定义 设平面空间内存在两点&#xff0c;它们的坐标为(x1,y1) (x2,y2) . 则 dis|x1−x2||y1−y2|&#xff0c;即两点横纵坐标差之和 切比雪夫距离 定义 设平面空间内存在两点&#xff0c;它们的坐标为(x1,y1)&#xff0c;(x2,y2) 则dismax(|x1−x2|,|y1−y2|)&a…

JumpServer 堡垒主机

JumpServer 堡垒机帮助企业以更安全的方式管控和登陆各种类型的资产 SSH&#xff1a;Linux/Unix/网络设备等Windows&#xff1a;Web方式连接/原生RDP连接数据库&#xff1a;MySQL、Oracle、SQLServer、PostgreSQL等Kubernetes&#xff1a;连接到K8s集群中的PodsWeb站点&#x…

微服务之分布式事务概念

微服务之分布式事务概念 CAP定理和Base理论 CAP定理 CAP定理在1998年被加州大学的计算机科学家 Eric Brewer 提出&#xff0c;分布式系统有三个指标&#xff1a; 一致性&#xff08;Consistency&#xff09;可用性&#xff08;Availability&#xff09;分区容错性&#xff…

Vastbase编程利器:PL/pgSQL原理简介

PL/pgSQL是Vastbase提供的一种过程语言&#xff0c;在普通SQL语句的使用上增加了编程语言的特点&#xff0c;可以用于创建函数、存储过程、触发器过程以及创建匿名块等。 本文介绍Vastbase中PL/pgSQL的执行流程&#xff0c;包括PL/pgSQL的编译与运行。 1、编译 PL/pgSQL的编译…

Netty教程之NIO基础

NIO 介绍 NIO 全称java non-blocking IO&#xff08;非阻塞 I/O&#xff09;&#xff0c;后续提供了一系列改进的输入/输出的新特性&#xff0c;被统称为 NIO(即 New IO)&#xff0c;是同步非阻塞的。 阻塞和非阻塞是进程在访问数据的时候&#xff0c;数据是否准备就绪的一种…

ctf题目

目录 1.文件包含的一道题目&#xff0c;没什么难度&#xff0c; 2.一道sql注入的题目&#xff0c;伪静态 3.限制只能本地访问。 1.文件包含的一道题目&#xff0c;没什么难度&#xff0c; 但是一个点就是它这里去包含的那个文件名就是flag&#xff0c;而不是flag.php也不是f…

CSS实现小车旅行动画实现

小车旅行动画实现 效果展示 CSS 知识点 灵活使用 background 属性下的 repeating-linear-gradient 实现路面效果灵活运用 animation 属性与 transform 实现小车和其他元素的动画效果 动画场景分析 从效果图可以看出需要实现此动画的话&#xff0c;需要position属性控制元素…

学习transformer模型-Dropout的简明介绍

Dropout的定义和目的&#xff1a; Dropout 是一种神经网络正则化技术&#xff0c;它在训练时以指定的概率丢弃一个单元&#xff08;以及连接&#xff09;p。 这个想法是为了防止神经网络变得过于依赖特定连接的共同适应&#xff0c;因为这可能是过度拟合的症状。直观上&#…

移动硬盘无法打开?原因与解决方案一网打尽

一、遭遇困境&#xff1a;移动硬盘突然罢工 在数字化日益盛行的今天&#xff0c;移动硬盘无疑是我们储存和转移数据的重要工具。然而&#xff0c;当某一天你突然发现移动硬盘无法打开时&#xff0c;那种焦虑与无助感无疑会席卷而来。插上电脑&#xff0c;硬盘灯闪烁却无响应&a…

软考之零碎片段记录(二)

一、位示图记录磁盘使用情况 1. 计算位示图的大小&#xff1f; 物理块大小4MB, 磁盘容量512GB, 系统字长64位&#xff08;64位 / 字长&#xff09; 计算物理块数量 512 * 1024 / 4 256 * 512 131072 每一位记录一个物理块 131072 / 64 2048&#xff08;字&#xff09; 二…

科研学习|论文解读——情感对感知偶然信息遭遇的影响研究(JASIST,2022)

原文题目 Investigating the impact of emotions on perceiving serendipitous information encountering 一、引言 serendipity一词最初是由霍勒斯沃波尔创造的&#xff0c;他将其定义为“通过意外和睿智发现你并不追求的事物”。信息研究中大多数现有的偶然性定义从几个角度看…

vue2 el-table指定某些数据不参与排序

vue2 el-table指定某些数据不参与排序 1、需求描述2、配置属性方法3、详细代码如下 1、需求描述 最后一行总计不参与排序 2、配置属性方法 el-table 需要配置 sort-change"soltHandle" 方法 el-table-column 需要配置 sortable"custom"属性3、详细代码如…