k8s pod使用sriov

之前的文章中讲了k8s + multus的使用,本章节来讲述下如何使用multus来实现sriov的使用。

一、sriov 简介

SR-IOV在2010年左右由Intel提出,但是随着容器技术的推广,intel官方也给出了SR-IOV技术在容器中使用的开源组件,例如:sriov-cni和sriov-device-plugin等,所以SR-IOV也开始在容器领域得到的大量使用。

在传统的虚拟化中,虚拟机的网卡通常是通过桥接(Bridge或OVS)的方式,因为这种方式最方便,也最简单,但是这样做最大的问题在于性能。本文讲的SR-IOV在2010年左右由Intel提出,SR-IOV全称Single-Root I/O Virtualization,是一种基于硬件的虚拟化解决方案,它允许多个云主机高效共享PCIe设备,且同时获得与物理设备性能媲美的I/O性能,能有效提高性能和可伸缩性。

SR-IOV技数主要是虚拟出来通道给用户使用的,通道分为两种:

  • PF(Physical Function,物理功能):管理 PCIe 设备在物理层面的通道功能,可以看作是一个完整的 PCIe 设备,包含了 SR-IOV 的功能结构,具有管理、配置 VF 的功能。
  • VF(Virtual Function,虚拟功能):是 PCIe 设备在虚拟层面的通道功能,即仅仅包含了 I/O 功能,VF 之间共享物理资源。VF 是一种裁剪版的 PCIe 设备,仅允许配置其自身的资源,虚拟机无法通过 VF 对 SR-IOV 网卡进行管理。所有的 VF 都是通过 PF 衍生而来,有些型号的 SR-IOV 网卡最多可以生成 256 个 VF。
    SR-IOV设备数据包分发机制

从逻辑上可以认为启用了 SR-IOV 技术后的物理网卡内置了一个特别的 Switch,将所有的 PF 和 VF 端口连接起来,通过 VF 和 PF 的 MAC 地址以及 VLAN ID 来进行数据包分发。

  • 在 Ingress 上(从外部进入网卡):如果数据包的目的MAC地址和VLANID都匹配某一个VF,那么数据包会分发到该VF,否则数据包会进入PF;如果数据包的目的MAC地址是广播地址,那么数据包会在同一个 VLAN 内广播,所有 VLAN ID 一致的 VF 都会收到该数据包。
  • 在 Egress 上(从 PF 或者 VF发出):如果数据包的MAC地址不匹配同一VLAN内的任何端口(VF或PF),那么数据包会向网卡外部转发,否则会直接在内部转发给对应的端口;如果数据包的 MAC 地址为广播地址,那么数据包会在同一个 VLAN 内以及向网卡外部广播。
    注意:所有未设置 VLAN ID 的 VF 和 PF,可以认为是在同一个 LAN 中,不带 VLAN 的数据包在该 LAN 中按照上述规则进行处理。此外,设置了 VLAN 的 VF,发出数据包时,会自动给数据包加上 VLAN,在接收到数据包时,可以设置是否由硬件剥离 VLAN 头部。

二、SR-IOV设备与容器网络

英特尔推出了 SR-IOV CNI 插件,支持 Kubernetes pod 在两种模式任意之一的条件下直接连接 SR-IOV 虚拟功能 (VF)。第一个模式在容器主机核心中使用标准 SR-IOV VF 驱动程序。第二个模式支持在用户空间执行 VF 驱动程序和网络协议的 DPDK VNF。本文介绍的是第一个模式,直接连接SR-IOV虚拟功能(vf设备),如下图所示:
在这里插入图片描述
上图中包含了一个node节点上使用的组件:kubelet、sriov-device-plugin、sriov-cni和multus-cni。节点上的vf设备需要提前生成,然后由sriov-device-plugin将vf设备发布到k8s集群中。在pod创建的时候,由kubelet调用multus-cni,multus-cni分别调用默认cni和sriov-cni插件为pod构建网络环境。sriov-cni就是将主机上的vf设备添加进容器的网络命名空间中并配置ip地址。

三、环境准备

  • k8s环境
