K8S架构

1、K8S的组件

kubernetes集群分为两个部分,kubernetes控制平面和工作节点。

1、控制平面的组件

  • etcd分布式持久化存储
  • API服务器
  • 调度器
  • 控制器管理器

2、工作节点上运行的组件

  • kubelet
  • kubelet服务代理(kube-proxy)
  • 容器运行时(Docker、containerd)

3、附加组件

  • kubernetes DNS服务器
  • 仪表盘
  • Ingress控制器
  • Heapster(容器集群监控)
  • 容器网络接口插件

2、kubernetes组件的分布式特性

若要启用Kubernetes提供的所有特性,需要运行所有的这些组件。但是有几个组件无须其他的组件,单独运行也能提供非常有用的工作。

1、组件间如何通信

Kubernetes 系统组件间只能通过API服务通信,他们之间不会直接通信。API服务器是和etcd通信的唯一组件。其他组件不会直接和etcd通信,而通过API服务器来修改集群状态。

API服务器和其他组件的连接基本都是由组件发起的。但是,当你使用kubectl获取日志、使用kubectl attach连接一个运行中的容器或运行kubectl port-forward命令时,API服务器会向kubelet发起连接。

2、单组件运行多实例

尽管工作节点上的组件都需要运行在用一个节点上,控制平面的组件可以被简单地分割在多台服务器上。为保证高可用性,控制平面的每个组件可以有多个实例。etcd和API服务的多个实例可以同时并行工作,但是,调度器和控制器管理器在给定时间内只能有一个实例起作用,其他实例处于待命模式。

3、组件的运行

控制平面的组件以及kube-proxy可以直接部署在系统上或者作为pod来运行。

Kubelet是唯一一直作为常规系统组件来运行的组件,他把其他组件作为pod来运行。为了将控制平面为pod来运行,kubelet被部署在master上。

3、kubernetes如何使用etcd

etcd是一个响应快、分布式、一致的key-value存储。因为它是分布式的,故可以运行多个etcd实例来获取高可用性和更好的性能。

唯一能直接和etcd通信的是Kubernetes的API服务器。所有的其他组件通过API服务间接的读取、写入数据到etcd。

1、确保存储对象的一致性和可验证性

Kubernetes要求所有的控制平面组件只能通过API服务器操作存储模块。使用这种方式更新集群状态总是一致的,因为API服务器实现了乐观锁机制,如果有错的化,也会更少。API服务器同时确保写入存储的数据总是有效的,只有授权的客户端才能更改策略。

2、确保etcd的一致性

为保证高可用性,常常会运行多个etcd实例。多个etcd实例需要保持一致。这种分布式系统需要对系统的实际状态达成一致。etcd使用RAFT一致性算法来保证这一点,确保任何时间点,每个节点的状态要么是大部分节点的当前状态,要么是之前确认过的状态。

一致性算法要求集群的大部分节点参与才能进行到下一个状态。

3、etcd的实例数量

etcd通常部署的是奇数个的实例,etcd 集群需要大多数节点(仲裁)才能就集群状态的更新达成一致。对于具有 n 个成员的集群,仲裁为 (n/2)+1。对于任何奇数大小的群集,添加一个节点将始终增加仲裁所需的节点数。当然节点数目不是越大越好,因为一致性机制下节点数目会影响写性能。

4、API服务器

Kubernetes API 服务器作为中心组件,其他组件或客户端都会去调度它。以RESTful API的形式提供了可以查询、修改集群状态的CRUD(Create、Read、Update、Delete)接口。他将状态存储到etcd中。

API服务器除了提供一种一致的方式将对象存储到 etcd,也对这些对象做校验这样客户端就无法存入非法的对象了 (直接写入存储的话是有可能的)。除了校验还会处理乐观锁,这样对于并发更新的情况,对对象做更改就不会被其他客户端覆盖。

1、通过认证插件认证客户端

首先,API 服务器需要认证发送请求的客户端。这是通过配置在 API服务器上的一个或多个认证插件来实现的。API 服务器会轮流调用这些插件,直到有一个能确认是谁发送了该请求。这是通过检查 HTTP 请求实现的。

2、通过授权插件授权客户端

除了认证插件,API服务器还可以配置使用一个或多个授权插件。它们的作用是决定认证的用户是否可以对请求资源执行请求操作。

3、通过准入控制插件验证AND/OR 修改资源请求

如果请求尝试创建、修改或者删除一个资源,请求需要经过准入控制插件的验证。同理,服务器会配置多个准入控制插件。这些插件会因为各种原因修改资源可能会初始化资源定义中漏配的字段为默认值甚至重写它们。插件其至会去修改并不在请求中的相关资源,同时也会因为某些原因拒绝一个请求。资源需要经过所有准入控制插件的验证。

