技术架构
所有的组件都会WatchAPI Server
informer机制
- 可以在本地查看etcd,减轻api-server的压力
- 资源对象有版本号
- 首先List下所有的资源,保留最新的版本号
- Reflector 包会和 apiServer 建立长连接,并使用 ListAndWatch 方法获取并监听某一个资源的变化。
- List 方法将会获取某个资源的所有实例,Watch 方法则监听资源对象的创建、更新以及删除事件,然后将事件放入到DeltaFIFO Queue中;
- 然后Informer会不断的从 Delta FIFO Queue 中 pop 增量事件,并根据事件的类型来决定新增、更新或者是删除本地缓存;
- 接着Informer 根据事件类型来触发事先注册好的 Event Handler触发回调函数,然后然后将该事件丢到 Work Queue 这个工作队列中。
Master节点
API Server
资源curd的所有入口
etcd
- 负责保存k8s集群的配置信息和各种资源的状态信息,当数据发生变化时,etcd会快速地通知k8s相关组件
- etcd提供了watch机制,键值发生变化会通知到API Server,并由其通过watch API向客户端输出。
Scheduler:
资源调度,负责决定将Pod放到哪个Node上运行
Filter过滤器:过滤,不符合规则的节点
1.PodFitsHostPorts:检查Node上是否不存在当前被调度Pod的端口
2.PodFitsHost:检查Pod是否通过主机名指定了特性的Node (是否在Pod中定义了nodeName)
3.PodFitsResources:检查Node是否有空闲资源(如CPU和内存)以满足Pod的需求。
4.PodMatchNodeSelector:检查Pod是否通过节点选择器选择了特定的Node (是否在Pod中定义了nodeSelector)。
5.NoVolumeZoneConflict:检查Pod请求的卷在Node上是否可用 (不可用的Node被Pass)。
6.NoDiskConflict:根据Pod请求的卷和已挂载的卷,检查Pod是否合适于某个Node (例如Pod要挂载/data到容器中,Node上/data/已经被其它Pod挂载,那么此Pod则不适合此Node)
8.CheckNodeMemoryPressure:对于内存有压力的Node,则不会被调度Pod。
9.CheckNodePIDPressure:对于进程ID不足的Node,则不会调度Pod
10.CheckNodeDiskPressure:对于磁盘存储已满或者接近满的Node,则不会调度Pod。
11.CheckNodeCondition:Node报告给API Server说自己文件系统不足,网络有写问题或者kubelet还没有准备好运行Pods等问题,则不会调度Pod。
12.PodToleratesNodeTaints:检查Pod的容忍度是否能承受被打上污点的Node。
13.CheckVolumeBinding:根据一个Pod并发流量来评估它是否合适(这适用于结合型和非结合型PVCs)。
Priority调度算法:打分优选,同分轮询节点
1.SelectorSpreadPriority:优先减少节点上属于同一个 Service 或 Replication Controller 的 Pod 数量
2.InterPodAffinityPriority:优先将 Pod 调度到相同的拓扑上(如同一个节点、Rack、Zone 等)
3.LeastRequestedPriority:节点上放置的Pod越多,这些Pod使用的资源越多,这个Node给出的打分就越低,所以优先调度到Pod少及资源使用少的节点上。
4.MostRequestedPriority:尽量调度到已经使用过的 Node 上,将把计划的Pods放到运行整个工作负载所需的最小节点数量上。
5.RequestedToCapacityRatioPriority:使用默认资源评分函数形状创建基于requestedToCapacity的ResourceAllocationPriority。
6.BalancedResourceAllocation:优先平衡各节点的资源使用。
7.NodePreferAvoidPodsPriority:根据节点注释对节点进行优先级排序,以使用它来提示两个不同的 Pod 不应在同一节点上运行。
scheduler.alpha.kubernetes.io/preferAvoidPods。
8.NodeAffinityPriority:优先调度到匹配 NodeAffinity (Node亲和性调度)的节点上。
9.TaintTolerationPriority:优先调度到匹配 TaintToleration (污点) 的节点上
10.ImageLocalityPriority:尽量将使用大镜像的容器调度到已经下拉了该镜像的节点上。
11.ServiceSpreadingPriority:尽量将同一个 service 的 Pod 分布到不同节点上,服务对单个节点故障更具弹性。
12.EqualPriority:将所有节点的权重设置为 1。
13.EvenPodsSpreadPriority:实现首选pod拓扑扩展约束。
抢占调度
- PriorityClassAPI对象声明优先级的值,然后和pod绑定
- 对于没有绑定 PriorityClass 的 Pod 来说,它们的优先级是 0
污点和容忍度
- 污点(taint)是定义在Node之上的键值型的数据,用于让节点拒绝将Pod调度运行于其上,除非该Pod对象具有接纳Node污点的容忍度,taint字段。
- 而容忍度(tolerations)是定义在Pod对象的键值型属性数据,用于配置其可容忍的Node污点,而且调度器仅能将Pod对象调度至其能够容忍该Node污点的Node之上,tolerations字段。
亲和性和反亲和性
- Node亲和性:通过Node label限制Pod调度
- 硬亲和性(required):硬亲和性实现的是强制性规则,它是Pod调度时必须要满足的规则,而在不存在满足规则的Node时,Pod对象会被置为Pending状态。
- 软亲和性(preferred):软亲和性规则实现的是一种柔性调度限制,它倾向于将Pod对象运行于某类特定节点之上,而调度器也将尽量满足此需求,但在无法满足需求时它将退而求其次地选择一个不匹配规则的节点之上。
- Pod亲和性:几个Pod调度到相同区域,计算量大,pod 必须调度在至少运行一个 security=S1 标签的 pod 的节点上
- 硬亲和性(required):硬亲和性实现的是强制性规则,它是Pod调度时必须要满足的规则,而在不存在满足规则的Node时,Pod对象会被置为Pending状态。
- 软亲和性(preferred):软亲和性规则实现的是一种柔性调度限制,它倾向于将Pod对象运行于某类特定节点之上,而调度器也将尽量满足此需求,但在无法满足需求时它将退而求其次地选择一个不匹配规则的节点之上。
Controller Manager:
- 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等
- 负责管理集群各种资源,保证资源处于预期的状态。
- 生命周期功能:包括Namespace创建和生命周期、Event垃圾回收、Pod终止相关的垃圾回收、级联垃圾回收及Node垃圾回收等。
- API业务逻辑:由ReplicaSet执行的Pod扩展等,资源滚动更新等
Node节点
kubelet
- Pod的管理:Pod的增删
- 如何获取描述一个 Pod 的 YAML 或 JSON 对象?
- apiserver:通过 API Server 监听 etcd 目录获取数据;
- File:启动参数 –config 指定的配置目录下的文件;
- 通过 url 从网络上某个地址来获取信息
- 如何获取描述一个 Pod 的 YAML 或 JSON 对象?
- 容器健康检查
- LivenessProbe :用于判断容器是否健康
- ReadinessProbe:用于判断容器是否启动完成且准备接收请求
- 容器监控
- Kubelet 通过 cAdvisor 获取其所在节点及容器的数据
- CRI:容器运行接口,通过Grpc去访问创建容器
- ImageService接口,主要是容器镜像相关的操作,比如拉取镜像、删除镜像等。
- RuntimeService接口,主要是跟容器相关的操作,比如创建、启动、删除Container、Exec等。
部分源码
- syncLoop主函数监听configCh管道的信息,完成对pod的生命周期进行管理,包括对pod进行add 、update、remove、delete等操作
Container Runtime
- 容器运行时环境
- 下载镜像运行容器
Kube-proxy
- 提供通信和负载均衡
常用资源对象
Pod
取值 | 描述 | 原因 |
---|---|---|
Pending(悬决) | Pod已被k8s接受,但有一个或者多个容器尚未创建亦未运行。 | 节点资源不足、Pod正在被调度、正在下载镜像 |
Running(运行中) | Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。 | |
Succeeded(成功) | Pod 中的所有容器都已成功终止,并且不会再重启。 | |
Failed(失败) | Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。 | |
Unknown(未知) | 因为某些原因无法取得 Pod 的状态 | 通常是因为与 Pod 所在主机通信失败 |
创建过程
Pending排查方法
- 查看资源
- 检查 nodeSelector(标签选择)及 affinity(亲和性)的配置
- 检查 Node 是否存在 Pod 不能容忍的污点
- 检查 kube-scheduler 是否正常运行
Pod级的Volume
pod中的容器可以共享宿主机的同一目录
Pod中的Projected Volume
为容器提供预先定义好的数据。
- Secret: 把 Pod 想要访问的加密数据,存放到 Etcd 中
- ConfigMap: 保存的是不需要加密的、应用所需的配置信息
- Downward API
- ServiceAccountToken
init容器
- Init容器总是运行到成功完成为止
- 每个Init容器都必须在下一个Init容器启动之前成功完成
判断Pod是否存活
- 发起TCP检测
- 发送HTTP请求
Deployment
Deployment 控制器实际操纵的是 ReplicaSet 对象
- 滚动更新
- 删除原ReplicaSet(一个个删除Pod),创建新ReplicaSet(一个个创建)
- 回滚
ReplicaSet
- 水平扩展
StatefulSet
管理有状态Pod
- 拓扑状态指的是应用的多个实例之间不是完全对等的关系,包含启动的顺序、创建之后的网络标识等必须保证。
- 存储状态指的是不同的实例绑定了不同的存储,如Pod A在它的生命周期中读取的数据必须是一致的,哪怕是重启之后还是需要读取到同一个存储。
DaemonSet
- 这个 Pod 运行在 Kubernetes 集群里的每一个节点(Node)上;
- 每个节点上只有一个这样的 Pod 实例;
- 当有新的节点加入 Kubernetes 集群后,该 Pod 会自动地在新节点上被创建出来;而当旧节点被删除后,它上面的 Pod 也相应地会被回收掉。
Job
Job主要是用来任务调用,可以一个或多个 Pod,并确保指定数量的 Pod 可以成功执行到进程正常结束。
存储
Volume:
Persistent Volume:实现,运维用
Persistent Volume Claim:接口,研发用
Dynamic Volume Provisioning:不用静态等PV的创建了
PV和PVC绑定的条件
- PV和PVC中的spec关键字段要匹配,比如存储(storage)大小。
- PV和PVC中的storageClassName字段必须一致
Dynamic Volume Provisioning
- 声明StorageClass API对象
- 声明PVC API对象,storageClassName字段为StorageClass API对象的name字段
- k8s自动搜寻创建PV对象