由于k8s中的错误配置导致无法创建新节点
记录下自己在使用KubeSphere过程中由于YAML中错误的配置导致Kubernetes经常资源紧张而无法创建与部署新节点的问题。
问题描述
部门在使用KubeSphere过程中经常遇到类似如下图所示的由于kubernetes无法调度而导致的无法部署的问题

进一步查看报错节点信息会发现提示CPU资源不足,从而导致无法部署。

之前自己采取的解决方案是暴力的删除一部分节点来释放CPU资源,但此种方式治标不治本,且随着KubeSphere在部门内部使用的普及,此问题发生的频率越来越高,只能想办法从根源上处理。
分析与解决
由于提示的是CPU资源不足,首先检查是否为CPU的问题,采用lscpu | egrep 'Model name|Socket|Thread|NUMA|CPU\(s\)'和free -g分别查看CPU和内存信息,结果如下

从查询结果可知系统的CPU配置和内存配置都很高,而自己在KubeSphere中部署的都是一些普通的Java程序,不可能占用特别多的CPU和内存资源,Linux服务器本身的配置问题排除。
接下来利用kubectl describe node查看节点信息,输出结果如下

在上图中可发现相关节点汇总后的CPU和内存占用的百分比非常大,其中CPU在Requests部分占比为84%,由于Linux系统自身运行和运行Kubesphere与Kubernetes都需要占用一定的CPU资源,从而导致当Kubersphere中部署的项目超过一定数量时,Linux系统无法给Kubernetes分配足够的CPU资源导致部署失败。至此,问题的表面原因找出来了。
进一步分析上面的问题,自己觉得很好奇的是为啥Requests部分占用的资源,自己在对应的YAML文件中压根就没指定Requests相关的参数,检查代码发现Limits配置的值比较大
resources:
limits:
cpu: 500m
memory: 2000Mi
同时基于kubectl describe node发现相关节点的Requests和Limits的值都相同,猜测是否Kubernetes默认将Ruquests的值设置为与Limits的值相同。

在Kubernetes官网发现如下说明
Note: If you specify a limit for a resource, but do not specify any request, and no admission-time mechanism has applied a default request for that resource, then Kubernetes copies the limit you specified and uses it as the requested value for the resource.
上述文字说明当我们在YAML文件中只设置了Limits但是没有指定Requests,则Kubernetes会将Request的值默认设置为与Limits相同,从而导致CPU和内存资源占用都很高,至此问题根源找到!
解决的方式也很简单,要么移除掉Limits,让Kubernetes根据Linux系统资源和节点状况给我们动态的分配节点,或者同时指定Requests和Limits即可。
# 屏蔽此部分代码
#resources:
# limits:
# cpu: 500m
# memory: 2000Mi
# 或者显示配置request和limits
resources:
limits:
cpu: 500m
memory: 2000Mi
requests:
cpu: 20m
memory: 64Mi
经验教训: 需要对自己项目中的代码要有更深入的理解,尤其是配置文件,要做到理解每一行的作用,不能简单的复制别人的代码。
参考文档: