linux 容器

在过去的几年中,容器不仅成为开发人员,而且也成为企业的热门话题。 这种日益增长的兴趣引起了对安全性改进和强化以及为可伸缩性和互操作性做准备的需求。 这需要大量的工程,这是在Red Hat的企业级发生了多少工程的故事。

当我在2013年秋天与Docker Inc.(Docker.io)的代表首次会面时,我们正在研究如何使Red Hat Enterprise Linux(RHEL)使用Docker容器。 (此后,Docker项目的一部分已更名为Moby 。)在将该技术引入RHEL时,我们遇到了一些问题。 第一个主要障碍是获得受支持的写时复制(COW)文件系统来处理容器图像分层。 红帽最终贡献了一些COW实现,包括Device Mapper , btrfs和OverlayFS的第一个版本。 对于RHEL,尽管我们对OverlayFS的支持越来越紧密,但我们默认使用Device Mapper。

下一个主要障碍是启动容器的工具。 当时,上游docker使用LXC工具启动容器,而我们不希望支持RHEL中设置的LXC工具。 在使用上游docker之前,我曾与libvirt团队合作开发了一个名为virt-sandbox的工具,该工具使用libvirt-lxc来启动容器。

当时,红帽公司的一些人认为替换掉LXC工具并添加网桥,以便Docker守护程序可以使用libvirt-lxc与libvirt通信以启动容器。 这种方法引起了严重的关注。 请考虑以下示例,该示例使用Docker客户端( docker-cli )和启动容器进程( pid1OfContainer )之前的调用层来启动容器:

docker-cli→docker-daemon→libvirt-lxc→pid1OfContainer

我不喜欢在您的工具之间使用两个守护程序来启动容器和最终运行的容器的想法。

我的团队与上游docker开发人员一起在容器运行时的本机Go编程语言实现libcontainer上进行了艰苦的工作 。 该库最终作为OCI运行时规范的初始实现与runc一起发布。

docker - cli docker -daemon @ pid1OfContainer

尽管大多数人错误地认为执行容器时,容器进程是docker-cli的子进程,但实际上他们已经执行了客户端/服务器操作,并且容器进程作为完全独立的环境的子进程运行。 此客户端/服务器操作可能导致不稳定和潜在的安全隐患,并且阻止了有用的功能。 例如, systemd具有称为套接字激活的功能,您可以在其中设置守护程序,使其仅在进程连接到套接字时才运行。 这意味着您的系统使用更少的内存,并且只有在需要时才执行服务。 套接字激活的工作方式是systemd在TCP套接字上侦听,并且当有数据包到达套接字时,systemd激活通常在套接字上侦听的服务。 服务激活后,systemd将套接字移交给新启动的守护程序。 将该守护程序移动到基于Docker的容器中会导致问题。 单元文件将使用Docker CLI启动容器,而systemd没有简单的方法通过Docker CLI将连接的套接字传递给Docker守护程序。

诸如此类的问题使我们意识到,我们需要使用替代方法来运行容器。

容器编排问题

上游docker项目使使用容器变得容易,它仍然是学习Linux容器的好工具。 您可以通过运行简单的命令(例如docker run -ti fedora sh)快速体验启动容器的操作,并且立即进入容器。

当您开始同时运行多个容器并将它们连接到一个功能更强大的应用程序中时,容器的真正威力就显现出来。 设置多容器应用程序的问题是复杂性Swift增加,并且使用简单的Docker命令将其连接起来就分崩离析了。 如何在资源有限的节点群集中管理容器应用程序的放置或编排? 如何管理自己的生命周期,依此类推?

在第一个DockerCon上,至少有七个不同的公司/开源项目展示了如何编排容器。 红帽公司的OpenShift有一个名为geard的项目,该项目大致基于我们所展示的OpenShift v2容器(称为“齿轮”)。 红帽认为我们需要重新审视业务流程,也许需要与开源社区中的其他人合作。

