前言
某天开发人员开发环境发布失败,于是找到了这边处理一下.
过程
<1>发布环境是Centos系统的k8s测试集群,从jenkins上看编译正常,编译后镜像正常,结果在启动和注册时候一直不成功直到超时发布失败.
<2>服务器上进行查看,发现pod状态为Pending
(该状态通常是调度异常,通常是k8s 的node资源不足)
kubectl get pod -n <namespace> |grep 项目名称
kubectl get pod -n <namespace> -o wide <pod-name>
kubectl get pod -n <namespace> -o yaml <pod-name>
<3>查看Pod的日志
kubectl logs -f <pod-name> -n <nameSpace> -c <container_name>
命令无错,容器没起来所以没有日志
<4>查看 Pod 的事件
kubectl describe pod <pod-name> -n <nameSpace>
没截图.英语不好的把报错复制到翻译软件,它会告知是哪个资源不足导致的异常
<5>查看node的资源
kubectl top node
kubectl top pod -n <namespace>
实际情况是各个节点上都有资源,但每个node剩余的资源,都不符合该项目的内存和cpu配置,无法调度pod到某一个node上启动
篮球无法放到小瓶子里
处理方法
方法一
新添加node节点
线上环境建议直接增加节点
方法二
对该项目中同一代码模块pod的数量进行调整,也就是调整实例数
需要和开发人员沟通,缩减某pod的数量到某个值,是否影响测试的可靠性和准确性
方法三
占用node节点资源的通常是pod的日志,过期的旧镜像和状态异常但未删除的pod
关于pod日志的切割和清理,建议配置计划任务和脚本进行切割和清理,但是重要的日志还是需要进行备份.否则当业务较繁忙时,日志大量产生触发脚本,虽然保证了节点的可用性,但日志会被清空.如果业务繁忙,在监控上会频繁出现短暂的磁盘报警再恢复的现象.
关于过期的旧镜像.可根据需求,清理未启动容器的镜像或者按创建时间删除老版本的镜像
关于状态异常但未删除的pod,应保持良好习惯,即使资源足够,在排错后也要删除异常pod,否则占用资源影响报警.
删除pod演示
<1>删除pod
kubectl delete pod -n <namespace> <pod-name>
如果只删除pod,deployment会自动重建,所以在删除后pod又重启了,应先删除deployment
<2>删除deployment
kubectl get deployment -n <namespace>
kubectl delete deployment <deployment_name> -n <namespace>
删除deployment后果是,其 对应的所有 pod 之后也会被删除
<3>再删除pod
kubectl delete pod -n <namespace> <pod-name>
<4>Terminating的pod有些特殊,需要强制删除
kubectl delete pod <pod-name> -n <namespace> --force --grace-period=0
补充
Pod的常见的几种状态,其他的百度即可
Pending 挂起
Pending 说明Pod还没有调度到某个Node 上面。可能的原因资源不足,集群内每个noode都不满足该Pod请求的资源需求;HostPort被占用
ContainerCreating 容器创建中
还处于创建中.可能的原因:网络问题导致Kubelet无法访问镜像或拉取镜像超时;配置镜像错误,导致容器无法启动;配置异常,无法分配pod网络
ImagePullBackOff 正在重试拉取
通常是镜像拉取失败。可能原因:配置镜像的名称错误,无法拉取.可以docker pull拉取试一下
CrashLoopBackOff 容器退出,kubelet正在将它重启
CrashLoopBackOff 容器启动但又异常退出。可能原因: apollo配置异常,例如内存相关 代码逻辑问题.可以查看该pod的日志
Terminating 结束
可能原因:node节点内核出现bug,导致状态异常,重启node. 可使用强制删除
Evicted 驱赶
可能原因: 系统内存或硬盘资源不足.驱赶pod到其他节点