[原创]kubernetes笔记之原理分析(上)

 

kubernetes是谷歌开源的容器编排系统,也是现在最流行的容器编排系统之一。我们在生产环境中使用了kubernetes, 后续会陆续分享相关的实践和踩过的坑。...



以下是《kubernetes权威指南》的学习笔记,我对书中的内容做了总结和提炼。 如有谬误之处, 还望各位指出。

先放一张kubernetes的架构设计图:



Apiserver原理分析



概述



整个系统的数据总线。提供以下功能特性:

  1. 集群管理的api入口
  2. 资源配额控制的入口
  3. 提供完善的集群安全机制

api 访问



访问api的三种方式:

  1. 直接curl调用api
  2. 启动内部代理(kubectl proxy ),然后访问内部代理进行调用,可以进行访问控制,如限制要访问的接口,增加允许访问的client的白名单
  3. 使用k8s提供的client lib ,通过编程的方式访问,这种方式有两种使用场景,一是pod需要发现同属于一个service的其它pod副本的信息来组建集群(如elasticsearch集群), 二是需要通过调用api来我开发基于k8s的管理平台
独特的k8s proxy api:

这种api可以用来代理rest请求, 把收到的请求转发到某一个node上的kubelet进程的端口上,由kubelet进行响应示例: curl 127.0.0.1:8080/api/v1/proxy/nodes/node-1/pods这里返回的pods的信息是由node上的kubelet进程收集的, 而不是从etcd的数据库获取, 二者的信息可能在某个时间点会有偏差。这种特殊的api的应用场景是: 通过这类api来直接访问pods上的应用, 可以用来逐一排查同一service的多个pod副本上的应用是否有异常。示例一: curl 127.0.0.1:8080/api/v1/proxy/namespaces/default/pods/xxxx-pod-1示例二: curl 127.0.0.1:8080/api/v1/proxy/namespaces/default/services/xxxx-svr-1

集群之间功能模块的通信



kubelet --> apiserver (汇报自身状态, 侦听pod信息)controller-manager --> apiserver (实时监控node信息,并做处理)scheduler --> apiserver (侦听新建pod的信息, 检索符合要求的node列表,并进行调度逻辑的执行)

