关键一句话:docker 容器的teminal失败,一定是等待资源导致的,不管是pid资源,还是内存资源。本文主要讲因为内存资源导致进程D状态,然后导致teminal容器失败。

目前在集群中,cpu占用率其实一直较低,也就是说,load高目前都是因为D状态的进程多,或者说D状态的进程时间比较久,这种情况下,如果该进程归属的容器需要terminal,则会失败。

总结的规律是:

1.有的集群,由于kmem的泄露,导致容器的runc有时候会在创建的时候出现申请内存失败而在内核态循环的情况,这种情况,只要增加对应容器的内存就能解决。然后升级runc不默认开启kmem的记账。

2.普通的业务集群,没有开启kmem记账,那么当用户态占用内存较多达到limit时,会因为申请不到内存而在内核态循环,而触发了oom,

常见的堆栈如下:

[<ffffffffba3da5f5>] wait_iff_congested+0x135/0x150
[<ffffffffba3cce5a>] shrink_inactive_list+0x30a/0x5d0
[<ffffffffba3cd815>] shrink_lruvec+0x385/0x730
[<ffffffffba3cdc36>] shrink_zone+0x76/0x1a0
[<ffffffffba3ce140>] do_try_to_free_pages+0xf0/0x4e0
[<ffffffffba3ce62c>] try_to_free_pages+0xfc/0x180
[<ffffffffba47941e>] free_more_memory+0xae/0x100
[<ffffffffba47a73b>] __getblk+0x15b/0x300---这个地方会有一个循环
[<ffffffffc075bd43>] __ext4_get_inode_loc+0xe3/0x3c0 [ext4]
[<ffffffffc075e49d>] ext4_get_inode_loc+0x1d/0x20 [ext4]
[<ffffffffc0760256>] ext4_reserve_inode_write+0x26/0xa0 [ext4]
[<ffffffffc0760323>] ext4_mark_inode_dirty+0x53/0x210 [ext4]
[<ffffffffc0763b20>] ext4_dirty_inode+0x40/0x60 [ext4]
[<ffffffffba4715ad>] __mark_inode_dirty+0x16d/0x270
[<ffffffffba45f6a9>] update_time+0x89/0xd0
[<ffffffffba45f790>] file_update_time+0xa0/0xf0
[<ffffffffc0763d4c>] ext4_page_mkwrite+0x6c/0x470 [ext4]
[<ffffffffba3e5a3a>] do_page_mkwrite+0x8a/0xe0
[<ffffffffba3e60d6>] do_shared_fault.isra.62+0x86/0x280
[<ffffffffba3ea664>] handle_pte_fault+0xe4/0xd10
[<ffffffffba3ed3ad>] handle_mm_fault+0x39d/0x9b0
[<ffffffffba971603>] __do_page_fault+0x203/0x4f0
[<ffffffffba971925>] do_page_fault+0x35/0x90
[<ffffffffba96d768>] page_fault+0x28/0x30
[<ffffffffffffffff>] 0xffffffffffffffff

这种就是典型的由于pagefault进来,然后因为申请内存不到而在内核态死循环的。此时pagefault的oom的执行需要

mem_cgroup_oom_enable,同时,也要求mem_cgroup_oom_synchronize能够顺利执行才会最终杀进程,而很多时候循环在

__getblk 的循环中,如果当前进程被选择为需要oom的进程,则必须退出循环才能处理。所以出现了软死锁,这个非常关键,我们要跳出循环才能执行oom杀进程,所以不是没有oom,

而是oom在这种情况下没法执行。

另外,不是所有的pagefault进来都是这个堆栈,比如是因为写时复制的原因进来,这个时候堆栈大多数情况下是如下:

