k8s Service网络详解(一)

news2024/11/24 13:26:03

有关K8s网络的几个概念

Service:服务

Endpoint:端点

Ingress:和Service类似,基于OSI(Open System Interconnection)网络模型的七层协议数据(如HTTP)的转发

Kube Proxy:负载均衡

Pod DNS:Service名称解析

Service Selector:Service 通过标签来选取服务后端

K8s网络模型

Kubernetes 强制要求所有网络设施都满足以下基本要求:

  • 各个Node节点上的Pod之间不需要网络地址转换(NAT)可以直接通信

  • Node节点上的代理(如:系统守护进程、Kubelet)可以和Node节点上的Pod通信

Kubernetes 网络解决四方面的问题:

  • Pod中的容器之间的通信(一个 Pod 中的容器之间通过本地回路(loopback)通信)——容器网络接口(CNI)

  • 不同Pod之间的通信——Pod网络

  • 外部网络访问集群Service——Service网络/Ingress网络

  • 可以使用 Service 来发布仅供集群内部使用的服务

Pod中的容器之间的通信

容器共享Pod的网络命名空间(Network Namespace)-包括它们的 IP 地址和 MAC 地址。 这就意味着 Pod 内的容器都可以通过 localhost 到达对方端口。

k8s网络插件

Kubernetes网络的设计目标是支持多种网络模型,并提供可插拔的网络插件,从而使Kubernetes能够在不同的云和物理环境中运行。以下是几种常用的 Kubernetes 网络插件

  1. Kube-router
  2. Flannel
  3. Calico
  4. Weave Net
  5. Cilium

Service

Service网络是Pod网络和Node节点网络的桥梁,Node上的kube-proxy监听着k8s-apiserver,一旦service资源发生变化(调k8s-api修改service信息),kube-proxy就会生成对应的负载调度的调整,保证service的最新状态。

k8s集群内的service:selector指定pod,自动创建Endpoints

k8s集群外的service:手动创建Endpoints,指定外部服务的ip,端口和协议

Service的访问方式

访问Service可以使用两种方式

1.通过IP方式

2.通过域名方式

通过域名的方式访问Service,k8s 为 Service 和 Pod 创建 DNS 记录。

Service的种类

1.无头Service

2.普通Service

无头服务(Headless Services)

有时不需要或不想要负载均衡,以及单独的 Service IP。 遇到这种情况,可以通过显式指定 Cluster IP(spec.clusterIP)的值为 "None" 来创建 Headless Service。

你可以使用一个无头 Service 与其他服务发现机制进行接口,而不必与 Kubernetes 的实现捆绑在一起。

无头 Services 不会获得 Cluster IP,kube-proxy 不会处理这类服务, 而且平台也不会为它们提供负载均衡或路由。 DNS 如何实现自动配置,依赖于 Service 是否定义了选择算符。

这种Service可以解决的问题:

  • 同时访问所有Pod
  • 一个Service内部的Pod互相访问

对于其他Service来说,客户端在访问服务时,DNS查询时只会返回Service的ClusterIP地址,具体访问到哪个Pod是由集群转发规则(IPVS或iptables)决定的。而Headless Service并不会分配单独的ClusterIP,在进行DNS查询时会返回所有Pod的DNS记录,这样就可查询到每个Pod的IP地址。StatefulSet中StatefulSet正是使用Headless Service解决Pod间互相访问的问题。

带选择算符的服务

对定义了选择算符的无头服务,Kubernetes 控制平面在 Kubernetes API 中创建 EndpointSlice 对象, 并且修改 DNS 配置返回 A 或 AAAA 条记录(IPv4 或 IPv6 地址),这些记录直接指向 Service 的后端 Pod 集合。

无选择算符的服务

