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

K8S MetalLB LoadBalancer

1. 简介

kubernetes集群没有L4负载均衡,对外暴漏服务时,只能使用nodePort的方式,比较麻烦,必须要记住不同的端口号。

LoadBalancer:使用云提供商的负载均衡器向外部暴露服务,外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上。

img

MetalLB 是裸机 Kubernetes 集群的负载均衡器实现,使用标准路由协议。

它提供了两个功能:

  • 地址分配(address allocation):当创建 LoadBalancer Service 时,MetalLB 会为其分配 IP 地址。这个 IP 地址是从预先配置的 IP 地址库获取的。同样,当 Service 删除后,已分配的 IP 地址会重新回到地址库。
  • 对外公告(external announcement):分配了 IP 地址之后,需要让集群外的网络知道这个地址的存在。使用了标准路由协议实现:
    • Layer2 模式:ARP(ipv4)、NDP(ipv6)
    • BGP 模式

不管是Layer2模式还是BGP模式,两者都不使用Linux的网络栈,即无法使用诸如ip命令准确的查看VIP所在的节点和相应的路由,相对应的是在每个节点上面都能看到一个kube-ipvs0网卡接口上面的IP。同时,两种模式都只是负责把VIP的请求引到对应的节点上面,之后的请求怎么到达pod,按什么规则轮询等都是由kube-proxy实现的。

对应的的两种工作负载:

  • ControllerDeployment,用于监听 Service 的变更,分配/回收 IP 地址。
  • SpeakerDaemonSet,对外广播 Service 的 IP 地址。把服务类型为LoadBalancer的服务的EXTERNAL-IP公布到网络中去,确保客户端能够正常访问到这个IP。

2. 部署

2.1 测试服务

apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-app
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.21.4ports:- name: httpcontainerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: nginx-svc
spec:ports:- name: httpport: 8080protocol: TCPtargetPort: 80selector:app: nginxtype: LoadBalancer

2.2 MetalLB

# 1. ipvs 开启严格 arp模式
$ kubectl edit configmap -n kube-system kube-proxy
...
ipvs:strictARP: true# 2. 安装组件
$ mkdir -p $HOME/metallb && cd $_
$ wget https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yaml$ kubectl apply -f metallb-native.yaml$ kubectl get pod -n metallb-system
NAME                          READY   STATUS    RESTARTS      AGE
controller-6f5c46d94b-b7psv   1/1     Running   1 (29s ago)   80s
speaker-6v8hn                 1/1     Running   0             80s
speaker-nzkb6                 1/1     Running   0             79s
speaker-wjqxx                 1/1     Running   0             79s

组件说明:

  • metallb-system/controller:负责IP地址的分配,以及service和endpoint的监听
  • metallb-system/speaker:负责保证service地址可达,在Layer 2模式下,speaker会负责ARP请求应答

3. Layer2 模式

  • 每个service会有集群中的一个node来负责。当服务客户端发起ARP解析的时候,对应的node会响应该ARP请求,之后,该service的流量都会指向该node(看上去该node上有多个地址)。

  • 并不是真正的负载均衡,因为流量都会先经过一个node后,再通过kube-proxy转给多个endpoints。如果该node故障,MetalLB会迁移 IP到另一个node,并重新发送ARP告知客户端迁移。

  • 更为通用,不需要用户有额外的设备;但由于Layer 2模式使用ARP/NDP,地址池分配需要跟客户端在同一子网,地址分配略为繁琐。

img

3.1 工作原理

  • Speaker 工作负载类型是 DeamonSet ,在每台节点上都调度一个 Pod。首先,几个 Pod 会先进行选举,选举出 LeaderLeader 获取所有 LoadBalancer 类型的 Service,将已分配的 IP 地址绑定到当前主机到网卡上。即所有 LoadBalancer 类型的 Service 的 IP 同一时间都是绑定在同一台节点的网卡上。

  • 当外部主机有请求要发往集群内的某个 Service,需要先确定目标主机网卡的 mac 地址。这是通过发送 ARP 请求,Leader 节点的会以其 mac 地址作为响应。外部主机会在本地 ARP 表中缓存下来,下次会直接从 ARP 表中获取。

  • 请求到达节点后,节点再通过 kube-proxy 将请求负载均衡目标 Pod。所以说,假如Service 是多 Pod 这里有可能会再跳去另一台主机。