Google展示了Kubernetes容器编排的基础,该知识基于Google在编排其内部架构方面所掌握的全部知识。 OpenShift决定放弃我们的Gear项目,并开始在Kubernetes上与Google合作。 Kubernetes现在是GitHub上最大的社区项目之一。

Kubernetes

Kubernetes的开发是为了使用Google的lmctfy容器运行时。 Lmctfy已于2014年夏天移植到Docker上。Kubernetes在Kubernetes集群中的每个节点上运行一个守护程序,称为kubelet 。 这意味着原始的带有Docker 1.8的Kubernetes看起来像:

kubelet→dockerdaemon @ PID1

返回两守护程序系统。

但情况变得更糟。 在Docker的每个发行版中,Kubernetes都崩溃了.Docker 1.10切换了后备存储,从而重建了所有映像.Docker 1.11开始使用runc启动容器:

kubelet→dockerdaemon @ runc @ PID1

Docker 1.12添加了一个容器守护进程来启动容器。 其主要目的是满足Docker Swarm(一个Kubernetes竞争对手)的需求:

kubelet→dockerdaemon→容器@runc @ pid1

如前所述, 每个 Docker版本都破坏了Kubernetes功能,这就是Kubernetes和OpenShift要求我们为工作负载提供较旧版本的Docker的原因。

现在,我们有了一个三守护程序系统,如果其中任何守护程序出了问题,那么整个纸牌屋就会分崩离析。

迈向集装箱标准化

CoreOS,rkt和备用运行时

由于Docker运行时的问题,一些组织正在寻找替代运行时。 这样的组织之一就是CoreOS。 CoreOS为上游docker提供了一个替代的容器运行时,称为rkt (火箭)。 他们还引入了称为appc (应用程序容器)的标准容器规范。 基本上,他们希望让每个人都能使用标准规范来规范如何将应用程序存储在容器映像包中。

这引发了红旗。 当我第一次开始使用上游docker处理容器时,我最大的担心是我们最终会遇到多种规格。 我不希望RPM与Debian之类的战争影响未来20年Linux软件的发行。 appc引入的一个很好的结果是,它说服了上游docker与开源社区合作,创建了一个名为开放容器倡议 (OCI)的标准机构。

OCI一直在制定两个规范:

OCI运行时规范 :OCI运行时规范“旨在指定容器的配置,执行环境和生命周期”。 它定义了容器在磁盘上的外观,描述将在容器内运行的应用程序的JSON文件,以及如何生成和执行容器。 上游docker贡献了libcontainer的工作,并构建了runc作为OCI运行时规范的默认实现。

OCI图像格式规范 :图像格式规范主要基于上游docker图像格式,并定义了位于容器注册表中的实际容器图像包。 该规范允许应用程序开发人员针对其应用程序采用单一格式进行标准化。 尽管appc中描述的某些想法仍然存在,但已添加到OCI图像格式规范中。 这两个OCI规范都接近1.0版本。 最终docker已同意在OCI映像规范完成后对其进行支持。 Rkt现在支持运行OCI映像以及传统的上游docker映像。

开放容器计划(Open Container Initiative)通过为行业提供围绕容器映像和运行时进行标准化的场所,帮助释放了工具和编排领域的创新。

抽象运行时接口

利用此标准化的创新之一是Kubernetes编排领域。 作为Kubernetes努力的大力支持者,CoreOS除了向上游docker引擎之外,还向Kubernetes提交了一系列补丁,以添加对通过rkt进行通信和运行容器的支持。 Google和上游Kubernetes看到,添加这些补丁,并可能在将来添加新的容器运行时接口,将会使Kubernetes的代码过于复杂。 上游Kubernetes团队决定实施称为容器运行时接口(CRI)的API协议规范。 然后他们将重新设计Kubernetes以调用CRI而不是Docker引擎,因此任何想要构建容器运行时接口的人都可以实现CRI的服务器端,并且可以支持Kubernetes。 上游Kubernetes创建了一个大型测试套件,供CRI开发人员进行测试以证明他们可以为Kubernetes提供服务。 目前正在进行一项工作,从Kubernetes删除所有Docker引擎调用,并将它们放在一个名为docker-shim的垫片后面。

