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. linux硬盘分区及挂载

    今天买的一台服务器发现其硬盘容量与购买界面的描述不符,于是我去问了客服才知道有一块硬盘需要自己挂载,所以记录自己硬盘分区以及挂载操作得此文. 测试环境 ​ 由于时间限制,本人仅在centos 8下测试 ...

  2. C++学习笔记---数据类型

    1.整型 C++中能够表示整型的类型有几下几种方式,区别在于所占内存空间不足 数据类型 占用空间 取值范围 short(短整型) 2字节 (-2^15~2^15-1) int(整型) 4字节 (-2^ ...

  3. redis过期事件,swoole监听

    $serv = new Swoole\Server('0.0.0.0', 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP); $serv->set(array( 'work ...

  4. Spring boot ConditionalOnClass原理解析

    Spring boot如何自动加载 对于Springboot的ConditionalOnClass注解一直非常好奇,原因是我们的jar包里面可能没有对应的class,而使用ConditionalOnC ...

  5. 20202405李昕亮《BASE64编码》

    BASE64编码 20202405李昕亮 参考网址: 1.https://baike.baidu.com/item/base64/8545775?fr=aladdin 2.https://blog.c ...

  6. 应该怎么提升4G工业路由器的无线信号?

    4G工业路由器如今应用的范围非常的广泛,在实际使用中也遇到了很多的问题,其中经常被问到的一个问题就是我们怎么保证4G工业路由器的良好信号强度.在互联网上也有很多关于如何找到最佳信号的方法,但对于固定和 ...

  7. [Luogu P2261] [CQOI2007]余数求和 (取模计算)

    题面 传送门:https://www.luogu.org/problemnew/show/P2261 Solution 这题显然有一个O(n)的直接计算法,60分到手. 接下来我们就可以拿出草稿纸推一 ...

  8. 数据库本地data source

    数据源表示数据库所在设备的ip地址或名称,基本上有以下几种写方法 data source = (local) data source = "127.0.0.1" data sour ...

  9. 简单操作elasticsearch(es版本7.6)

    简单操作elasticsearch(es版本7.6) es 官方文档 https://www.elastic.co/guide/index.html 简单操作elasticsearch主要是指管理索引 ...

  10. 浅谈OpenGL之DSA

    今天准备写一篇文章简单介绍一下OpenGL4.5引入的一个新的扩展ARB_direct_state_access,这个扩展为OpenGL引入了一个新的特性就是Direct State Acess,下文 ...