img

3.2 试验

配置 layer2 IP池 (layer2.yaml):

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:name: layer2-poolnamespace: metallb-system
spec:addresses:- 192.168.3.170-192.168.3.179
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:name: layer2-lbnamespace: metallb-system
spec:ipAddressPools:- layer2-pool

查看结果:

# 获取
$ kubectl get svc nginx-svc
NAME        TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)          AGE
nginx-svc   LoadBalancer   10.96.155.95   192.168.3.170   8080:31717/TCP   9m34s$ kubectl get ep nginx-svc
NAME        ENDPOINTS                                           AGE
nginx-svc   10.244.172.62:80,10.244.172.63:80,10.244.46.53:80   9m38s$ ipvsadm -Ln | grep 192.168.3.170 -A 3
TCP  192.168.3.170:8080 rr-> 10.244.46.53:80              Masq    1      0          0-> 10.244.172.62:80             Masq    1      0          0-> 10.244.172.63:80             Masq    1      0          0# 每个节点自动增加配置
$ ip addr show kube-ipvs0 | grep 192.168.3.170 -A 1inet 192.168.3.170/32 scope global kube-ipvs0valid_lft forever preferred_lft forever

查询实际的工作代理节点:

$ curl -I 192.168.3.170:8080
HTTP/1.1 200 OK
Server: nginx/1.21.4
Date: Thu, 10 Aug 2023 06:44:21 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 02 Nov 2021 14:49:22 GMT
Connection: keep-alive
ETag: "61814ff2-267"
Accept-Ranges: bytes$ arp 192.168.3.170
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.3.170            ether   52:54:00:63:8f:d3   C                     br0

根据mac地址,查询实际的节点:

$ ip addr | grep 52:54:00:63:8f:d3 -A 1 -B 1
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 52:54:00:63:8f:d3 brd ff:ff:ff:ff:ff:ffinet 192.168.3.105/24 brd 192.168.3.255 scope global ens3

3.3 清理

kubectl delete -f layer2.yamlkubectl get pod -n metallb-system | grep Running | awk '{print $1}' | xargs kubectl delete pod -n metallb-system

4. BGP 模式

  • 所有node都会跟上级路由器建立BGP连接,并会告知路由器应该如何转发service流量
  • 是真正的 Load Balancer

在这里插入图片描述

4.1 工作原理

BGP模式不限于一个二层网络里,各个节点都会与交换机建立BGP Peer,宣告Service External IP的下一跳为自身,这样通过ECMP实现了一层负载。客户端请求通过交换机负载到后端某个节点后,再由Kube-proxy进行转发

img

4.2 路由配置

通过 openwrt 旁路由实现 BGP。使用命令 vtysh 进行 AS 配置

  • 本地:AS 65000

  • 远端:AS 65001

$ vtysh
OpenWrt# conf t
OpenWrt(config)# router bgp 65000
OpenWrt(config-router)# neighbor 192.168.3.103 remote-as 65001
OpenWrt(config-router)# neighbor 192.168.3.103 description master-01
OpenWrt(config-router)# neighbor 192.168.3.104 remote-as 65001
OpenWrt(config-router)# neighbor 192.168.3.104 description worker-01
OpenWrt(config-router)# neighbor 192.168.3.105 remote-as 65001
OpenWrt(config-router)# neighbor 192.168.3.105 description worker-02
OpenWrt(config-router)# exit
OpenWrt(config)# exitOpenWrt# show ip bgp summary
BGP router identifier 192.168.3.180, local AS number 65000
RIB entries 0, using 0 bytes of memory
Peers 3, using 27 KiB of memoryNeighbor        V         AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
192.168.3.103   4 65001       0       6        0    0    0 never    Active
192.168.3.104   4 65001       0       4        0    0    0 never    Active
192.168.3.105   4 65001       0       3        0    0    0 never    ActiveTotal number of neighbors 3OpenWrt# exit