容器工具的创新

Skopeo的容器注册表创新

几年前,我们在原子CLI上与Project Atomic团队合作。 我们希望能够在容器映像位于容器注册表上时对其进行检查。 当时,在容器注册表中查看与容器映像关联的JSON数据的唯一方法是将映像拉到本地服务器,然后可以使用docker inspect读取JSON文件。 这些图像可能非常大,高达数GB。 因为我们想允许用户检查图像并决定不拉图像,所以我们想向docker inspect添加一个新的--remote接口。 上游docker拒绝了pull请求,告诉我们他们不想使Docker CLI复杂化,并且我们可以轻松地构建自己的工具来做到这一点。

我的团队在安东尼奥·穆尔达卡 ( Antonio Murdaca)的带领下实现了这一想法并创建了skopeo 。 Antonio不仅止步于拉取与图像关联的JSON文件,他决定实现整个协议,以将容器图像从容器注册表中拉出到本地主机或从本地主机中拉出。

现在,在原子CLI中大量使用Skopeo做诸如检查容器的新更新和原子扫描内部之类的事情。 Atomic还使用skopeo来拉入和推送图像,而不是使用上游docker守护程序。

容器/图像

我们一直在与CoreOS讨论可能将skopeo与rkt一起使用,他们说他们不想执行助手程序,但会考虑使用skopeo使用的库。 我们决定将skopeo拆分为一个库和可执行文件,并创建映像

容器/图像库和skopeo用于其他几个上游项目和云基础架构工具。 Skopeo和容器/映像已经发展到可以支持除Docker之外的多个存储后端,并且可以在容器注册表和许多很酷的功能之间移动容器映像。 关于skopeo的一件好事是它不需要任何守护程序即可完成其工作。 容器/图像库的突破还使我们能够添加增强功能,例如容器图像签名 。

图像处理和扫描方面的创新

我在本文前面提到了原子 CLI命令。 我们构建了此工具,以向不适合Docker CLI的容器中添加功能,以及我们认为无法进入上游docker的功能。 我们还希望提供灵活性,以支持其他容器运行时,工具和存储的开发。 Skopeo就是一个例子。

我们要添加到atomic的功能之一是atomic mount 。 基本上,我们想获取存储在Docker映像存储中的内容(上游docker将此称为图形驱动程序),然后将映像安装在某个位置,以便工具可以检查该映像。 当前,如果您使用上游docker,查看映像的唯一方法是启动容器。 如果您拥有不受信任的内容,则在容器内部执行代码以查看图像可能很危险。 通过启动图像检查图像的第二个问题是用于检查容器的工具可能不在容器图像中。

大多数容器图像扫描仪似乎具有以下模式:它们连接到Docker套接字,进行docker保存以创建tarball,然后将磁盘上的tarball炸开,最后检查内容。 这是一个缓慢的操作。

使用atomic mount ,我们想进入Docker图形驱动程序并挂载映像。 如果Docker守护程序正在使用设备映射器,我们将挂载设备。 如果使用的是叠加层,我们将挂载叠加层。 这是一个非常快的操作,可以满足我们的需求。 您现在可以执行以下操作:


# atomic mount fedora /mnt
# cd /mnt

并开始检查内容。 完成后,请执行以下操作:


# atomic umount /mnt

我们在原子扫描中使用此功能,它使您可以使用一些最快的容器扫描仪。

工具协调问题