对没有定义选择算符的无头服务,控制平面不会创建 EndpointSlice 对象。 然而 DNS 系统会查找和配置以下之一:

  • 对于 type: ExternalName 服务,查找和配置其 CNAME 记录
  • 对所有其他类型的服务,针对 Service 的就绪端点的所有 IP 地址,查找和配置 DNS A / AAAA 条记录
    • 对于 IPv4 端点,DNS 系统创建 A 条记录。
    • 对于 IPv6 端点,DNS 系统创建 AAAA 条记录。

当你定义无选择算符的无头服务时,port 必须与 targetPort 匹配。

Service的类型

  • ClusterIP

  • nodeport

  • LoadBalancer

  • ExternalName

另外,也可以将已有的服务以 Service 的形式加入到 Kubernetes 集群中来,只需要在创建 Service 的时候不指定 Label selector,而是在 Service 创建好后手动为其添加 endpoint。

ClusterIP

默认类型,自动分配一个仅 cluster 内部可以访问的虚拟 IP

可以选择自定义一个IP,在 Service 创建的请求中,可以通过设置 spec.clusterIP 字段来指定自己的集群 IP 地址。用户选择的 IP 地址必须合法,并且这个 IP 地址在 service-cluster-ip-range CIDR 范围内,如果 IP 地址不合法,API 服务器会返回 HTTP 状态码 422,表示值不合法。

  • ClusterIP 是默认和最常见的服务类型。
  • Kubernetes 会为 ClusterIP 服务分配一个集群内部 IP 地址。 这使得服务只能在集群内访问。
  • 您不能从集群外部向服务(pods)发出请求。
  • 您可以选择在服务定义文件中设置集群 IP。

使用场景

集群内的服务间通信。 例如,应用程序的前端(front-end)和后端(back-end)组件之间的通信。

示例

apiVersion: v1
kind: Service
metadata:
  name: my-backend-service
spec:
  type: ClusterIP # Optional field (default)
  clusterIP: 10.10.0.1 # within service cluster ip range
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 8080

保留源IP

各种类型的 Service 对源 IP 的处理方法不同:

ClusterIP Service:使用 iptables 模式,集群内部的源 IP 会保留(不做 SNAT)。如果 client 和 server pod 在同一个 Node 上,那源 IP 就是 client pod 的 IP 地址;如果在不同的 Node 上,源 IP 则取决于网络插件是如何处理的,比如使用 flannel 时,源 IP 是 node flannel IP 地址。

Nodeport

可以在k8s集群外部,通过k8s分配的端口号,或者自定义的端口来访问k8s集群内部的容器。NodePort类型的Service可以让Kubernetes集群每个节点上保留一个相同的端口, 外部访问连接首先访问节点IP:Port,然后将这些连接转发给服务对应的Pod。

k8s 将在指定的范围内分配端口(默认值:30000-32767),端口范围可以通过 --service-node-port-range 字段进行自定义

image-20230723095119657

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    # 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
    - port: 80
      targetPort: 80
      # 可选字段
      # 默认情况下,为了方便起见,Kubernetes 控制平面会从某个范围内分配一个端口号(默认:30000-32767)
      nodePort: 30007
  • NodePort 服务是 ClusterIP 服务的扩展。 NodePort服务路由到的 ClusterIP 服务会自动创建。
  • 它通过在 ClusterIP 之上添加一个集群范围的端口来公开集群外部的服务。
  • NodePort 在静态端口(NodePort)上公开每个节点 IP 上的服务。每个节点将该端口代理到您的服务中。因此,外部流量可以访问每个节点上的固定端口。这意味着对该端口上的集群的任何请求都会转发到该服务。
  • 您可以通过请求 : 从集群外部联系 NodePort 服务。
  • 节点端口必须在 30000-32767 范围内。手动为服务分配端口是可选的。如果未定义,Kubernetes 会自动分配一个。
  • 如果您要明确选择节点端口,请确保该端口尚未被其他服务使用。

