1.由来

  最近在使用kylin_v10系统,发现当在此系统下运行的容器内执行#ansible localhost -m setup 命令会卡住不动,于是和同事一起经过如下排查最终找到解决问题的办法。

2.环境

2.1.系统信息

# cat /etc/*-release
Kylin Linux Advanced Server release V10 (Tercel)
NAME="Kylin Linux Advanced Server"
VERSION="V10 (Tercel)"
ID="kylin"
VERSION_ID="V10"
PRETTY_NAME="Kylin Linux Advanced Server V10 (Tercel)"
ANSI_COLOR="0;31" Kylin Linux Advanced Server release V10 (Tercel)  

2.2.内核信息

# uname -a
Linux reg.wps.lan 4.19.90-17.ky10.aarch64 #1 SMP Sun Jun 28 14:27:40 CST 2020 aarch64 aarch64 aarch64 GNU/Linux

2.3. docker信息

# docker info
Containers: 1
Running: 1
Paused: 0
Stopped: 0
Images: 1
Server Version: 18.09.9
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs

2.4.ansible信息

# ansible --version
ansible 2.6.2
config file = None
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.16 (default, Jul 9 2020, 06:35:45) [GCC 7.3.0]

3.分析排查

  在排查时候发现#ansible localhost -m setup命令卡住,放将localhost换成自定义ip+账号密码的配置文件即可正常运行。

于是加入export ANSIBLE_DEBUG=True用于输出debug日志。

发现卡在如下地方:

    82 1606185861.10586: transferring module to remote /root/.ansible/tmp/ansible-tmp-1606185860.41-269842916667107/AnsiballZ_setup.py
82 1606185861.10840: done transferring module to remote
82 1606185861.10894: _low_level_execute_command(): starting
82 1606185861.10924: _low_level_execute_command(): executing: /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1606185860.41-269842916667107/ /root/.ansible/tmp/ansible-tmp-1606185860.41-269842916667107/AnsiballZ_setup.py && sleep 0'
82 1606185861.10940: in local.exec_command()
82 1606185861.10957: opening command with Popen()
82 1606185861.11488: done running command with Popen()
82 1606185861.11523: getting output with communicate()
82 1606185861.11918: done communicating
82 1606185861.11936: done with local.exec_command()
82 1606185861.11961: _low_level_execute_command() done: rc=0, stdout=, stderr=
82 1606185861.11977: _low_level_execute_command(): starting
82 1606185861.12019: _low_level_execute_command(): executing: /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1606185860.41-269842916667107/AnsiballZ_setup.py && sleep 0'
82 1606185861.12038: in local.exec_command()
82 1606185861.12055: opening command with Popen()
82 1606185861.12599: done running command with Popen()
82 1606185861.12631: getting output with communicate()

  于是进到物理机上去查看ansible进程

# ps -ef |grep ansible
root 672540 672016 99 10:44 pts/0 00:03:06 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1606185860.41-269842916667107/AnsiballZ_setup.py
root 673881 672428 51 10:47 pts/0 00:00:02 /usr/bin/python /usr/local/bin/ansible localhost -m setup
root 673893 673881 33 10:47 pts/0 00:00:00 /usr/bin/python /usr/local/bin/ansible localhost -m setup
root 673908 673893 0 10:47 pts/0 00:00:00 /bin/sh -c /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1606186046.03-129145088760493/AnsiballZ_setup.py && sleep 0'
root 673909 673908 0 10:47 pts/0 00:00:00 /bin/sh -c /usr/bin/python /root/.ansible/tmp/ansible-tmp-1606186046.03-129145088760493/AnsiballZ_setup.py && sleep 0
root 673910 673909 23 10:47 pts/0 00:00:00 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1606186046.03-129145088760493/AnsiballZ_setup.py
root 673914 673910 99 10:47 pts/0 00:00:01 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1606186046.03-129145088760493/AnsiballZ_setup.py
root 673971 443741 0 10:47 pts/1 00:00:00 grep ansible

  再用strace追踪下673914进程

# strace -p 673914
close(216995106) = -1 EBADF (错误的文件描述符)
close(216995107) = -1 EBADF (错误的文件描述符)
close(216995108) = -1 EBADF (错误的文件描述符)
close(216995109) = -1 EBADF (错误的文件描述符)
close(216995110) = -1 EBADF (错误的文件描述符)
close(216995111) = -1 EBADF (错误的文件描述符)
close(216995112) = -1 EBADF (错误的文件描述符)
close(216995113) = -1 EBADF (错误的文件描述符)
close(216995114) = -1 EBADF (错误的文件描述符)
close(216995115) = -1 EBADF (错误的文件描述符)
close(216995116) = -1 EBADF (错误的文件描述符)
close(216995117) = -1 EBADF (错误的文件描述符)
close(216995118) = -1 EBADF (错误的文件描述符)
close(216995119) = -1 EBADF (错误的文件描述符)
close(216995120) = -1 EBADF (错误的文件描述符)
close(216995121) = -1 EBADF (错误的文件描述符)
close(216995122) = -1 EBADF (错误的文件描述符)
close(216995123) = -1 EBADF (错误的文件描述符)
close(216995124) = -1 EBADF (错误的文件描述符)
close(216995125) = -1 EBADF (错误的文件描述符)
close(216995126) = -1 EBADF (错误的文件描述符)
close(216995127) = -1 EBADF (错误的文件描述符)
close(216995128) = -1 EBADF (错误的文件描述符)
close(216995129) = -1 EBADF (错误的文件描述符)
close(216995130) = -1 EBADF (错误的文件描述符)
close(216995131) = -1 EBADF (错误的文件描述符)
close(216995132) = -1 EBADF (错误的文件描述符)

  终端一直刷上面的,看样子是文件描述符泄露,搜了下  docker Bad file descriptor,找到了 Spawning PTY processes is many times slower on Docker 18.09 里几位大佬排查到是容器的 nofile 太高就会卡,如果启动容器 nofile 设置低则没问题,

