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. ServletRequest使用介绍

    ServletRequest: 定义将客户端请求信息提供给某个 servlet 的对象:servlet 容器创建 ServletRequest 对象,并将该对象作为参数传递给该servlet的serv ...

  2. Linux入门到放弃之五《用户管理》

    用户管理 1.创建新用户user123,以此用户登陆系统,在tmp下创建文件test123: 2.修改test123文件的所有者为root,所属组也为root: 需要先切换为root用户 3.修改te ...

  3. 《JavaScript高级程序设计》——第三章 基本概念

    这章讲了JavaScript的语法.数据类型.流控制语句和函数.理解还是挺好理解的,但有很多和C.C++.Java不同的地方需要记忆.比如, JavaScript标识符可以由Unicode字符字符组成 ...

  4. SpringMVC的@InitBinder参数转换

    @Controller @RequestMapping("/index") public class IndexController { /** * 解决前端传递的日期参数验证异常 ...

  5. 【总结】mybatis

    一.config配置文件详解 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE config ...

  6. 配置kuernetes集群pod拉取私有镜像仓库中的镜像

    目录 1 背景说明 2 实现方法 3 具体实现 配置镜像仓库项目为公开类型(任何人可以访问) 配置docker-registry类型的secret(pod使用secret获取镜像认证) 通过账户名密码 ...

  7. RS485转以太网的概述和应用领域

    如今随着物联网技术的不断发展,各种接口更新换代的速度非常的快,RS485转以太网的主要作用就是提供串口转TCP/IP网络接口的功能,它可以将RS232/485/422串口转换成TCP/IP网络接口,实 ...

  8. Scala-Mongodb入门之CRUD

    Scala入门之Mongo增删改查 环境jdk1.8,scala2.13 使用sbt管理依赖,在build.sbt中添加依赖: libraryDependencies += "org.mon ...

  9. [Luogu P1613]跑路 (DP+倍增+最短路)

    题面 传送门:https://www.luogu.org/problemnew/show/P1613 Solution 挺有意思的一道题. 题面已经挺明显的描述出了这题的主要思想:倍增. 先这样想,我 ...

  10. gdb高级技巧

    注意: 这里是讲gdb的高级技巧.如果没有接触过gdb,请看这篇:点这里. gdb是一个功能极其强大的命令行调试器.其实,除了我们常用的 file b s n q disp p 等命令,也有很多高级技 ...