Kubernetes初识——核心组件

核心组件

在这里插入图片描述

  • etcd 保存了整个集群的状态;
  • API Server 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册 和发现等机制;
  • Controller Manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新 等
  • Scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;
  • Kubelet 负责维护容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的 管理;
  • Container Runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI);
  • Kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡;

组件通信

Kubernetes 多组件之间的通信原理

  • API Server负责etcd存储的所有操作,且只有 API Server才能直接操作etcd集群;
  • API Server 对内和对外提供统一的Rest API,其他组件均通过API Server进行通信:
    • Controller Manager、Scheduler、Kube-proxy和Kubelet 等均通过API Server waych API监测资源变化情况,并对资源相应的操作;
    • 所有需要更新资源状态的操作均通过API Server的Rest API进行;
  • API Server也会直接调用Kubelet API;

在这里插入图片描述
创建Pod的流程为:

  1. 用户通过Rest API创建一个Pod;
  2. API server将其写入etcd;
  3. Scheduluer检测到未绑定Node的Pod,开始调度并更新Pod的Node绑定;
  4. Kubelet 检测到有新的Pod调度过来,通过Container Runtime运行该Pod;
  5. Kubelet通过Container Runtime取到Pod状态,并更新到API Server中;

etcd

etcd是分布式key-value存储,可用于服务发现、共享配置以及一致性保障;

主要功能

  • 基本的key-value存储;
  • 监听机制;
  • key的过期及续约机制,勇于监控和服务发现;
  • 原子CAS和CAD,勇于分布式锁和leader选举;

etcd给予RAFT的一致性

选举方法

  1. 初始启动时,节点处于follower状态并被设定一个election timeout,如果在这一时间周期内没有收到来自leader的heartbeat,节点将发起选举:将自己切换为candidate之后,向集群中其他follower节点发送请求,询问其是否选举自己成为leader;
  2. 当收到来自集群中过半数节点的接受投票后,节点即成为leader,开始接收保存client的数据并向其他follower节点同步日志,如果没有达成一致,则candidate随机选择一个等待间隔(150-300ms)再次发起投票,得到集群中半数以上的follower接受的candidate将成为leader;
  3. leader节点依靠定时向follower发送heartbeat来保持其地位;
  4. 任何时候如果其他follower在election timeout期间都没有收到来自leader的heartbeat,同样会将自己的状态切换为candidate并发起选举,每成功选举一次,新的leader的任期都会比之前的leader的任期大1;

日志复制
当前leader收到客户端的日志后先把该日志追加到本地的Log中,然后通过heartbeat把改Entry同步给其他follower,follower接收到日志后记录日志然后向leader发送ack,当leader收到大多数(n/2+1)follower的ack信息后将该日志设置为已提交并追加到本地磁盘中,通知客户端在下个heartbeat中leader将通知所有的follower将该日志存储在本地磁盘中。

安全性
安全性是用于保证每个节点都执行相同序列的安全机制,如当某个 Follower 在当前 Leader commit Log 时变得不可用了,稍后可能该 Follower 又会被选举为 Leader,这 时新 Leader 可能会用新的 Log 覆盖先前已 committed 的 Log,这就是导致节点执行不 同序列;Safety 就是用于保证选举出来的 Leader 一定包含先前 committed Log 的机 制;

  • 选举安全性:每个任期只能选举出一个leader;
  • leader完整性:指的是leader日志的完整性,当Log在任期term1被commit后,那么以后任期的leader必须包含该Log,Raft在选举节点使用term的判断用于保证完整性:当请求投票的该candidate的term较大或term相同index更大则投票,否则拒绝该请求。

失效处理

  1. leader失效:其他没有收到heartbeat的节点会发起新的选举,而当leader回复后由于步进数小会自动成为follower,日志也会被新的leader的日志覆盖;
  2. follower节点不可用:follower节点不可用的情况相对容易解决,因为集群中的日志内容始终是从leader节点同步的,只要这一节点再次加入集群时重新从leader节点处复制日志即可。
  3. 多个candidate:冲突后candidate将随机选择一个等待间隔(150-300ms),再次发起投票,得到集群中半数以上follower接受的candidate将成为leader。