查看 bgpd 端口监听 179 是否已打开:

$  netstat -lantp | grep -E 'zebra|bgpd'
tcp        0      0 0.0.0.0:179             0.0.0.0:*               LISTEN      5355/bgpd
tcp        0      0 0.0.0.0:2601            0.0.0.0:*               LISTEN      5350/zebra
tcp        0      0 0.0.0.0:2605            0.0.0.0:*               LISTEN      5355/bgpd
tcp        0      0 :::179                  :::*                    LISTEN      5355/bgpd
tcp        0      0 :::2601                 :::*                    LISTEN      5350/zebra
tcp        0      0 :::2605                 :::*                    LISTEN      5355/bgpd

4.3 试验

配置BPG IP池 (bgp.yaml):

apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:name: samplenamespace: metallb-system
spec:myASN: 65001peerASN: 65000peerAddress: 192.168.3.180
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:name: first-poolnamespace: metallb-system
spec:addresses:- 192.168.0.10-192.168.0.99
---
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:name: examplenamespace: metallb-system
spec:ipAddressPools:- first-pool

查看结果:

$ kubectl get svc nginx-svc
NAME        TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)          AGE
nginx-svc   LoadBalancer   10.96.167.171   192.168.0.10   8080:31323/TCP   25h$ kubectl get ep nginx-svc
NAME        ENDPOINTS                                           AGE
nginx-svc   10.244.172.59:80,10.244.172.60:80,10.244.46.52:80   25h# 每个节点均添加
$ ip addr show kube-ipvs0 | grep 192.168.0.10 -A 1inet 192.168.0.10/32 scope global kube-ipvs0valid_lft forever preferred_lft forever$ curl -I 192.168.0.10:8080
HTTP/1.1 200 OK
Server: nginx/1.21.4
Date: Thu, 10 Aug 2023 03:39:37 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 02 Nov 2021 14:49:22 GMT
Connection: keep-alive
ETag: "61814ff2-267"
Accept-Ranges: bytes$ ipvsadm -Ln | grep 192.168.0 -A 3
TCP  192.168.0.10:8080 rr-> 10.244.46.52:80              Masq    1      0          0-> 10.244.172.59:80             Masq    1      0          0-> 10.244.172.60:80             Masq    1      0          0

客户端(windows, 192.168.3.3)添加路由:

route add 192.168.0.0 MASK 255.255.0.0 192.168.3.180

访问:https://192.168.0.10:8080 ok

4.4 清理

kubectl delete -f bgp.yamlkubectl get pod -n metallb-system | grep Running | awk '{print $1}' | xargs kubectl delete pod -n metallb-system

5. IP地址共享

默认情况下,MetalLB只会将一个IP地址分配到一个LoadBalancer Service上,用户可以通过spec.loadBalancerIP来指定自己想用的IP,如果用户指定了已被分配了的IP会,则会报错。但MetalLB也提供了方式去支持多个Service共享相同的IP,主要为了解决:K8S不支持对LoadBalancer Service中的Port指定多协议;有限的IP地址资源。

具体的方式是:创建两个Service,并加上metallb.universe.tf/allow-shared-ip为Key的annotation,表明Service能容忍使用共享的LoadBalancerIP;然后通过spec.loadBalancerIP给两个Service指定共享的IP。

IP地址共享也有限制:

1)两个Service的metallb.universe.tf/allow-shared-ip值是一样的。

2)两个Service的“端口”(带协议)不同,比如tcp/53udp/53是属于不同的“端口”。

3)两个Service对应的后端Pod要一致,如果不一致,那么他们的externalTrafficPolicy需要都是Cluster,不然会无法进行正确的BGP。

6. 总结

6.1 nodeport

在创建LoadBalancer服务时,会默认创建一个nodeport服务,可通过配置allocateLoadBalancerNodePorts来关闭。

不同的loadbalancer实现原理不同,有的需要依赖nodeport来进行流量转发,有些则直接转发请求到pod中。

对于MetalLB而言,是通过kube-proxy将请求的流量直接转发到pod,因此可以关闭nodeport。