一个大问题是原子安装正在幕后进行。 Docker守护程序不知道其他进程正在使用该映像。 这可能会导致问题(例如,如果您在上面安装了Fedora映像,然后有人去执行了docker rmi fedora ,则在尝试删除Fedora映像说它很忙时,Docker守护程序会奇怪地失败)。 Docker守护程序可能会进入怪异状态。

集装箱存放

为了解决此问题,我们开始研究将图形驱动程序代码从上游docker守护程序中拉出到其自己的存储库中。 Docker守护程序将其所有锁定都锁定在图形驱动程序的内存中。 我们希望将这种锁定转移到文件系统中,这样我们可以有多个不同的进程能够同时操作容器存储,而不必执行单个守护进程。

我们创建了一个名为container / storage的项目,该项目可以执行运行,构建和存储容器所需的所有COW功能,而无需一个过程来控制和监视它(即不需要守护程序)。 现在,skopeo和其他工具和项目可以利用该存储。 其他开放源代码项目已开始使用容器/存储,并且在某些时候,我们希望将该项目合并回上游docker项目。

取消停靠,让我们创新

如果您考虑使用Kubernetes使用Docker守护程序在节点上运行容器时会发生什么情况,那么首先Kubernetes将执行以下命令:


kubelet run nginx –image=nginx

此命令告诉kubelet在节点上运行NGINX应用程序。 kubelet调用CRI,并要求它启动NGINX应用程序。 此时,实现CRI的容器运行时必须执行以下步骤:

  1. 检查本地存储中是否有一个名为nginx的容器。 如果不是本地的,则容器运行时将在容器注册表中搜索标准化的容器映像。
  2. 如果映像不在本地存储中,则将其从容器注册表下载到本地系统。
  3. 在容器存储(通常是COW存储器)顶部展开下载容器映像,然后将其安装。
  4. 使用标准化容器运行时执行容器。

让我们看一下上述功能:

  1. OCI图像格式规范为存储在容器注册表中的图像定义了标准图像格式。
  2. 容器/映像是一种库,实现了将容器映像从容器注册表拉到容器主机所需的所有功能。
  3. 容器/存储提供了将OCI图像格式展开到COW存储中的库,并允许您处理图像。
  4. OCI运行时规范和runc提供了用于执行容器的工具(与Docker守护程序用于运行容器的工具相同)。

这意味着我们可以使用这些工具来实现使用容器的功能,而无需使用大型容器守护程序。

在基于中型和大型DevOps的CI / CD环境中,效率,速度和安全性至关重要。 并且,只要您的工具符合OCI规范,开发人员或操作员就应该使用最佳工具,以实现通过CI / CD管道到生产的自动化。 大多数容器工具都隐藏在业务流程或更高级别的容器平台技术之下。 我们设想到某个时候,运行时或映像包工具的选择可能会成为容器平台的安装选项。

系统(独立)容器

在Project Atomic上,我们介绍了atomic host ,它是一种构建操作系统的新方式,在该操作系统中可以“原子”更新该软件,并且在其上运行的大多数应用程序都将作为容器运行。 我们使用此平台的目标是证明将来大多数软件都可以OCI映像格式交付,并使用标准协议从容器注册表中获取映像并将其安装在系统上。 通过提供软件作为容器映像,可以以不同于主机操作系统上运行的应用程序的速度来更新主机操作系统。 传统的RPM / yum / DNF分发程序包方式将应用程序锁定到主机操作系统的实时周期。

我们将大多数基础结构作为容器交付时遇到的一个问题是,有时您必须在容器运行时守护程序执行之前运行应用程序。 让我们看一下与Docker守护程序一起运行的Kubernetes示例:Kubernetes需要建立一个网络,以便可以将其pod /容器放入隔离的网络中。 当前我们为此使用的默认守护程序是flanneld ,它必须在启动Docker守护程序之前运行,以便将Docker守护程序传递给网络接口以运行Kubernetes Pod。 而且,flanneld将etcd用于其数据存储。 需要启动flanneld之前运行该守护程序。

