k8s用到的架构和算法:
1. 构建工具Bazel
2. 代码生成工具xxx-gen,其实都可以用code-generator来生成
3. 命令行架构工具cobra
4. client-go交互
k8s源码中已经集成了client-go的源码,无需单独下载,路径为vendor/k8s.io/client-go.
(1) informer机制
<1> Reflector
Reflector用于实现对资源对象的缓存和监视更新。当资源发生变化时,触发相应的变更事件,例如Added、Updated、Deleted等事件,并将其资源对象存放到本地缓存DeltaFIFO中。
<2> DeltaFIFO
可以保存不同类型的资源对象(Delta),的一种先进先出队列。入队的是Reflector调用的Add方法,出队的是Controller调用的Pop方法。另外,Reflector调用Resync函数将Index本地存储中的资源同步到DeltaFIFO中。
<3> Indexer
client-go用来存储资源对象并自带索引功能的本地存储。使用了ThreadSafeMap并发安全存储。
(2) WorkQueue
基于FIFO队列;添加了标记、去重特性;并支持并发性、通知机制(不再接收新元素);支持延迟入队、限速入队;支持metric监控指标。
此外,WorkQueue提供了4种限速算法:
i 令牌桶算法
第三方库golang.org/x/time/rate实现
ii 排队指数算法
代码路径:vendor/k8s.io/client-go/util/workqueue/default_rate_limiters.go
iii 计数器算法
iv 混合模式
(3) EventBroadcaster事件管理器
5. kube-apiserver 核心实现
kube-apiserver架构设计
kube-apiserver启动流程
(1) 使用的web框架:go-restful
(2) OpenAPI规范
OpenAPI规范早期叫Swagger规范,Swagger是OpenAPI规范的落地实现:
<1>用于定义RESTful API的规范;
<2>可以用Swagger UI自动生成API文档;
<3>支持从API定义自动生成客户端SDK、服务器端代码;
<4>可以用于自动化测试工具,生成测试用例,验证API的实现是否符合定义。工具如Postman、Assertible等支持基于OpenAPI规范的测试。
(3) 认证
<1> BasicAuth认证
<2> ClientCA认证
<3> TokenAuth认证
<4> BootstrapToken认证
<5> RequestHeader认证
<6> WebhookTokenAuth认证
<7> Anonymous认证
<8> OIDC认证
<9> ServiceAccountAuth认证
(4) 授权
<1> AlwaysAllow授权
<2> AlwaysDeny授权
<3> ABAC授权 Attribute-Based Access Control
<4> Webhook授权
<5> RBAC授权 Role-Based Access Control
<6> Node授权
(5) 准入控制器
<1> AlwaysPullImages准入控制器
<2> PodNodeSelector准入控制器
6. kube-scheduler 核心实现
这部分功能用到了SchedulingQueue、SchedulingCache、FIFO和PriorityQueue等数据结构。
(1) 两种最优解:全局最优解和局部最优解
全局最优解指每个调度周期都会遍历k8s集群所有的节点; 局部最优解是指每个调度周期只会遍历部分k8s集群中的节点,找出局部最优的节点。
(2) 优先调度算法
基于Map-Reduce方式对节点计算分数(0-10之间),然后该优选调度算法乘以每种调度算法的权重值得到的分数,调度器会选择分数最高的节点。
(3) Preempt抢占机制和bind绑定机制
Preempt是指当没有足够资源来调度高优先级的 Pod 时,调度器会检查是否有低优先级的 Pod 可以被驱逐(抢占),以腾出资源给高优先级的 Pod。被抢占的低优先级 Pod 会被终止或驱逐,从而释放资源。
Bind 机制是在调度决策完成后,将 Pod 确定绑定到具体的节点上。
(4) 领导者选举机制
该机制用于多个kube-scheduler之间的协同工作, 基于分布式锁。不同于Raft协议,Raft 协议是一个完整的一致性算法,涵盖领导者选举、日志复制和数据一致性保证。本部分的代码在封装在client-go/tools/leaderelection/
k8s用到的存储
除了基于内存的存储,就是ETCD了,这里暂不介绍。