API Server

主要功能:

  • 提供集群管理的REST API接口,包括认证授权、数据校验以及集群状态变更等;
  • 提供其他模块之间的数据交互和通信枢纽,其他模块通过API SERVER查询或修改数据,只有API Server才直接操作etcd;

在实际使用中,通常通过kubectl来访问apiserver,也可以通过Kubernetes各个语言的client库来访问apiserver,在使用kubectl时,打开调试日志也可以看到每个api调用的格式。

访问控制

Kubernetes API的每个请求都会经过多阶段的访问控制之后才会被接受,包括认证、授权以及准入控制等。
在这里插入图片描述
认证

开启TLS时,所有的请求都需要首先认证,Kubernetes支持多种认证机制,并支持同时开启多个认证插件,如果认证成功,则用户的username会传入授权模块做进一步授权验证,而对于认证失败的请求则返回HTTP 401;

授权

认证之后的请求就到了授权模块,跟认证类似,Kubernetes也支持多种授权机制,并支持同时开启多个授权插件,如果授权成功,则用户的请求会发送到准入模块做进一步的请求验证,而对于授权失败的请求则返回HTTP 403;

准入控制

准入控制用来对请求做进一步的验证或添加默认参数,不同于授权和认证只关心请求的用户和操作,准入控制还处理请求的内容,并且仅对创建、更新、删除或链接等有效,而对读操作无效,同时也支持同时开启多个插件,依次调用,只有全部插件都通过的请求才可以放过进入系统。

工作原理

kube-apiserver提供了Kubernetes的REST API,实现了认证、授权、准入控制等安全校验功能,同时也负责集群状态的存储操作。

在这里插入图片描述

kube-scheduler

kube-Scheduler负责分配调度Pod到集群内的节点上,它坚挺kube-apiserver,查询还未分配Node的Pod,然后根据调度策略为这些Pod分配节点;

调度器需要充分考虑诸多因素:

  • 公平调度;
  • 资源高效利用;
  • QoS;
  • affinity和anti-affinity;
  • 数据本地化;
  • 内部负载干扰;
  • deadlines;

指定Node节点调度

有三种方式指定Pod只运行在指定的Node节点上:

  • nodeSelector:之调度到匹配制定label的Node上;
  • nodeAffinity:功能更丰富的Node选择器,支持集合操作;
  • podAffinity:调度到满足条件的Pod所在的Node上;

nodeSelector示例

首先给Node打上标签:

kubectl label nodes node-01 disktype=ssd

然后在daemonset中指定nodeSelector为disktype=ssd:

spec: 
	nodeSelector: 
		disktype: ssd

nodeAffinity示例

nodeAffinity目前支持两种:requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution,分别代表必须满足条件和优选条件。比如下面的例子代表调度到包含标签 kubernetes.io/e2e-az-name 并且值为 e2e-az1 或 e2e-az2 的 Node 上,并且优选还带有标签 another-node-label- key=another-node-label-value 的 Node。

apiVersion: v1 
kind: Pod 
metadata: 
	name: with-node-affinity 
spec: 
	affinity: 
		nodeAffinity: 
		  requiredDuringSchedulingIgnoredDuringExecution: 
			nodeSelectorTerms: 			    
			- matchExpressions: 
			- key: kubernetes.io/e2e-az-name 
			  operator: In 
			  values: 
			  - e2e-az1 
			  - e2e-az2 
			preferredDuringSchedulingIgnoredDuringExecution: 
			- weight: 1 
			  preference: 
			    matchExpressions: 
			    - key: another-node-label-key 
			      operator: In 
			      values: 
			      - another-node-label-value
	containers: 
	- name: with-node-affinity 
	  image: gcr.io/google_containers/pause:2.0

podAffinity示例

podAffinity基于Pod的标签来选择Node,仅调度到满足条件Pod所在的Node上,支持podAffinity和podAntiAffinity。

Taints和tolerations

Taints 和 tolerations用于保证Pod不被调度到不合适的Node上,其中Taint应用于Node上,而toleration则用于Pod上;

