kubernetes网络(一)之calico详解

摘要

本文介绍Kubernetes最流行的网络解决方案calico。

kubernetes中不同宿主上的pod需要相互通信,如果按TCP/IP协议分层进行分类:

  • 二层方案:flannel的udp和vxlan模式

  • 三层方案:flannel的host-gw模式;calico的IPIP模式与BGP模式;kube-router

本文我们学习calico具体是如何运作的。

引出

在介绍calico之前,先来看一个网络中最最常见也最简单的网络通信案例, 如图所示:

在这里插入图片描述

有2个三层交换机,每个交换机下面有一个网段,分别是192.168.1.0/24和192.168.2.0/24网段。同时每个交换机各自连接了2台服务器,各个服务器的IP如上图所示。为了实现服务器之前相互通信,可以这些实现:

1) 两个交换机运行三层路由协议比如ospf,bgp,进行相互路由学习。

2)各个服务器将网关指向对应的交换机。

当两个三层交换机路由协议完成邻接状态后,交换机A学习到,要去192.168.2.0/24网段,下一跳地址是交换机B。同理交换机B学习到,要去192.168.1.0/24网段,下一跳地址是交换机A。

这是如何服务器A需要与服务器C通信,路由是这样的:

  1. 服务器A先判断服务器C的IP地址,不是与其在同一网段,那么服务器A将数据包交给网关即交换机A ,数据包的格式:

|目的IP=192.168.2.10|源IP=192.168.1.10| DATA |

  1. 交换机收到数据包后,查询自己的路由表,发现数据包的目的IP是192.168.2.10,是属于192.168.2.0/24网段。进而从路由表查到下一跳是交换机B的互联地址192.168.100.2,于是数据包被传递给交换机B
  2. 交换机B收到数据包后,先查看数据包的目的IP是192.168.2.10,再查询交换机自己的路由表,查询到192.168.2.0/24是属于它的直连网段,于是交换机通过arp查询到服务器C的mac是CCCC.CCCC.CCCC.CCCC,于是将数据包通过二层转发给服务器C。至此,就完成了单边路由,同理回程路由也是一样的。

再多想一下,假如上图中的服务器演变是pod,而三层交换机演变为宿主中的一个运行了bgp路由协议的进程(bird),如下图:

在这里插入图片描述

这就是calico的雏形。所以某种程度上说,calico看似很简单,就是将宿主节点当作虚拟路由vRouter,为POD做路由转发能力。

Calico的介绍

calico简介

Calico是一个开源的网络和网络安全解决方案,适用于容器、虚拟机和基于本机主机的工作负载。Calico支持多种平台,包括Kubernetes、OpenShift、Docker EE、OpenStack和裸机服务。 Calico将灵活的网络功能与随时随地运行的安全实施相结合,提供了具有本地Linux内核性能和真正的云本地可伸缩性的解决方案。Calico为开发人员和集群运营商提供一致的体验和功能集,无论是在公共云中运行还是在本地运行,都可以在单个节点上运行。 — calico官网

Calico 方案的特点:

  • 由于Calico是一种纯三层的实现,因此可以避免与二层方案相关的数据包封装的操作,中间没有任何的NAT,没有任何的overlay,所以它的转发效率可能是所有方案中最高的。
  • Calico还能为通信实现网络控制策略,因为数据包直接走原生TCP/IP的协议栈,而TCP/IP的协议栈提供了一整套的防火墙的规则,所以它可以通过IPTABLES的规则达到比较复杂的隔离逻辑。

Calico优劣势