如果我们想将etcd和flanneld作为容器图像进行运输,那么我们遇到了麻烦。 我们需要容器运行时守护程序来启动容器化的应用程序,但是这些应用程序需要在容器运行时守护程序启动之前运行。 我已经看到了几种处理这种情况的工具,但是没有一个是干净的。 另外,Docker守护程序当前还没有合适的方法来配置容器启动的优先级顺序。 我已经看到了有关此问题的建议,但是它们看起来都像是旧的SysVInit启动服务的方式(而且我们知道所造成的复杂性)。

系统的

用systemd替换SysVInit的一个原因是要处理启动服务的优先级和顺序,那么为什么不利用这项技术呢? 在Project Atomic中,我们决定希望在主机上运行容器而不需要容器运行时守护程序,特别是对于早期启动。 我们增强了原子CLI,允许您安装容器映像。 如果执行atomic install --system etcd ,它将使用skopeo进入容器注册表并拉下etcd OCI映像。 然后,它将图像爆炸(或扩展)到OSTree后备存储中。 因为我们在生产中运行etcd,所以我们将映像视为只读。 接下来, atomic命令从容器映像中获取systemd单位文件模板,并在磁盘上创建一个单位文件以启动该映像。 单元文件实际上使用runc在主机上启动容器(尽管不需要runc )。

如果执行原子安装--system flanneld会发生类似的情况,除了这次flanneld单元文件指定在启动前需要运行etcd单元。

系统启动时,systemd确保etcd在flanneld之前运行,并且直到flanneld启动之后才启动容器运行时。 这使您可以将Docker守护程序和Kubernetes移至系统容器中。 这意味着您可以启动原子主机或基于rpm的传统操作系统,该操作系统将整个容器编排堆栈作为容器运行。 这非常强大,因为我们知道客户希望继续独立于这些组件来修补其容器主机。 此外,它将主机操作系统的占用空间降至最低。

甚至有关于将传统应用程序放入可以作为独立/系统容器或协调容器运行的容器的讨论。 考虑可以使用原子install --system httpd命令安装的Apache容器。 将以与启动基于rpm的httpd服务相同的方式启动该容器映像( systemctl start httpd除外,但httpd将在容器中启动)。 该存储可能是本地的,这意味着主机上的/ var / www已安装到容器中,并且该容器在端口80上侦听本地网络。这表明您可以在容器内部的主机上运行传统的工作负载,而无需容器运行时守护程序。

建筑容器图像

从我的角度来看,过去四年中有关容器创新的最可悲的事情之一就是缺乏用于构建容器映像的机制的创新。 容器映像不过是压缩包和一些JSON文件的压缩包。 容器的基本映像是rootfs以及描述基本映像的JSON文件。 然后,当您添加图层时,图层之间的差异会随着对JSON文件的更改而被压缩。 这些图层和基本文件一起压缩,以形成容器映像。

几乎每个人都在使用docker build和Dockerfile格式进行构建 。 上游docker停止接受请求来修改或改进Dockerfile格式的请求,并在几年前进行了构建。 Dockerfile在容器的演变中发挥了重要作用。 开发人员或管理员/操作员可以以简单直接的方式构建容器; 但是,在我看来,Dockerfile实际上只是一个穷人的bash脚本,并且会产生一些从未解决的问题。 例如:

  • 要构建容器映像,Dockerfile需要运行Docker守护程序。

    • 除了执行Docker命令外,没有人构建标准工具来创建OCI映像。
    • 甚至ansible -containers和OpenShift S2I(Source2Image)之类的工具在后台也使用了docker -engine
  • Dockerfile中的每一行都会创建一个新映像,这将有助于创建容器的开发过程,因为该工具足够聪明,可以知道Dockerfile中的行没有更改,因此可以使用现有映像,而这些行不会需要重新处理。 这可能导致层的数量巨大
    • 由于这些原因,一些人已经请求压缩图像以消除层的机制。 我认为上游docker终于接受了满足需求的东西。
  • 要将内容从受保护的站点提取到容器映像中,通常需要某种形式的秘密。 例如,您需要访问RHEL证书和订阅才能将RHEL内容添加到映像。
    • 这些秘密可以最终存储在图像中的层中。 并且开发人员需要跳过圈来删除秘密。
    • 为了允许在Docker构建过程中装入卷,我们在所交付的projectatomic / docker软件包中添加了-v卷开关,但上游docker未接受这些补丁。
  • 构建工件最终出现在容器映像内部。 因此,尽管Dockerfiles非常适合入门或在笔记本电脑上构建容器,同时试图了解您可能想要构建的映像,但它们实际上并不是在大型企业环境中构建映像的有效或高效手段。 在自动容器平台的背后,您不必在乎是否使用了更有效的方法来构建符合OCI的图像。