apiVersion: v1
kind: Service
metadata:name: nginx-svc
spec:allocateLoadBalancerNodePorts: falseexternalTrafficPolicy: ClusterinternalTrafficPolicy: Clusterports:- name: httpport: 8080protocol: TCPtargetPort: 80selector:app: nginxtype: LoadBalancerloadBalancerIP: 192.168.0.20  

验证:

$ kubectl delete svc nginx-svc
$ kubectl apply -f nginx-svc-disable-nodeport.yaml$ kubectl get svc nginx-svc
NAME        TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)    AGE
nginx-svc   LoadBalancer   10.96.54.226   192.168.0.20   8080/TCP   3s

6.2 Layer2

优点:

  • 通用性强,不需要BGP路由器支持,几乎可以适用于任何网络环境,云厂商例外

缺点:

  • 所有的流量都会在同一个节点上,该节点的容易成为流量的瓶颈;
  • 当VIP所在节点宕机之后,需要较长时间进行故障转移(一般在10s),主要是因为MetalLB使用了memberlist来进行选主,当VIP所在节点宕机之后重新选主的时间要比传统的keepalived使用的vrrp协议要更长;
  • 难以定位VIP所在节点,没有提供一个简单直观的方式查看到底哪一个节点是VIP所属节点,只能通过抓包或者查看pod日志来确定,当集群规模变大的时会非常麻烦

6.3 BGP

优点:

  • 无单点故障,在开启ECMP的前提下,k8s集群内所有的节点都有请求流量,都会参与负载均衡并转发请求

缺点:

  • 条件苛刻,需要有BGP路由器支持,配置起来也更复杂;
  • ECMP的故障转移(failover)并不是特别地优雅,这个问题的严重程度取决于使用的ECMP算法;当集群的节点出现变动导致BGP连接出现变动,所有的连接都会进行重新哈希(使用三元组或五元组哈希),这对一些服务来说可能会有影响;

7. 附录

7.1 BGP

BGP,Border Gateway Protocol,边界网关协议

BGP是互联网上一个核心的去中心化自治路由协议。它通过维护IP路由表或“前缀”表来实现自治系统(AS)之间的可达性,属于矢量路由协议。BGP不使用传统的内部网关协议(IGP)的指标,而使用基于路径、网络策略或规则集来决定路由。因此,它更适合被称为矢量性协议,而不是路由协议。

BGP的邻居关系(或称通信对端/对等实体,peer)是通过人工配置实现的,对等实体之间通过TCP端口179建立会话交换数据。BGP路由器会周期地发送19字节的保持存活(keep-alive)消息来维护连接(默认周期为60秒)。在各种路由协议中,只有BGP使用TCP作为传输层协议。

同一个AS自治系统中的两个或多个对等实体之间运行的BGP被称为iBGP(Internal/Interior BGP)。归属不同的AS的对等实体之间运行的BGP称为eBGP(External/Exterior BGP)。在AS边界上与其他AS交换信息的路由器被称作边界路由器(border/edge router),边界路由器之间互为eBGP对端。在Cisco IOS中,iBGP通告的路由距离为200,优先级比eBGP和任何内部网关协议(IGP)通告的路由都低。其他的路由器实现中,优先级顺序也是eBGP高于IGP,而IGP又高于iBGP。

iBGP和eBGP的区别主要在于转发路由信息的行为。例如,从eBGP peer获得的路由信息会分发给所有iBGP peer和eBGP peer,但从iBGP peer获得的路由信息仅会分发给所有eBGP peer。所有的iBGP peer之间需要全互联。

在这里插入图片描述

三个核心名词:

  • 自治系统(AS)
  • 内部网关协议(IGP)
  • 外部网关协议(EGP)

7.1.1 自治系统 AS

自制系统(Autonomous system,缩写 AS),是指在互联网中,一个或多个实体管辖下的所有IP 网络和路由器的组合,它们对互联网执行共同的路由策略。自治系统编号都是16位长的整数,这最多能被分配给65536个自治系统。自治系统编号被分成两个范围。第一个范围是公开的ASN,从1到64511,它们可在互联网上使用;第二个范围是被称为私有编号的从64512到65535的那些,它们仅能在一个组织自己的网络内使用。

