Docker容器的运行整体流程详细解释

介绍

整篇文章会介绍一个容器开始到结束的全过程。我们来使用一个 busybox 镜像来做例子因为它是一个非常轻量化的基础镜像。我们会把这个镜像运行起来,分析一下运行时候的状态,最后把它关掉,来看一下这个过程docker的怎么控制这个容器的。

这个指令可以把busybox镜像下载下来。


代码解读

复制代码

docker pull busybox

流程

查看开始前的状态

查看docker守护程序(daemon)

dockerd是docker服务的守护程序,它有什么作用呢?

  • 负责跟用户的交互来处理请求
  • 管理容器的周期(创建、启动、停止、删除)
  • 管理镜像
  • 容器的网络与存储管理

通过ps来查看一下它的PID吧


perl

代码解读

复制代码

ps aux | grep dockerd

  • a: 显示全部用户的全部进程(默认只显示当前用户在这个shell启动的进程)
  • u:展示更好看的显示格式
  • x: 显示没有交互终端的进程(守护程序一般没有交互终端)

输出是


ini

代码解读

复制代码

root 260776 0.1 0.6 4056156 98584 ? Ssl Nov26 2:21 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock kaifeng 358710 0.0 0.0 17812 2304 pts/1 S+ 23:17 0:00 grep --color=auto dockerd

  • 第2行是我们刚刚运行的grep指令,跟docker没有关系。
  • 第一列是进程所有者,可以看到我们的docker守护进程是root管理的。
  • 守护进程的PID是260776(记住之后还会看到的)
  • dockerd和containerd是可以通过socket交流的
containerd是什么?

containerd是container的守护程序,负责处理从dockerd放送来的请求,来做一些容器的底层的操作比如资源的分配,查看容器的状态等等

所以我们可以推断到,创建docker容器的请求会被放送给它,那么它做什么来处理这个请求呢?

运行containerd-shim-runc-v2! 这个会帮助创建一个容器的进程,这个进程可以通过套接字跟containerd进程交流来管理全部的容器。

可以通过ps查找是否有通过这个指令containerd-shim-runc-v2运行的程序


perl

代码解读

复制代码

ps axu | grep containerd-shim

因为我们还没有运行任何的容器,所以应该什么都没有

运行容器

运行指令

运行一下


arduino

代码解读

复制代码

docker run -d busybox top

  • -d: 后台继续运行
  • top: top是一个长时间运行的指令所以保证容器不会exit.
查看一下容器的id

运行一下


代码解读

复制代码

docker ps

输出


arduino

代码解读

复制代码

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b97f1233ba3a busybox "top" 2 minutes ago Up 2 minutes compassionate_sinoussi

  • 容器的id是 b97f1233ba3a
查看containerd-shim-runc-v2运行的程序

运行一下


perl

代码解读

复制代码

ps axu | grep containerd-shim

输出


bash

代码解读

复制代码

root 359757 0.0 0.0 1237940 14080 ? Sl 23:57 0:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id b97f1233ba3acfad81b68a100575b134e1f455b5a069705bdb71ab6ddc4c2cd0 -address /run/containerd/containerd.sock

容器的运行导致了一个进程开始运行,我们可以从id看出来这个进程跟我们的容器有关系。

  • 进程使用者是root
  • -address /run/containerd/containerd.sock 告诉了我们使用的套接字
  • 这个进程的PID是359757
查看一下跟这个容器进程相关的子进程

可以使用pstree来寻找


scss

代码解读

复制代码

kaifeng@kaifeng-Lenovo-XiaoXinPro-16IHU-2021:~$ pstree -p 359757 containerd-shim(359757)─┬─top(359777) ├─{containerd-shim}(359758) ├─{containerd-shim}(359759) ├─{containerd-shim}(359760) ├─{containerd-shim}(359761) ├─{containerd-shim}(359762) ├─{containerd-shim}(359763) ├─{containerd-shim}(359764) ├─{containerd-shim}(359765) ├─{containerd-shim}(359766) ├─{containerd-shim}(359815) └─{containerd-shim}(360278)

  • 只有一个top子进程(359777),就是我们想在容器里面执行的指令的进程,没有多余的子进程
  • 下面都是线进程,每一个线进程处理一个特定的任务。

我们可以总结,外面仍然可以看到容器里面的进程,因为docker的隔离性有局限因为容器和宿主机共有了一个内核

运行的容器

容器内部的用户和第一个进程是谁?

我们可以使用exec来执行sh来跟容器交互


bash

代码解读

复制代码

docker exec -it <容器名字或者id> sh

  • -it打开交互模式 进入之后使用ps来查看全部的进程

sql

代码解读

复制代码

PID USER TIME COMMAND 1 root 0:00 top 7 root 0:00 sh 14 root 0:00 ps aux

  • top就是容器的开始进程

查看我现在是哪一个用户


bash

代码解读

复制代码

whoami

结果


代码解读

复制代码

root

  • docker的默认用户是root
root的权限

root的权限在容器里面就是超级用户可以在容器执行任何操作。

  • 容器里面root在挂载目录做的创建的任何文件和文件夹,在容器外面查看都是root创建的。
  • 无论挂载点里面的内容哪一个用户的,都可以在容器内部通过root用户来执行任何操作
  • 如果挂载的目录,宿主机和容器里面都有文件,那宿主机在挂载点的文件优先显示。

结束运行

结束运行指令


arduino

代码解读

复制代码

docker stop <container name or id>

然后我们会发现属于这个容器的containerd-shim-runc-v2运行进程结束了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值