不止Docker:8款容器管理开源方案

标签: docker 容器 管理 | 发表时间:2021-06-28 16:20 | 作者:Andy_Lee
出处:http://weekly.dockone.io

Docker诞生于2013年,并普及了容器的概念,以至于大多数人仍然将容器的概念等同于“Docker容器”。

作为第一个吃螃蟹的人,Docker设置了新加入者必须遵守的标准。例如,Docker有一个大型系统镜像库。所有的替代方案都必须使用相同的镜像格式,同时试图改变Docker所基于的整个堆栈的一个或多个部分。

在此期间,出现了新的容器标准,容器生态系统朝着不同方向发展。现在除了Docker之外,还有很多方法可以使用容器。

在本文中,我们将介绍以下内容:
  • 将Chroot、cgroups和命名空间作为容器的技术基础
  • 定义Docker所基于的软件堆栈
  • 说明Docker和Kubernetes需要坚持和遵守的标准
  • 介绍替代解决方案,这些解决方案尝试使用具有更好更安全的组件来替换原始Docker容器。


容器的软件堆栈

像Chroot 调用、 cgroups 和命名空间等 Linux 特性帮助容器在与所有其他进程隔离的情况下运行,从而保证运行时的安全性。

Chroot

所有类似Docker的技术都起源于类似Unix操作系统(OS)的根目录。在根目录上方是根文件系统和其他目录。

从长远来看,这是很危险的,因为根目录中任何不需要的删除都会影响整个操作系统。这就是为什么存在一个系统调用 chroot()。它创建了额外的根目录,例如一个用于运行遗留软件,另一个用于包含数据库等等。

对于所有这些环境, chroot似乎是一个真正的根目录,而是实际上,它只是将路径名添加到任何以/开头的名字上。真正的根目录仍然存在,并且任何进程都可以引用指定根目录以外的任何位置。

Linux cgroups

自2008年2.6.24版本以来,Control groups(cgroups)一直是Linux内核的一项功能。Cgroup将同时限制、隔离和测量多个进程的系统资源(内存、CPU、网络和I/O)使用情况。

假设我们想阻止用户从服务器发送大量电子邮件。我们创建了一个内存限制为1GB、CPU占用率为50%的cgroup,并将应用程序的 processid添加到该组中。当达到这些限制时,系统将限制电子邮件发送过程。它甚至可能终止进程,这取决于托管策略。

Namespaces

Linux命名空间是另一个有用的抽象层。命名空间允许我们拥有许多进程层次,每个层次都有自己的嵌套“子树(subtree)”。命名空间可以使用全局资源,并将其呈现给其成员,就像它是自己的资源一样。

具体来看,Linux系统开始时的进程标识符(PID)为1,并且所有其他进程将包含在其树中。PID命名空间允许我们跨越一棵新树,它拥有自己的PID 1进程。现在有两个值为1的PID,每个命名空间可以产生自己的命名空间,并且相同的过程可以附加了几个PID。

子命名空间中的一个进程将不知道父级的进程存在,而父命名空间将可以访问整个子命名空间。

有七种类型的名称空间:cgroup、IPC、网络、mount、PID、用户和UTS。

Network Namespace

一些资源是稀缺的。按照惯例,有些端口具有预定义的角色,不应用于其他任何用途:端口80仅服务于HTTP调用,端口443仅服务于HTTPS调用等等。在共享主机环境中,两个或多个站点可以监听来自端口80的HTTP请求。第一个获得该端口的站点不允许任何其他应用程序访问该端口上的数据。第一个应用程序在互联网上是可见的,而其他所有应用程序将不可见。

解决方案是使用网络命名空间,通过网络命名空间,内部进程将看到不同的网络接口。

在一个网络命名空间中,同一端口可以是开放的,而在另一个网络命名空间中,可以关闭该端口。为此,我们必须采用额外的“虚拟”网络接口,这些接口同时属于多个命名空间。中间还必须有一个路由器进程,将到达物理设备的请求连接到相应的名称空间和其中的进程。

复杂吗?这就是为什么Docker和类似工具如此受欢迎。现在让我们来介绍一下Docker,以及它的替代方案。

Docker:人人可用的容器