优势
  • 更优的资源利用
    二层网络通讯需要依赖广播消息机制,广播消息的开销与host的数量呈指数级增长,Calico使用的三层路由方法,则完全抑制了二层广播,减少了资源开销。此外,二层网络使用Vlan隔离技术,天生有4096个规格限制,即便可以使用Vxlan解决,但Vxlan又带来了隧道开销的问题。Calico不使用vlan或者vxlan技术,使资源利用率更高。

  • 可扩展性
    Calico使用与Internet类似的方案,Internet的网络比任何数据中心都大,Calico同样天然具有扩展性。

  • 简单更容易调试
    由于没有隧道,意味着workloads之间路径更短,配置更少,在host之间更容易进行debug调试。

  • 更少的依赖
    Calico仅依赖三层路由可达

  • 可适配性
    Calico较少的依赖性使它能适配所有的VM、Container、白盒或者混合环境场景。

  • 支持网络策略

    可以配合使用 Network Policy 做 pod 和 pod 之前的访问控制

劣势
  • 要求宿主机处于同一个2层网络下,也就是连在一台交换机上
  • 路由的数目与容器数目相同,非常容易超过路由器、三层交换、甚至node的处理能力,从而限制了整个网络的扩张。(可以使用大规模方式解决)
  • 每个node上会设置海量的iptables规则、路由,运维、排障难度大。
  • 原理决定了它不可能支持VPC,容器只能从calico设置的网段中获取ip。

calico的架构

在这里插入图片描述

(图片来自网络,如有请求请联系作者)

Calico的主要工作组件包括:

  1. Felix:运行在每一台 Host 的 agent 进程,主要负责网络接口管理和监听、路由、ARP 管理、ACL 管理和同步、状态上报等。Felix会监听ECTD中心的存储,从它获取事件,比如说用户在这台机器上加了一个IP,或者是创建了一个容器等。用户创建pod后,Felix负责将其网卡、IP、MAC都设置好,然后在内核的路由表里面写一条,注明这个IP应该到这张网卡。同样如果用户制定了隔离策略,Felix同样会将该策略创建到ACL中,以实现隔离。
    • 接口管理:Felix为内核编写一些接口信息,以便让内核能正确的处理主机endpoint的流量。特别是主机之间的ARP请求和处理ip转发。
    • 路由规则:Felix负责主机之间路由信息写到linux内核的FIB(Forwarding Information Base)转发信息库,保证数据包可以在主机之间相互转发。
    • ACL规则:Felix负责将ACL策略写入到linux内核中,保证主机endpoint的为有效流量不能绕过calico的安全措施。
    • 状态报告:Felix负责提供关于网络健康状况的数据。特别是,它报告配置主机时出现的错误和问题。这些数据被写入etcd,使其对网络的其他组件和操作人员可见。
  2. etcd:分布式键值存储,主要负责网络元数据一致性,确保Calico网络状态的准确性,可以与kubernetes共用;
  3. BIRD :Calico 为每一台 Host 部署一个 BGP Client,使用 BIRD 实现,BIRD 是一个单独的持续发展的项目,实现了众多动态路由协议比如 BGP、OSPF、RIP 等。在 Calico 的角色是监听 Host 上由 Felix 注入的路由信息,然后通过 BGP 协议广播告诉剩余 Host 节点,从而实现网络互通。
  4. BGP Route Reflector:在大型网络规模中,如果仅仅使用 BGP client 形成 mesh 全网互联的方案就会导致规模限制,因为所有节点之间俩俩互联,需要 N^2 个连接,为了解决这个规模问题,可以采用 BGP 的 Router Reflector 的方法,使所有 BGP Client 仅与特定 RR 节点互联并做路由同步,从而大大减少连接数。
  5. Calicoctl:calico 命令行管理工具。
  6. Orchestrator plugin:协调器插件负责允许kubernetes或OpenStack等原生云平台方便管理Calico,可以通过各自的API来配置Calico网络实现无缝集成。如kubernetes的cni网络插件。

IPIP与BGP模式

  1. BGP

边界网关协议(Border Gateway Protocol, BGP)是互联网上一个核心的去中心化自治路由协议。它通过维护IP路由表或‘前缀’表来实现自治系统(AS)之间的可达性,属于矢量路由协议。BGP不使用传统的内部网关协议(IGP)的指标,而使用基于路径、网络策略或规则集来决定路由。因此,它更适合被称为矢量性协议,而不是路由协议。BGP路由模式使用直接路由,避免了数据包封装与解封,所以性能是最好的。