使用场景

  • 当您想要启用与您的服务的外部连接时。
  • 使用 NodePort 可以让您自由地设置自己的负载平衡解决方案,配置 Kubernetes 不完全支持的环境,甚至直接公开一个或多个节点的 IP。
  • 最好在节点上方放置负载均衡器以避免节点故障。

示例

apiVersion: v1
kind: Service
metadata:
  name: my-frontend-service
spec:
  type: NodePort
  selector:
    app: web
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 8080
    nodePort: 30000 # 30000-32767, Optional field

保留源IP

默认情况下,源 IP 会做 SNAT,server pod 看到的源 IP 是 Node IP。为了避免这种情况,可以给 service 设置 spec.ExternalTrafficPolicy=Local (1.6-1.7 版本设置 Annotation service.beta.kubernetes.io/external-traffic=OnlyLocal),让 service 只代理本地 endpoint 的请求(如果没有本地 endpoint 则直接丢包),从而保留源 IP。

LoadBalancer

LoadBalancer类型的Service其实是NodePort类型Service的扩展,通过一个特定的LoadBalancer访问Service,这个LoadBalancer将请求转发到节点的NodePort。

在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到 <NodeIP>:NodePort

image-20230723095058433

  • LoadBalancer 服务是 NodePort 服务的扩展。 外部负载均衡器路由到的 NodePort 和 ClusterIP 服务是自动创建的。
  • 它将 NodePort 与基于云的负载均衡器集成在一起。
  • 它使用云厂商的负载均衡器在外部公开服务。
  • 每个云厂商(AWS、Azure、GCP 、阿里云、腾讯云等)都有自己的原生负载均衡器实现。 云厂商将创建一个负载均衡器,然后它会自动将请求路由到您的 Kubernetes 服务。
  • 来自外部负载均衡器的流量被定向到后端 Pod。 云厂商决定如何进行负载平衡。
  • 负载均衡器的实际创建是异步发生的。
  • 每次要向外界公开服务时,都必须创建一个新的 LoadBalancer 并获取 IP 地址。

使用场景

当您使用云厂商来托管您的 Kubernetes 集群时。

举例

apiVersion: v1
kind: Service
metadata:
  name: my-frontend-service
spec:
  type: LoadBalancer
  clusterIP: 10.0.171.123
  loadBalancerIP: 123.123.123.123
  selector:
    app: web
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 8080

保留源IP

默认情况下,源 IP 会做 SNAT,server pod 看到的源 IP 是 Node IP。设置 service.spec.ExternalTrafficPolicy=Local 后可以自动从云平台负载均衡器中删除没有本地 endpoint 的 Node,从而保留源 IP。

ExternalName

将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)。需要 kube-dns 版本在 1.7 以上

  • ExternalName 类型的服务将 Service 映射到 DNS 名称,而不是典型的选择器,例如 my-service。
  • 您可以使用 spec.externalName 参数指定这些服务。
  • 它通过返回带有其值的 CNAME 记录,将服务映射到 externalName 字段(例如 foo.bar.example.com)的内容。
  • 没有建立任何类型的代理。

使用场景

  • 这通常用于在 Kubernetes 内创建服务来表示外部数据存储,例如在 Kubernetes 外部运行的数据库。
  • 当来自一个命名空间的 Pod 与另一个命名空间中的服务通信时,您可以使用该 ExternalName 服务(作为本地服务)。

示例

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: ExternalName
  externalName: my.database.example.com

多端口的service

对于某些服务,你需要公开多个端口。 Kubernetes 允许你在 Service 对象上配置多个端口定义。 为服务使用多个端口时,必须提供所有端口名称,以使它们无冲突。 例如:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 9376
    - name: https
      protocol: TCP
      port: 443
      targetPort: 9377

Endpoint

Kubernetes正是通过Endpoints监控到Pod的IP,从而让Service能够发现Pod。

在 Kubernetes API 中,Endpoints 定义了网络端点的列表(EndpointsList),通常由 Service 引用,以定义可以将流量发送到哪些 Pod。