在容器统治云计算世界之前,虚拟机非常流行。如果你有一台Windows机器,但想为iOS开发移动应用程序,你可以购买一台新的Mac,或者将其虚拟机安装到Windows硬件上。虚拟机也可能是笨重的,它们经常吞噬不需要的资源,而且启动速度通常很慢(长达一分钟)。

容器是标准软件单元,具有运行程序所需的一切:操作系统、数据库、镜像、图标,软件库、代码和所需的其他组件。容器的运行也与所有其他容器,甚至与操作系统本身隔离。与虚拟机相比,容器是轻量级的,所以它们可以快速启动,并且容易被替换。

要运行隔离和保护,容器需要基于Chroot、cgroups和命名空间。

容器的镜像是在实际机器上形成应用程序的模板,能够根据单个镜像创建尽可能多的容器,一个名为Dockerfile的文本文件包含了组装镜像所需的所有信息。

Docker带来的真正革命是创建了Docker镜像仓库和开发了Docker引擎,这些镜像以相同的方式在各地运行,作为第一个被广泛采用的容器镜像,形成了一个不成文的世界标准,所有后来的入局者都必须关注它。

CRI and OCI


OCI 全称为Open Container Initiative,它发布镜像和容器的规范。它于2015年由Docker发起,并被微软、Facebook、英特尔、VMWare、甲骨文和许多其他行业巨头接受。

OCI还提供了规范的一个实现,被称为 runc ,它可以直接使用容器,创建并运行它们等。

容器运行时接口(Container Runtime Interface,简称CRI)是一个Kubernetes API,它定义了Kubernetes如何与容器运行时交互。它也是标准化的,所以我们可以选择采用哪个CRI实现。

用于CRI和OCI的容器的软件堆栈

Linux是运行容器的软件堆栈中最基本的部分:

请注意,Containerd和CRI-O都坚持CRI和OCI规范。对于Kubernetes而言,这意味着它可以使用Containerd或CRI-O,而用户不会注意到其中的区别。它还可以使用我们现在要提到的任何其他替代方案——这正是创建和采用了OCI和CRI等软件标准的目标。

Docker软件堆栈

Docker的软件堆栈包括:
  • docker-cli,面向开发者的Docker命令行界面
  • containerd,最初由Docker编写,后来作为一个独立的项目启动; 它实现了CRI规范
  • runc,它实现了OCI规范
  • 容器(使用chroot、cgroups、命名空间等)


Kubernetes的软件堆栈几乎是相同的;Kubernetes使用CRI-O,而不是Containerd,这是由Red Hat / IBM和其他人创建的CRI实现。

containerd


containerd作为一个守护程序在Linux和Windows上运行。它加载镜像,将其作为容器执行,监督底层存储,并负责整个容器的运行时间和生命周期。

Containerd诞生于2014年,一开始作为Docker的一部分,2017年成为云原生计算基金会(CNCF)中的一个项目,并于 2019年年初毕业

runc

runc是OCI规范的参考实现。它创建并运行容器以及其中的进程。它使用较低级别的Linux特性,比如cgroup和命名空间。

runc的替代方案包括Kata-Runtime、GVisor和CRI-O。

Kata-Runtime使用硬件虚拟化作为单独的轻量级VM实现OCI规范。它的运行时与OCI、CRI-O和Containerd兼容,因此它可以与Docker和Kubernetes无缝工作。

Google的gVisor创建包含自己内核的容器。它通过名为 runsc的项目实现OCI,该项目与Docker和Kubernetes集成。有自己内核的容器比没有内核的容器更安全,但它不是万能的,而且这种方法在资源使用上要付出代价。

CRI-O是一个纯粹为Kubernetes设计的容器堆栈,是CRI标准的第一个实现。它从任何容器镜像仓库中 提取镜像,可以作为使用Docker的轻量级替代方案。

今天它支持runc和Kata Containers作为容器运行时,但也可以插入任何其他OC兼容的运行时(至少在理论上)。

它是一个CNCF孵化项目。

Podman


Podman是一个没有守护进程的Docker替代品。它的命令有意与Docker尽可能兼容,以至于您可以在CLI界面中创建一个别名并开始使用单词“Docker”而不是“podman”。

Podman的目标是取代Docker,因此坚持使用相同的命令集是有意义的。Podman试图改进Docker中的两个问题。

首先,Docker总是使用内部守护进程执行。守护进程是在后台运行的单进程。如果它失败了,整个系统就会失败。

