在宿主机上使用
kubectl get configmap -A 发现命令卡死没有输出,但是在特定的某一个namespace下进行kubectl get configmap是有返回的。所以怀疑其中的某一个namespace下有大量的configmap,kubectl get configma卡死从而导致kubectl get configmap -A卡死。
下面就尝试在每一个namespace下执行kubectl get configmap。当执行到kubectl get configmap -n kubesphere-controls-system,时发现命令卡住,在等待了3分钟后有数据返回。使用wc统计了数量发现kubesphere-controls-system下有17万多的configmap,大多是kubeconfig-xxxx样子的。后面的xxx是用户名。使用kubectl get user同样发现了有17万多的用户。应该是之前同步的ldap的用户,每创建一个用户,就会在kubesphere-controls-system下新建一个configmaps。查看etcd db文件,发现达到了1.5g左右,其他正常的集群db文件一般在50M甚至更低。
分析到这里,问题基本明朗了。可能是kubesphere 2.x版本时同步了ldap的数据到kubesphere中,kubesphere每创建一个user就会新建个对应的configmap里面存着key和cert。17万configmap,导致api-server去list configmap时无法一次获取到,就会一直创建slice(这里应该是golang语言包里的一个bug https://studygolang.com/artic...,从而使api-server耗尽内存。
解决方案
最终的解决方案就是删除这些ldap用户,kubesphere升级到3.0后每一次登录都直接到ldap验证,且是在host集群上执行的。被纳管集群不需要存贮这些数据。在使用kubectl delete user发现用户无法删除,因为etcd数据量太大了,kube-apiserver与etcd之间的调用性能下降很严重。kube-apiserver已经无法正常的提供服务了。所以考虑使用etcdctl直接链接etcd来删除数据
#删除 user
ETCDCTL_API=3 etcdctl --endpoints https://10.250.7.21:2379 --cacert $ETCD_TRUSTED_CA_FILE --cert $ETCD_CERT_FILE --key $ETCD_KEY_FILE del /registry/iam.kubesphere.io/users/ --prefix
#删除对应的 configmap
ETCDCTL_API=3 etcdctl --endpoints https://10.250.7.21:2379 --cacert $ETCD_TRUSTED_CA_FILE --cert $ETCD_CERT_FILE --key $ETCD_KEY_FILE del /registry/configmaps/kubesphere-controls-system/kubeconfig- --prefix
删除完数据后,使用docker restart 重启kube-apiserver,观测了一会,发现内存一直保持在1g左右。kubectl操作以及sit集群的web页面响应都比之前快了许多。
本文来自:Segmentfault
感谢作者:qd19zzx
查看原文:kube-apiserver内存溢出问题调查及go tool pprof工具的使用
相关阅读 >>
更多相关阅读请进入《Go》频道 >>

Go语言101
一个与时俱进的Go编程知识库。