简单理解,电信、移动、联通都有自己的 AS 编号,且不只一个。除了互联网公开的 ASN 以外,私有的编号可以在内部使用。比如我可以我的家庭网络中使用私有编号创建几个 AS。

7.1.2 内部路由协议 IGP

内部路由协议(Interior Gateway Protocol,IGP)是指在一个自治系统(AS)内部所使用的一种路由协议。

7.1.3 外部网关协议 EGP

外部网关协议(Exterior Gateway Protocol,EGP)是一个已经过时互联网路由协议。已由 BPG 取代。

7.1.4 BGP

BPG 是为了替换 EGP 而创建的,而除了应用于 AS 外部,也可以应用在 AS 内部。因此又分为 EBGP 和 IBGP。

7.2 OpenWrt

7.2.1 安装

wget https://mirrors.aliyun.com/openwrt/releases/19.07.4/targets/x86/64/openwrt-19.07.4-x86-64-combined-ext4.img.gzgunzip openwrt-19.07.4-x86-64-combined-ext4.img.gz
cp openwrt-19.07.4-x86-64-combined-ext4.img  openwrt.img# 双网口(wan+lan)
virt-install --name=openwrt --vcpus=1 --ram=512 --os-type=generic --disk path=/root/eli/openwrt.img,bus=ide --autostart --network bridge=br0,model=e1000 --network bridge=br0,model=e1000 --import --noautoconsole --graphics vnc,listen=0.0.0.0,password=123456# 单网口(lan)
virt-install --name=openwrt --vcpus=1 --ram=512 --os-type=generic --disk path=/root/eli/openwrt.img,bus=ide --autostart --network bridge=br0,model=e1000 --import --noautoconsole --graphics vnc

修改网络配置:

# 改成与宿主机在同一网络下
$ vi /etc/config/network
...
config interface 'lan'option type 'bridge'option ifname 'eth0'option proto 'static'option ipaddr '192.168.3.180'option netmask '255.255.255.0'option ip6assign '60'option gateway '192.168.3.1'option dns '114.114.114.114'$ service network restart

登录配置页面:http://192.168.3.180

7.2.2 Quagga

为了让 OpenWrt 支持 BGP,需要安装路由软件套件 Quagga。它提供了 OSPFv2、OSPFv3、RIP v1 v2、RIPng 和 BGP-4 的实现。

Quagga 架构由核心守护进程和 zebra 组成,后者作为底层 Unix 内核的抽象层,并通过 Unix 或者 TCP 向 Quagga 客户端提供 Zserv API。正是这些 Zserv 客户端实现了路由协议,并将路由的更新发送给 zebra 守护进程。当前 Zserv 的实现:

img

Quagga 的守护进程可以通过网络可访问的 CLI(简称 vty)进行配置。 CLI 遵循与其他路由软件类似的风格。还额外提供了一个工具 vtysh,充当了所有守护进程的聚合前端,允许在一个地方管理所有 Quagga 守护进程的所有功能。

$ opkg update && opkg install quagga quagga-zebra quagga-bgpd quagga-vtysh$ netstat -lantp | grep -E 'zebra|bgpd'
tcp        0      0 0.0.0.0:2601            0.0.0.0:*               LISTEN      5350/zebra
tcp        0      0 0.0.0.0:2605            0.0.0.0:*               LISTEN      5355/bgpd
tcp        0      0 :::2601                 :::*                    LISTEN      5350/zebra
tcp        0      0 :::2605                 :::*                    LISTEN      5355/bgpd

参考资料:

https://metallb.universe.tf/configuration/

https://tinychen.com/20220519-k8s-06-loadbalancer-metallb/

https://atbug.com/load-balancer-service-with-metallb-bgp-mode/

https://ieevee.com/tech/2019/06/30/metallb.html

相关文章:

K8S MetalLB LoadBalancer

1. 简介 kubernetes集群没有L4负载均衡&#xff0c;对外暴漏服务时&#xff0c;只能使用nodePort的方式&#xff0c;比较麻烦&#xff0c;必须要记住不同的端口号。 LoadBalancer&#xff1a;使用云提供商的负载均衡器向外部暴露服务&#xff0c;外部负载均衡器可以将流量路由…...