第二,Docker作为后台进程运行,具有root权限,所以当你给一个新的用户访问权时,你实际上是给了整个服务器的访问权。

Podman是一个远程Linux客户端,可直接从操作系统运行容器。你也可以以rootless模式运行它们。它从DockerHub下载镜像,并以与Docker完全相同的方式运行它们,具有完全相同的命令。

Podman以root以外的用户身份运行命令和镜像,所以它比Docker更安全。另一方面,有许多为Docker开发的工具在Podman上是不可用的,如Portainer和Watchtower。摆脱Docker意味着放弃你之前建立的工作流程。

Podman的目录结构与buildah、skopeo和CRI-I类似。它的Pod也非常类似于KubernetesPod。

Linux容器:LXC和LXD

LXC(LinuX Containers)于2008年推出,是Linux上第一个上游内核的容器。Docker的第一个版本使用了LXC,但在后来的发展中,由于已经实现了 runc,所以LXC被移除了。

LXC的目标是使用一个Linux内核在一个控制主机上运行多个隔离的Linux虚拟环境。为此,它使用了cgroups功能,而不需要启动任何虚拟机;它还使用命名空间,将应用程序与底层系统完全隔离。

LXC旨在创建系统容器,几乎就像你在虚拟机中一样——但硬件开销很小,因为这些硬件是被虚拟化的。

LXC不模拟硬件和软件包,只包含需要的应用程序,所以它几乎以裸机速度执行。相反,虚拟机包含整个操作系统,然后模拟硬件,如硬盘、虚拟处理器和网络接口。

所以,LXC是小而快的,而虚拟机是大而慢的。另一方面,虚拟环境不能被打包成现成的、可快速部署的机器,而且很难通过GUI管理控制台进行管理。LXC要求技术人员有很高的技术水平,并且优化后的机器可能与其他环境不兼容。

LXC VS Docker

LXC就像Linux上的一个增压chroot,它产生的“小”服务器启动更快,需要更少的RAM。然而,Docker提供了更多特性:
  • 跨机器的可移植部署:使用一个版本的Docker创建的对象可以传输并安装到任何其他支持Docker的Linux主机上。
  • 版本控制:Docker可以用一种类似git的方式跟踪版本——您可以创建容器的新版本,将它们回滚等等。
  • 重复使用组件:使用Docker,您可以将已经创建的包堆叠到新包中。如果您想要一个LAMP环境,可以安装一次它的组件,然后将它们作为预先制作的LAMP镜像重新使用。
  • Docker镜像存档:可以从专用站点下载数十万个Docker镜像,并且很容易将新镜像上传到这样的镜像仓库中。


LXC面向系统管理员,而Docker更面向开发人员。这就是Docker更受欢迎的原因所在。

LXD

LXD有一个特权守护进程,它通过本地UNIX socket和网络(如果启用)公开REST API。您可以通过命令行工具访问它,但它总是使用REST API调用进行通信。无论客户端是在本地机器上还是在远程服务器上,它的功能都是一样的。

LXD可以从一台本地机器扩展到几千台远程机器。与Docker类似,它是基于镜像的,所有更流行的Linux发行版都可以使用镜像。Ubuntu的公司Canonical正在资助LXD的开发,因此它将始终运行在Ubuntu以及其他类似Linux操作系统的最新版本上。LXD可以与OpenNebula和OpenStack标准无缝集成。

从技术上讲,LXD是站在LXC的肩膀上(两者都使用相同的liblxc库和Go语言创建容器),但LXD的目标是改善用户体验。

Docker会永远存在吗?

Docker拥有1100万开发者、700万个应用程序和每月130亿次的镜像下载。如果仅仅说Docker仍然是领导,那就太轻描淡写了。然而,在这篇文章中,我们已经看到,现在已经有许多产品可以取代Docker软件栈的一个或多个部分,并且通常情况下没有兼容性问题。而且与Docker提供的服务相比,其他软件的主要目标是安全性。

原文链接: https://mp.weixin.qq.com/s/o_sqMDTS5JGuD-gu0RxDEg

相关 [docker 容器 管理] 推荐:

不止Docker:8款容器管理开源方案

