kubernetes 核心组件

整体架构

在这里插入图片描述

核心组件

master节点

  • etcd
    • 保存了整个集群的状态
    • 所有对etcd的操作都要走apiserver
      • 因为需要 apiserver 负责授权
  • apiserver
    • 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制
    • 所有尝试访问或更改 Kubernetes 系统状态的请求都会通过 apiserver 进行
  • controller manager
    • 负责维护集群的状态,比如故障检测、自动扩展、滚动更新
    • 通过控制循环不断将系统状态从“当前状态”修正到“期望状态”,最终达到与申明一致
    • 每种API对象都有一个对应的control负责维护对应对象
  • scheduler
    • 负责资源的调度,按照预定的调度策略将Pod调度到相应的node上

node节点

  • kubelet
    • 负责 Pod 生命周期管理、网络配置、Volume 管理、设备管理、资源管理等一系列跟容器基础设施
      • 会定时上报node状态给 apiserver
  • kube-proxy
    • 负责为Service提供cluster内部的服务发现和负载均衡

控制器

在这里插入图片描述

  • informer从 APIServer 获取关心的API对象, 缓存在了本地,并负责更新和维护这个缓存
    • 其中的Reflector使用的是一种叫作 ListAndWatch 的方法,来 “获取”并“监听” 这些 Network 对象实例的 变化
      • 如果一个master 管理的node非常多,通过ListAndWatch 会对master的性能有影响
        • 所以迄今为止k8s最大规模为5000
    • 一旦 APIServer 端有新的对象实例被创建、删除或者更新Reflector 都会收到“事件通知”
    • 该事件及它对应的 API 对象这个组合,就被称为增量(Delta),它会被放进一个 Delta FIFO Queue
    • 另一方面,Informer 会定时不断地从这个Queue 里读取增量
      • 每拿到一个增量,Informer 就会判断这个增量里的事件类型,然后创建或者更新本地对象的缓存LocalStore
      • 如果事件类型是 Added,那么 Informer 就会通过一个叫作·Indexer 的库把这个增量里的 API 对象保存在本地缓存中,并为它创建索引
      • 相反地,如果增量的事件类型是 Deleted,那么 Informer 就会从本地缓存中删除这个对象
    • 然后informer把要操作(更新)的API对象放入working queue
      • 工作队列是为了解耦以及匹配双方速度不一致
        • 防止控制循环执行过慢把Informer 拖死
        • 也可以控制并发度
  • Control Loop不断定时从working queue取出对象,对比“期望状态”和“实际状态”,然后决定接下来要做的业务逻辑

调度

  • 调度器对一个 Pod 调度成功的行为,实际上就是将它的spec.nodeName 字段填上调度结果的node的名字
    在这里插入图片描述
  • 选择pod的算法
    • 首先调用一组叫作Predicate 的调度算法,挑选出所有可以运行该 Pod 的节点
    • 再调用一组叫作Priority的调度算法,来给上一步得到的结果里的每个 Node 打分,最终的调度结果,就是得分最高的那个 Node
  • 亲和度
    • 当pod之间有清河或排斥关系时,可以通过podAffinitypodAntiaffinity设定
    • 当pod和node之间有考核或排斥关系时,可以通过NodeSelectorNodeAffinity
  • 调度失败后的抢占机制
    • 当一个高优先级的 Pod 调度失败后希望能 “挤走”某个 Node 上的一些低优先级的 Pod
    • 可以通过PriorityClassAPI对象定义
      • 优先级value是一个 32 bit 的整数,最大值不超过10 亿,值越大代表优先级越高
        • 超过10亿的值被保留给系统pod,避免其被用户抢占
      • pod可以通过设置spec.containers.priorityClassName使用上面定义的对象,从而获得高优先级

容器运行时接口(CRI)

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

  • 容器运行时接口(CRI)调用底层容器运行时
    • 例如 Docker 和 Rkt
    • CRI 提供了 Kubelet 和特定的运行时之间的抽象接口,它们之间通过gRPC通信
    • 屏蔽下层容器运行时的差异
      • 通过使用 Kubelet 和运行时之间定义的契约关系,可以以最小的开销添加新的运行时实现
  • CRI shim负责响应CRI的指令,组装成API 请求发给具体容器运行时,例如 Docker Daemon
    • CRI shim实现 CRI 规定的每个接口,然后把具体的 CRI 请求 “翻译” 成对后端容器项目的请求或者操作
  • CRI 接口的设计是比较宽松的,作为底层容器在实现 CRI 的具体接口时,往往拥有着很高的自由度:
    • 容器的生命周期管理
    • 如何将 Pod 映射成为我自己的实现
    • 如何调用 CNI 插件来为 Pod 设置网络的过程

API 对象

  • k8s是声明式API,而不是命令式API
    • 只需要声明对象的理想状态,而不是一系列控制命令
    • 允许有多个 API 写端,以 PATCH 的方式对 API 对象进行修改,而无需关心本地原始 YAML 文件的内容
  • 每个API对象有三大类属性
    • 元数据(metadata)
      • 用于标示对象
      • 包括namspace, name, labels
    • 规范(spec)
      • 用于描述期望的理想状态
      • 所有配置都是通过spec来设置的
    • 状态(status)
      • 当前系统的实际状态
  • 由于k8s对象之间是有依赖关系的,在部署时是需要按照顺序启动的
    • 部署次序:Secret->ConfigMap->Volume->Deployment->Service
  • k8s通过label 组织,分类和选择这些对象
    • 一个对象可以包含多个label,从而实现多维度管理
    • label是keyvalue都是string类型的map
      • 其中key只能由a-z,0-9,-,_,. 组成,且开头结尾需小写,最多长63个字符

集群(namespace)

  • 可以通过资源配额在多个namespace之间划分群集(cluster) 资源
  • 默认namespace是default
  • 系统组件(kube-proxy等)位于kube-system命名空间下,而不是default
  • 同一个namespace里的pod的很多信息都是通过环境变量写入每一个pod中的
    • 例如每个service的IP和端口等
    • 但是这会导致环境变量泛滥的问题

参考资料

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值