[root@node1 ~]# kubectl get node 
NAME    STATUS   ROLES                  AGE   VERSION
node1   Ready    control-plane,master   47d   v1.23.17
node2   Ready    control-plane,master   47d   v1.23.17
node3   Ready    control-plane,master   47d   v1.23.17
  • 硬件环境
[root@node1 ~]# lspci -nn  | grep -i eth  
23:00.0 Ethernet controller [0200]: Intel Corporation I350 Gigabit Network Connection [8086:1521] (rev 01)
23:00.1 Ethernet controller [0200]: Intel Corporation I350 Gigabit Network Connection [8086:1521] (rev 01)
41:00.0 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
41:00.1 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
42:00.0 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
42:00.1 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
63:00.0 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
63:00.1 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
a1:00.0 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
a1:00.1 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
[root@node1 ~]# 本环境将使用Mellanox Technologies MT27710进行实验测试。
########确认网卡是否支持sriov
[root@node1 ~]# lspci -v -s 41:00.0
41:00.0 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx]Subsystem: Mellanox Technologies Stand-up ConnectX-4 Lx EN, 25GbE dual-port SFP28, PCIe3.0 x8, MCX4121A-ACATPhysical Slot: 19Flags: bus master, fast devsel, latency 0, IRQ 195, IOMMU group 56Memory at 2bf48000000 (64-bit, prefetchable) [size=32M]Expansion ROM at c6f00000 [disabled] [size=1M]Capabilities: [60] Express Endpoint, MSI 00Capabilities: [48] Vital Product DataCapabilities: [9c] MSI-X: Enable+ Count=64 Masked-Capabilities: [c0] Vendor Specific Information: Len=18 <?>Capabilities: [40] Power Management version 3Capabilities: [100] Advanced Error ReportingCapabilities: [150] Alternative Routing-ID Interpretation (ARI)Capabilities: [180] Single Root I/O Virtualization (SR-IOV)   ##支持sriovCapabilities: [1c0] Secondary PCI ExpressCapabilities: [230] Access Control ServicesKernel driver in use: mlx5_coreKernel modules: mlx5_core    ####网卡支持的驱动类型
  • 开启vf
[root@node1 ~]# echo 8 > /sys/class/net/ens19f0/device/sriov_numvfs####物理机查看开启的vf
[root@node1 ~]# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
4: ens19f0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 9000 qdisc mq state UP mode DEFAULT group default qlen 1000link/ether e8:eb:d3:33:be:ea brd ff:ff:ff:ff:ff:ffvf 0     link/ether 00:00:00:00:00:00, spoof checking off, link-state auto, trust off, query_rss offvf 1     link/ether 00:00:00:00:00:00, spoof checking off, link-state auto, trust off, query_rss offvf 2     link/ether 00:00:00:00:00:00, spoof checking off, link-state auto, trust off, query_rss offvf 3     link/ether 00:00:00:00:00:00, spoof checking off, link-state auto, trust off, query_rss offvf 4     link/ether 00:00:00:00:00:00, spoof checking off, link-state auto, trust off, query_rss offvf 5     link/ether 00:00:00:00:00:00, spoof checking off, link-state auto, trust off, query_rss offvf 6     link/ether 00:00:00:00:00:00, spoof checking off, link-state auto, trust off, query_rss offvf 7     link/ether 00:00:00:00:00:00, spoof checking off, link-state auto, trust off, query_rss off###确认vf被开启
[root@node1 ~]# lspci -nn  | grep -i ether
23:00.0 Ethernet controller [0200]: Intel Corporation I350 Gigabit Network Connection [8086:1521] (rev 01)
23:00.1 Ethernet controller [0200]: Intel Corporation I350 Gigabit Network Connection [8086:1521] (rev 01)
41:00.0 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
41:00.1 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
41:00.2 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function] [15b3:1016]
41:00.3 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function] [15b3:1016]
41:00.4 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function] [15b3:1016]
41:00.5 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function] [15b3:1016]
41:00.6 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function] [15b3:1016]
41:00.7 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function] [15b3:1016]
41:01.0 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function] [15b3:1016]
41:01.1 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function] [15b3:1016]
42:00.0 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
42:00.1 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
63:00.0 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
63:00.1 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
a1:00.0 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]
a1:00.1 Ethernet controller [0200]: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] [15b3:1015]#####ip a查看在系统中被识别
[root@node1 ~]# ip a | grep ens19f0v
18: ens19f0v0: <BROADCAST,MULTICAST,ALLMULTI,PROMISC,UP,LOWER_UP> mtu 9000 qdisc mq state UP group default qlen 1000
19: ens19f0v1: <BROADCAST,MULTICAST,ALLMULTI,PROMISC,UP,LOWER_UP> mtu 9000 qdisc mq state UP group default qlen 1000
20: ens19f0v2: <BROADCAST,MULTICAST,ALLMULTI,PROMISC,UP,LOWER_UP> mtu 9000 qdisc mq state UP group default qlen 1000
21: ens19f0v3: <BROADCAST,MULTICAST,ALLMULTI,PROMISC,UP,LOWER_UP> mtu 9000 qdisc mq state UP group default qlen 1000
22: ens19f0v4: <BROADCAST,MULTICAST,ALLMULTI,PROMISC,UP,LOWER_UP> mtu 9000 qdisc mq state UP group default qlen 1000
23: ens19f0v5: <BROADCAST,MULTICAST,ALLMULTI,PROMISC,UP,LOWER_UP> mtu 9000 qdisc mq state UP group default qlen 1000
24: ens19f0v6: <BROADCAST,MULTICAST,ALLMULTI,PROMISC,UP,LOWER_UP> mtu 9000 qdisc mq state UP group default qlen 1000
25: ens19f0v7: <BROADCAST,MULTICAST,ALLMULTI,PROMISC,UP,LOWER_UP> mtu 9000 qdisc mq state UP group default qlen 1000
[root@node1 ~]#

