Kubernetes APIServer 内存爆满分析

本文涉及的产品
无影云电脑企业版,4核8GB 120小时 1个月
无影云电脑个人版,1个月黄金款+200核时
资源编排,不限时长
简介: 董江,容器技术布道者及实践者,中国移动高级系统架构专家,曾担任华为云核心网技术专家,CloudNative社区核心成员,KubeServiceStack社区发起者,Prometheus社区PMC,Knative Committer,Grafana社区Contributer。 欢迎关注:https://kubeservice.cn/

Kubernetes APIServer 内存爆满

现象

线上Kubernetes集群, 一共5台机器,其中4台机器内存80%+1台机器内存3.59%, 其中一台master apiserver Node 内存飙升到98%后,OOM掉后,重启了apiserver

问题分析

apiserver内存持续升高,肯定是有资源在堆内存里申请了空间但是没有释放。首先考虑是否是因为建立了太多的链接导致的,使用如下指令查询apiserver链接数:

$ netstat -nat | grep -i "6443" | wc -l
1345

发现链接数在1300+, 对于128Core和745G内存机器多并不算多。

继续分析只能考虑导出kube-apiserverheap文件来查看其详细的内存分布。

这种方式需要使用go语言包的pprof工具,下面详细讲解go tool pprof 工具的使用以及kube-apiserver的配置

go tool pprof工具使用

kubernetes 1.18这个功能是默认打开的, 但线上集群是1.16, 需要手动打开

$ cat ./manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    component: kube-apiserver
    tier: control-plane
  name: kube-apiserver
  namespace: kube-system
spec:
  ...
  - --profiling=true

使用 端口转发,将Pod端口转发到本地端口上

$ kubectl port-forward kube-apiserver-8pmpz 6443:6443 

$ go tool pprof http://127.0.0.1:6443/debug/pprof/heap
Fetching profile over HTTP from http://127.0.0.1:6443/debug/pprof/heap
Saved profile in /root/pprof/pprof.kube-apiserver.alloc_objects.alloc_space.inuse_objects.inuse_space.004.pb.gz
File: kube-apiserver
Type: inuse_space
Time: Dec 10, 2020 at 2:46pm (CST)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof)top 20

Showing nodes accounting for 11123.22MB, 95.76% of 11616.18MB total
Dropped 890 nodes (cum <= 58.08MB)
Showing top 20 nodes out of 113
     flat  flat%   sum%        cum   cum%
9226.15MB 79.43% 79.43%  9226.15MB 79.43%  bytes.makeSlice
1122.61MB  9.66% 89.09%  1243.65MB 10.71%  k8s.io/kubernetes/vendor/k8s.io/api/core/v1.(*ConfigMap).Unmarshal
 139.55MB  1.20% 90.29%   153.05MB  1.32%  k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1.(*ObjectMeta).Unmarshal
 120.53MB  1.04% 91.33%   165.03MB  1.42%  encoding/json.(*decodeState).objectInterface
 117.29MB  1.01% 92.34%   117.29MB  1.01%  reflect.unsafe_NewArray
 108.03MB  0.93% 93.27%   108.03MB  0.93%  reflect.mapassign
  66.51MB  0.57% 93.84%    66.51MB  0.57%  k8s.io/kubernetes/vendor/github.com/json-iterator/go.(*Iterator).ReadString
  62.51MB  0.54% 94.38%    62.51MB  0.54%  k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/registry/generic.ObjectMetaFieldsSet
  61.51MB  0.53% 94.91%    61.51MB  0.53%  k8s.io/kubernetes/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource.objectMetaFieldsSet
  43.01MB  0.37% 95.28%   137.03MB  1.18%  k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime.structToUnstructured
     18MB  0.15% 95.43%   183.61MB  1.58%  k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/storage/cacher.(*watchCache).Replace
  13.50MB  0.12% 95.55%   137.03MB  1.18%  k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime.toUnstructured
      9MB 0.077% 95.63%   237.54MB  2.04%  k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured.unstructuredJSONScheme.decodeToUnstructured
   7.50MB 0.065% 95.69%   144.53MB  1.24%  k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime.(*unstructuredConverter).ToUnstructured
      6MB 0.052% 95.74%   123.29MB  1.06%  reflect.MakeSlice
   1.50MB 0.013% 95.76%  8944.02MB 77.00%  encoding/json.mapEncoder.encode