BGP模式使用的是直接路由方式,在kubernetes中,由于pod所在网段对于内网交换机是无法识别的,所以使用的BGP模式的前提是:宿主之间必须在同一个二层域内。(如果对网络不是特别熟悉的话,可能无法准确理解,后面我会单独分析。请见"补充")

  1. IPIP

IPIP模式是把 IP 层封装到 IP 层的一个 tunnel。它的作用其实基本上就相当于一个基于IP层的网桥!一般来说,普通的网桥是基于mac层的,根本不需 IP,而这个 ipip 则是通过两端的路由做一个 tunnel,把两个本来不通的网络通过点对点连接起来。ipip 是由linx内核实现,的源代码在内核 net/ipv4/ipip.c 中可以找到。

IPIP模式是calico默认的模式,无论宿主是否在同一二层域都可以。缺点是经过IPIP封装与解封,性能有稍微损失。性能对比请详解文章:calico的两种网络模式BGP和IP-IP性能分析。

特别说明:IPIP模式下,宿主上的bird进程仍然会跑BGP,只是POD to POD 通信的数据包会被,宿主利用隧道进行封装。

  1. 混合模式

从上面可以看出IPIP模式的优点是只要宿主之间三层互通即可,而BGP模式需要宿主之间必须在一个二层域内。但BGP使用直接路由,性能又是最好的。 所以calico的混合模式,可以动态的自行选择模式:即如果两宿主在同一二层域就选择BGP模式,不再同一二层域就选择IPIP模式。

calico模式调整

接下来介绍如何修改calico的网络模式:

kubectl edit ippool

在这里插入图片描述

ipipMode: Always 为默认值,即使用IPIP模式。如果要修改为BPG模式,需要将值改Never。另外,可以将值修改为CrossSubnet,表示如果两宿主节点在同一个二层网络使用BGP模式,而不在同一二层模式这使用IPIP模式

如下图,我们将calico网络模式修改为混合模式后,观察路由表如下:
在这里插入图片描述

可以看到如果目的宿主10.234.12.77/85与本宿主10.234.12.78在同一网段,那么使用的是直接路由即BGP模式,如果目的宿主172.23.67.73与本宿主10.234.12.78不在同一网段,使用的IPIP模式(走的隧道tunl0)。

代理ARP

calico方案中,将veth pair一段插入pod,另一端插入宿主内核协议栈中,无需为宿主段的veth配置IP,也无需接入bridge.借用代理arp,将pod的默认路由都转发到宿主的网络协议栈,借助宿主进行路由转发。

进入Pod,可以看到pod的默认路由是走169.254.1.1

在这里插入图片描述

pod的mac地址

在这里插入图片描述

pod里面查看arp表, 169.254.1.1对应的mac是特殊的地址ee:ee:ee:ee:ee:ee

在这里插入图片描述

登录宿主可以看到,去往pod的接口是cali5ef7fb336ae

在这里插入图片描述

宿主上可以看到 cali5ef7fb336ae 没有配置IP地址

在这里插入图片描述

Pod 与 宿主互联的示意图

在这里插入图片描述

169.254.1.1 是一个特殊的 IP 。不过这里这个 IP 并不重要,只是为了防止冲突才选择了这个特殊值。当 Pod 要访问其他 IP 时,如果该 IP 在同一个网段,那就需要获取该 IP 的 MAC 地址。如果目的IP不在一个网段,那么根据路由表,就要获取网关的 IP 地址。所以无论如何,arp 请求都会到达上图中的 calico5e7fb336ac。因为宿主开启了代理ARP功能 proxy_arp=1,所以宿主就会返回自己的 MAC 地址ee:ee:ee:ee:ee:ee,然后 Pod 的流量就发到了主机的网络协议栈。到达网络协议栈之后,被可以被宿主转发到对端的主机上。

calico路由反射器

为何需要路由反射器