推荐用 EndpointSlice API 替换 Endpoints

Endpoint资源对象

apiVersion: v1
kind: Endpoints
metadata (ObjectMeta)
 
 Name: "mysvc",
 Subsets: [
   {
     Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}],
     Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}]
   },
   {
     Addresses: [{"ip": "10.10.3.3"}],
     Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}]
   },
]

metadata (ObjectMeta)

subsets ([]EndpointSubset)

所有 subsets 的并集组成所有端点的集合,不同的IP地址放入不同子集,对应一个IP开放多个端口,就绪的端口,放入addresses 中;未就绪的端口,放入notReadyAddress中

EndpointSubset 是一组具有公共端口集的地址。扩展的端点集是 addresses 和 ports 的笛卡尔乘积。例如假设:

{ Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}], Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}] }

则最终的端点集可以看作:

a: [ 10.10.1.1:8675, 10.10.2.2:8675 ], b: [ 10.10.1.1:309, 10.10.2.2:309 ]*

subsets.addresses ([]EndpointAddress):提供标记为就绪的相关端口的 IP 地址。 这些端点应该被认为是负载均衡器和客户端可以安全使用的。

subsets.notReadyAddresses ([]EndpointAddress):提供相关端口但由于尚未完成启动、最近未通过就绪态检查或最近未通过活跃性检查而被标记为当前未就绪的 IP 地址

subsets.ports ([]EndpointPort):相关 IP 地址上可用的端口号。

端点列表(EndpointsList)

apiVersion: v1
kind: EndpointsList
metadata (ListMeta)
items ([]Endpoints)

ListMeta:描述了合成资源必须具有的元数据,包括列表和各种状态对象。 一个资源仅能有 {ObjectMeta, ListMeta} 中的一个。

  • continue (string)

    通过 continue 设置返回的条目数量,表示服务器有更多可用的数据。 该值是不透明的,可用于向提供此列表服务的端点发出另一个请求,以检索下一组可用的对象。 如果服务器配置已更改或时间已过去几分钟,则可能无法继续提供一致的列表。 除非你在错误消息中收到此令牌(token),否则使用此 continue 值时返回的 resourceVersion 字段应该和第一个响应中的值是相同的。

  • remainingItemCount (int64)

    remainingItemCount 是列表中未包含在此列表响应中的后续项目的数量。 如果列表请求包含标签(tag)或字段选择器(selector),则剩余项目的数量是未知的,并且在序列化期间该字段将保持未设置和省略。 如果列表是完整的(因为它没有分块或者这是最后一个块),那么就没有剩余的项目,并且在序列化过程中该字段将保持未设置和省略。 早于 v1.15 的服务器不设置此字段。remainingItemCount 的预期用途是估计集合的大小。 客户端不应依赖于设置准确的 remainingItemCount

  • resourceVersion (string)

    标识该对象的服务器内部版本的字符串,客户端可以用该字段来确定对象何时被更改。 该值对客户端是不透明的,并且应该原样传回给服务器。该值由系统填充,只读。 更多信息: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency 。

  • selfLink (string)

    selfLink 表示此对象的 URL,由系统填充,只读。

    已弃用:selfLink 是一个遗留的只读字段,不再由系统填充。

超出容量的端点

Kubernetes 限制单个 Endpoints 对象中可以容纳的端点数量。 当一个服务有超过 1000 个后备端点时,Kubernetes 会截断 Endpoints 对象中的数据。

对于旧版本的 Endpoints ,超过1000 后备端点的情况,流量仍会发送到后端,Kubernetes 选择最多 1000 个可能的后端端点来存储到 Endpoints 对象中,并在 Endpoints: endpoints.kubernetes.io/over-capacity: truncated 上设置注解如果后端 Pod 的数量低于 1000,控制平面也会移除该注解。

Endpoints 端点 API使用

