Kubernetes资源对象:node讲解

每个资源对象都有3大类属性:元数据metadata、规范spec和状态status。

元数据metadata是用来标识API对象的,每个对象都至少有3个元数据: namespace,name和uid;

规范spec是根据资源对象不同,有着各自的结构;

状态status作为资源状态,有别于资源规范的一点,就是状态往往是通过组件去维护的,比如deployment 是通过kube-controller-manager 去维护状态,node 是通过kubelet 去维护。

node

node 作为pod  运行的 主机, 可以是物理机,也可以是虚拟机,但为了管理pod,在node上必须运行 container runtime (docker 或 rkt),以及kubelet 与 kube-proxy。

 

node,不同于其他资源注册方式,是通过kubelet 主动触发,发送请求给kube-apiserver去创建出来,之后kubelet通过定时心跳去维护node的状态。

 

每一个node都会包含一下的状态信息,都是通过kubelet 收集:

  • address: 包括节点的hostname,内网ip,外网ip
  • condition: 包括OutOfDisk、Ready、MemoryPressure 和 DiskPressure
  • capacity: Node 上的可用资源,包括 CPU、内存和 Pod 总数
  • nodeInfo: 包括内核版本、容器引擎版本、OS 类型等

【拓展】node状态维护

kubelet 根据 --node-status-update-frequency (default 10s)配置,定时维护node的状态(会更新node.status.condition中,保留着最近一次心跳时间);

在kubelet 出现异常状态,导致无法发送心跳给kube-apiserver的时候, kube-controller-manager的node controller 会根据 --node-monitor-grace-period duration(default 40s)配置,若最后一次心跳时间,超过这个配置, node controller会去将node的状态变为not ready ,并将 node上的pod 状态变为not ready, endpoint controller 就会在endpoint内移除相关not ready pod 的ip;

当kubelet 的一直没有恢复心跳, kube-controller-manager的node controller 会根据--pod-eviction-timeout(default 5m0s)配置,若最后一次心跳时间,超过这个配置, node controller 会去移除掉该node上所有pod。

注意: 大规模节点not ready 现象,超过一定比例,则不会进行移除node 上的pod操作 ,但在大集群的场景下,往往大规模node not ready ,并不会超过比例,这个时候就会出现雪崩式的pod 移除现象,从而pod调度到其他正常节点,就可能会影响正常节点,故在部署应用的时候引入租户概念以及nodeselect,affinity等调度策略是有非常必要性的

​​​​​​​【拓展】节点调度

kubernetes 上的应用创建出来,是处于未调度状态,kube-scheduler 组件这时候就会捕获到这些应用,根据调度策略来为这些应用分配节点(更新 Pod 的 NodeName 字段

 

Kubernetes资源对象:node讲解

kube-scheduler 调度分为两个阶段,predicate 和 priority

  • predicate:过滤不符合条件的节点
  • priority:优先级排序,选择优先级最高的节点

kubernetes 调度策略

predicates 策略

  • PodFitsPorts:同 PodFitsHostPorts
  • PodFitsHostPorts:检查是否有 Host Ports 冲突
  • PodFitsResources:检查 Node 的资源是否充足,包括允许的 Pod 数量、CPU、内存、GPU 个数以及其他的 OpaqueIntResources
  • HostName:检查 pod.Spec.NodeName 是否与候选节点一致
  • MatchNodeSelector:检查候选节点的 pod.Spec.NodeSelector 是否匹配
  • NoVolumeZoneConflict:检查 volume zone 是否冲突
  • MaxEBSVolumeCount:检查 AWS EBS Volume 数量是否过多(默认不超过 39)
  • MaxGCEPDVolumeCount:检查 GCE PD Volume 数量是否过多(默认不超过 16)
  • MaxAzureDiskVolumeCount:检查 Azure Disk Volume 数量是否过多(默认不超过 16)
  • MatchInterPodAffinity:检查是否匹配 Pod 的亲和性要求
  • NoDiskConflict:检查是否存在 Volume 冲突,仅限于 GCE PD、AWS EBS、Ceph RBD 以及 ISCSI
  • GeneralPredicates:分为 noncriticalPredicates 和 EssentialPredicates。noncriticalPredicates 中包含 PodFitsResources,EssentialPredicates 中包含 PodFitsHost,PodFitsHostPorts 和 PodSelectorMatches。
  • PodToleratesNodeTaints:检查 Pod 是否容忍 Node Taints
  • CheckNodeMemoryPressure:检查 Pod 是否可以调度到 MemoryPressure 的节点上
  • CheckNodeDiskPressure:检查 Pod 是否可以调度到 DiskPressure 的节点上
  • NoVolumeNodeConflict:检查节点是否满足 Pod 所引用的 Volume 的条件

priorities 策略:每条策略有着权重比,节点打分 = sum(每条策略分数*权重)

  • SelectorSpreadPriority:优先减少节点上属于同一个 Service 或 Replication Controller 的 Pod 数量
  • InterPodAffinityPriority:优先将 Pod 调度到相同的拓扑上(如同一个节点、Rack、Zone 等)
  • LeastRequestedPriority:优先调度到请求资源少的节点上
  • BalancedResourceAllocation:优先平衡各节点的资源使用
  • NodePreferAvoidPodsPriority:alpha.kubernetes.io/preferAvoidPods 字段判断, 权重为 10000,避免其他优先级策略的影响
  • NodeAffinityPriority:优先调度到匹配 NodeAffinity 的节点上
  • TaintTolerationPriority:优先调度到匹配 TaintToleration 的节点上
  • ServiceSpreadingPriority:尽量将同一个 service 的 Pod 分布到不同节点上,已经被 SelectorSpreadPriority 替代 [默认未使用]
  • EqualPriority:将所有节点的优先级设置为 1[默认未使用]
  • ImageLocalityPriority:尽量将使用大镜像的容器调度到已经下拉了该镜像的节点上 [默认未使用]
  • MostRequestedPriority:尽量调度到已经使用过的 Node 上,特别适用于 cluster-autoscaler[默认未使用]

kube-scheduler原理

1.  获取还未调度的pods列表,获取当前所有nodes列表

2.  根据predicates 策略,过滤出符合条件的节点

3.  根据priorities 策略,对符合条件的节点进行打分

4.  选取分数最高的节点,更新pod,将pod.spec.nodeName配置成该节点

​​​​​​​【拓展】 不可调度node 

在node上出现异常的时候,可以设置不可调度,避免其他pod调度到该节点,可以使用命令: kubectl crodon $NODENAME 来使node进入不可调度状态,其本质上是修改node.spec.unschedulable 为 true