在容器内执行ulimit  -n果然默认值很高

> ulimit -n
1073741816

再查了下 docker nofile limit  找到 Docker: How to increase number of open files limit 里面描述可以在run  docker的时候设置容器内的nofile参数大小。

于是添加 --ulimit nofile=65535 重新启动docker,并查看容器内ulimit  -n值果然变小了,而且#ansible localhost -m setup 问题也得到了解决。

4.参考

  https://github.com/pexpect/ptyprocess/issues/50
  https://github.com/docker/for-linux/issues/502
  https://github.com/moby/moby/issues/38814

记一次容器内执行ansible命令卡住的更多相关文章

  1. PHP 代码内执行Linux命令

    还是那个问题,就是那个php填写pdf表单,因为副武器的原因,改用命令执行了,哎,一个问题好多知识点啊,先来说说PHP执行linux命令,其实挺简单的,但是呢,后面说说我遇到的问题 1.PHP执行命令 ...

  2. 在容器内执行go编译程序的坑

    如果你编译了一个go程序,让后把它放到容器里面.很多时候这个程序都会无法执行,大概的样子是: /tmp # ls pub sub /tmp # ./pub /bin/ash: pub: not fou ...

  3. 3. docker容器内信息获取、命令的执行、容器的导入和导出

    一.依附容器 依附操作attach通常用在由docker start或者docker restart启动的交互型容器中.由于docker start启动的交互型容器并没有具体终端可以依附,而容器本身是 ...

  4. Jenkins(Docker容器内)使用宿主机的docker命令

    1.Jenkins镜像 Docker容器内的Jenkins使用容器外宿主机的Docker(即DooD,还有另外的情况就是DioD),google一下有几种说法,但是都没试成功(试过一种就是修改宿主机/ ...

  5. Docker 容器生命周期管理命令

    docker run 命令 -d: 后台运行容器,并返回容器ID: -i: 以交互模式运行容器,通常与 -t 同时使用: -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用: --name= ...

  6. 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 ...

  7. 入手Docker容器注意事项:命令结束容器退出

    在没有 docker 容器的时候,在终端(terminal)中运行 shell 命令,我们知道当终端退出时(比如关闭终端窗口或退出 ssh 会话),终端中执行的命令也会结束.所以,当我们在终端中执行持 ...

  8. 【docker】 docker容器内部安装vi命令

    有时会需要在docker容器内使用vi命令,但是新启动的docker容器内并没有vi命令,那就需要自己安装一个 1.使用命令 apt-get update 2.进行安装 apt-get install ...

  9. Ubuntu不输入密码执行sudo命令方法介绍

    作为ubuntu等桌面系统,默认登录的帐号是没有root权限的,为了提升权限来执行任务,我们一般用到sudo+命令来执行,但是不难发现我们一般都要输入密码.那么有没有什么方法可以让我们执行sudo的时 ...

随机推荐

  1. QT/C++插件式框架、利用智能指针管理内存空间的实现、动态加载动态库文件

    QT.C++插件式框架.主要原理还是 动态库的动态加载. dlopen()函数.下面为动态加载拿到Plugininstance对应指针.void**pp=(void**)dlsym(handle,&q ...

  2. MVC IIS 403.14

    描述:HTTP Error 403.14 - Forbidden The Web server is configured to not list the contents of this direc ...

  3. Learn day6 模块pickle\json\random\os\zipfile\面对对象(类的封装 操作 __init__)

    1.模块 1.1 pickle模块 # ### pickle 序列化模块 import pickle """ 序列化: 把不能够直接存储的数据变得可存储 反序列化: 把数 ...

  4. K8S的Kafka监控(Prometheus+Grafana)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  5. 《Clojure编程》笔记 第4章 多线程和并发

    目录 背景简述 第4章 多线程和并发 4.0 我的问题 4.1 术语 4.1.1 一个必须要先确定的思考基础 4.2 计算在时间和空间内的转换 4.2.1 delay 4.2.2 future 4.2 ...

  6. Spider Storage Engine

    这个引擎可以完成MySQL的数据库分片

  7. PASS模型-第一周个人总结

    目录 PASS模型-第一周个人报告 1.个人任务 2.个人工作内容 2.1 登陆界面 2.2 信息采集 2.3 视觉搜索 3.个人小结 3.1 收获 3.2 优化 PASS模型-第一周个人报告 博客班 ...

  8. 10万用户一年365天的登录情况如何用redis存储,并快速检索任意时间窗内的活跃用户

    1.redsi的bitmap数据结构介绍 bitmap本质上是一个string类型,只是他操作的是string的某个位是0还是1. setbit和getbit 两条命令是对字符串的位操作.每个位只能是 ...

  9. Java泛型主题讨论

    说明:在学习泛型这一知识点中,主要参考自<疯狂Java讲义>第7章P307-P330的泛型内容,因为是跳着阅读,所以前面的一些名词不是特别清楚,这里也做出适当备注,供自己识记与理解. 1. ...

  10. SpringBoot第五集:整合Druid和MyBatis(2020最新最易懂)

    SpringBoot第五集:整合Druid和MyBatis(2020最新最易懂) 1.SpringBoot整合Druid Druid是阿里巴巴的一个开源项目,是一个数据库连接池的实现,结合了C3P0. ...