list 列出或监测 Endpoints 类型的对象

GET /api/v1/namespaces/{namespace}/endpoints

参数:

  • allowWatchBookmarks (查询参数):boolean

  • continue (查询参数):string

  • fieldSelector (查询参数):string

  • labelSelector (查询参数):string

  • limit (查询参数):integer

  • pretty (查询参数):string

  • resourceVersion (查询参数):string

  • resourceVersionMatch (查询参数):string

  • sendInitialEvents (查询参数): boolean

  • timeoutSeconds (查询参数):integer

  • watch (查询参数):boolean

响应

200 (EndpointsList): OK

401: Unauthorized

create 创建 Endpoints

POST /api/v1/namespaces/{namespace}/endpoints

参数

  • namespace (路径参数):string,必需

  • body: Endpoints, 必需

  • dryRun (查询参数):string

  • fieldManager (查询参数):string

  • fieldValidation (查询参数):string

  • pretty (查询参数):string

响应

200 (Endpoints): OK

201 (Endpoints): Created

202 (Endpoints): Accepted

401: Unauthorized

update 替换指定的 Endpoints

PUT /api/v1/namespaces/{namespace}/endpoints/{name}

参数

  • name (路径参数):string,必需 Endpoints 名称

  • namespace (路径参数):string,必需

  • body: Endpoints, required

  • dryRun (查询参数):string

  • fieldManager (查询参数):string

  • fieldValidation (查询参数):string

  • pretty (查询参数):string

响应

200 (Endpoints): OK

201 (Endpoints): Created

401: Unauthorized

delete 删除 Endpoints

DELETE /api/v1/namespaces/{namespace}/endpoints/{name}

参数

  • name (路径参数):string,必需 Endpoints 名称

  • namespace (路径参数):string,必需

  • body: DeleteOptions

  • dryRun (查询参数):string

  • gracePeriodSeconds (查询参数):integer

  • pretty (查询参数):string

  • propagationPolicy (查询参数):string

响应

200 (Status): OK

202 (Status): Accepted

401: Unauthorized

EndpointSlice

Kubernetes 的 EndpointSlice API 提供了一种简单的方法来跟踪 Kubernetes 集群中的网络端点(network endpoints)。EndpointSlices 为 Endpoints 提供了一种可扩缩、可拓展的替代方案。

API Server 自动为设置了选择算符的 Kubernetes Service 创建 EndpointSlice。EndpointSlice 通过唯一的 协议端口号Service 名称将网络端点(network endpoints)组织在一起。

默认情况下,API Server 创建和管理的 EndpointSlice 将包含不超过 100 个Pod。 可以使用 kube-controller-manager的 --max-endpoints-per-slice 标志设置此值,最大值为 1000

EndpointSlice状态

Ready(就绪)

ready 状况是映射 Pod 的 Ready 状况的。对于处于运行中的 Pod,它的 Ready 状况被设置为 True,应该将此 EndpointSlice 状况也设置为 true

Serving(服务中)

如果 EndpointSlice API 的使用者关心 Pod 终止时的就绪情况,就应检查 serving 状况

Terminating(终止中)

特性状态: Kubernetes v1.22 [beta]

Terminating 是表示端点是否处于终止中的状况。 对于 Pod 来说,这是设置了删除时间戳的 Pod

参阅:

k8s中的endpoint

k8s 理解Service工作原理

K8s 核心组件讲解——kube-proxy

详解k8s 4种类型Service

kubernetes集群内部DNS解析原理、域名解析超时问题记录

CoreDNS简介

Kubernetes网络

Service

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

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

相关文章

155、基于STM32单片机老人防跌倒摔倒GSM短信报警系统ADXL345加速度设计(程序+原理图+PCB源文件+参考论文+硬件设计资料+元器件清单等)

