文章目录

  • 01 资源对象概述
  • 02 集群类
    • 2.1 Master
    • 2.2 Node
    • 2.3 命名空间
  • 03 应用类
    • 3.1 service和pod
    • 3.2 label与标签选择器
    • 3.3 Pod和Deployment
    • 3.4 Service和ClusterIp
    • 3.5 Service外网访问
    • 3.6 有状态的应用集群
    • 3.7 批处理应用
    • 3.8 应用的配置
      • 3.8.1 ConfigMap
      • 3.8.2 Secret
    • 3.9 应用的运维
      • 3.9.1 HPA横向扩容
      • 3.9.2 VPA垂直扩容
  • 04 存储类
    • 4.1 Volume(存储卷)
      • 4.1.1 emptyDir(临时目录)
      • 4.1.2 hostPath(宿主机目录)
      • 4.1.3 公有云Volume
      • 4.1.4 其它类型的Volume
      • 4.1.5 动态存储
  • 05 安全类
    • 5.1 Service Account
    • 5.2 Role
    • 5.2 Role Binding
    • 5.3 NetworkPolicy(网络策略)

01 资源对象概述

Kubernetes 中的基本概念和术语大多是围绕 资源对象Resource Object)来说 的,而资源对象在总体上可分为以下两类:

  1. 某种资源的对象。例如节点NodePod、服务Service、存储卷 Volume
  2. 与资源对象相关的事物与动作。例如标签Label、注解Annotation、命名空间Namespace、部署DeploymentHPAPVC

资源对象一般包括几个通用属性:版本、类别(Kind)、名称、标签、注解,如下所述。

  • 版本信息:包括了此对象所属的资源组,一些资源对象的属性会随着版本的升级而变化,在定义资源对象时要特别注意这一点。
  • 类别属性:用于定义资源对象的类型。
  • 资源对象的名称(Name)、标签、注解这三个属性属于资源对象的元数据(metadata),资源对象的名称要唯一。资源对象的标签是很重要的数据,也是 Kubernetes 的一大设计特性,比如通过标签来表明资源对象的特征、类别,以及通过标签筛选不同的资源对象并实现对象之间的关联、控制或协作功能。
  • 注解:可被理解为一种特殊的标签,不过更多地是与程序挂钩,通常用于实现资源对象属性的自定义扩展。

我们可以采用 YAMLJSON 格式声明(定义或创建)一个 Kubernetes 资源对象,每个资源对象都有自己的特定结构定义(可以理解为数据库中一个特定的表),并且统一保存在 etcd 这种非关系型数据库中,以实现最快的读写速度。此外,所有资源对象都可以通过 Kubernetes 提供的kubectl工具(或者 API 编程调用)执行增、删、改、查等操作。

这里按照功能或用途对众多资源对象其进行分类,将其分为集群类、应用类、存储类及安全类这四大类,下面来讲解。

02 集群类

集群(Cluster)表示一个由 MasterNode 组成的 Kubernetes 集群。

2.1 Master

Master指的是集群的控制节点。在每个 Kubernetes 集群中都需要有一个或一组被称为 Master 的节点,来负责整个集群的管理和控制。Master 通常占据一个独立的服务器(在高可用部署中建议至少使用 3 台服务器),是整个集群的“大脑”,如果它发生宕机或者不可用,那么对集群内容器应用的管理都将无法实施。

Master上运行着以下关键进程:

  • Kubernetes API Server (kube-apiserver):提供 HTTP RESTful API 接口的主要服务,是 Kubernetes 里对所有资源进行增、删、改、查等操作的唯一入口,也是集群控制的入口进程。
  • Kubernetes Controller Manager:Kubernetes 里所有资源对象的自动化控制中心,可以将其理解为资源对象的“大总管”。
  • Kubernetes Scheduler:负责资源调度(Pod 调度)的进程,相当于公交公司的调度室。
  • Master上通常还需要部署etcd服务。

2.2 Node

Kubernetes集群中除 Master 外的其他服务器被称为 NodeNode 可以是一台物理主机,也可以是一台虚拟机。NodeKubernetes集群中的工作负载节点,每个 Node 都会被 Master 分配一些工作负载(Docker 容器),当某个Node宕机时,其上的工作负载会被 Master 自动转移到其他 Node 上。