准入控制插件包括:

  • AlwaysPullImages:重写 pod 的imagePullPolicy为Always,强制每次部署 pod 时拉取镜像
  • ServiceAccount:未明确定义服务账户的使用默认账户。
  • NamespaceLifecycle:防止在命名空间中创建正在被删除的 pod,或在不存在的命名空间中创建 pod。
  • ResourceQuota:保证特定命名空间中的 pod 只能使用该命名空间分配数量的资源,如 CPU 和内存。
  • 还有很多

4、验证资源以及持久化存储

请求通过了所有的准入控制插件后,API服务器会验证存储到 etcd的对象,然后返回一个响应给客户端。

5、API服务器如何通知客户端资源变更

客户端通过创建到API服务器的 HTTP 连接来监听变更。通过此连接,客户端会接收到监听对象的一系列变更通知。每当更新对象,服务器把新版本对象发送至所有监听该对象的客户端。图 11.4 显示客户端如何监听 pod 的变更,以及如何将pod 的变更存储到 etcd,然后通知所有监听该 pod 的客户端。

6、了解调度器

调度器的操作比较简单。就是利用APT服务器的监听机制等待新创建的 pod,然后给每个新的、没有节点集的 pod分配节点。

调度器不会命令选中的节点(或者节点上运行的 Kubelet)去运行pod。调度器做的就是通过API服务器更新 pod 的定义。然后API服务器再去通知 Kubelet( 同样通过之前描述的监听机制)该 pod 已经被调度过。当目标节点上的 Kubelet发现该pod 被调度到本节点,它就会创建并且运行 pod 的容器。

1、默认的调度器算法

选择节点操作可以分解为两部分。

  • 过滤所有节点,找出能分配给 pod 的可用节点列表
  • 对可用节点按优先级排序,找出最优节点。如果多个节点都有最高的优先级分数,那么则循环分配,确保平均分配给 pod

2、查找可用节点

为了决定那些节点对pod可用,调度器会给每个节点下发一组配置好的预测函数。

所有这些测试都必须通过,节点才有资格调度给 pod。在对每个节点做过检查后,调度器得到节点集的一个子集。任何这些节点都可以运行 pod,因为它们都有足够的可用资源,也确认过满足 pod 定义的所有要求

3、为pod选择最佳节点

尽管所有这些节点都能运行 pod,其中的一些可能还是优于另外一些。假设有一个2节点集群,两个节点都可用,但是其中一个运行 10个 pod,而另一个,不知道什么原因,当前没有运行任何 pod。很明显调度器应该选第二个节点。

如果两个节点是由云平台提供的服务,那么更好的方式是,pod调度给第一个节点,将第二个节点释放回云服务商以节省资金。

4、pod高级调度

默认情况下,归属同一服务和 ReplicaSet的 pod 会分散在多个节点上。但不保证每次都是这样。不过可以通过定义 pod 的亲缘性、非亲缘规则强制 pod 分散在集群内或者集中在一起。

5、使用多个调度器

可以在集群中运行多个调度器而非单个。然后,对每一个pod,可以通过在 pod特性中设置 schedulerName 属性指定调度器来调度特定的 pod。

未设置该属性的 pod 由默认调度器调度,因此其 schedulerName 被设置为default-scheduler。其他设置了该属性的 pod会被默认调度器忽略掉,它们要么是手动调用,要么被监听这类 pod 的调度器调用。

7、介绍控制器管理器中运行的控制器

API服务器只做了存储资源到 etcd 和通知客户端有变更的工作.调度器则只是给 pod分配节点,所以需要有活跃的组件确保系统真实状态朝API服务器定义的期望的状态收敛。这个工作由控制器管理器里的控制器来实现。

单个控制器、管理器进程当前组合了多个执行不同非冲突任务的控制器。这些控制器最终会被分解到不同的进程,如果需要的话,我们能够用自定义实现替换它们每一个。

控制器:

  • Replication 管理器 (ReplicationController 资源的管理器)
  • ReplicaSet、DaemonSet 以及 Job 控制器
  • Deployment控制器
  • StatefulSet 控制器
  • Node 控制器
  • Service 控制器
  • Endpoints 控制器
  • Namespace控制器
  • PersistentVolume控制器
  • 其他

1、了解控制器做了什么以及如何做的

控制器做了许多不同的事情,但是它们都通过API服务器监听资源(部署、服务等)变更,并且不论是创建新对象还是更新、删除已有对象,都对变更执行相应操作。大多数情况下,这些操作涵盖了新建其他资源或者更新监听的资源本身

1、Replication 管理器

启动 ReplicationController 资源的控制器叫作 Replication 管理器。 ReplicationController 是如何工作的,其实不是 ReplicationController 做了实际的工作,而是 Replication 管理器。

控制器不会每次循环去轮询 pod,而是通过监听机制订阅可能影响期望的复制集 (replica)数量或者符合条件 pod 数量的变更事件。任何该类型的变化,将触发控制器重新检查期望的以及实际的复制集数量,然后做出相应操作。

