IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> [ docker-ce源码分析系列 ]docker exec残留sh进程的原因 -> 正文阅读

[系统运维][ docker-ce源码分析系列 ]docker exec残留sh进程的原因

1 概述:

1.1 环境

版本信息如下:
a、操作系统: centos 7.6,amd64
b、服务器docker版本:v18.09.2
c、docker的存储驱动: overlay2

2 现象:

执行 [ docker exec -it 容器ID sh ]命令,用户可在容器中执行shell指令进行各种操作,此时用户直接kill掉docker exec命令,或者直接关闭xshell,则该sh进程依然残留在容器中,这种sh进程会消耗虚拟终端的数量,本质上是消耗文件描述符。如果用户退出时不是通过执行exit指令,这种方式会导致操作系统上的虚拟终端数消耗完毕,需要手动杀死残留在容器中的sh进程或增大内核的虚拟终端最大数量。

查看当前系统正在使用的虚拟终端数量的命令:

sysctl kernel.pty.nr

修改虚拟终端数量最大值的命令:

sysctl -w kernel.pty.max=8192

3 源码简析:

通过docker源码,分析目标进程(sh进程)为什么会残留。杀死进程,肯定是通过发送系统信号TERM或信号KILL,个人估计发送系统信号相关的业务逻辑应该是在错误处理代码块中。

3.1 服务端注册路由initRoutes()

func (r *containerRouter) initRoutes() {
	r.routes = []router.Route{
		/*
			其他方法
		*/
		// 本方法主要是返回一个exec ID,客户端会再发起这样的请求:/v1.39/exec/{exec ID}/start
		router.NewPostRoute("/containers/{name:.*}/exec", r.postContainerExecCreate),
		router.NewPostRoute("/exec/{name:.*}/start", r.postContainerExecStart),
	}
}

3.2 func (s *containerRouter) postContainerExecStart(…)

本方法的核心方法是s.backend.ContainerExecStart(…)。

func (s *containerRouter) postContainerExecStart(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {

	/*
	 	其他逻辑
	*/
	
	// ContainerExecStart(...)会一直阻塞,直到docker exec命令关闭
	if err := s.backend.ContainerExecStart(context.Background(), execName, stdin, stdout, stderr); err != nil {
		if execStartCheck.Detach {
			return err
		}
		stdout.Write([]byte(err.Error() + "\r\n"))
		logrus.Errorf("Error running exec %s in container: %v", execName, err)
	}
	return nil
}

3.3 func (d *Daemon) ContainerExecStart(…)

docker exec意外退出(通过直接关闭xshell窗口或者kill命令),或者在容器中执行exit指令,dockerd都不会调用containerd的接口来给目标进程发送系统信号,因此导致目标进程的残留。

func (d *Daemon) ContainerExecStart(ctx context.Context, name string, stdin io.Reader, stdout io.Writer, stderr io.Writer) (err error) {
	/*
		其他逻辑
	*/

	// attachErr是一个管道,用于后续select语句
	attachErr := ec.StreamConfig.CopyStreams(ctx, &attachConfig)

	// d.containerd.Exec()是通过grpc调用containerd进程的接口,以在目标容器中创建进程(例如sh)
	// systemPid是容器中新建的进程在root pid namespace中的pid
	systemPid, err := d.containerd.Exec(ctx, c.ID, ec.ID, p, cStdin != nil, ec.InitializeStdio)
	
	/*
		其他逻辑
	*/

	// 一直select语句阻塞
	// docker exec退出,或者在容器中执行exit指令,管道attachErr都会返回nil值
	select {
	case <-ctx.Done():
		// 本方法的入参ctx对象,来自context.Background(),因此分支是没机会进入。
		// 本方法的入参ctx对象,来自context.Background(),因此分支是没机会进入。
		// 本方法的入参ctx对象,来自context.Background(),因此分支是没机会进入。
		
		/*
			调用d.containerd.SignalProcess(...)方法,往目标进程(例如sh进程)发送TERM或KILL信号
		*/
		return ctx.Err()
		
	case err := <-attachErr:
		// 此分支没有实际的业务操作,只是日志记录。
		// 因此目标进程(例如sh进程)不会接收到任何系统信号,残留在了容器中。
		if err != nil {
			if _, ok := err.(term.EscapeError); !ok {
				return errdefs.System(errors.Wrap(err, "exec attach failed"))
			}
			attributes := map[string]string{
				"execID": ec.ID,
			}
			d.LogContainerEventWithAttributes(c, "exec_detach", attributes)
		}
	}

	return nil
}

docker exec意外退出(通过直接关闭xshell窗口或者kill命令),或者在容器中执行exit指令,管道attachErr都会返回nil值
在这里插入图片描述


4 总结:

用户通过docker exec命令进入容器创建的sh进程,dockerd在代码层面是没有机会往sh进程发送系统信号(虽然containerd进程已经暴露了往进程发送信号的接口),因此sh进程不执行exit指令,是会残留在操作系统中的。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-10-11 17:55:43  更:2021-10-11 17:57:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 17:27:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码