毕设帮助、开题指导、技术解答(有偿)见文未 目录 一、硬件方案 二、设计功能 三、实物图 四、原理图 五、PCB图 六、程序源码 资料包括&#xff1a; 需要完整的资料可以点击下面的名片加下我&#xff0c;找我要资源压缩包的百度网盘下载地址及提取码。 单片机主芯片选…

【C语言初阶】指针的运算or数组与指针的关系你了解吗?

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《快速入门C语言》《C语言初阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 &#x1f4cb; 前言&#x1f4ac; 指针运算&#x1f4ad; 指针-整数&#x1f4ad; 指针-指针&#x1f4ad; 指针…

类和对象(中)--运算符重载

目录 1.运算符重载①运算符重载的概念②日期类和运算符重载 2.赋值运算符重载3. 流插入运算符<<重载4.Date类实现5.const成员6.取地址及const取地址操作符重载 1.运算符重载 大家有没有想过内置类型可以使用的运算符是否自定义类型的成员变量也可以使用呢&#xff1f; …

pyqt5-多行文本区QTextEdit实现鼠标滚轮调整文本大小

核心 在 PyQt5 中&#xff0c;你可以通过处理鼠标滚轮事件来设置 QTextEdit 的字体大小。具体做法是在 QTextEdit 上重新实现 wheelEvent 方法&#xff0c;并根据滚轮方向调整字体大小。 代码 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5…

MATLAB 最小二乘法拟合直线点云 方法一 (26)

MATLAB 最小二乘法拟合直线点云 方法一 (26) 一、算法简介二、算法实现1.代码(详细注释)2.结果展示2.1 拟合效果可视化2.2 对比拟合系数与实际值一、算法简介 提供一组点云(x1 y1 )(x2 y2 )(x3 y3 )…等等多个点… 算法自动拟合直线方程 二维点云的直线方程为:y=kx+…

Mac 预览(Preview)丢失PDF标注恢复

感谢https://blog.csdn.net/yaoyao_chen/article/details/127462497的推荐&#xff01; 辛苦用预览在pdf上做的阅读标记&#xff0c;关闭后打开全丢失了&#xff0c;推荐尝试下网站导入文件进行恢复&#xff1a; 直接使用该网页应用PDF Annotation Recovery 或者访问该项目&a…

在 Windows 中通过 WSL 2 高效使用 Docker

大家好&#xff0c;我是比特桃。平时开发中&#xff0c;不免会使用一些容器来跑中间件。而开发者使用的操作系统&#xff0c;大多是Mac OS 、Windows。Docker 为了兼顾这两个平台的用户&#xff0c;推出了 Docker Desktop 应用。Docker Desktop 中的内核还是采用了 Linux 的内核…

swift简单弹幕例子,仿哔哩哔哩

先看例子 每个弹幕的速度都是不一样的&#xff0c;支持弹幕整体开始暂停。 如果弹幕实在是太多了&#xff0c;有个缓冲队列&#xff0c;不停的重试能否显示&#xff0c;保证文字都能显示全&#xff0c;并且每条都能显示。 实现是基于 CADisplayLink 实现的&#xff0c;如此来…

mac使用教程【快速从windows切换为mac,mac快捷键合集】

mac使用教程 1. 安装brew并通过brew安装git 1.1 安装brew 打开终端输入如下命令&#xff1a; % /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"选择对应的镜像进行安装 # 例如&#xff1a;输入5&#xff…

了解 3DS MAX 3D摄像机跟踪设置:第 5部分

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 创建陨石坑 步骤 1 启动 3ds Max 和 打开本教程最后一部分中保存的文件。 启动 3ds Max 步骤 2 删除所有占位符 从头开始创建陨石坑。 删除所有占位符 步骤 3 创建具有“长度”的平面 段和宽度段各…

如何创建vue2,vue3项目