默认情况下calico的BGP建立 peer 关系是node to node mesh,见下图PEER TYPE。Calico集群中的节点之间都会相互建立连接,用于路由交换。但是随着集群规模的扩大,mesh模式将形成一个巨大服务网格,连接数成倍增加。这时就需要使用 Route Reflector(路由器反射)模式解决这个问题。确定一个或多个Calico节点充当路由反射器,让其他节点从这个RR节点获取路由信息。

在这里插入图片描述

路由反射器的实战

实验环境有4个 calico node节点。 默认情况下,他们使用 node to node mesh 即全互联模式。我们的目标是使用10.234.12.78选做一台路由反射器RR。RR会与其他所有calico node 建立BGP peer, 而calico node 只会与 RR 建立 BGP Peer关系。

在这里插入图片描述

在这里插入图片描述

1) 先禁用nodetonode mesh模式,将nodeToNodeMeshEnabled对应值改为false

$ cat << EOF | calicoctl create -f -
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:name: default
spec:logSeverityScreen: InfonodeToNodeMeshEnabled: falseasNumber: 64512
EOF

在这里插入图片描述

2) 配置 BGP node 与 Route Reflector 的连接建立规则

$ cat << EOF | calicoctl create -f -
kind: BGPPeer
apiVersion: projectcalico.org/v3
metadata:name: peer-to-rrs
spec:# 规则1:普通 bgp node 与 rr 建立连接nodeSelector: "!has(i-am-a-route-reflector)"peerSelector: has(i-am-a-route-reflector)---
kind: BGPPeer
apiVersion: projectcalico.org/v3
metadata:name: rr-mesh
spec:# 规则2:route reflectors 之间也建立连接nodeSelector: has(i-am-a-route-reflector)peerSelector: has(i-am-a-route-reflector)
EOF

nodeSelector 表示这个规则针对谁生效的。

peerSelector 表示与谁建立peer关系

在这里插入图片描述

3) 选择并配置 Route Reflector 节点

Save the node YAML.

$ calicoctl get node 10.234.12.78 -o yaml --export > node.yaml

Edit the YAML to add

metadata:labels:# 设置标签, 表示本节点作为 rr 角色i-am-a-route-reflector: true
spec:bgp:# 设置集群IDrouteReflectorClusterID: 224.0.0.1

Reapply the YAML

$ calicoctl apply -f node.yaml

Reapply 之后查询 calico node 信息。

在这里插入图片描述

4) 确认 RR peer 状态

当完成使用路由反射器建立BGP邻居关系后,PEER TYPE 将显示为 “node specific”,下图是RR上执行命令结果,可以看到 RR 与 其他calico node 都建立了 PEER关系。

在这里插入图片描述

另一台calico node 只与 RR 建立 PEER关系

在这里插入图片描述

另一台calico node 只与 RR 建立 PEER关系
在这里插入图片描述

RR 上查看 BGPPEER
在这里插入图片描述

说明:对于生产环境为了保证高可用性,在节点数较多的K8S集群建议配置3-4个 RR 节点。

关于路由反射器的使用,还可详解官方文档configure-bgp-peering

补充

calicoctl的安装与使用

  • 安装 calicoctl

curl -O -L https://github.com/projectcalico/calicoctl/releases/download/v3.14.2/calicoctl

chmod +x calicoctl

mv calicoctl /usr/local/bin/

  • 设置 calicoctl 配置文件
# 设置 calicoctl 配置文件
$ vim /etc/calico/calicoctl.cfg
apiVersion: projectcalico.org/v3
kind: CalicoAPIConfig
metadata:
spec:datastoreType: "kubernetes"kubeconfig: "/path/to/.kube/config"# pod 的网络endpoints
$ calicoctl get workloadendpoints# 查看 calico 节点
$ calicoctl get nodes# 查看 IPAM的IP地址池以及IPIP模式
$ calicoctl get ippool -o wide# 查看 calico node 详细信息
$ calicoctl get node -oyaml# 查看bgp网络配置情况, 可调整是否启用路由反射器
$ calicoctl get bgpconfig -oyaml# 查看ASN号,一个编号就是一个自治系统
$ calicoctl get nodes -owide# 查看 bgp peer
$ calicoctl get bgppeer

