kubernetes 故障排除、处理、预防
故障排除顺序和思路
第一步:
我们可以通过查看节点是否正常,一是保证 K8S API Server 是正常的,二是可以查看节点集群网络中是否存在节点异常。如果我们在第一步发现哪个节点挂掉了,这时候我们可以重启节点,对节点上的应用进行恢复。假如我们发现这个节点挂掉是因为集群资源不够,这时候我们要及时增加集群节点,否则哪怕是重启集群,可能还是会挂掉。
第二步:
通过第一步,我们并没有发现集群中的节点有什么问题,我可能需要看到应用本身的部分,我们需要查看应用本身的日志,需要查看涉及的 Pod 日志。执行时可以看到确认两点,一是看 Pod 基础网络是否通畅,通过日志查看这个应用是不是在运行过程中发现一些问题,是不是有一些错误的日志在里面。二是解决在启动时遇到的常见问题。
第三步:
假设我们发现 Pod 没有错误情况发生,这时候我们可能需要看看 K8S 核心组件,包括 kube-apiserver,kube-scheduler,kube-controller-manager 的日志。这时候我们可以查看 K8S 核心组件的配置,看有没有问题。
第四步:
第四步工作是检查 Service 是否可以访问,这时候我们需要查看 DNS 或者 kube-proxy 日志,可以很简单的查看 DNS 或者 kube-proxy 有没有报错。有些人习惯性地在某些 Pod 上抓包或者在节点上进行抓包,这种效率是非常低的。
第五步:
实在没有定位到问题的话,还可以看看每个节点上 Kubelet,如果 Kubelet 上有错误信息发生,可能就是因为这个节点上 Kubelet 发生了一场灾难,需要我们重新做节点。
以上五种情况可以解决集群中大部分的网络、存储和应用本身的异常。核心依赖是本身集群就有监控系统、监控告警系统,通过这种方式直接在我们监控系统中查看集群中是不是有哪个节点异常。假如我们是微服务应用,还可以查看是不是某一个微服务中的某个链路断开了。
常见应用故障
第一种是 Pod 启动后一直处于 Pending 的状态,表示这个 pod 没有被调度到一个节点上。在我们实际场景中,大部分是因为节点上的资源不足引起的。
第二种是使用了 hostPort 导致端口出现冲突,服务无法正常启动。
第三种是如果你的程序在 Waiting 中,则表示这个 pod 已经调试到节点上,但是没有运行起来,通过 kubectl describe 这个命令来查看相关信息。最常见的原因是拉取镜像失败,这个情况在私有云环境中非常常见。
第四种跟我们应用本身使用参数或者应用本身的代码有关系,这里有一个典型的例子——MySQL。我相信有在 K8S 上部署 MySQL 的用户,都可能遇到这个问题。MySQL 在使用时,假如你的磁盘中缓存不足,这时候我们需要查一查 MySQL 的报错,错误信息会很明确地告诉你需要调大参数,这是都是通过 Controller 命令就可以查到的。假如 Pod 一直 restart 的话,我们可能需要查看它之前的日志。
第五种,Service 提供了多个服务和多个 Pod 之间的负载均衡功能。假设你的服务不可访问时,这时候我们需要考量,可以通过 Controller 查看 Service 下有没有挂载具体的 Pod。
常见集群故障
1、节点异常
2、基础网络异常
3、k8s组件异常
4、容器存储和网络
我们的集群有时候会出现状况,比如我们的 CPU 或者内存不足,导致节点异常、宕机,或者整个集群网络中断、闪断。
如果节点异常,这时候需要快速重启节点,资源不足要增加节点。如果节点频繁抖动导致业务出现漂移,这时候我们会检查一下 Controller-Manager 中的参数,配置响应参数,设置它整个节点状态检测周期。
如果我们发现 K8S 中发生异常,比如我们发现 Controller-Manager 挂了,或者 Cloud-Controller-Manager 挂了,最核心的是查看日志,及时把这些节点重启起来。最核心的需求是我们需要保证关键组件高可用,包括我们需要让这些组件一直保持在多个副本中。
存储和网络是 K8S 整个环境中最容易出问题的地方,一般像网络出现问题,定位它会像其他似的,我们需要由上至下一层层地筛选,在哪一层的网络出现问题。
如何避免故障
1、实时监控集群资源
避免资源不足导致的pod漂移,及时添加节点
2、给pod设置合适的资源
k8s提供了limitRange API,可以配置某个namespace默认的limit、request值
同时集群插件(监控,告警,日志收集)等也会占用资源,随集群扩大而增加,所以需要做资源限制。如果不设置资源限制,会导致被不断地杀死(资源不足,k8s驱逐pod有优先级,会优先杀死没有设置资源限制的pod,并且随着监控资源变多,负载变大,占用的资源增加后,没有设置合适的内存限制,会被不断杀死重启)
3、关注社区动态
及时修复集群中组件的bug
4、应用层面优化
尽量使应用无状态化,结合k8s deployment 资源对象,实现多副本,自动伸缩功能。
由于 K8S 整个集群的负载是我们平时无法应付的,所以我们要想办法避免问题,我总结以下四点,帮助我们开发者规避集群中可能遇到的情况。
第一点是我们集群搭建起来,真正落地到生产环境中时,我们非常依赖集群中的监控系统,我们需要 Prometheus,需要 Docker 系统,帮助我们实时监控集群中的资源状况。如果哪个节点发生异常,我们需要及时收到通知。
开发者或者运维人员很容易忽略的一点,假设我们集群中部署了一些 Prometheus 或者日志的组件,我们可能会忽略这些系统组件本身会消耗掉一部分系统资源。
当我们节点不断增加,这些系统组件上面会有 overhead ,它还是会消耗资源。如果应用越来越多、Pod 越来越多,这些系统组件也会有更多的资源消耗,如果没有给系统组件足够的资源会导致这些关键系统组件崩溃,我们需要给他们设置合适的资源限制,需要根据集群规模不断地调整。至少保证我们的监控告警系统正常运行。
第二点是很多时候 K8S 往往会暴露出非常多的安全问题,我们要实时关注,及时修复集群中可能出现的问题。
第三点是应用层的优化,当我们应用出现问题时,如果我们想要快速恢复它,一个大前提是我们要保证应用是无状态的,不依赖于任何存储。有状态应用的恢复比无状态应用的恢复起来麻烦得多。无状态应用,我们可以让应用恢复副本数,充分利用 K8S 调度编排的优势,这是和普通传统应用有区别的地方。我们可以通过这种方式避免我们在 K8S 集群中的应用出现问题。
最重要一点,我们需要及时备份集群中的数据,之前我们发生了一场线上灾难,通过备份数据得以进行恢复,没有影响到业务。
原文地址:https://www.cnblogs.com/h-gallop/p/11682098.html