前提需安装node.js和Vue CLI node.js:https://nodejs.org/zh-cn Vue CLI&#xff1a; npm install -g vue/cli 如何创建一个vue2项目 &#xff08;1&#xff09; 使用cmd终端直接创建 进入到vue项目所创建的目录里&#xff08;我是直接创建在桌面上&#xff09; 选择vue2 …

【mysql】聚簇索引和非聚簇索引(B树和B+树)

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: mysql 目录 一、索引分类 二、索引的数据结构 2.1 B树&#xff1a;改造二叉树 2.2 B树&#xff1a;改造B树 三、Mysql索引实现—InnoDB引擎 3.1 主键索引&#xff08;聚簇索引&#xff09; 3.2 …

如何利用plotly和geopandas根据美国邮政编码(Zip-Code)绘制美国地图

对于我自己来说&#xff0c;该需求源自于分析Movielens-1m数据集的用户数据&#xff1a; UserID::Gender::Age::Occupation::Zip-code 1::F::1::10::48067 2::M::56::16::70072 3::M::25::15::55117 4::M::45::7::02460 5::M::25::20::55455 6::F::50::9::55117我希望根据Zip-…

Python读写csv文件

简介 通过Python内置csv模块&#xff0c;可以读取和写入CSV&#xff08;逗号分隔值&#xff09;文件。 CSV是一种常见的文件格式&#xff0c;通常用于存储表格数据&#xff0c;每行数据由逗号分隔&#xff0c;每个字段可以用引号括起来。 测试文件内容如下 列号,年龄,姓名,性别…

香橙派Zero2安装wiringPi外设库

安装wiringOP库 直接在香橙派上下载 wiringOP 的代码 sudo apt update sudo apt install -y git git clone https://github.com/orangepi-xunlong/wiringOP 如果在香橙派上下载不下来&#xff0c;也可以在通过windows浏览器打开https://github.com/orangepi-xunlong/wiringOP …

【【高级程序设计语言C++】C++多态的概念及原理

1. 多态的概念2. 多态的定义及实现2.1. 多态的条件2.2. 虚函数2.3. 虚函数的重写2.4. 虚函数重写的两个例外2.5. C11的override和final2.6. 重载、重写、重定义的对比 3. 抽象类3.1. 概念3.2. 实现继承和接口继承的对比 4. 多态的原理4.1. 虚函数表4.2. 多态原理4.3. 动态绑定和…

(34)继电器开关

文章目录 前言 34.1 装有IOMCU的自动驾驶仪上的继电器引脚 34.2 通过任务规划器定义继电器引脚 34.3 飞行员控制继电器 34.4 任务控制继电器 34.5 任务规划器控制继电器 前言 "继电器"是自动驾驶仪上的一个数字输出引脚&#xff0c;可在 0V 和 3.3V 或 5V 之间…

商城-学习整理-基础-分布式组件(三)

目录 一、前言二、Spring Cloud&Spring Cloud Alibaba1、Spring Cloud 与Spring Cloud Alibaba简介2、为什么使用Spring Cloud Alibaba3、版本选择4、项目中的依赖 三、Spring Cloud Alibaba-Nacos作为注册中心1、Nacos1&#xff09;、下载 nacos-server2&#xff09;、启动…

【C++ 程序设计】第 1~9 章:常见知识点汇总

目录 一、C 语言简介 二、面向对象的基本概念 三、类和对象进阶 四、运算符重载 五、类的继承与派生 六、多态与虚函数 七、输入/输出流 八、文件操作 九、函数模板与类模板 一、C 语言简介 知识点名称内容C语言的发展简史★★1. C 语言是 C 语言的前身 &…

让GPT人工智能变身常用工具-上

1.密码生成器:GPT为您创建安全密码 想象GPT作为您的个人密码生成器,负责从头到尾为您创建复杂且安全的密码。您只需要告诉他您的密码需求,比如密码的长度,是否包含大写字母、小写字母、数字或特殊字符,他会立即为您生成一个复杂但经过深度设计的密码。 例子: 我希望您…