看到这边数据到,问题基本明朗了。configmap瞬间大批量操作(平均每个configmap大小在347KB),导致APIServerlist/update configmap时无法一次获取到,就会一直创建slice, 从而使APIServer耗尽内存。

业务请求表现


configmap 和 Pod 业务瞬间瞬间变大,导致host内存耗尽

解决方案

  • 监控好每台机器内存,安全水位线60%,快速扩容apiserver服务

  • 升级1.18以上版本kubernetes,开启goaway=0.001

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
13天前
|
Web App开发 监控 JavaScript
监控和分析 JavaScript 内存使用情况
【10月更文挑战第30天】通过使用上述的浏览器开发者工具、性能分析工具和内存泄漏检测工具,可以有效地监控和分析JavaScript内存使用情况,及时发现和解决内存泄漏、过度内存消耗等问题,从而提高JavaScript应用程序的性能和稳定性。在实际开发中,可以根据具体的需求和场景选择合适的工具和方法来进行内存监控和分析。
|
1月前
|
编译器 C语言
动态内存分配与管理详解(附加笔试题分析)(上)
动态内存分配与管理详解(附加笔试题分析)
49 1
|
2月前
|
程序员 编译器 C++
【C++核心】C++内存分区模型分析
这篇文章详细解释了C++程序执行时内存的四个区域:代码区、全局区、栈区和堆区,以及如何在这些区域中分配和释放内存。
51 2
|
8天前
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
|
9天前
|
弹性计算 Kubernetes Perl
k8s 设置pod 的cpu 和内存
在 Kubernetes (k8s) 中,设置 Pod 的 CPU 和内存资源限制和请求是非常重要的,因为这有助于确保集群资源的合理分配和有效利用。你可以通过定义 Pod 的 `resources` 字段来设置这些限制。 以下是一个示例 YAML 文件,展示了如何为一个 Pod 设置 CPU 和内存资源请求(requests)和限制(limits): ```yaml apiVersion: v1 kind: Pod metadata: name: example-pod spec: containers: - name: example-container image:
|
18天前
|
Web App开发 JavaScript 前端开发
使用 Chrome 浏览器的内存分析工具来检测 JavaScript 中的内存泄漏
【10月更文挑战第25天】利用 Chrome 浏览器的内存分析工具,可以较为准确地检测 JavaScript 中的内存泄漏问题,并帮助我们找出潜在的泄漏点,以便采取相应的解决措施。
127 9
|
22天前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
1月前
|
程序员 编译器 C语言
动态内存分配与管理详解(附加笔试题分析)(下)
动态内存分配与管理详解(附加笔试题分析)(下)
46 2
|
2月前
|
算法 程序员 Python
程序员必看!Python复杂度分析全攻略,让你的算法设计既快又省内存!
在编程领域,Python以简洁的语法和强大的库支持成为众多程序员的首选语言。然而,性能优化仍是挑战。本文将带你深入了解Python算法的复杂度分析,从时间与空间复杂度入手,分享四大最佳实践:选择合适算法、优化实现、利用Python特性减少空间消耗及定期评估调整,助你写出高效且节省内存的代码,轻松应对各种编程挑战。
41 1
|
2月前
|
存储 Prometheus NoSQL
Redis 内存突增时,如何定量分析其内存使用情况
【9月更文挑战第21天】当Redis内存突增时,可采用多种方法分析内存使用情况:1)使用`INFO memory`命令查看详细内存信息;2)借助`redis-cli --bigkeys`和RMA工具定位大键;3)利用Prometheus和Grafana监控内存变化;4)优化数据类型和存储结构;5)检查并调整内存碎片率。通过这些方法,可有效定位并解决内存问题,保障Redis稳定运行。