与Buildah停靠

在2017年DevConf.cz大会上,我请团队的Nalin Dahyabhai研究构建所谓的container-coreutils ,基本上是使用container / storage和container / image库,并构建一系列可以模仿Dockerfile的语法。 纳林决定取名为buildah ,取笑我在波士顿的口音。 使用一些buildah原语,您可以构建容器映像:

  • 安全性的主要概念之一是使OS映像内的内容量尽可能小,以消除不需要的工具。 这个想法是,黑客可能需要工具来破坏应用程序,并且如果不存在诸如gccmakednf之类的工具,则可以阻止或限制攻击者。
  • 由于这些图像是通过Internet拉动的,因此缩小容器的大小始终是一个好主意。
  • Docker构建的工作方式是安装软件或编译软件的命令必须位于容器的uildroot中。
  • 执行run命令要求所有可执行文件都在容器映像中。 仅在容器映像中使用dnf要求存在整个Python堆栈,即使您从未在应用程序中使用Python。
  • ctr = $(来自fedora的buildah)
    • 使用容器/图像从容器注册表中提取Fedora图像。
    • 返回容器ID( ctr )。
  • mnt = $(buildah mount $ ctr)
    • 挂载新创建的容器映像( $ ctr )。
    • 返回安装点的路径。
    • 现在,您可以使用此安装点写入内容。
  • dnf安装httpd –installroot = $ mnt
    • 您可以在主机上使用命令将内容重定向到容器中,这意味着您可以将机密信息保留在主机上,而不必将其放入容器中,并且可以将构建工具保留在主机上。
    • 除非您的应用程序要使用它,否则您不需要在容器或Python堆栈中使用dnf
  • cp foobar $ mnt / dir
    • 您可以使用bash中可用的任何命令来填充容器。
  • buildah commit $ ctr
    • 您可以随时决定创建一个图层。 您控制图层而不是工具。
  • buildah config --env container = oci --entrypoint / usr / bin / httpd $ ctr
    • 可以指定Dockerfile内部可用的所有命令。
  • buildah运行$ ctr dnf -y install httpd
    • 支持Buildah run ,但是buildah不再依赖容器运行时守护程序,而是执行runc在锁定的容器内运行命令。
  • buildah build-using-dockerfile -f Dockerfile。

    我们想要移动诸如ansible-containers和OpenShift S2I之类的工具以使用buildah而不是需要容器运行时守护程序。

    在用于生产中运行容器的同一容器运行时中构建的另一个大问题是,就安全性而言,您最终会得到最低的公分母。 与运行容器相比,构建容器往往需要更多的特权。 例如,默认情况下,我们允许mknod功能。 mknod功能允许进程创建设备节点。 某些软件包安装会尝试创建设备节点,但在生产中几乎没有应用程序会这样做。 在生产中从容器中删除mknod功能将使您的系统更安全。

    另一个示例是我们默认将容器映像读取/写入,因为安装过程意味着将软件包写入/ usr 。 但是在生产中,我认为您确实应该以只读模式运行所有容器。 仅允许容器写入已批量安装到容器中的tmpfs或目录。 通过从建筑物中拆分容器的运行方式,我们可以更改默认值,并提供一个更加安全的环境。

    • 是的,buildah可以使用Dockerfile构建容器映像。