目前支持的Taint类型:

  • NoSchedule:新的Pod不调度到该Node上,不影响正在运行的Pod;
  • PreferNodeSchedule:soft版的NoSchedule,尽量不调度到该Node上;
  • NoExecute:新的Pod不调度到该Node上,并且删除(evict)已在运行的Pod,Pod可以增加一个时间。

然而,当Pod的Tolerations匹配Node的所有Taints 的时候可以调度到该Node上;当Pod是运行的时候,也不会被删除(evictd)。另外对于NoExecute,如果Pod增加了一个tolerationSeconds,则会在该时间之后才删除Pod。

假设node1上应用以下几个taint:

kubectl taint nodes node1 key1=value1:NoSchedule 
kubectl taint nodes node1 key1=value1:NoExecute 
kubectl taint nodes node1 key2=value2:NoSchedule

下面这个Pod由于没有tolerate key2=value2:NoSchedule无法调度到node1上

tolerations: 
- key: "key1" 
  operator: "Equal" 
  value: "value1" 
  effect: "NoSchedule" 
 - key: "key1" 
   operator: "Equal" 
   value: "value1" 
   effect: "NoExecute"

而正在运行且带有tolerationSeconds的Pod则会在600s之后删除:

tolerations: 
- key: "key1" 
  operator: "Equal" 
  value: "value1" 
  effect: "NoSchedule" 
- key: "key1" 
  operator: "Equal" 
  value: "value1" 
  effect: "NoExecute"
- key: "key2" 
  operator: "Equal" 
  value: "value2" 
  effect: "NoSchedule"

DaemonSet 创建的 Pod 会自动加上对 node.alpha.kubernetes.io/unreachable 和 node.alpha.kubernetes.io/notReady 的 NoExecute Toleration,以避免它们因此 被删除。

优先级调度
从v1.8开始,kube-scheduler支持定义Pod的优先级,从而保证高优先级的Pod优点调度,并从v1.11开始默认开启。

在指定Pod的优先级之前需要先定义一个PriorityClass,如:

apiVersion: v1 
kind: PriorityClass 
metadata: 
  name: high-priority 
value: 1000000 
globalDefault: false 
description: "This priority class should be used for XYZ service pods only."
  • value 为32位整数的优先级,该值越大,优先级越高;
  • globalDefault 用于未配置PriorityClassName的Pod,整个集群中应该只有一个PriorityClass将其设置为true;

然后在Pod Spec中通过PriorityClassName设置Pod的优先级:

apiVersion: v1 
kind: Pod 
metadata: 
  name: nginx 
  labels: 
    env: test 
spec: 
  containers: 
  - name: nginx 
    image: nginx 
    imagePullPolicy: IfNotPresent 
    priorityClassName: high-priority

多调度器

如果默认的调度器不满足要求,还可以部署自定义的调度器,并且,在整个集群中还可以同时运行多个调度器实例,通过podSpec.SchedulerName来选择使用哪一个调度器。

spec: # 选择使用自定义调度器 
  my-scheduler 
  schedulerName: my-scheduler 
  containers: 
  - name: nginx 
    image: nginx:1.10

kube-scheduler工作原理

kube-scheduler 调度分为两个阶段:predictcate 和 priority

  • predicate:过滤不符合条件的节点;
  • priority:优先级排序,选择优先级最高的节点;

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

Controller Manager

Controller Manager由kube-controller-manager 和 cloud-controller-manager组成,是Kubernetes的大脑,它通过apiserver监控整个集群状态,并确保集群处于预期的工作状态。

在这里插入图片描述
kube-controller-manager由一系列的控制器组成:Replication Controller、Node controller等;cloud-controller-manager在Kubernetes启用cloud provider的时候才需要。

Kubelet

每个Node节点上都运行一个Kubelet服务进程,默认监听端口10250,接收并执行Master发来的指令,管理Pod及Pod中的容器,每个kubelet进程会在API server注册所在Node节点的信息,定期向Master节点汇报该节点的资源使用情况,并通过cAdvise监控节点和容器的资源。

节点管理