在每个 Node 上都运行着以下关键进程:

  • kubelet:负责 Pod 对应容器的创建、启停等任务,同时与 Master 密切协作,实现集群管理的基本功能。
  • kube-proxy:实现 Kubernetes Service 的通信与负载均衡机制的服务。
  • 容器运行时(如 Docker : 负责本机的容器创建和管理。

我们可以运行以下命令查看在集群中有多少个 Node:

查询node详情:

2.3 命名空间

在集群类里还有一个重要的基础概念一一命名空间,它在很多情况下用于实现多租户的资源隔离,典型的一种思路就是给每个租户都分配一个命名空间。每个命名空间都是相互独立的存在,属于不同命名空间的资源对象从逻辑上相互隔离。

在每个 Kubernetes 集群安装完成且正常运行之后,Master 会自动创建两个命名空间。

  • 默认级(default:用户创建的资源对象如果没有指定命名空间,则被默认存放在default命名空间中;
  • 系统级(kube-system:系统相关的资源对象如网络组件、DNS 组件、监控类组件等,都被安装在 kube-system 命名空间中。

我们可以通过命名空间将集群内部的资源对象“分配”到不同的命名空间中,形成逻辑上分组的不同项目、小组或用户组,便于不同的分组在共享使用整个集群的资源的同时能被分别管理。当给每个租户都创建一个命名空间来实现多租户的资源隔离时,还能结合 Kubernetes 的资源配额管理,限定不同租户能占用的资源,例如 CPU 使用量、内存使用量等。

命名空间的定义很简单,如下所示的 YAML 文件定义了名为development的命名空间:

查看(注意加上-namespace-n):

03 应用类

3.1 service和pod

Node、Pod与容器间的关系图如下:

Pod及周边对象:

应用类相关的资源对象主要是围绕 Service(服务)和 Pod 这两个核心对象展开的。

  • Service :一般指的是无状态服务,通常由多个程序副本提供服务,在特殊情况下也可以是有状态的单实例服务,比如 MySQL 这种数据存储类的服务。
  • Pod:有一个特殊的被称为“根容器”的 Pause 容器,Pause 容器对应的镜像属于 Kubernetes 平台的一部分,还包含一个或多个紧密相关的用户业务容器。

3.2 label与标签选择器

给某个资源对象定义一个 label,就相当于给它打了一个标签,随后可以通过 Label Selector(标签选择器)查询和筛选拥有某些 Label 的资源对象,Kubernetes 通过这种方式实现了类似 SQL 的简单又通用的对象查询机制。

写法举例:

举例图:

3.3 Pod和Deployment

Pod、Deployment和Service的关系:

前面提到,大部分 Service 都是无状态的服务,可以由多个Pod副本实例提供服务。通常情况下,每个 Service 对应的Pod服务实例数量都是固定的,如果一个一个地手工创建 Pod 实例,就太麻烦了,最好是用模板的思路,即提供一个 Pod 模板(Template),然后由程序根据我们指定的模板自动创建指定数量的 Pod 实例。这就是Deployment这个资源对象所要完成的事情了,举例:

3.4 Service和ClusterIp

Kubernetes 内部在每个 Node 上都运行了一套全局的虚拟负载均衡器,自动注入并自动实时更新集群中所有 Service 的路由表,通过 iptables或者 IPVS 机制,把对 Service 的请求转发到其后端对应的某个 Pod 实例上,并在内部实现服务的负载均衡与会话保持机制。

不仅如此,Kubernetes 还采用了一种很巧妙又影响深远的设计一 ClusterIP 地址

Service 一旦被创建,Kubernetes 就会自动为它分配一个全局唯一的虚拟 IP 地址,即ClusterIP 地址,而且在Service的整个生命周期内,其 ClusterIP 地址不会发生改变,这样一来,每个服务就变成了具备唯一 IP 地址的通信节点,远程服务之间的通信问题就变成了基础的 TCP 网络通信问题。

3.5 Service外网访问

我们需要先弄明白 Kubernetes 的三种 IP,分别如下:

  • Node IP: 是 Kubernetes集群中每个节点的物理网卡的 IP 地址,是一个真实存在的物理网络,所有属于这个网络的服务器都能通过这个网络直接通信。
  • Pod IP: 每个 Pod 的 IP 地址,在使用 Docker 作为容器支持引擎的情况下,它是 Docker Engine 根据 dockero 网桥的 IP 地址段进行分配的,通常是一个虚拟二层网络,通过Pod IP所在的虚拟二层网络进行通信的,真实的TCP/IP 流量是通过Node IP 所在的物理网卡流出。
  • Service IP: Service 的 ClusterIP 地址属于集群内的地址,无法在集群外直接使用这个地址。为了解决这个问题,Kubernetes 首先引入了 NodePort。

对于每个 Service,我们通常需要配置一个对应的负载均衡器实例来转发流量到后端的 Node 上,这的确增加了工作量及出错的概率,如下图:

NodePort 的确功能强大且通用性强,但也存在一个问题,即每个 Service 都需要在 Node 上独占一个端口,而端口又是有限的物理资源,那能不能让多个 Service 共用一个对外端口呢,这就是后来增加的 Ingress资源对象所要解决的问题。

Ingress其实只能将多个 HTTP (HTTPS)的 Service“聚合”,通过虚拟域名或者 URL Path 的特征进行路由转发功能,考虑到常见的微服务都采用了 HTTP REST 协议,所以 Ingress 这种聚合多个 Service 并将其暴露到外网的做法还是很有效的

在一定程度上,我们可以把 Ingress 的实现机制理解为基于 Nginx 的支持虚拟主机的 HTTP 代理。下面是一个 Ingress 的实例:

3.6 有状态的应用集群

我们知道,Deployment 对象是用来实现无状态服务的多副本自动控制功能的,那么有状态的服务,比如: ZooKeeper:集群、MySQL 高可用集群(3 节点集群)、Kafka 集群等是怎么实现自动部署和管理的呢?

这个问题就复杂多了,这些一开始是依赖 StatefulSet 解决的,但后来发现对于一些复杂的有状态的集群应用来说,StatefulSet 还是不够通用和强大,所以后面又出现了 Kubernetes Operator

平台开发者借助 Operator 框架提供的 API,可以更方便地开发一个类似 StatefulSet 的控制器。在这个控制器里,开发者通过编码方式实现对目标集群的自定义操控,包括集群部署、故障发现及集群调整等方面都可以实现有针对性的操控,从而实现更好的自动部署和智能运维功能。

从发展趋势来看,未来主流的有状态集群基本都会以 Operator 方式部署到 Kubernetes集群中。

3.7 批处理应用

除了无状态服务、有状态集群、常见的第三种应用,还有批处理应用。批处理应用的特点是一个或多个进程处理一组数据(图像、文件、视频等),在这组数据都处理完成后,批处理任务自动结束。为了支持这类应用,Kubernetes 引入了新的资源对象一一 Job,下面是一个计算圆周率的经典例子:


Jobs 控制器提供了两个控制并发数的参数:completionsparallelism, completions 表示需要运行任务数的总数,parallelism 表示并发运行的个数。后来kubernetes增加了cronjob可以周期性的执行某个任务。

3.8 应用的配置

通过前面的学习,我们初步理解了三种应用建模的资源对象,总结如下。

  • 无状态服务的建模:Deployment
  • 有状态集群的建模:StatefulSet
  • 批处理应用的建模:Job

在进行应用建模时,应该如何解决应用需要在不同的环境中修改配置的问题呢?这就涉及 ConfigMapSecret 两个对象。

3.8.1 ConfigMap

用户将配置文件的内容保存到 ConfigMap 中,文件名可作为 key, value 就是整个文件的内容,多个配置文件都可被放入同一个 ConfigMap。

在建模用户应用时,在 Pod 里将 ConfigMap。定义为特殊的 Volume 进行挂载。在 Pod 被调度到某个具体 Node 上时,ConfigMap 里的配置文件会被自动还原到本地目录下,然后映射到 Pod 里指定的配置目录下,这样用户的程序就可以无感知地读取配置了。

在 ConfigMap 的内容发生修改后,Kubernetes 会自动重新获取 ConfigMap 的内容,并在目标节点上更新对应的文件。

3.8.2 Secret

Secrett也用于解决应用配置的问题,不过它解决的是对敏感信息的配置问题,比如数据库的用户名和密码、应用的数字证书、Tokn、SSH 密钥及其他需要保密的敏感配置。对于这类敏感信息,我们可以创建一个 Secret 对象,然后被 Pod 引用。Secret 中的数据要求以 BASE64 编码格式存放。注意,BASE64 编码并不是加密的,在 Kubernetes1.7 版本以后,Secret 中的数据才可以以加密的形式进行保存,更加安全。

3.9 应用的运维

3.9.1 HPA横向扩容

首先就是 HPA (Horizontal Pod Autoscaler),我们可以将 HPA 理解为 Pod 横向自动扩容,即自动控制 Pod 数量的增加或减少。通过追踪分析指定 Deployment 控制的所有目标Pod的负载变化情况,来确定是否需要有针对性地调整目标 Pod 的副本数量,这是 HPA 的实现原理。

例如:Kubernetes 内置了基于PodCPU利用率进行自动扩缩容的机制,应用开发者也可以自定义度量指标如每秒请求数,来实现自定义的 HPA 功能。下面是一个 HPA 定义的例子:

根据上面的定义,我们可以知道这个 HPA 控制的目标对象是一个名为 php-apacheDeployment里的 Pod 副本,当这些 Pod 副本的 CPU 利用率的值超过 90% 时,会触发自动动态扩容。

3.9.2 VPA垂直扩容

VPA (Vertical Pod Autoscaler) 即垂直 Pod 自动扩缩容,它根据容器资源使用率自动推测并设置 Pod 合理的CPU和内存的需求指标,从而更加精确地调度 Pod,实现整体上节省集群资源的目标,因为无须人为操作,因此也进一步提升了运维自动化的水平。

04 存储类

存储类的资源对象主要包括: VolumePersistent VolumePVCStorageClass

4.1 Volume(存储卷)

VolumePod 中能够被多个容器访问的共享目录。

首先Kubernetes 中的 Volume 被定义在 Pod上,被一个 Pod 里的多个容器挂载到具体的文件目录下;其次,Kubernetes 中的 VolumePod 的生命周期相同,但与容器的生命周期不相关,当容器终止或者重启时,Volume 中的数据也不会丢失;最后,Kubernetes支持多种类型的 Volume,例如 GlusterFS、Ceph 等分布式文件系统。

Volume 的使用:在大多数情况下,我们先在 Pod 上声明一个 Volume,然后在容器里引用该 Volume并将其挂载(Mount)到容器里的某个目录下。

举例来说,若我们要给之前的 Tomcat Pod增加一个名为 datavolVolume,并将其挂载到容器的/mydata-data 目录下,则只对Pod 的定义文件做如下修正即可(代码中的粗体部分):

Kubernetes提供了非常丰富的Volume类型供容器使用,例如:临时目录、宿主机目录、共享存储等,下面对其中一些常见的类型进行说明。

4.1.1 emptyDir(临时目录)

一个 emptyDir 是在 Pod 分配到 Node 时创建的。从它的名称就可以看出,它的初始内容为空,并且无须指定宿主机上对应的目录文件,因为这是 Kubernetes 自动分配的一个目录,当 PodNode 上移除时,emptyDir 中的数据也被永久移除。

emptyDir 的一些用途如下。

  • 临时空间,例如用于某些应用程序运行时所需的临时目录,且无须永久保留。
  • 长时间任务执行过程中使用的临时目录。
  • 一个容器需要从另一个容器中获取数据的目录(多容器共享目录)。在默认情况下,emptyDir 使用的是节点的存储介质,例如磁盘或者网络存储。

还可以使用 emptyDir. Nedium 属性,把这个属性设置为“Memory”,就可以使用更快的基于内存的后端存储了。需要注意的是,这种情况下的 emptyDir 使用的内存会被计入容器的内存消耗,将受到资源限制和配额机制的管理。

4.1.2 hostPath(宿主机目录)

HostPath 为在 Pod 上挂载宿主机上的文件或目录,通常可以用于以下几方面:

  • 在容器应用程序生成的日志文件需要永久保存时,可以使用宿主机的高速文件系统对其进行存储。
  • 需要访问宿主机上 Docker 引擎内部数据结构的容器应用时,可以通过定hostPath为宿主机/var/Iib/docker目录,使容器内部的应用可以直接访问 Docker 的文件系统。

在使用这种类型的 Volume时,需要注意以下几点。

  • 在不同的 Node 上具有相同配置的 Pod,可能会因为宿主机上的目录和文件不同,而导致对 Volume上目录和文件的访问结果不一致。
  • 如果使用了资源配额管理,则 Kubernetes 无法将 hostPath 在宿主机上使用的资源纳入管理。

在下面的例子中使用了宿主机的/data目录定义了一个hostPath 类型的 Volume:

4.1.3 公有云Volume

公有云提供的 Volume 类型包括谷歌公有云提供的 GCEPersistentDisk、亚马逊公有云提供的 AWS Elastic Block Store (EBS Volume)等。当我们的Kubernetes集群运行在公有云上或者使用公有云厂家提供的 Kubernetes 集群时,就可以使用这类 Volume

4.1.4 其它类型的Volume

  • Iscsi:将 SCSI 存储设备上的目录挂载到 Pod 中。
  • nfs:将 NFS Server上的目录挂载到 Pod 中。
  • glusterfs:将开源 GlusterFS 网络文件系统的目录挂载到 Pod 中。
  • rbd:将 Ceph 块设备共享存储(Rados Block Device)挂载到Pod中。
  • gitRepo:通过挂载一个空目录,并从 Git 库克隆(clone)一个 git repository 以供 Pod 使用。
  • configmap:将配置数据挂载为容器内的文件。
  • secret:将 Secret数据挂载为容器内的文件。

4.1.5 动态存储

Volume属于静态管理的存储,即我们需要事先定义每个 Volume,然后将其挂载到 Pod 中去用,这种方式存在很多弊端,典型的弊端如下。

  • 配置参数烦琐,存在大量手工操作,违背了 Kubernetes 自动化的追求目标。
  • 预定义的静态 Volume 可能不符合目标应用的需求,比如容量问题、性能问题。

所以 Kubernetes 后面就发展了存储动态化的新机制,来实现存储的自动化管理。相关的核心对象(概念)有三个:Persistent Volume(简称 PV)、StorageClass、PVC

  • PV: 表示由系统动态创建(dynamically provisioned)的一个存储卷,可以被理解成 Kubernetes集群中某个网络存储对应的一块存储,它与 Volume 类似,但 PV 并不是被定义在 Pod 上的,而是独立于 Pod 之外定义的。PV 目前支持的类型主要有 gcePersistentDisk、AWSElasticBlockStore、AzureFile、AzureDisk、FC (Fibre Channel)、NFS、iSCSI、RBD (Rados Block Device)、CephFS、Cinder、GlusterFS、VsphereVolume、Quobyte Volumes、Mware Photon、Portworx Volumes、ScaleIO Volumes、ostPath、Local 等
  • StorageClass 用来描述和定义某种存储系统的特征,例如:StorageClass 有几个关键属性:provisioner、parameters 和 reclaimPolicy,系统在动态创建 PV 时会用到这几个参数。简单地说,provisioner 代表了创建 PV 的第三方存储插件,parameters 是创建 PV 时的必要参数,reclaimPolicy则表明了 PV 回收策略,回收策略包括删除或则保留。
  • PVC :StorageClass名称会在 PVC (PV Claim)中出现,下面就是一个典型的 PVC 定义:PVC 正如其名,表示应用希望申请的 PV 规格,其中重要的属性包括 accessModes(存储访问模式)、storageClassName(用哪种 StorageClass 来实现动态创建)及 resources(存储的具体规格)

有了以 StorageClassPVC 为基础的动态 PV 管理机制,我们就很容易管理和使用 Volume 了,只要在 Pod 里引用 PVC 即可达到目的,如下面的例子所示:

05 安全类

安全始终是 Kubernetes 发展过程中的一个关键领域。

从本质上来说 ,Kubernetes 可被看作一个多用户共享资源的资源管理系统,这里的资源主要是各种Kubernetes里的各类资源对象,比如 Pod、Service、Deployment 等。只有通过认证的用户才能通过 KubernetesAPI Server 查询、创建及维护相应的资源对象,理解这一点很关键。

5.1 Service Account

在默认情况下,Kubernetes在每个命名空间中都会创建一个默认的名称为 defaultService Account,因此 Service Account 是不能全局使用的,只能被它所在命名空间中的 Pod 使用。通过以下命令可以查看集群中的所有 Service Account

Service Account 是通过 Secret 来保存对应的用户(应用)身份凭证的,这些凭证信息有 CA 根证书数据(ca.crt)和签名后的Token信息(Token)。

Token 信息中就包括了对应的Service Account的名称,因此 API Server 通过接收到的Token信息就能确定 Service Account 的身份。在默认情况下,用户创建一个 Pod 时,Pod 会绑定对应命名空间中的 default 这个 Service Account 作为其“公民身份证”。

Pod 里的容器被创建时,Kubernetes 会把对应的Secret对象中的身份信息(ca.crt、Token 等)持久化保存到容器里固定位置的本地文件中,因此当容器里的用户进程通过 Kubernetes 提供的客户端 API 去访问 API Server 时,这些API会自动读取这些身份信息文件,并将其附加到 HTTPS 请求中传递给API Server以完成身份认证逻辑。在身份认证通过以后,就涉及“访问授权”的问题,这就是 RBAC 要解决的问题了。

5.2 Role

首先我们要学习的是 Role 这个资源对象,包括 RoleClusterRole两种类型的角色。角色定义了一组特定权限的规则,比如可以操作某类资源对象。局限于某个命名空间的角色由Role对象定义,作用于整个 Kubernetes 集群范围内的角色则通过 Cluster Role 对象定义。

下面是 Role 的一个例子,表示在命名空间 default 中定义一个Role对象,用于授予对 Pod 资源的读访问权限,绑定到该 Role 的用户则具有对 Pod 资源的 getwatchlist权限:

5.2 Role Binding

接下来就是如何将 Role 与具体用户绑定(用户授权)的问题了。我们可以通过 RoleBindingClusterRoleBinding 来解决这个问题。下面是一个具体的例子,在命名空间 default 中将“pod-reader”角色授予用户“Caden”,结合对应的 Role 的定义,表明这一授权将允许用户“Caden”从命名空间 default 中读取 pod:

RoleBinding 中使用 subjects(目标主体)来表示要授权的对象,这是因为我们可以授权三类目标账号:Group(用户组)、User(某个具体用户)和 Service Account (Pod 应用所使用的账号)。

5.3 NetworkPolicy(网络策略)

在安全领域,除了以上针对 API Server 访问安全相关的资源对象,还有一种特殊的资源对象一一 NetworkPolicy(网络策略),它是网络安全相关的资源对象,用于解决用户应用之间的网络隔离和授权问题。

NetworkPolicy 是一种关于 Pod 间相互通信,以及 Pod 与其他网络端点间相互通信的安全规则设定。

NetworkPolicy资源使用标签选择 Pod,并定义选定 Pod 所允许的通信规则。在默认情况下,Pod 间及Pod与其他网络端点间的访问是没有限制的,这假设了 Kubernetes集群被一个厂商(公司/租户)独占,其中部署的应用都是相互可信的,无须相互防范。但是,如果存在多个厂商共同使用一个Kubernetes集群的情况,则特别是在公有云环境中,不同厂商的应用要相互隔离以增加安全性,这就可以通过 NetworkPolicy 来实现了。

k8s教程(基础篇)-基本概念和术语相关推荐

  1. 基于c++和asio的网络编程框架asio2教程基础篇:1、基本概念和使用说明

    基于c++和asio的网络编程框架asio2教程基础篇:1.基本概念和使用说明 由于asio2没有写技术文档,因此打算写几篇文章介绍一下如何使用它,主要是针对新手. 1.asio2如何使用? asio ...

  2. K8S实战基础篇:一文带你深入了解K8S实战部署SpringBoot项目

    K8S实战基础篇:一文带你深入了解K8S实战部署SpringBoot项目 1.前言 2.简介 2.1.为什么写这篇文章 2.2.需求描述 2.3.需求分析 3. 部署实战 3.1 环境准备 3.2 i ...

  3. Midjourney|文心一格prompt教程[基础篇]:注册使用教程、风格设置、参数介绍、隐私模式等

    Midjourney|文心一格prompt教程[基础篇]:注册使用教程.风格设置.参数介绍.隐私模式等 开头讲一下为什么选择Midjourney和文心一格,首先Midjourney功能效果好不多阐述: ...

  4. 基于c++和asio的网络编程框架asio2教程基础篇:2、各个回调函数的触发顺序和执行流程

    基于c++和asio的网络编程框架asio2教程基础篇:2.各个回调函数的触发顺序和执行流程 以tcp举例: tcp服务端流程: #include <asio2/asio2.hpp>int ...

  5. 付呗聚合支付快速教程 基础篇①——基本介绍和配置

    文章目录 一.对接手册 二.商户后台 三.银行分账 四.其他介绍 一.对接手册 付呗聚合支付对接手册 第一步自然是商务对接 本专栏是作为付呗的普通级商户,商户后台 使用付呗开发平台的支付API,接入到 ...

  6. ESP32-C3入门教程 基础篇⑪——Non-Volatile Storage (NVS) 非易失性存储参数的读写

    文章目录 一.前言 二.NVS介绍 三.操作流程 3.1 读操作流程 3.2 写操作流程 四.关键函数 五.随机整数 读写示例 六.对象/数组 读写示例 七.总结 八.参考 一.前言 本文基于VS C ...

  7. ESP32-C3入门教程 基础篇②——GPIO口输入,按键的长按和短按

    文章目录 一.前言 二.硬件准备 三.知识要点 3.1 GPIO使用 3.2 时钟节拍 四.参考例程 五.功能简述 六.源码实现 6.1 中断方式 6.2 定时扫描 七.源码详解 一.前言 本文基于V ...

  8. Redis进阶教程—基础篇-叶向阳-专题视频课程

    Redis进阶教程-基础篇-217人已学习 课程介绍         该系列教程涵盖了redis的方方面面,大亮点是实战经验分享总结.系列视频包含Redis基础篇.Redis提升篇.从零编写Redis ...

  9. 视频教程-Redis进阶教程—基础篇-NoSQL

    Redis进阶教程-基础篇 雅座Java架构师,架构开发公司百万级订单支付平台 叶向阳 ¥49.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅课程,领取优惠 ...

  10. python人生苦短_人生苦短,我用Python(教程基础篇)

    人生苦短,我用Python(Python快速教程 - 基础篇) Life is short, you need Python 人生苦短,我用Python Python简介 本章将介绍Python的最基 ...

最新文章

  1. 适配器(GenericServlet)改造Servlet
  2. directory not found for option
  3. STC89C52单片机 独立键盘
  4. YUM更换源(1)--yum找不到安装包 2013-01-18 20:08 8687人阅读 评论(1) 收藏 举报 分类: linux(70) 公司提供的CentOS VM中,/etc/yum.r
  5. 基于 HTML5 WebGL 的 3D 服务器与客户端的通信
  6. Windows下窗口的生命周期
  7. make make install出现recipe for target 'install-binPROGRAMS' failed解决办法
  8. 【Elasticsearch】Elasticsearch analyzer 中文 分词器
  9. Palo Alto Networks下一代安全平台五大创新功能:云安全为重中之重
  10. mqtt 变为乱码 接受16进制字节流_常见乱码问题分析和总结
  11. 微信小程序-template使用:实现购物车商品数量加减功能
  12. 如何从网站提取数据?
  13. Java输出杨辉三角形
  14. 解除极域电子教室软件控屏的方法
  15. RFCOMM简单介绍
  16. 欧盟物联网推动措施重点与趋势观察
  17. C#桌面办公应用-工资管理系统系列二
  18. mac系统怎么给文件夹加密?mac文件夹加密教程
  19. 1341:【例题】一笔画问题——欧拉(回)路
  20. 有介质的高斯定理详细证明(电偶极子模型)以及例题讲解

热门文章

  1. str_rot13() 函数
  2. 给定一个递增序列,a1 a2 ...an 。定义这个序列的最大间隔为d=max{ai+1 - ai }(1≤in),现在要从a2 ,a3 ..an-1 中删除一个元素。问剩余序列的最大间隔最小...
  3. ICP与IP备案管理系统常见问题总结(FAQ)
  4. 功放与喇叭的匹配原则
  5. 养兔子c语言sdut,SDUT 养兔子
  6. 【个人亲历】上海市人才引进落户最详细的流程记录说明
  7. 全国高校中文档--json
  8. 高德地图哪个语音包最好_高德地图VS百度地图,哪个更靠谱?
  9. 编写SQL语句,检索Customers表中所有的列,再编写另外的SELECT语句,仅检索顾客的ID
  10. 算法竞赛——进阶指南——acwing355. 异象石 dfn的性质+lca (简单的小证明)