CRI-O Kubernetes的运行时抽象

Kubernetes添加了一个API来为名为Pod的容器运行时接口(CRI)的Pod插入任何运行时。 我不是在系统上运行许多守护程序的忠实拥护者,但是我们添加了另一个守护程序。 我的团队由Mrunal Patel领导,于2016年底开始研究CRI-O守护程序。这是一个用于运行基于OCI的应用程序的Container Runtime Interface守护程序。 从理论上讲,将来我们可以将CRI-O代码直接编译到kubelet中,以消除第二个守护程序。

与其他容器运行时不同,CRI-O的唯一目的就是满足Kubernetes的需求。 请记住上述Kubernetes运行容器所需的步骤。

Kubernetes向kubelet发送一条消息,要求它运行NGINX服务器:

  1. kubelet调用CRI-O来告诉它运行NGINX。
  2. CRI-O回答CRI请求。
  3. CRI-O在容器注册表中找到一个OCI映像。
  4. CRI-O使用容器/映像将映像从注册表拉到主机。
  5. CRI-O使用容器/存储将映像解压缩到本地存储。
  6. CRI-O启动OCI运行时规范(通常为runc )并启动容器。 如前所述,Docker守护进程使用runc启动容器,其方式完全相同。
  7. 如果需要,kubelet也可以使用备用运行时启动容器,例如Clear Containers runv

CRI-O旨在成为运行Kubernetes的稳定平台,并且除非通过整个Kubernetes测试套件,否则我们不会发布CRI-O的新版本。 所有转到https://github.com/Kubernetes-incubator/cri-o的拉取请求都针对整个Kubernetes测试套件运行。 如果不通过测试,您将无法向CRI-O发送拉取请求。 CRI-O完全开放,我们有来自多家不同公司的贡献者,包括Intel,SUSE,IBM,Google,Hyper.sh。 只要大多数维护者都同意CRI-O的补丁程序,即使该补丁程序不是Red Hat想要的,它也会被接受。

结论

我希望这次深入的探讨可以帮助您了解Linux容器的发展方式。 曾经,Linux容器是每个厂商都面对的情况。 Docker帮助专注于事实上的图像创建标准,并简化了用于容器的工具。 现在,“开放容器计划”意味着该行业正在围绕核心图像格式和运行时开展工作,这将围绕使工具更有效地实现自动化,更安全,高度可扩展且更易于使用而进行创新。 容器使我们能够以新颖的方式检查安装软件,无论它们是运行在主机上的传统应用程序,还是运行在云中的经编排的微服务。 在许多方面,这仅仅是开始。

翻译自: https://opensource.com/article/17/7/how-linux-containers-evolved

linux 容器