- - DockOne.io
Docker诞生于2013年,并普及了容器的概念,以至于大多数人仍然将容器的概念等同于“Docker容器”. 作为第一个吃螃蟹的人,Docker设置了新加入者必须遵守的标准. 例如,Docker有一个大型系统镜像库. 所有的替代方案都必须使用相同的镜像格式,同时试图改变Docker所基于的整个堆栈的一个或多个部分.

关于docker容器的监控

- - CSDN博客推荐文章
1 docker inspect [容器ID | 镜像ID]. 查看容器创建时间、容器的IP、映射的端口、挂载的目录等信息. 此命令同样也能用来查看镜像的详细信息. 2 docker stats 容器ID. 用来查看容器的资源使用情况,如:CPU、内存、网络、I/O. 另外,在docker的配置文件中添加如下的参数之后,可以采用curl来调用stats API接口.

Docker容器安全性分析

- - FreeBuf互联网安全新媒体平台
Docker是目前最具代表性的容器技术之一,对云计算及虚拟化技术产生了颠覆性的影响. 本文对Docker容器在应用中可能面临的安全问题和风险进行了研究,并将Docker容器应用环境中的安全机制与相关解决方案分为容器虚拟化安全、容器安全管理、容器网络安全三部分进行分析. 一、从虚拟化安全到容器安全 .

调试 Docker 容器内部进程

- - 掘金后端
摘要:本文以 Nebula Graph 进程为例,讲解如何不破坏原有容器的内容,也不用在其中安装任何的工具包前提下,像在本地一样来调试进程. 在开发或者测试过程中,我们经常会用到. vesoft-inc/nebula-docker-compose 这个 repo 下的部署方式,因为当初为了尽可能的压缩每个.

使用Mesos和Marathon管理Docker集群

- - zzm
分 布式系统是难于理解、设计、构建 和管理的,他们将比单个机器成倍还要多的变量引入到设计中,使应用程序的根源问题更难发现. SLA(服务水平协议)是衡量停机和/或性能下降的标准,大多 数现代应用程序有一个期望的弹性SLA水平,通常按"9"的数量增加(如,每月99.9或99.99%可用性).    分布式系统通常是以静态分区,比如Akka/Play、 Spark/Hadoop、Storm和 Redis各自分区分组划分.

减少使用Java应用服务器,迎接Docker容器

- - ITeye资讯频道
【编者的话】随着Docker的发展,越来越多的应用开发者开始使用Docker. James Strachan写了一篇有关Java开发者如何使用Docker进行轻量级快速开发的文章. 他告诉我们,使用Docker和服务发现的机制,可以有效减轻Java运维人员的负担,进行项目的快速启动和持续迭代. 多年来,Java生态系统一直在使用应用服务器.

理解Docker跨多主机容器网络

- - Tony Bai
在 Docker 1.9 出世前,跨多主机的容器通信方案大致有如下三种:. 将宿主机A的端口P映射到容器C的网络空间监听的端口P’上,仅提供四层及以上应用和服务使用. 这样其他主机上的容器通过访问宿主机A的端口P实 现与容器C的通信. 显然这个方案的应用场景很有局限. 2、将物理网卡桥接到虚拟网桥,使得容器与宿主机配置在同一网段下.

Docker容器的自动化监控实现

- - DockerInfo
2016年对于网易杭州研究院(以下简称“杭研”)而言是重要的,成立十周年之际,杭研正式推出了网易云. “十年•杭研技术秀”系列文章,由杭研研发团队倾情奉献,为您展示杭研那些有用、有趣的技术实践经验,涵盖云计算、大前端、信息安全、运维、QA、大数据、人工智能等领域,涉及前沿的分布式、 容器、深度学习等技术.

docker容器部署Spring Boot项目及更新

- - 编程语言 - ITeye博客
Docker这项容器技术已经是十分的火热了,读者要是不了解docker的话可以吧docker先理解为虚拟机. 我们的Springboot最终是要部署在Linux上的,docker作为Linux轻量级的实现. docker也是可以用来部署Springboot应用的. 1.创建Dockerfile . 创建一个文件名为Dockerfile的文件,复制以下内容到文件中.

elk-filebeat收集docker容器日志 - devzxd - 博客园

- -
filebeat安装与配置. 1、使用docker-compose文件构建elk. 2、执行docker-compose up -d 启动elk. 可以使用docker logs 命令查看elk启动日志. 启动成功后打开浏览器访问 http://127.0.0.1:5601. 关于filebeat本文也不做过多介绍.