节点管理主要是节点自注册和节点状态更新:

  • kubelet可以通过设置启动参数–register-node 来确定是否向API server注册自己;
  • 如果kubelet 没有选择自注册模式,则需要用户自己配置Node资源信息,同时需要告知kubelet集群上的API server位置;
  • kubelet在启动时通过API server注册节点信息,并定时向api server发送节点新消息,api server在接收到新消息后,将信息写入etcd。

Pod管理

获取Pod清单

kubelet以podspec 的方式工作,podspec是描述一个pod的YAML或JSON对象。kubelet采用一组通过各种机制提供的PodSpecs,并确保这些PodSpecs中描述的Pod正常健康运行。

向kubelet提供节点上运行的Pod清单的方法:

  • 文件:启动参数 --config 指定的配置目录下的文件,改文件每20秒重新检查一次(可配置);
  • HTTP endpoint(URL):启动参数 --manifest-url设置,每20秒检查一次这个端点(可配置);
  • API Server:通过API server监听etcd目录,同步Pod清单;
  • HTTP server:kubelet侦听HTTP请求,并响应简单的API以提交新的Pod清单。

通过API server 获取Pod清单及创建Pod的过程
kubelet读取监听到的消息,如果是创建和修改Pod任务,则执行如下处理:

  • 为该Pod创建一个数据目录;
  • 从API server读取该Pod清单;
  • 为该Pod挂载外部卷;
  • 下载Pod用到的secret;
  • 检查已经在节点上运行的Pod,如果该Pod没有容器或Pause容器没有启动,则先停止Pod里所有容器的进程,如果在Pod中有需要删除的容器,则删除这些容器。
  • “Kubernetes/pause”镜像为每个Pod创建一个容器,pause容器用于接管Pod中所有其他容器的网络。每创建一个新的Pod,kubelet都会先创建一个Pause容器,然后创建其他容器。
  • 为Pod中的每个容器做如下处理:
    1. 为容器计算一个hash值,然后用容器的名字去docker查询对应容器的hash值,若查找到容器,并且hash值不同,则停止docker中容器的进程,并停止与之关联的pause容器进程,如果两者相同,则不做任何处理。
    2. 如果容器被终止了,并且容器没有指定的restartPolicy则不做任何处理。
    3. 调用docker client 下载容器镜像,调用docker client运行容器。

static Pod

所有以非API server方式创建的pod都叫static pod,kubelet将static pod的状态汇报给api server,api server为该static pod创建一个mirror Pod和其相匹配。Mirror Pod的状态将真实反映static pod的状态,放static pod被删除时,与之相对应的Mirror Pod也会被删除。

容器健康检查

Pod通过两类探针检查容器的健康状态:

  1. LivenessProbe探针:用于判断容器是否健康,告诉kubelet一个容器什么时候处于不健康状态。如果LivenessProbe探针检测到容器不健康,则kubelet将删除该容器,并根据容器的重启策略做响应的处理,如果一个容器不包含LivenessProbe探针,则认为该容器的LivenessProbe探针返回值永远是success。
  2. ReadinessProbe:用于判断容器是否启动完成并且准备接收请求,如果ReadnessProbe探针检测到失败,则Pod的状态将被修改,Endpoint Controller将从service 的endpoint中删除包含该容器所在Pod的IP地址的endpoint条目。

kubelet定期调用容器中的LivenessProbe探针来诊断容器的健康状况,LivenessProbe包含如下三种方式:

  • ExecAction:在容器内部执行一个命令,如果该命令的推出状态吗为0,则表明容器健康;
  • TCPSocketAction:通过容器的IP地址和端口号执行TCP检查,如果端口能被访问,则表明容器健康。
  • HTTPGetAction:通过容器的IP地址和端口号及路径调用HTTP GET方法,如果响应的状态码大于等于200且小于400,则认为容器状态健康。

Kubelet Eviction(驱逐)

Kubelet会监控资源的使用情况,并使用驱逐机制防止计算和存储资源耗尽,在驱逐时,Kubelet会将Pod的所有容器停止,并将PodPhase设置为Failed。

