【发布时间】:2022-10-21 13:08:48
【问题描述】:
我是 docker 新手,我正在与另一家公司的开发人员合作。我相信他们也是 docker 的新手。我有一位开发人员问我“我是在 docker 容器内部还是外部运行命令”或“我是否在容器外部创建新分支”。
有人可以帮助澄清容器内部或外部的含义吗?
我似乎无法理解,我在网上搜索,我似乎没有在内部或外部找到任何关于运行命令或其他类似内容的术语。
【问题讨论】:
标签: docker
我是 docker 新手,我正在与另一家公司的开发人员合作。我相信他们也是 docker 的新手。我有一位开发人员问我“我是在 docker 容器内部还是外部运行命令”或“我是否在容器外部创建新分支”。
有人可以帮助澄清容器内部或外部的含义吗?
我似乎无法理解,我在网上搜索,我似乎没有在内部或外部找到任何关于运行命令或其他类似内容的术语。
【问题讨论】:
标签: docker
是的,这是正常的(Docker 使用主机上的内核,而不是它自己的,您将在主机上的ps 命令中看到它。)查看在您的主机的 docker 容器“内部”运行的进程(如果您使用top 或ps 命令检查正在运行的进程)。尝试以这种方式运行pstree,您将看到所有正在运行的进程都是containerd 的子进程。
在容器内运行的进程只是一个常规进程。在大多数方面,它与在容器外运行的常规进程没有什么不同。 Docker 使用namespaces 和cgroups 将进程与系统的其余部分隔离开来。
Namespaces 和 cgroups 是允许内核隔离进程的抽象。
docker 守护进程只是一个进程,它可以方便地将其他进程放入命名空间/cgroups 中。
【讨论】:
docker 文件描述了您希望 Linux 对于特定应用程序的外观。也就是说,没有任何应用程序不需要的东西,并且它使用的所有工具和库都已经安装。可以包含用于例如数据库或 Web 服务器的专用 docker 文件,从而简化定义。
Docker 映像基本上是应用 docker 文件中的所有规范。即建立一个文件系统,将docker文件中指定的所有软件都安装到这个文件系统中,就好像它是真正的Linux一样。
一个 docker 容器基本上是在启动镜像文件,所以所有的启动脚本都会被执行,并且在它完成时所有预期的进程都会运行。它运行的任何软件都会认为它是在独立机器上启动的 Linux 上运行的。除了它所做的一切都只发生在容器内。如果一个文件被写入,它只被写入容器的文件系统,这是从实际文件系统借来的一块空间。
通常你还需要指定容器内应该运行什么,否则一旦它启动,它就没有更多的事情可做,所以停止。一旦它停止,内存和文件空间就会被释放,所以里面所做的一切都会消失。
您可以启动一个运行服务的 Web 服务器,或者一个您可以与之交互的 shell,等等。您通常还希望能够连接到容器外部的网络、读取或写入文件外部的文件等等。您可以将现实世界的事物映射到容器(例如,容器中的端口 8080 映射到实际 Linux 中的端口 18080,/tmp/scratch 映射到容器中的/tmp/scratch,等等)。
您还可以使用exec 命令启动在容器中运行的另一个进程。例如,您可以将输入和输出映射到终端并启动 bash。
最后你可以停止容器,里面的一切都会停止运行,所有的内存和文件都将被释放。
【讨论】:
上述两个答案在阐明“在容器内”时的含义方面做得很好。没有“内部或外部”之类的东西。您需要了解一种内核结构——“命名空间”。
命名空间为进程或应用程序提供了一种隔离的错觉。它们缩小了应用程序的视图,因此它只能看到某些资源。这些资源可以是其他进程、文件、IP 地址等。今天(截至 2022 年)有 7 种类型的命名空间 - 这些命名空间中的每一种都有助于隔离特定资源。例如,PID 命名空间限制了特定进程或应用程序可以看到的其他进程。 Mount Namespace 限制给定应用程序可以看到的文件。
我最近一直在学习命名空间和 Cgroups 以更好地理解容器 - 发现这个很棒的资源 https://www.udemy.com/course/containers-under-the-hood 已经得到了巨大的帮助。
强烈推荐给有兴趣深入了解 Containers 工作原理的任何人。
【讨论】: