跳到主要内容

关于 Docker 的更多知识

OCI 标准

OCI 指的是开放容器标准,这也是 Docker 在 2015 发起的开源项目,旨在将容器标准化并提供更广泛的兼容性,OCI 专注于创建开放的、标准化的容器镜像格式与容器运行规范,确保跨平台的兼容性。

容器中的 PID 1 进程

回到刚刚进入的 Ubuntu 容器,输入

ps aux

输出如下

root@3881dd835228:/# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   4296  3548 pts/0    Ss   09:16   0:00 bash
root        13  0.0  0.0   7628  3524 pts/0    R+   09:20   0:00 ps aux

可以看到 PID 1 进程是一个 Bash 回想一下刚刚我们是如何运行容器的

docker run -it ubuntu bash

这里运行 ubuntu 的命令刚好和 PID 1 的 COMMAND 对上了 那如果我只运行 ps aux 呢

docker run -it --rm ubuntu ps aux

可以看到 PID 1 就是启动容器时的那个命令

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   7628  3340 pts/0    Rs+  09:33   0:00 ps aux

并且运行完容器就退出了,PID 1 退出后容器就会退出 而真实情况或虚拟机内的 PID 1 是系统启动的 init 程序

$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.5 23040 11528 ? Ss Aug29 8:48 /sbin/init showopts
root 2 0.0 0.0 0 0 ? S Aug29 0:01 [kthreadd]
root 3 0.0 0.0 0 0 ? S Aug29 0:00 [pool_workqueue_release]
...

这就是容器和虚拟机的区别: 容器是通过 Linux Namespace + Cgroup 实现的轻量化进程隔离,而不是一台完整的虚拟机。因此,容器内部的 PID 1 与真实机器或虚拟机中的 PID 1(init/systemd) 本质上有很大的不同。 虚拟机的 PID 1 是系统的 init,用来管理整台机器。 容器的 PID 1 是你的应用本身,用来作为容器生命周期的根。

Docker 的 runtime

Docker 使用的默认容器运行时是 runc,它是一个轻量级的、符合 OCI 规范的容器运行时。runc 负责创建和运行容器,管理容器的生命周期,并与 Linux 内核的命名空间和 cgroup 功能进行交互。

其实,Docker 作为一个容器管理平台,可以支持多种容器运行时。除了 runc,Docker 还可以与其他符合 OCI 规范的运行时集成,例如 containerdCRI-O。 甚至还可以使用 gVisor 这样的独立内核容器运行时,不再使用宿主共同内核,以提供更强的隔离性和安全性。

Docker Swarm

把多台机器组成一个 Docker 集群,并在上面自动部署、扩容、健康检查、滚动更新容器服务的系统。 Docker Swarm 是 Docker 官方提供的容器编排工具,类似于 Kubernetes,但更轻量级,适合小型集群和简单的应用场景。 Docker Swarm 允许用户将多台 Docker 主机组合成一个虚拟的 Docker 主机,从而实现容器的分布式部署和管理。

Docker in Docker

Docker in Docker(DinD)是指在一个 Docker 容器内部运行另一个 Docker 容器的技术。简单来说,就是在一个容器中安装和运行 Docker 引擎,从而允许该容器内的应用程序能够像在宿主机上一样使用 Docker 功能。比如说:运行在 Docker 中的 Action Runner 需要打包容器,容器中也需要使用 docker,这时候就需要 Dind 了。