PID: 112272 TASK: ffff9ae9eaff8000 CPU: 21 COMMAND: "runc:[2:INIT]"
#0 [ffff9adf48673608] __schedule at ffffffffb6769a72
#1 [ffff9adf48673698] schedule at ffffffffb6769f19
#2 [ffff9adf486736a8] schedule_timeout at ffffffffb6767968
#3 [ffff9adf48673758] io_schedule_timeout at ffffffffb67695ed
#4 [ffff9adf48673788] wait_iff_congested at ffffffffb61da5f5
#5 [ffff9adf486737e8] shrink_inactive_list at ffffffffb61cce5a
#6 [ffff9adf486738b0] shrink_lruvec at ffffffffb61cd815
#7 [ffff9adf486739b0] shrink_zone at ffffffffb61cdc36
#8 [ffff9adf48673a08] do_try_to_free_pages at ffffffffb61ce140
#9 [ffff9adf48673a80] try_to_free_mem_cgroup_pages at ffffffffb61ce78a
#10 [ffff9adf48673b18] mem_cgroup_reclaim at ffffffffb6234d1e
#11 [ffff9adf48673b58] __mem_cgroup_try_charge at ffffffffb62356dc
#12 [ffff9adf48673c10] mem_cgroup_charge_common at ffffffffb6236049
#13 [ffff9adf48673c58] wp_page_copy at ffffffffb61e6b50
#14 [ffff9adf48673cc8] do_wp_page at ffffffffb61e8f6b
#15 [ffff9adf48673d70] handle_pte_fault at ffffffffb61ea8fd
#16 [ffff9adf48673e08] handle_mm_fault at ffffffffb61ed3ad
#17 [ffff9adf48673eb0] __do_page_fault at ffffffffb6771603
#18 [ffff9adf48673f20] do_page_fault at ffffffffb6771925
#19 [ffff9adf48673f50] page_fault at ffffffffb676d768

这种情况下,runc会由于写时复制而出现没有内存的情况,返回值一般是:

mem_cgroup_charge_common return=0xfffffffffffffff4,这个就是-12了,也就是没有内存。

这种情况虽然不会出现死循环,但是由于用户态确实需要访问写时复制的page,这样会导致它长期地持有

mmap_sem这把锁,一方面会导致load升高,其他等待这把锁的会处于D状态,另一方面,runc的阻塞,也会导致docker exec 卡住。

3.还有一种load高,是因为内存翻转导致,比如提交的io飞了,一直在等待某个page释放等,这种概率虽然低,但是一旦遇到很难定位,我在oppo短短半年就遇到3次,都是mce

检测不出来,但是堆栈明显是内存翻转,后来升级bios解决。

4.很多ps进程阻塞,这个也是表象,ps阻塞还出现过读锁堵塞读,只要是因为防止写饥饿,因为虽然读者持有sem的读端,当写者来写时,排队会阻塞后端再来的读。

既然说到load高,如果是cpu占用高,则需要分析cpu占用,如果是D状态,比如说之前一直出现的lxcfs导致的fuse的D状态,则一方面会导致load升高,另外一方面就会导致

进程杀不掉,也就是container 在teminnal的时候会出现阻塞。前段时间一直报的重启lxcfs来规避,就是fuse阻塞较多,后来运维发现lxcfs复位也不能解决所有D状态,这个是很

正常的,因为D状态的触发路径有很多,fuse只是占了其中一部分而已。