kubernetes二进制部署2之 CNI 网络组件部署

CNI 网络组件部署 一&#xff1a;K8S提供三大接口1容器运行时接口CRI2云原生网络接口CNI3云原生存储接口CSI 部署 flannelK8S 中 Pod 网络通信&#xff1a;Overlay Network&#xff1a;VXLAN&#xff1a;Flannel:Flannel udp 模式的工作原理&#xff1a;ETCD 之 Flannel 提供说…...

docker通用镜像方法,程序更新时不用重新构建镜像

docker通用镜像方法&#xff0c;程序更新时不用重新构建镜像。更新可执行文件后&#xff0c;重新启动容器就可运行。 功能 1、在demo目录下添加脚本文件start.sh&#xff0c;里面执行demo.jar文件。 2、将demo目录映射到镜像下的 /workspace目录。 3、Dockerfile文件中默认…...

Spring Cloud构建微服务断路器介绍

什么是断路器 断路器模式源于Martin Fowler的Circuit Breaker一文。“断路器”本身是一种开关装置&#xff0c;用于在电路上保护线路过载&#xff0c;当线路中有电器发生短路时&#xff0c;“断路器”能够及时的切断故障电路&#xff0c;防止发生过载、发热、甚至起火等严重后果…...

[国产MCU]-BL602开发实例-OLED-SSD1306驱动与U8g2移植

OLED-SSD1306驱动与U8g2移植 文章目录 OLED-SSD1306驱动与U8g2移植1、OLED介绍2、SSD1306介绍2、U8g2介绍3、U8g2移植3.1 定义U8g2图形库的移植函数3.2 移植函数实现3.3 移植函数调用4、驱动测试本文将详细介绍如何在BL602中移植U8g2图形库,并通过U8g2库驱动OLED SSD1306显示屏…...

AWS asg(Auto Scaling Group)部署时报错Error: Termination Reason: Client.InternalError

背景 最近用一个terraform asg模块部署asg时一直报错 Error: Termination Reason: Client.InternalError: Client error on launch 搜索资料发现和KMS下面的asg 对应的policy有关系. 解决方法 在AWS界面找到KMS, 然后找到customer managed key导航栏, 最后找到对应AMI加密用…...

Redis—过期删除策略和内存淘汰策略

目录标题 过期删除策略如何设置过期时间查看key过期时间取消key过期时间如果判定key已过期过期删除策略定时删除惰性删除定期删除 Redis过期删除策略Redis如何实现定期删除第一种版本第二种版本 内存淘汰策略如何设置Redis最大运行内存第一种版本第二种版本 Redis内存淘汰策略不…...

连续两年增收不增利,比亚迪电子靠新能源汽车业务再次起飞?

在净利润连续两年下挫之后&#xff0c;比亚迪电子&#xff08;00285.HK&#xff09;终于迎来了好消息。 不久前比亚迪电子发布2023年中期盈利预告显示&#xff0c;上半年净利润同比增加115%-146%&#xff08;2022年上半年的净利润显示6.34亿元&#xff09;。 这主要受益于大客…...

echarts3d柱状图

//画立方体三个面 const CubeLeft echarts.graphic.extendShape({shape: {x: 0,y: 0,width: 9.5, //柱状图宽zWidth: 4, //阴影折角宽zHeight: 3, //阴影折角高},buildPath: function (ctx, shape) {const api shape.api;const xAxisPoint api.coord([shape.xValue, 0]);con…...

使用webpack插件webpack-dev-server 出现Cannot GET/的解决办法

问题描述 文档地址深入浅出webpack 使用 DevServer运行webpack&#xff0c;跑起来之后提示Cannot GET/&#xff1a; 解决方案&#xff1a; 查阅官方文档 根据目录结构修改对应的配置&#xff1a; 然后就可以成功访问&#xff1a;...

老网工必备好物,分享15个网络监控神器