Replication 管理器通过API 服务器操 pod API对象来完成其工作。所有控制器就是这样运作的。

2、RerlicaSet、DaemonSet 以及 Job 控制器

ReplicaSet控制器基本上做了和前面描述的 Replication 管理器一样的事情,所以这里不再赘述。DaemonSe 以及Job 控制器比较相似,从它们各自资源集中定义的pod 模板创建pod 资源。与Replication 管理器类似,这些控制器不会运行 pod,而是将 pod 定义到发布API服务器,让Kubelet 创建容器并运行。

3、Deployment控制器

Deployment控制器负责使deployment的实际状态与对应DeploymentAPI对象的期望状态同步。
每次Deployment对象修改后(如果修改会影响到部署的 pod),Deployment控制器都会滚动升级到新的版本。通过创建一个ReplicaSet,然后按照 Deployment中定义的策略同时伸缩新、旧 RelicaSet,直到旧 pod 被新的代替。并不会直接创建任何pod.

4、StatefulSet 控制器

StatefulSer 控制器,类似于ReplicaSet 控制器以及其他相关控制器,根据StatcfiulSer 资源定义创建、管理、除pod。其他的控制器只管理pod,而StatcfiulSer控器会初始化并管理每个pod实例的持久卷声明字段。

5、Node 控制器

Node控制器管理Node资源,描述了集群工作节点。其中,Node控制器使#点对象列表与集群中实际运行的机器列表保持同步。同时监控每个节点的健康状态删除不可达节点的 pod。

Node 控制器不是唯一对Node对象做更改的组件。Kubelet 也可以做更改,那么显然可以由用户通过RESTAPI调用做更改。

6、Service 控制器

Service 控制器就是用来在 LoadBalancer 类型服务被创建或删除时,从基础设施服务请求、释放负载均衡器的。

7、Endpoint 控制器

Endpoint控制器作为活动的组件,定期根据匹配标签选择器的 pod的I、端口更新端点列表。

Endpoint 对象是个独立的对象,所以当需要的时候控制器会创建它。同样地,当删除 Service 时,Endpoint 对象也会被删除。

8、Namespace 控制器

大部分资源归属于某个特定命名空间。当删除一个Namcspace 资源时,该命名空间里的所有资源都会被除。这就是Namespace控制器做的事情。当收到删除Namespace对象的通知时,控制器通过API服务器删除所有归属该命名空间的资源。

9、PersistentVolume 控制器

用户创建了一个持久卷声明Kubernetes必须找到一个合适的持久卷同时将其和声明绑定。这些由持久卷控制器实现。

对于一个持久卷声明,控制器为声明查找最佳匹配项,通过选择匹配声明中的访问模式,并且声明的容量大于需求的容量的最小持久卷。实现方式是保存一份有序的持久卷列表,对于每种访问模式按照容量升序排列,返回列表的第一个卷。当用户删除持久卷声明时,会解绑卷,然后根据卷的回收策略进行回收

10、唤醒控制器

所有这些控制器是通过 API服务器来操作 API对象的它们不会直接和 Kubelet 通信或者发送任何类型的指令。控制器更新API服务器的一个资源后,Kubelet和 Kuberetes Service Proxy会做它们的工作。

8、Kubelet

所有 Kubernetes 控制平面的控制器都运行在主节点上,而 Kubelet 以及 ServiceProxy都运行在工作节点(实际 pod容器运行的地方)上。

 1、Kubelet 的工作内容

Kubelet 就是负责所有运行在工作节点上内容的组件。它第一个任务就是在API服务器中创建一个Node 资源来注册该节点。然后需要持续监控API服务器是否把该节点分配给 pod,然后启动 pod 容器。Kubelct 随后持续监控运行的容器,向API服务器报告它们的状态、事件资源消耗。

Kubelet 也是运行容器存活探针的组件,当探针报错时它会重启容器。

当pod从API服务器删除时,Kubelet 终正容器,并通知服务器 pod 已经被终止了。

2、抛开API服务器运行静态pod

管Kubelct一般会和API服务器通信并从中获取 pod清单,它也可以基于本地指定目录下的 pod清单来运行 pod,该特性用于将容器化版本的控制平面组件以 pod 形式运行。

9、Kubernetes Service Proxy 的作用

除了Kubelet,每个工作节点还会运行 kube-proxy,用于确保客户端可以通过KubernetesAPI连接到你定义的服务。kube-proxy 确保对服务I和端口的连接最终能到达支持服务(或者其他,非 pod 服务终端)的某个 pod处。如果有多个 pod 支撑一个服务,那么代理会发挥对 pod 的负载均衡作用。

10、其他插件

Kubernetes还有一些其他插件,但是,他们并不是必须的。其他插件也都需要监听集群状态,当变更时执行相应的动作。

11、总结

API服务器、调度器、控制器管理器中运行的控制器、Kubelet以及 kube-proxy一起合作来保证实际的状态和你定义的期望状态一致。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值