docker 容器terminal失败的更多相关文章

  1. win7 docker Toolbox 启动Docker Quickstart Terminal 失败!

    解决办法: 在windows下安装docker Toolbox 启动Docker Quickstart Terminal 失败! 主要是用如下文件启动,临时解决,或设置环境变量

  2. Docker:虚拟机挂起后,再启动docker容器连接失败

    问题描述 当我们使用VMware15 Pro 创建虚拟机并运行Linux搭建的Docker时,挂起虚拟机后再次运行发现访问Docker容器失败. 解决方式  我们正常的挂起其实是:挂起客户机,博主尝试 ...

  3. Docker容器启动失败 Failed to start Docker Application Container Engine的解决办法

    当编辑完daemon.json时,准备systemctl start docker.service启动docker时报以下错误: 网上查找的诸多方法都不行,后面看到一篇类似的文章:http://www ...

  4. Docker容器启动失败 Failed to start Docker Application Container Engine

    1.在k8s mster节点执行 1.kubectl get nodes 发现node节点没起来 [root@guanbin-k8s-master ~]# kubectl get nodes NAME ...

  5. OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ip": executable file not found in $PATH: unknown (Docker容器没有ip addr命令:exec ip addr 报错)

    一.报错 1.报错信息1: OCI runtime exec failed: exec failed: container_linux.go:380: starting container proce ...

  6. Job 失败了怎么办?- 每天5分钟玩转 Docker 容器技术(133)

    上一节讨论了 Job 执行成功的情况,如果失败了会怎么样呢? 修改 myjob.yml,故意引入一个错误: 先删除之前的 Job: 如果将 restartPolicy 设置为 OnFailure 会怎 ...

  7. FTP在docker容器中上传失败解决,改为被动模式

    package com.mayocase.takeout.utils; import org.apache.commons.net.ftp.FTPClient; import org.apache.c ...

  8. redis 连接 docker容器 6379端口失败

    redis部署在docker容器中Could not connect to Redis 容器内redis-cli是可以直接连上的,但是在另一台服务器上就不能用外网ip来连了 虽然我创建redis容器时 ...

  9. Docker windows 容器启动失败 network not found

    前几天由于重启了服务器,docker配置的网络出了些问题导致在docker容器中安装的mysql识别用户权限时发生错误.(从宿主机A以user身份 登入到容器B中安装的Mysql时,用户竟然不是use ...

随机推荐

  1. MySQL数据库3

    内容概要 自增特性 约束条件之外键 外键简介 外键关系 外键SQL语句之一对多关系 外键SQL语句之多对多关系 外键SQL语句之一对一关系 查询关键字 数据准备 查询关键字之select与from 查 ...

  2. pycharm相关介绍

    一.settings设置   1.搜font 设置字体 2.Keymap------快捷键 二.常用快捷键 1.Ctrl + Enter:在下方新建行但不移动光标: 2.Shift + Enter:在 ...

  3. QQ空间未授权评论_已忽略

    看群友们聊天时发现的, 大概是做了查看了动态访问时间的一个设置, 但是仅自己可见的说说还是被评论了的这么一个问题. 闲的没事就翻了一下找一下问题. 这个方法嘎嘎鸡肋, 可以说完全没用, 交到tsrc, ...

  4. 怎么理解相互独立事件?真的是没有任何关系的事件吗?《考研概率论学习之我见》 -by zobol

    1.从条件概率的定义来看独立事件的定义 2.从古典概率的定义来看独立事件的定义 3.P(A|B)和P(A)的关系是什么? 4.由P(AB)=P(A)P(B)推出"独立" 5.从韦恩 ...

  5. C语言学习之我见-strncmp()字符串比较函数(控制范围)

    strncmp()函数,用于范围内,两个字符串的比较,n表示最大比较范围. (1)函数原型 int strncmp(const char *_Str1,const char *_Str2,size_t ...

  6. Python Socket Sever

    1. Server code 1 # !/usr/bin/env python 2 # coding:utf-8 3 import multiprocessing 4 import socket 5 ...

  7. 用console画条龙?

    相识 console一定是各位前端er最熟悉的小伙伴了,无论是console控制台,还是console对象,做前端做久了,打开一个网页总是莫名自然的顺手打开控制台,有些调皮的网站还会故意在控制台输出一 ...

  8. Python: list列表的11个内置方法

    先来逼逼两句: 在实际开发中,经常需要将一组(不只一个)数据存储起来,以便后边的代码使用.在VBA中有使用数组,可以把多个数据存储到一起,通过数组下标可以访问数组中的每个元素.Python 中没有数组 ...

  9. java导出excel单sheet超过65535数据报错拆分多sheet导出

    在开发过程中,数据导出excel的功能很常见,数据少,到没问题,一旦超过65535条数据就会报错,因此可以考虑导出多个sheet来解决,代码如下: private static void export ...

  10. 研发效能生态完整图谱&DevOps工具选型必看

    本文主要梳理了研发效能领域完整的方向图谱以及主流工具,其中对少部分工具也做了一些点评.看了之后,大家可以对研发效能这个领域有个整体认识,同时研发效能落地的时候也有对应的工具(黑话叫抓手)可以选择. 我 ...