下午好&#xff0c;我的网工朋友。 近年来&#xff0c;随着虚拟、云和边缘网络的增加&#xff0c;网络监控工具已经显得越来越重要。 在当今大多数企业中&#xff0c;监控混合IT环境中的网络流量对于主动网络管理至关重要。 无论是检测行为异常、占用带宽、应对新威胁&#…...

拒绝摆烂!C语言练习打卡第一天

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;每日一练 &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ &#x1f5d2;️前言&#xff1a; 在前面我们学习完C语言的所以知识&#xff0c;当…...

Spring 使用注解开发、代理模式、AOP

使用注解开发 在Spring4之后&#xff0c;要使用注解开发&#xff0c;必须要保证AOP的包导入了 项目搭建&#xff1a; 在配置文件中导入约束&#xff0c;增加注解支持 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.spri…...

考公-判断推理-逻辑判断-翻译推理

第十节 前推后 例题 例题 例题 例题 例题 翻译规则之后推前 不 不能落下 谁必不可少&#xff0c;谁房箭头后面 例题 例题 例题 现实生活中觉得对&#xff0c;题干推不出 例题 例题...

关于MPU6050的VLOGIC引脚作用

关键字&#xff1a;MPU6X0X、 MPU6050、数字逻辑电平、VLOGIC 框图&#xff1a; 一、VLOGIC引脚作用? VLOGIC引脚主要用于设置为I2C供电引脚&#xff0c;以保证正确的I2C通信。 The bias and LDO section generates the internal supply and the reference voltages and cu…...

对约瑟夫问题的进一步思考

约瑟夫问题重述&#xff1a; 在计算机编程的算法中&#xff0c;类似问题又称为约瑟夫环 约瑟夫环&#xff1a;N个人围成一圈&#xff0c;从第一个开始报数&#xff0c;第M个将被杀掉&#xff0c;最后剩下一个&#xff0c;其余人都将被杀掉。 例如N6&#xff0c;M5&#xff0…...

程序员如何优雅的提升软件开发效率?

一、前言 面对日益发达的&#xff0c;极具诱惑力的夜生活&#xff0c;很少有人能置身事外。 但是有那么一群人&#xff0c;即使黑幕高垂还坚守在工作之位&#xff0c;无视夜晚的繁荣和喧嚣。 是的&#xff0c;他们就是程序员&#xff0c;一群成天编写代码的程序员。 相信&#…...

宽屏企业网站介绍

宽屏企业网站是一种以宽屏设计为特点的网站&#xff0c;旨在提供更丰富、精美的网页展示效果&#xff0c;适合于展示企业的品牌形象、产品介绍和服务内容。该类网站常用于企业展示、商务推广、企业形象塑造等场景。 宽屏企业网站的内容介绍一般包括以下几个方面&#xff1a; 公…...

OPENCV C++(八)HOG的实现

hog适合做行人的识别和车辆识别 对一定区域的形状描述方法 可以表示较大的形状 把图像分成一个一个小的区域的直方图 用cell做单位做直方图 计算各个像素的梯度强度和方向 用3*3的像素组成一个cell 3*3的cell组成一个block来归一化 提高亮度不变性 常用SVM分类器一起使用…...

干货分享:制作婚礼请柬的技巧,从零基础起步

在现代社会&#xff0c;婚礼请柬已经成为了婚礼必备的一部分。而如何制作一个个性化的婚礼请柬呢&#xff1f;今天&#xff0c;我们将分享一个简便而可靠的制作方法&#xff0c;那就是使用乔拓云平台。 乔拓云平台是一个可靠的第三方制作工具&#xff0c;提供了丰富的H5模板&am…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量&#xff1a;setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...

大数据治理的常见方式

大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法&#xff0c;以下是几种常见的治理方式&#xff1a; 1. 数据质量管理 核心方法&#xff1a; 数据校验&#xff1a;建立数据校验规则&#xff08;格式、范围、一致性等&#xff09;数据清洗&…...

用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法

用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法 大家好,我是Echo_Wish。最近刷短视频、看直播,有没有发现,越来越多的应用都开始“懂你”了——它们能感知你的情绪,推荐更合适的内容,甚至帮客服识别用户情绪,提升服务体验。这背后,神经网络在悄悄发力,撑起…...