linux 容器_Linux容器如何演变相关推荐

  1. java部署容器_Linux容器——Docker(二)之 JavaWeb部署

    1.拉取镜像 a.拉取Mysql镜像 #拉取Mysql镜像 $ docker pull mysql:8.0.18 b.拉取Tomcat镜像 #拉取Tomcat镜像 $ docker pull tomc ...

  2. linux 容器_Linux容器的幕后花絮

    linux 容器 您可以拥有没有Docker的 Linux容器吗? 没有OpenShift ? 没有Kubernetes ? 是的你可以. 在Docker成为家喻户晓的容器的几年前(也就是说,如果您生 ...

  3. linux 路由表_Linux 容器网络笔记:underlay

    容器网络相比过去虚拟机的网络虚拟化有一些变化,过去虚拟机的网络虚拟化,要模拟的是 NIC 设备,要模拟虚拟网卡的硬件细节.到容器时代,网络虚拟化会更多地重用 linux 自身的网络设备,可以在协议栈的 ...

  4. Linux主机Windows容器,了解用于Linux和 Windows容器的Docker“容器主机”与“容器操作系统”...

    让我们来探讨一下"容器主机"和"容器操作系统"之间的关系,以及它们在 Linux 和 Windows 容器之间的区别. 一些定义 容器主机:也称为主机操作系统. ...

  5. linux docker创建容器教程

                                                                            linux docker创建容器教程 目录 0.dock ...

  6. Linux 设置Docker容器开机自启动,Dokcer容器常用命令总结。

    文章目录 Linux Dokcer容器常用命令总结 一.docker 常用基础命令总结 二.工作中常用docker命令 三.查看容器挂载目录 四.容器拷贝文件 五.设置搭建好容器开机自启 六.开启do ...

  7. docker 僵尸进程解决方案 Baseimage-docker,胖容器和“容器也是虚拟机”

    Baseimage-docker 是针对 Docker 优化地 Ubuntu 最小化基础镜像.我们可以从 Docker 仓库中拉取回来作为基础镜像用在自己的镜像中. 笔者也算是 Docker 的早期使 ...

  8. 《Docker——容器与容器云》:第一章 从容器到容器云

    2013年初,一个名字从云计算领域横空出世,并在整个IT行业激起千层浪.这就是Docker--一个孕育着新思想的"容器".Docker选择容器作为核心和基础,依靠容器技术支撑的Do ...

  9. 容器和容器镜像的区别,您真的了解吗

    很多刚刚接触容器技术的朋友,不容易弄清楚容器,容器镜像和Docker这几个词的区别和联系. 我们首先来看容器和容器镜像.举个例子,执行命令行docker search nginx,搜索结果的一条条记录 ...

最新文章

  1. mac txt 换行符_推荐两款免费的网页代码编辑器(Win和Mac系统)
  2. 基础练习 字母图形 c语言
  3. Linux操作系统文档
  4. 利用VC++实现局域网实时传输
  5. C++11新特性之智能指针
  6. 笔记本vm系统的分辨率不好调整_苹果笔记本电脑怎么设置使用今声优盒
  7. oracle em界面监控出来的奇怪图像_监控工程常见的5大难题,项目中都会遇到
  8. C++自学22:复制内存(memcpy)/设置内存(memset)
  9. android 讲程序设为默认主屏幕_轻松搞定 PC 副屏,双屏幕更方便!
  10. ios开发--企业帐号发布
  11. 视频编解码(六):264解码器学习
  12. IO中的阻塞、非阻塞、同步、异步概念分析详解(通俗易懂)
  13. Unity3D 退出游戏应用的代码
  14. 高可用分布式系统架构图
  15. Batch批处理最全学习教程
  16. 库存进销存出入库销售mysql表结构_进销存数据库表结构设计.doc
  17. php判断caj文件页数,2M内的CAJ文档如何转PDF免费?不限页数手机在线操作分享
  18. 《少有人走的路:心智成熟的旅程》
  19. 达达O2O后台架构演进实践:从0到4000高并发请求背后的努力
  20. #R语言# 生成随机数

热门文章

  1. 《程序员代码面试指南》第二章 链表问题 删除无序链表中值重复的链表
  2. Linux 僵尸进程
  3. 《Servlet和JSP学习指南》一导读
  4. 你真会用setTimeout吗?
  5. Flash+XML 加载图片
  6. MS speech SDK5.1朗读控件
  7. WIFI,WiMAX和WAPI
  8. Springboot2.0 集成 Elasticsearch 6.x 未添加 transport-netty4-client 依赖 启动时报错
  9. jmeter中控制器3个请求其中一个访问不到_性能测试干货丨盘点JMeter常见的逻辑控制器...
  10. 关于E: Sub-process /usr/bin/dpkg returned an error code (1)错误解决