详情可参考calicao官网config calicoctl

为何BGP模式下要求宿主在同一个二层域内

在同一个二层域内的宿主,可以通过mac地址通信,无需借助三层路由器中转数据包。

在这里插入图片描述

假设两台宿主分别连接到一个三层路由器,注意三层路由器具有二层和三层能力,这里特别说明下,这里三层交换机划分了2个二层域,也就是2个网段,一个网段连接宿主1,一个网段连接宿主2。

两个宿主上运行calico,使用BGP模式。宿主之间建立BGP Peer,因为BGP建立邻居关系是通过TCP,所以即使两个宿主在不同网段也是可以建立BGP Peer的。所以宿主1与宿主2也能相互学习到对方”下挂“的容器所在网段。当完成路由学习后,两宿主与交换机的路由表如上图。

  • 下面我们看看POD A访问POD C会出现什么问题。
  1. POD A访问 POD C,数据包如下:

    |目的IP=192.168.2.10|源IP=192.168.1.10| DATA |

  2. POD A发现目的IP所在网段与自己不是同一网段,所以POD A把数据包交给宿主1,宿主1由于之前通过BIRD学习到目的IP在宿主2,通俗的说即要去往192.168.2.0/24网段,下一跳是172.16.2.20。于是宿主1查询本地路由表,要去往172.16.2.20,需要把数据包交给三层交换机172.16.1.1。

  3. 交换机收到数据包后,查询数据包的目的IP是192.168.2.20,这时问题来了,由于三层交换机没有通过路由协议与宿主2进行路由交换路由信息,所以交换机不知道192.168.2.0/24网段是需要去往宿主2。这时交换机由于从自己路由表匹配到目标网段。所以被迫选择0.0.0.0作为下一跳,于是将数据包错误地发往核心网络中。最终导致了数据包无法到达POD C

  • 那么问题又来了,如何解决这种问题呢?

方法一: 将交换机参与与宿主之间的BGP路由交换,交换机就可以学习到宿主下的容器网段。这种方法也就是把kubernetes的容器网段同步内网中去,所以要求kubernetes的网段得整体规划,不能与现有内网网段冲突,如下图所示。想要具体如何实现可参考文档:使用Calico的BGP发布Kubernetes Service IP路由在这里插入图片描述

方法二:改用IPIP模式。即数据包到达宿主1后,calico的IPIP模式,会将数据包进行封装,在原数据包基础上加一层IP包头。封装后的IP包如下:

|外层目的IP=172.16.2.20|外层源IP=172.16.1.10|目的IP=192.168.1.10|源IP=192.168.2.10| DATA |

这样经过封装后,交换机收到数据包后,查询看外层目的IP是172.16.2.20,于是就能将数据包发到宿主2,宿主2收到数据包,先将数据包接封装,解封装后里层的数据包的目的IP是192.168.2.20,于是就能将数据包发往POD C。

参考文档

calico bgp mode

calico 配置 BGP Route Reflectors

calico-bgp-rr

calico 简介

calicoctl install

calico的两种网络模式BGP和IP-IP性能分析

K8S Calico网络插件之BGP模式

brid的基本使用

Calico中的网络模式选择最佳实践

bird官网

使用Calico的BGP发布Kubernetes Service IP路由

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

pod介绍与配置

1、pod概念介绍 Pod 是 kubernetes 基本调度单位。每个 Pod 中可以运 行一个或多个容器&#xff0c;共享 Pod 的文件系统、IP 和网络等资源&#xff0c;每个 Pod 只有一个 IP。 2、使用 yaml或json 文件创建 Pod 声明式文件方式创建 Pod&#xff0c;支持 yaml 和 json 1&…

【Fastapi】参数获取,json和query

