kubernetes相关之内存泄露

kubernetes与docker内存泄露问题

近期在生产环境中遇到一些关于pod,docker的的 Linux Kernel cgroup kmem accounting 泄露问题,总结一下。

关键字

/cgroup/memory - no space left on device

主要原因

cgroup kernel memory (kmem) accounting 统计特性在低版本 Kernel 中有 bug。随着堆积的cgroup越来越多,会把主机内存吃光,主机挂掉。

涉及的组件

kubernetes v1.9+ (其中的runc) 默认开启kmem accounting 特性

docker v18.09.1+(其中的runc)默认关闭kmem accounting特性

主要出现在centos7.4(网上查阅看到的),centos7.5(当时在生产环境我使用的就是该版本)。

遇见这样的问题,解决方案:

  1. 将Linux升级到7.6+,或者升级kernel到最新版本(这个是在集群安装时或者未上生产环境)

  2. 使用万能的重启主机也是可以的(重启可以解决百分之90的问题)

  3. 就是调整kubelet关闭其中内置runc的kmem accounting功能(需要删除部分相关代码重新编译)(在生产环境当中有业务在运行的方法)

    func (s *MemoryGroup) Apply(d *cgroupData) (err error) {  
        path, err := d.path("memory")  
        if err != nil && !cgroups.IsNotFound(err) {  
                return err  
           } else if path == "" {  
                   return nil  
        }  
        if memoryAssigned(d.config) {  
                   if path != "" {  
                   if _, err := os.Stat(path); os.IsNotExist(err) {  
                        if err := os.MkdirAll(path, 0755); err != nil {  
                                return err  
                        }  
                  }  
                  if d.config.KernelMemory != 0 { // 删除这行的判断, 默认就 enable cgroup kernel memory 特性  
    						// Only enable kernel memory accouting when this cgroup  
                           // is created by libcontainer, otherwise we might get  
                          // error when people use `cgroupsPath` to join an existed  
                           // cgroup whose kernel memory is not initialized.  
                        if err := EnableKernelMemoryAccounting(path); err != nil {  
                                return err  
                        }
    
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页