Joh*_*Doe 3 linux namespaces containers linux-kernel docker
我知道容器使用主机的内核,据我所知,这就是我们不需要操作系统的原因。我的问题是(我在网上找不到任何好的解释):
1) 如果是这种情况,那么我们是否会收到 shell 提示以及我们如何在容器上添加 systemctl、services 等内容
2) 例如,我们如何在 Ubuntu 主机上安装 CentOS 容器?在这种情况下,容器是否在容器映像中安装了操作系统?
这在很大程度上取决于您对操作系统的看法。
容器从根本上是一种将正在运行的进程与机器上的所有其他进程以及二进制文件及其所有依赖项与主机文件系统隔离的方法。这使得它们在任意数量的机器之间移动和运行变得微不足道。它们绝不是虚拟化,因此正如您在问题中提到的,在容器中运行的任何进程都在主机内核上运行。从某些角度来看一个操作系统,从根本上来说就是内核。
与此平衡的是,大多数软件不是构建为整体的,而是在编译时链接到任意数量的共享库。因此,当您安装操作系统发行版和内核时,您将获得一系列库和实用程序,并且您从操作系统存储库安装的任何程序都将针对该操作系统发行版附带的库进行构建。
现在,在构建容器时,所需的只是您要运行的二进制文件,以及该二进制文件所依赖的任何内容。不需要打包完整的 OS 发行版文件系统。如果您的二进制文件没有与任何其他库链接,您几乎可以摆脱单个二进制文件而没有其他任何东西。看看这个项目https://github.com/davidcarboni-archive/ddd由一位与我目前使用的客户端一起工作的小伙子编写的,它展示了构建一个功能性容器所需的很少。
因此,在理想的世界中,鉴于最佳实践主要是构建一个运行单个进程的容器,每个容器仅包含相关的二进制文件,以及它需要的任何库、配置文件和工作目录。然而,在很多情况下,要做到这一点是一个相当复杂且耗时的过程。因此,它现在已经成为一种非常常见的模式,简单地将来自捐助者操作系统的整个文件系统打包到一个容器中,这样您就知道要运行的进程具有的任何依赖项都将存在。它还增加了包管理工具将出现的便利性,这使得构建容器更容易。这也意味着还存在诸如 shell 之类的实用程序,这使得调试容器的工作变得更容易(在某些人看来,
虽然我理解为什么这种模式变得如此普遍,但我确实认为它有缺点。首先由您的问题证明 - 它使容器看起来很像虚拟化,因此造成了很多混乱。此外,作为刚刚完成将 CIS 服务器强化应用于机器资产的人,将包括厨房水槽在内的所有东西都打包在每个容器中,感觉不是很好的安全实践,我怀疑在某些时候,这可能会回到咬我们。
要扩展您的两个具体问题:
1) 我已经讨论过 shell 的主题。至于 systemd 之类的东西,它们在容器中基本上没有位置。Dockefile 定义了容器启动时要运行的进程。如果您尝试在容器内运行服务管理器和多个服务,您可能做错了。
2)这又回到了什么是操作系统的问题上?在容器中安装给定发行版的唯一意义是获得文件系统,因此获得二进制文件和共享库的发行版副本。它与虚拟化不同,在虚拟化中,您可以在运行 Debian 的主机上的虚拟机中运行 Centos 的副本。
是的,他们确实这么做了。每个容器都基于操作系统映像,例如 Alpine、CentOS 或 Ubuntu。
它们只是共享主机内核,但在特定于该容器的单独名称空间中运行每个用户空间进程。
查看dockerfile 示例(由我改编)来理解这一点:
FROM ubuntu
MAINTAINER Kimbro Staken version: 0.1
RUN apt-get update && apt-get install -y apache2 && apt-get clean && rm -rf /var/lib/apt/lists/*
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
EXPOSE 80
CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]
Run Code Online (Sandbox Code Playgroud)
这告诉 Docker 从 Ubuntu 基础镜像(如果未指定版本,则为最新版本)创建一个容器,在其中安装并运行 Apache,并向主机操作系统公开端口 80。
到底什么是操作系统?
Linux 内核本身满足了操作系统的大部分关键要求。它对 CPU 进行时间切片,管理控制台 IO、磁盘 IO 和网络,它可以为图形输出等提供与硬件无关的帧缓冲区。您可以编写一个在不加载任何库的情况下在 Linux 内核上运行的程序,并利用这些功能。
然而,当谈论现代通用操作系统时,大多数人对操作系统的含义有着更广泛的看法。除了内核之外,它们还包含许多其他内容。shell、init 系统、X 服务器、公共库、用于加载驱动程序模块的系统(因此您不必将所有驱动程序构建到内核中)、用于启动网络接口的工具、用于安装附加文件的工具-系统、包管理器等等。我们将这些除了内核之外用于构建现代操作系统的部分统称为“用户区”。
Linux 发行版的大部分标识来自用户空间。如果你有一个在 Ubuntu 内核上运行的 Centos 用户区,它会感觉更像 Centos 而不是 Ubuntu。
容器是一项允许单个内核伪装成多个单独内核的功能。每个都有自己的 PID、自己的文件系统继承权、自己的网络接口和自己的用户帐户。
与运行 Linux 内核的真实系统一样,您可以编写在没有支持的容器中运行的程序。事实上,在容器中比在真实系统中更容易,因为您不必担心驱动程序,并且您的容器管理器可能能够预先初始化容器,以便已经安装了正确的文件系统并且网络接口已经启动。
但大多数时候,人们对容器的期望是“虚拟化但更便宜”。他们希望拆分服务器的逻辑功能,以便每个服务器都可以单独备份、迁移、更新等,但他们希望继续使用他们正在使用的软件堆栈,该堆栈利用了部分或全部上述非现代操作系统的内核部分,他们不想支付虚拟机的成本。
因此,容器通常最终包含常规 Linux 发行版的整个用户空间。包含一个 init 系统、一个 shell、一个 ssh 服务器。这算作操作系统吗?好吧,这最终是一个如何定义操作系统的问题!
| 归档时间: |
|
| 查看次数: |
8302 次 |
| 最近记录: |