为缓解apiserver的压力, 各个模块会缓存从apiserver获取的数据, 某些情况下会直接使用缓存的数据(什么情况使用缓存, 如何保证数据的一致性?

controller manager原理分析



集群内部的管理控制中心,是一个“修正系统”。负责以下对象的管理:

  • node
  • pod副本
  • endpoint
  • namespace
  • service accout
  • resource quota
包含了以下controller:

  • replication controller
  • node controller
  • resourcequota controller
  • namespace controller
  • serviceaccount controller
  • token controller
  • service controller
  • endpoint controller

replication controller



职责是: 保证pod副本数量始终保持预设值应用场景:

  1. 确保pod数量, 以保证高可用要求
  2. 系统扩容和缩容
  3. 滚动更新
只有当pod的重启策略是Always时(RestartPolicy=Always)时, replication controller 才会管理该pod的操作(例如创建, 销毁, 重启等)

pod通过修改标签可以脱离replication controller的控制

node controller



通过apiserver获取node的信息,实现管理和监控集群的各个node节点的相关控制功能。节点的健康状态有三种: 就绪(true), 未就绪(false), 未知(unknown)master节点的系统时间作为探测时间, 状态变化的时间可能是上一次保存的状态时间,或者本次节点变化的时间。如果有段时间没有收到节点信息,则状态设置为unknown.当状态为非就绪状态时, 将节点加入待删除队列。

resourcequota controller



资源配额管理, 确保指定的资源对象在任何情况下都不会超量占用系统资源,避免业务进程的设计和实现的缺陷导致整个系统的紊乱, 对整个集群的平稳运行起着重要作用。

k8s集群对资源配额的管理有三个维度: 容器级别, pod级别, namespace级别。容器级别: cpu & memorypod级别: 所有容器的可用资源namespace级别: pod数量, rc数量, svr数量, resourcequota数量, secret数量, pv数量

配额管理的控制:由apiserver中的admission control来控制, 实际上apiserver是配额控制的一个入口。两种配额约束方式: limitranger(容器级别, pod级别), resourcequota(namespace级别)

resourcequota controller组件负责定期统计namespace下pod, rc, svr, resourcequota, secret, pv等资源对象的数量, 还有container实例使用的资源,将统计结果写入etcd。这些信息会被admission controller使用, 如果不符合配额约束, 则创建对象失败。如果既在namespace上命名了resourcequota约束, 又在pod级别声明了limitranger,admission control 会同时计算二者的情况, 需要同时满足才会创建对象。

namespace controller



用户通过api server创建新的namespace, 并保存在etcd中。 而这个controller可以通过api server读取namespace的相关信息。当namespace的状态被设置为terminating时, 这个controller会删除改namespace下的所有对象资源。admission controller会通过namespacelifecycle插件来阻止为该namespace创建新的资源。

serviceaccount controller



token controller



service controller



k8s集群和外部云平台的一个接口控制器,负责侦听service的变化。如果service的type是loadbalancer, 那么service controller就会负责动态更新创建对于的loadbalancer实例, 和路由转发表等

endpoint controller



负责侦听service和相应的pod副本的变化,以及生成和维护所有endpoints对象。 当service被删除时,该controller会负责删除该service同名的endpoints对象。 当新的service被创建或修改, pod产生相关事件时, 该controller就会更新对应service的endpoints对象(更改对应的endpoint条目)。

注: endpoints对象维护一个service对应的所有pod副本的访问地址。

scheduler 原理分析



scheduler是负责pod调度的重要组件。起着承上启下的作用, 从上游接收controller manager 创建的pod, 为起安排node落脚, 然后交给目标node上的kubelet进程, 由其负责pod的“下半生”的生命周期管理。

默认调度流程分两步:

  1. 预选(predicates): 遍历所有node, 先根据预选策略初步筛选出符合条件的node
  2. 优选(priority): 从预选的node中挑出最优的选择
调度流程是通过插件的方式加载调度算法提供者。 每个algorithmprovider都要提供3个参数, 算法名称name, 预选策略集合predicatekeys, 优选策略集合prioritykeys

7个可用的预选策略:

  • NoDiskConflict
  • PodFirstResources
  • PodSelectorMatches
  • PodFitsHost
  • CheckNodeLablePresence
  • CheckServiceAffinity
  • PodFitsPorts
默认的algorithmprovider加载的预选策略:

  • NoDiskConflict
  • PodFirstResources
  • PodSelectorMatches
  • PodFitsHost
  • PodFitsPorts
所有预选策略的说明

  • NoDiskConflict

判断备选pod的gcepersistentdisk或者awselasticblockstore和备选的节点已存在的pod是否存在冲突

  • PodFirstResources

node的资源是否满足备选pod的需求。需要对备选pod和node上已有pod的资源进行求和,看是否超过node所能提供的资源

  • PodSelectorMatches

node是否有pod的标签选择器所指定的标签, 即nodeselector所指定的标签

  • PodFitsHost

node的名称是否和pod所指定的node名称一致, 即nodename所指定的名称

  • CheckNodeLablePresence

用于判断当策略列出的标签在备选节点存在是, 是否选择该备选节点

  • CheckServiceAffinity

用于判断备选节点是否包含策略指定的标签

  • PodFitsPorts

判断备选pod所用的端口是否在备选的node中被占用

3个优选策略:

  • LeastRequestedPriority
  • CalculateNodeLabelPriority
  • BalancedResourceAllocation
注:每个节点通过优选策略会算出一个得分, 得分最大的节点作为最终的优选结果。

问题: 所有的优选策略都要计算一遍么?还是只是挑选其中的一个?如果挑选其中一个,又是如何挑选?

所有优选策略的说明:

  • LeastRequestedPriority

选出资源消耗最少的节点, 即资源最充足的节点(cpu, mem两个维度), 有对应的计算公式

  • CalculateNodeLabelPriority

    判断策略列出的标签在备选节点出现时,是否选择该备选节点

  • BalancedResourceAllocation

从备选节点中选出各项资源使用率最均衡的方法, 与1类似,但是计算公式又不同


    关注 云时代的运维开发


微信扫一扫关注公众号

0 个评论

要回复文章请先登录注册