【Fastapi】参数获取&#xff0c;json和query 前言giteegithub query形式json传递同步方法使用json 前言 花了半个月的时间看了一本小说&#xff0c;懈怠了…今天更新下fastapi框架的参数获取 gitee https://gitee.com/zz1521145346/fastapi_frame.git github https://git…

【网络通信基础与实践番外一】多图预警之图解UDP和TCP前置知识

参考大佬的文章https://www.cnblogs.com/cxuanBlog/p/14059379.html 一、宏观架构中的传输层 在计算机中&#xff0c;任何一个可以交换信息的介质都可以称为端系统。计算机网络的运输层则负责把报文从一端运输到另一端&#xff0c;运输层实现了让两个互不相关的主机进行了逻辑…

【洛谷】P10417 [蓝桥杯 2023 国 A] 第 K 小的和 的题解

【洛谷】P10417 [蓝桥杯 2023 国 A] 第 K 小的和 的题解 题目传送门 题解 CSP-S1 补全程序&#xff0c;致敬全 A 的答案&#xff0c;和神奇的预言家。 写一下这篇的题解说不定能加 CSP 2024 的 RP 首先看到 k k k 这么大的一个常数&#xff0c;就想到了二分。然后写一个判…

Netty系列-4 Pipeline和Handler

背景 Netty将IO事件按照流向划分为两个部分&#xff1a;Inbound入站事件和Outbound出站事件。入站事件由外部触发&#xff0c;包括通道注册(register)、通道激活(active)、数据可读(read)、通道异常(exceptionCaught)等&#xff1b;出站事件由程序主动触发&#xff0c;如连接的…

人工智能不是人工“制”能

文/孟永辉 如果你去过今年在上海举办的世界人工智能大会&#xff0c;就会知道当下的人工智能行业在中国是多么火爆。 的确&#xff0c;作为第四次工业革命的重要组成部分&#xff0c;人工智能愈发引起越来越多的重视。 不仅仅是在中国&#xff0c;当今世界的很多工业强国都在将…

828华为云征文|云服务器Flexus X实例|MacOS系统-宝塔部署Nuxt项目

文章目录 1. Flexus云服务器X实例1.1 与Flexus应用服务器L实例相比具备以下优势1.2 服务器的详细配置 2.宝塔部署Nuxt项目2.1 登录实例2.1 宝塔面板 3. Nuxt 项目与部署3.1 Nuxt3.2创建Nuxt项目3.3 部署3.4 部署成功 4.结语 1. Flexus云服务器X实例 华为云的Flexus云服务是为中…

C++高精度计时方法总结(测试函数运行时间)

文章目录 一、clock()函数——毫妙级二、GetTickCount()函数&#xff08;精度16ms左右&#xff09;——毫妙级三、高精度时控函数QueryPerformanceCounter()——微妙级四、高精度计时chrono函数——纳妙级五、几种计时比较六、linux下的计时函数gettimeofday()-未测试参考文献 …

typedef的用法

typedef只有一种用法&#xff0c;那就是&#xff1a; 1,代替各种类型或某类&#xff08;结构体&#xff09;成员。 比如下列代码&#xff1a; #include <iostream> #include <string> int main() {typedef int i;i e3;int f3;std::string t_or_f(ef)?"tru…

OpenAI的O1模型达到AGI二级,类人推理能力被提示危险,细思极恐!

大家好&#xff0c;我是Shelly&#xff0c;一个专注于输出AI工具和科技前沿内容的AI应用教练&#xff0c;体验过300款以上的AI应用工具。关注科技及大模型领域对社会的影响10年。关注我一起驾驭AI工具&#xff0c;拥抱AI时代的到来。 今天让我们一起来聊聊最近科技圈的大新闻—…

利士策分享,家庭内耗:隐形的风暴,无声的侵蚀

利士策分享&#xff0c;家庭内耗&#xff1a;隐形的风暴&#xff0c;无声的侵蚀 在温馨的灯光下&#xff0c;家本应是我们心灵的港湾&#xff0c;是疲惫时最坚实的依靠。 然而&#xff0c;当家庭内部出现裂痕&#xff0c;无形的内耗便如同冬日里的寒风&#xff0c;悄无声息地…