Kubelet定期检查系统的资源是否达到了预先配置的驱逐阈值。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spark是一种大数据处理的框架,它可以处理大量的数据并进行分析。初学者可以通过学习Spark的基本概念和使用方法,了解Spark的工作原理和应用场景。在学习Spark的过程中,需要掌握Spark的核心组件和API,例如Spark Core、Spark SQL、Spark Streaming等。此外,还需要学习Spark的部署和调优,以及与其他大数据技术的集成。 ### 回答2: Spark是一种基于内存的分布式计算框架,是大数据处理中最流行的技术之一。Spark简单易用,能够快速地处理海量数据,尤其是在机器学习和数据挖掘领域中表现突出。本文将从初识Spark的角度入手,介绍Spark的基本概念和使用。 一、Spark的基本概念 1. RDD RDD全称为Resilient Distributed Datasets,中文意思是弹性分布式数据集,它是Spark的核心数据结构。RDD是一个不可变的分布式的对象集合,可以跨越多个节点进行并行处理。一个RDD可以分为多个分区,每个分区可以在不同的节点上存储。 2. DAG DAG即Directed Acyclic Graph(有向无环图),它是Spark中的一个概念,用来表示作业的依赖关系。Spark将一个作业拆分成一系列具有依赖关系的任务,每个任务之间的依赖形成了DAG。 3. 窄依赖和宽依赖 对于一个RDD,如果一个子RDD的每个分区只依赖于父RDD的一个分区,这种依赖就称为窄依赖。如果一个子RDD的每个分区依赖于父RDD的多个分区,这种依赖就称为宽依赖。宽依赖会影响Spark的性能,应尽量避免。 二、Spark的使用 1. 安装Spark 要使用Spark,首先需要在本地或者集群上安装Spark。下载安装包解压缩即可,然后设置环境变量,即可在命令行中运行Spark。 2. Spark Shell Spark Shell是Spark的交互式命令行界面,类似于Python的交互式控制台,可以快速测试Spark代码。在命令行中输入spark-shell即可进入。 3. Spark应用程序 除了Spark Shell,Spark还支持以应用程序的形式运行。要创建一个Spark应用程序,可以使用Scala、Java、Python等语言进行编写。使用Spark API,读取数据、处理数据、保存数据等操作都可以通过编写代码完成。 总之,Spark是一种优秀的分布式计算框架,能够在海量数据处理中发挥出强大的作用。初学者可以从掌握RDD、DAG、依赖关系等基本概念开始,逐步深入学习Spark的使用。 ### 回答3: Spark是一种快速、分布式数据处理框架,它能够在成千上万个计算节点之间分配数据和计算任务。Spark的优势在于它支持多种语言和数据源,可以在内存中快速存储和处理数据。 在初学Spark时,我们需要对Spark的架构和核心组件有一些了解。首先,Spark的核心组件是Spark Core,它是一个可以用于建立各种应用程序的计算引擎。与此同时,Spark持有丰富的库,包括Spark SQL、Spark Streaming、MLLib和GraphX等,以支持在各种数据类型(文本、图像、视频、地理定位数据等)上运行各种算法。 若想要在Spark中进行任务,有两种编程API可供选择:Spark的核心API和Spark的SQL及DataFrame API。Spark的核心API基于RDDs(弹性分布式数据集),它是不可变的分布式对象集合,Spark使用RDD来处理、缓存和共享数据。此外,Spark的SQL及DataFrame API提供了更高层次的语言,可以处理结构化和半结构化数据。 除了组件和API之外,我们还需要了解Spark的4个运行模式:本地模式、Standalone模式、YARN模式和Mesos模式。本地模式由单个JVM上单个线程(本地模式)或四个线程(local[*]模式)运行。Standalone通常用于小规模集群或开发和测试环境。在YARN或Mesos模式下,Spark将任务提交给集群管理器,并通过管理器分配和管理资源。 总体来说,初学Spark时,我们需要了解Spark的核心组件、编程API和运行模式。熟悉这些概念以及Spark的架构,可以帮助我们更好地理解Spark和构建高效且可扩展的Spark应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值