1.k8s集群节点notready状态的几种情况
情况1: 刚安装好k8s集群的node节点notready
现象:node节点notready,查看coredns的pod状态为pending
可能原因: 可能是没有部署网络插件(calico或flannel),需要安装网络插件
情况2: k8s运行一段时间后,node节点notready
可能原因:
(1).查看node节点宿主机的网络情况、磁盘情况、内存情况、cpu情况,查看资源是否足够
(2).查看node节点的kubelet服务是否正常
如果node节点的kubelet服务不正常,也会显示notready状态
(3).查看node节点的详细信息排查原因
#kubectl describe node node名
2.pod的几种调度方式
当我们发送请求创建pod,调度器就会把pod调度到合适的物理节点,大致分为以下过程:
1).Scheduler根据预选策略和优选函数,选择合适node节点调度。
a).预选阶段(Predicates):过滤节点,调度器用一组规则过滤掉不符合要求的node节点,比如pod设置了资源的request,那么可用资源比pod需要资源少的主机显然就会被过滤掉
b).优选阶段(Priorities):为节点的优先级打分,将上一阶段过滤出来的node列表进行打分,调度器会考虑一些整体的优化策略,比如把deployment控制的多个pod 副本尽量分布到不同的主机上,使用最低负载的主机等等策略
2).可以通过定义nodeName(一般不经过调度器,使用很少)或nodeSelector进行调度。
3).可以根据节点亲和性进行调度。
nodeAffinity: 节点亲和性,与nodeSelector作用一样,但相比更灵活,满足更多条件:
-匹配有更多的逻辑组合,不只是字符串的完全相等。
-调度分为软策略和硬策略,而不是硬性要求。
a).硬(required): 必须满足
b).软(preferred):尝试满足,但不保证
操作符:In、NotIn、Exists、DoesNotExist、Gt、Lt (操作符支持这些,标签选择不一定等于,也可是包含或其他等操作)
节点选择器2:nodeAffinity分两种:硬性需求:必须满足。软性需求:尝试满足,但不保证。
硬性需求应用场景: 创建pod资源或其他资源时候,yaml文件里指定在打了具体标签的node节点上,就必须只能在该node节点上创建资源,如果node节点上没有符合的标签,就不会被调度。所有node节点都不满足,就都不调度创建资源。
软性需求应用场景: 创建pod资源或其他资源时候,yaml文件里指定在打了具体标签的node节点上,则尽可能在该node节点上创建资源,如果所有node节点上都没有符合的标签,就再按其他调度算法创建在相应的node节点上
注意:pod在调度的时候会找到一个合适的节点,所以如果节点资源不足;pod定义了指定的节点,但是指定的节点出现故障;或者pod定义了亲和性,但是节点没有满足的条件,都会导致调度失败。
解释:亲和性和反亲和性概念:
pod 亲和性(podAffinity)主要解决pod可以和哪些pod部署在同一个拓扑域中的问题(其中拓扑域用主机标签实现,可以是单个主机,也可以是多个主机组成的 cluster、zone 等等),而 pod 反亲和性主要是解决 pod 不能和哪些pod部署在同一个拓扑域中的问题,它们都是处理的 pod 与pod 之间的关系,比如一个Pod在一个节点上了,那么我这个也得在这个节点,或者你这个Pod在节点上了,那么我就不想和你待在同一个节点上。
3.k8s中一个node节点突然断电,恢复后上面的pod无法启动故障
1).故障现象:
k8s中pod一直正常运行,偶尔一次node节点突然断电,恢复之后,发现pod无法启动
报错日志: node节点包含污点,但是没有配置容忍度
2).排查思路:
(1).首先查看node节点是否有污点存在
当node节点宕机,k8s会自动为这个节点加上不可调度污点。有可能开机后,污点没有自动消失,导致有污点,让pod调度不过去。
(2).检查node节点的主机名是否更改,主机名更改后连接不到集群,也会添加污点
如果初始化后的集群的某个node节点的主机名更改后,重启kubelet服务后,该node节点就注册不到k8s集群了,这是该node节点也显示notready状态。即使将该node节点和master的hosts解析改成新主机名,也不行,kubelet还是按最初初始化集群时定义的主机名注册,除非再将node节点的主机名改成原来初始化时候的主机名才能恢复。所以,初始化时候一般要定义好主机名,后面不要随意修改主机名。
(3).检查node节点的kubelet服务是否正常
如果node节点的kubelet服务不正常,也会使node节点notready状态。
注意:只要node节点的状态为notready状态,k8s就会给该node节点打上一个污点,如果node节点恢复了,污点一般会自动消失,但也有可能没消失,这时候可以手动删除污点或看看别的原因。
3).解决思路:
(1).在相应node节点查看kubelet服务状态,如果不行,重启kubelet服务。
(2).将相应node节点上的污点手动删除。
#kubectl taint node node名 污点-
4.当前内置的污点包括:
node.kubernetes.io/not-ready:节点未准备好。这相当于节点状况 Ready 的值为 "False"。
node.kubernetes.io/unreachable:节点控制器访问不到节点. 这相当于节点状况 Ready 的值为 "Unknown"。
node.kubernetes.io/memory-pressure:节点存在内存压力。
node.kubernetes.io/disk-pressure:节点存在磁盘压力。
node.kubernetes.io/pid-pressure: 节点的 PID 压力。
node.kubernetes.io/network-unavailable:节点网络不可用。
node.kubernetes.io/unschedulable: 节点不可调度。
node.cloudprovider.kubernetes.io/uninitialized:如果 kubelet 启动时指定了一个“外部”云平台驱动, 它将给当前节点添加一个污点将其标志为不可用。在 cloud-controller-manager 的一个控制器初始化这个节点后,kubelet 将删除这个污点。
在节点被驱逐时,节点控制器或者 kubelet 会添加带有 NoExecute 效果的相关污点。 如果异常状态恢复正常,kubelet 或节点控制器能够移除相关的污点。
5.pod超过节点资源限制
1).pod数量太多超过物理节点限制
故障现象: 监控系统大量报警,大量pod在批量重启,还有pod一直处于pending状态
处理思路:
(1).查看pod详细信息,看有没有报错,污点: xx:NoExecute。(当pod数量太多不可调度时也会自动加污点)
#kubectl describe pod pod名
(2).查看相应node节点详细信息,有没有报错: OOM内存泄露。
#kubectl describe node node名
(3).到相应node节点,查看磁盘、cpu、内存等资源情况是否足够。 #df -h free top
(4).到相应node节点查看kubelet的状态,看有没有报错。
#systemctl status kubelet
(5).查看相应node节点数量是否超出了默认的110个
#kubectl get pod | wc -l |grep node名
当node节点上pod数量太多,超过默认110个后,无法再运行pod的处理:
(1).给相应node节点增加资源,磁盘/内存/cpu,在kubelet服务中增加启动参数,调大node节点运行pod数量,如: --max-pods=300
(2).增加node节点数量。
2).pod资源超过物理节点资源限制
故障现象: 在k8s中部署pod,发现一直处于pending状态
处理思路:
(1).查看pod详细信息,看有没有污点报错,在查看有没有资源限制报错、内存/cpu/磁盘等.
#kubectl describe pod pod名
(2).查看pod的yaml文件中limit相关的资源限制,看定义资源范围node节点是否能满足。
解决方法:
(1).扩容相应的node宿主机节点的资源。
(2).增加一个新的node节点。
(3).缩小部署的pod相关的limit的资源限制,资源参数改小一点。