SpringBoot 3.4.0还没来之前,又又又更新啦!SpringBoot 3.3.4版本依赖升级,性能与稳定性再提升!

为什么要使用SpringBoot在现代开发中&#xff0c;高效与灵活性是每个开发团队追求的核心目标。然而&#xff0c;如何在不牺牲灵活性的前提下&#xff0c;快速构建复杂的应用程序&#xff0c;常常成为开发者的难题。SpringBoot的出现&#xff0c;正是为了解决这个矛盾。它以“约…

Spring Boot技术在高校心理辅导系统中的应用研究

3 系统分析 3.1可行性分析 在进行可行性分析时&#xff0c;我们通常根据软件工程里方法&#xff0c;通过四个方面来进行分析&#xff0c;分别是技术、经济、操作和法律可行性。因此&#xff0c;在基于对目标系统的基本调查和研究后&#xff0c;对提出的基本方案进行可行性分析。…

【C++初阶】探索STL之——vector

【C初阶】探索STL之——vector 1.什么是vector2.vector的使用2.1 vector的定义2.2 vector iterator(迭代器)的使用2.3 vector空间问题2.4 vector的增删查改2.5 vector迭代器失效的问题2.5.1 vector常见迭代器失效的操作 3 动态二位数组 1.什么是vector vector其实就是一个可以…

GNU链接器(LD):设置入口点(ENTRY命令)的用法及实例解析

0 参考资料 GNU-LD-v2.30-中文手册.pdf GNU linker.pdf1 前言 一个完整的编译工具链应该包含以下4个部分&#xff1a; &#xff08;1&#xff09;编译器 &#xff08;2&#xff09;汇编器 &#xff08;3&#xff09;链接器 &#xff08;4&#xff09;lib库 在GNU工具链中&…

3.5.2 __ipipe_init()之完成中断处理程序设置

点击查看系列文章 》 Interrupt Pipeline系列文章大纲-CSDN博客 原创不易&#xff0c;需要大家多多鼓励&#xff01;您的关注、点赞、收藏就是我的创作动力&#xff01; 3.5.2 __ipipe_init()之完成中断处理程序设置 __ipipe_init()最核心的就是__ipipe_enable_pipeline()&am…

Mybatis自定义TypeHandler,直接存储枚举类对象

在这篇文章中&#xff0c;我们已经知道如何使用枚举类直接接受前端的数字类型参数&#xff0c;省去了麻烦的转换。如果数据库需要保存枚举类的code&#xff0c;一般做法也是代码中手动转换&#xff0c;那么能不能通过某种机制&#xff0c;省去转换&#xff0c;达到代码中直接保…

PowerMill 2025简体中文版百度云资源分享下载

如大家所了解的&#xff0c;PowerMill是一款专业的CAM&#xff08;计算机辅助制造&#xff09;软件。主要用于加工行业&#xff0c;可以帮助用户进行高效、精准的加工工艺设计和数控编程&#xff0c;以达到生产部件的高精度和高质量。 对于初次接触的小伙伴来说&#xff0c;目…

k均值vs高斯混合模型

K均值&#xff08;K-means&#xff09;和高斯混合模型&#xff08;Gaussian Mixture Model, GMM&#xff09;是常用的聚类算法。 K均值是非概率模型&#xff0c;根据&#xff08;欧氏&#xff09;距离判断&#xff0c;类比最小距离分类器&#xff08;分类&#xff09;。高斯混…

240922-chromadb的基本使用

A. 基本使用 ChromaDB 是一个专门为向量数据库和嵌入查询优化的数据库。它可以与嵌入模型结合使用&#xff0c;存储和查询高维向量数据&#xff0c;通常用于大规模语义搜索、推荐系统等领域。 以下是使用 ChromaDB 的步骤&#xff1a; 1. 安装 ChromaDB 你可以通过 pip 安装…