四、sriov安装

  • sriov-device-plugin安装
[root@node1 ~]# git clone https://github.com/k8snetworkplumbingwg/sriov-network-device-plugin.git
[root@node1 ~]# cd sriov-network-device-plugin/
[root@node1 ~]# make image  ###编译镜像
[root@node1 ~]#
或者直接通过pull 命令下载镜像
[root@node1 ~]# docker pull ghcr.io/k8snetworkplumbingwg/sriov-network-device-plugin:latest-amd##############################
SR-IOV设备的pf资源和vf资源需要发布到k8s集群中以供pod使用,所以这边需要用到device-plugin,device-plugin的pod是用daemonset部署的,运行在每个node节点上,节点上的kubelet服务会通过grpc方式调用device-plugin里的ListAndWatch接口获取节点上的所有SR-IOV设备device信息,device-plugin也会通过register方法向kubelet注册自己的服务,当kubelet需要为pod分配SR-IOV设备时,会调用device-plugin的Allocate方法,传入deviceId,获取设备的详细信息。##############修改configmap,主要是用于筛选节点上的SR-IOV的vf设备,注册vf到k8s集群
[root@node1 ~]# vim sriov-network-device-plugin/deployments/configMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: sriovdp-confignamespace: kube-system
data:config.json: |{"resourceList": [{"resourcePrefix": "Mellanox.com","resourceName": "Mellanox_sriov_switchdev_MT27710_ens19f0_vf","selectors": { "drivers": ["mlx5_core"],"pfNames": ["ens19f0#0-7"]   ###填写被系统中识别到设备名称也可以使用设备厂商的vendors,配置方式多种}}]   }#######部署sriov-device-plugin
[root@node1 ~]# kubectl create -f deployments/configMap.yaml
[root@node1 ~]# kubectl create -f deployments/sriovdp-daemonset.yaml######查看sriov已经启动
[root@node1 ~]# kubectl get po -A  -o wide | grep sriov
kube-system   kube-sriov-device-plugin-amd64-d7ctb              1/1     Running     0               6d5h    172.28.30.165    node3   <none>           <none>
kube-system   kube-sriov-device-plugin-amd64-h86dl              1/1     Running     0               6d5h    172.28.30.164    node2   <none>           <none>
kube-system   kube-sriov-device-plugin-amd64-rlpwb              1/1     Running     0               6d5h    172.28.30.163    node1   <none>           <none>
[root@node1 ~]# #####describe node查看vf已经被注册到节点
[root@node1 ~]# kubectl describe  node node1 
---------
Capacity:cpu:                                                  128devices.kubevirt.io/kvm:                              1kdevices.kubevirt.io/tun:                              1kdevices.kubevirt.io/vhost-net:                        1kephemeral-storage:                                    256374468Kihugepages-1Gi:                                        120GiMellanox.com/Mellanox_sriov_switchdev_MT27710_ens19f0_vf:   8  ##已经被注册memory:                                               527839304Kipods:                                                 110
Allocatable:cpu:                                                  112devices.kubevirt.io/kvm:                              1kdevices.kubevirt.io/tun:                              1kdevices.kubevirt.io/vhost-net:                        1kephemeral-storage:                                    236274709318hugepages-1Gi:                                        120GiMellanox.com/Mellanox_sriov_switchdev_MT27710_ens19f0_vf:   8  ##可分配数量
  • sriov cni安装
[root@node1 ~]# git clone https://github.com/k8snetworkplumbingwg/sriov-cni.git
[root@node1 ~]# cd sriov-cni
[root@node1 ~]# make  ###编译sriov cni
[root@node1 ~]# cp build/sriov /opt/cni/bin/ #每个sriov节点都要拷贝以及执行下面修改权限的命令
[root@node1 ~]# chmod 777  /opt/cni/bin/sriovsriov-cni主要做的事情:首先sriov-cni部署后,会在/opt/cni/bin目录下放一个sriov的可执行文件。
然后,当kubelet会调用multus-cni插件,然后multus-cni插件里会调用delegates数组里的插件,delegates数组中会有SR-IOV信息,然后通过执行/opt/cni/bin/sriov命令为容器构建网络环境,这边构建的网络环境的工作有:
根据kubelet分配的sriov设备id找到设备,并将其添加到容器的网络命名空间中
为该设备添加ip地址
  • multus安装
安装步骤可以参考前面的文章https://blog.csdn.net/weixin_40579389/article/details/134183179?spm=1001.2014.3001.5501

五、pod使用sriov

  • 创建net-attach-def
[root@node1 ~]# vim sriov-attach.yaml
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:name: sriov-attachannotations:k8s.v1.cni.cncf.io/resourceName: Mellanox.com/Mellanox_sriov_switchdev_MT27710_ens19f0_vf
spec:config: '{"cniVersion": "0.3.1","name": "sriov-attach","type": "sriov","ipam": {"type": "calico-ipam","range": "222.0.0.0/8"}
}'
[root@node1 ~]# kubectl apply -f  sriov-attach.yaml 
networkattachmentdefinition.k8s.cni.cncf.io/sriov-attach created
[root@node1 ~]# kubectl get net-attach-def
NAME           AGE
sriov-attach   12s
  • 定义pod yaml
[root@node1 ~]# cat sriov-attach.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:name: sriovlabels:app: sriov-attach
spec:replicas: 1selector: matchLabels:app: sriov-attachtemplate: metadata:annotations: k8s.v1.cni.cncf.io/networks: sriov-attachlabels:app: sriov-attachspec:containers:- name: sriov-attachimage: docker.io/library/nginx:latestimagePullPolicy: IfNotPresentresources:requests:cpu: 1memory: 1GiMellanox.com/Mellanox_sriov_switchdev_MT27710_ens19f0_vf: '1'limits: cpu: 1memory: 1GiMellanox.com/Mellanox_sriov_switchdev_MT27710_ens19f0_vf: '1'
[root@node1 ~]# #####启动pod测试
[root@node1 ~]# kubectl apply -f sriov-attach.yaml 
deployment.apps/sriov created
[root@node1 ~]# kubectl get po -o wide 
NAME                     READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
sriov-65c8f754f9-jlcd5   1/1     Running   0          6s    172.25.36.87   node1   <none>           <none>
  • 查看pod
#########1:describe pod查看资源分配情况
[root@node1 wzb]# kubectl describe po sriov-65c8f754f9-jlcd5
Name:         sriov-65c8f754f9-jlcd5
Namespace:    default
Priority:     0
Node:         node1/172.28.30.163
Start Time:   Wed, 28 Feb 2024 20:56:24 +0800
Labels:       app=sriov-attachpod-template-hash=65c8f754f9
Annotations:  cni.projectcalico.org/containerID: 21ec82394a00c893e5304577b59984441bd3adac82929b5f9b5538f988245bf5cni.projectcalico.org/podIP: 172.25.36.87/32cni.projectcalico.org/podIPs: 172.25.36.87/32k8s.v1.cni.cncf.io/network-status:[{"name": "k8s-pod-network","ips": ["172.25.36.87"],"default": true,"dns": {}},{"name": "default/sriov-attach","interface": "net1","ips": ["172.25.36.90"],"mac": "f6:c2:e5:d1:7b:fa","dns": {},"device-info": {"type": "pci","version": "1.1.0","pci": {"pci-address": "0000:41:00.6"}}}]k8s.v1.cni.cncf.io/networks: sriov-attach
Status:       Running
IP:           172.25.36.87
IPs:IP:           172.25.36.87
Controlled By:  ReplicaSet/sriov-65c8f754f9
Containers:nginx:Container ID:   containerd://6d5246c3e36a125ba60bad6af63f8bffe4710d78c2e14e6afb0d466c3f0f5d6eImage:          docker.io/library/nginx:latestImage ID:       sha256:12766a6745eea133de9fdcd03ff720fa971fdaf21113d4bc72b417c123b15619Port:           <none>Host Port:      <none>State:          RunningStarted:      Wed, 28 Feb 2024 20:56:28 +0800Ready:          TrueRestart Count:  0Limits:cpu:                                                 1intel.com/intel_sriov_switchdev_MT27710_ens19f0_vf:  1memory:                                              1GiRequests:cpu:                                                 1intel.com/intel_sriov_switchdev_MT27710_ens19f0_vf:  1  ##pod中已经分配了sriov资源memory:                                              1GiEnvironment:                                           <none>Mounts:/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pnl9d (ro)
Conditions:Type              StatusInitialized       True Ready             True ContainersReady   True PodScheduled      True 
Volumes:kube-api-access-pnl9d:Type:                    Projected (a volume that contains injected data from multiple sources)TokenExpirationSeconds:  3607ConfigMapName:           kube-root-ca.crtConfigMapOptional:       <nil>DownwardAPI:             true
QoS Class:                   Guaranteed
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300snode.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:Type    Reason          Age   From               Message----    ------          ----  ----               -------Normal  Scheduled       105s  default-scheduler  Successfully assigned default/sriov-65c8f754f9-jlcd5 to node1Normal  AddedInterface  103s  multus             Add eth0 [172.25.36.87/32] from k8s-pod-networkNormal  AddedInterface  102s  multus             Add net1 [172.25.36.90/26] from default/sriov-attach  ####sriov网卡正常被添加Normal  Pulled          102s  kubelet            Container image "docker.io/library/nginx:latest" already present on machineNormal  Created         102s  kubelet            Created container nginxNormal  Started         102s  kubelet            Started container nginx
[root@node1 wzb]# #######################
进入pod内部查看,已经有网卡net1 获取到地址
[root@node1 ~]# crictl ps | grep sriov-attach
6d5246c3e36a1       12766a6745eea       4 minutes ago       Running             nginx                      0                   21ec82394a00c
[root@node1 ~]# crictl inspect  6d5246c3e36a1 | grep -i pid "pid": 2775224,"pid": 1"type": "pid"
[root@node1 ~]# ns
nsec3hash         nsenter           nslookup          nss-policy-check  nstat             nsupdate          
[root@node1 ~]# nsenter -t 2775224 -n bash 
[root@node1 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ip_vti0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000link/ipip 0.0.0.0 brd 0.0.0.0
4: eth0@if30729: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc noqueue state UP group default link/ether ae:f9:85:03:13:2f brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 172.25.36.87/32 scope global eth0valid_lft forever preferred_lft foreverinet6 fe80::acf9:85ff:fe03:132f/64 scope link valid_lft forever preferred_lft forever
21: net1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc mq state UP group default qlen 1000link/ether f6:c2:e5:d1:7b:fa brd ff:ff:ff:ff:ff:ffinet 172.25.36.90/26 brd 172.25.36.127 scope global net1valid_lft forever preferred_lft foreverinet6 fe80::f4c2:e5ff:fed1:7bfa/64 scope link valid_lft forever preferred_lft forever
[root@node1 ~]# 

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

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

相关文章

机器人抓取综述

抓取物体的能力是大多数机器人操作任务所需的基 本能力之一。抓取涉及到物体的三维几何和物理特性的 推理&#xff0c;如质量和摩擦&#xff0c;以及复杂接触物理的推理。研究 方向主要有两个:已知物体三维模型或类别的基于模型抓取和不知道物体先验知识的无模型抓取。 基于三…

JavaScript函数(声明函数、调用函数、匿名函数、箭头函数、构造函数)

目录 1. 函数1.1 声明函数1.2 调用函数1.3 匿名函数1.3.1 函数表达式1.3.2 立即执行函数 1.4 箭头函数1.5 构造函数 1. 函数 1.1 声明函数 函数的调用不传递值给形参&#xff0c;且形参没有默认值&#xff0c;则其值为undefined如果没有return返回值&#xff0c;则返回undefi…

MySQL商城数据库表(61-65)

61——订单结算表&#xff08;guo_settlements&#xff09; CREATE TABLE guo_settlements (settlementId int(11) NOT NULL AUTO_INCREMENT COMMENT 自增ID,settlementNo varchar(20) NOT NULL COMMENT 结算单号,settlementType tinyint(4) NOT NULL DEFAULT 0 COMMENT 结算类…

axios下载接口后端返回了json但前端得到的是blob

背景&#xff1a; 通过axios下载文件&#xff0c;正常情况下后端返回内容blob&#xff0c;前端接收并导出文件。但有时候&#xff0c;后端业务逻辑需要提示错误&#xff0c;于是返回json&#xff0c;但前端预期接收的是blob&#xff0c;所以导出去的文件内容是json字符串。 原…

3MF体积设计扩展

3MF 联盟最近宣布了他们最新的体积设计扩展&#xff08;volumetric design extension&#xff09;&#xff0c;用于通过基于体积的描述来编码几何形状和空间多样性属性。 该组织致力于推进 3D 打印的通用规范&#xff0c;目前正在新扩展达到 1.0 之前征求公众反馈。 NSDT工具推…

Linux内核驱动开发-001字符设备开发-内核中断驱动独立按键+等待队列优化

1驱动程序 /*************************************************************************> File Name: key_wait.c> Author: yas> Mail: rage_yashotmail.com> Created Time: 2024年04月23日 星期二 13时20分42秒**********************************************…

OpenCV 实现重新映射

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV 实现霍夫圆变换 下一篇 :OpenCV实现仿射变换 目标 在本教程中&#xff0c;您将学习如何&#xff1a; 一个。使用 OpenCV 函数 cv&#xff1a;&#xff1a;remap 实现简单的重新…

thinkphp 各层简介介绍

Controller层负责和视图打交道&#xff0c;Logic层负责处理逻辑&#xff0c;沟通Controller和Model&#xff0c;Model层负责和数据库打交道&#xff0c;Service层负责封装公共服务 controller 工作&#xff1a;接受请求数据&#xff0c;与业务侧logic打交道获取结果数据返回vie…

20240428如何利用IDM下载磁链视频

缘起&#xff1a; https://weibo.com/tv/show/1034:4864336909500449 中国获奖独立纪录片《阿辉》揭秘红灯区“教父”的生存法则 5,751次观看 1年前 发布于 陕西 身为里中横 67.7万粉丝 互联网科技博主 微博原创视频博主 头条文章作者 https://weibo.com/tv/show/1034:4864…

数据通信-A

数据通信 一、数据通信网络基础二、VRP系统三、eNSP配置命令 不是从零开始&#xff0c;有一些基础&#xff0c;主要记录配置命令。一、数据通信网络基础 图标&#xff1a;主要是认识第一行。 常见术语&#xff1a;数据通信网络最基本的功能是实现数据互通。 数据载荷&#…

解决IDEA下springboot项目打包没有主清单属性

1.问题出现在SpringBoot学习中 , 运行maven打包后无法运行 报错为spring_boot01_Demo-0.0.1-SNAPSHOT.jar中没有主清单属性 SpringBoot版本为 2.6.13 Java 版本用的8 解决方法 1.执行clean 删除之前的打包 2.进行打包规范设置 2.1 3.进行问题解决 (借鉴了阿里开发社区) 使用…

[嵌入式系统-53]:嵌入式系统集成开发环境大全

目录 一、嵌入式系统集成开发环境分类 二、由MCU芯片厂家提供的集成开发工具 三、由嵌入式操作提供的集成开发工具 四、由第三方工具厂家提供的集成开发工具 一、嵌入式系统集成开发环境分类 嵌入式系统集成开发工具和集成开发环境可以按照不同的分类方式进行划分&#xff…

【LAMMPS学习】八、基础知识(5.2)粒度模型

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

将针孔模型相机 应用到3DGS

Motivation 3DGS 的 投影采用的是 CG系的投影矩阵 P P P, 默认相机的 principal point (相机光心) 位于图像的中点处。但是 实际应用的 绝大多数的 相机 并不满足这样一个设定&#xff0c; 因此我们 需要根据 f , c x , c y {f,c_x, c_y} f,cx​,cy​ 这几个参数重新构建3D …

centos 7 yum install -y nagios

centos 7 systemctl disable firewalld --now vi /etc/selinux/config SELINUXdisabled yum install -y epel-release httpd nagios yum install -y httpd nagios systemctl enable httpd --now systemctl enable nagios --now 浏览器 IP/nagios 用户名&#xff1a;…

Anaconda-用conda创建python虚拟环境常用命令

查看安装了哪些包 conda list查看当前存在哪些虚拟环境 conda env list conda info -e检查更新当前conda conda update condaPython创建虚拟环境 conda create -n your_env_name pythonx.xanaconda命令创建python版本为x.x&#xff0c;名字为your_env_name的虚拟环境。you…

Leetcode 第395场周赛 问题和解法

题目 找出与数组相加的整数 I 给你两个长度相等的数组nums1和nums2。 数组nums1中的每个元素都与变量x所表示的整数相加。如果x为负数&#xff0c;则表现为元素值的减少。 在与x相加后&#xff0c;nums1和nums2相等。当两个数组中包含相同的整数&#xff0c;并且这些整数出…

vue学习的预备知识为学好vue打好基础

目录 Vue是什么 &#xff1f;如何使用Vue &#xff1f;Vue ApiVue入口apiVue实例apiVue函数api 无构建过程的渐进式增强静态HTMLVue模块化构建工具npmyarnWebpackvue-cliVite Vue是什么 &#xff1f; 文章基于Vue3叙述。 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于…

探秘STM32内部FLASH的读写操作

探秘STM32内部FLASH的读写操作 在STM32嵌入式系统开发中&#xff0c;内部FLASH是一个重要的存储器&#xff0c;用于存储程序代码和数据。了解如何进行内部FLASH的读写操作对于开发者来说至关重要&#xff0c;可以帮助他们实现数据的存储与更新。本文将深入探讨STM32内部FLASH的…

十大USDT交易平台大全XEX交易所

USDT是一种基于比特币区块链网络的加密代币&#xff0c;主要运用于数字货币交易平台&#xff0c;以稳定币为主。USDT的核心价值在于其与真实货币的固定兑换比率1:1&#xff0c;所以被称为Tether。随着加密货币市场的不断壮大&#xff0c;越来越多的交易平台开始支持USDT&#x…