我们今天讨论的是《下一代容器架构已出,Docker何去何处?》
其实就目前来说,下一代容器架构可以约等于≒Podman+Skopeo+Buildah
其实这半年来很多自媒体都在鼓吹新的容器架构,吹嘘将要很快的替代Docker。但是很少人讨论新的架构和老的架构的区别,以及目前迁移的可能性等等等等。。。这些都是摆在企业面前去接触新架构的大山。所以,我们今天不做具体的新容器架构实战,我们只回答以下几个问题。
Q1
什么是Linux容器以及它如何工作?
一句话回答:就像港口的集装箱
(1)linux容器又名LXC(Linux Container),我们要形象的理解Linux容器的话,我们可以把它想象成集装箱,而操作系统就像港口。集装箱的特色,在于其格式划一,并可以层层重叠。它是一种内核轻量级的操作系统层虚拟化技术。
Q2
什么是OCI、CRI、CNI?
一句话回答:接口抽象化
(1)回答这个问题之前呢?需要先说一下容器发展的历史:一开始是Docker.io公司推出了容器Docker,但其实容器并非只要Docker,这样带来一个问题是很多做容器编排的公司都要去兼容所有的容器类型。于是后来北美的一些大厂就开始讨论联合指定一个统一的规范,以后做容器的公司都要以这个为准,这个标准就是 Open Container Initiative(OCI)。
(2)CRI是OCI标准中的其中一个,“容器运行时标准”,它定义了容器在硬盘上存储的方式,用于描述容器中应用程序的 JSON 文件和如何创建和运行容器。Docker.io贡献了 libcontainer,并且提供了 runc 作为 OCI 运行时规范的默认实现。
(3)CNI则是CNCF旗下的一个项目,由一组用于配置Linux容器的网络接口的规范和库组成,同时还包含了一些插件。CNI仅关心容器创建时的网络分配,和当容器被删除时释放网络资源。
Q3
新容器架构是什么样的?
一句话回答:新时代容器“三兄弟”
就像开头我们说的一样,新容器架构是Podman+Skopeo+Buildah,这里我们一一介绍这些工具:
(1)Podman: Podman 原来是 CRI-O 项目的一部分,后来被分离成一个单独的项目叫 libpod。Podman 的使用体验和 Docker 类似,不同的是 Podman 没有 daemon。以前使用 Docker CLI 的时候,Docker CLI 会通过 gRPC API 去跟 Docker Engine 说「我要启动一个容器」,然后 Docker Engine 才会通过 OCI Container runtime(默认是 runc)来启动一个容器。这就意味着容器的进程不可能是 Docker CLI 的子进程,而是 Docker Engine 的子进程。Podman 比较简单粗暴,它不使用 Daemon,而是直接通过 OCI runtime(默认也是 runc)来启动容器,所以容器的进程是 podman 的子进程。这比较像 Linux 的 fork/exec 模型,而 Docker 采用的是 C/S(客户端/服务器)模型。
(2)Skopeo:Skopeo是一个工具,允许我们通过推,拉和复制镜像来处理Docker和OC镜像。我们都知道我们可以通过Docker来拉取远程的镜像。但是我们不能在本地直接查看手游交易平台远程镜像的详细信息,必须要先拉到本地才行,而Skopeo就解决了这样一个痛点。而它还有一个优点是是它不需要任何守护进程的协助来完成任务。
(3)Buildah: Buildah用来构建OCI图像。虽然Podman也可以用户构建Docker镜像,但是构建速度超慢,并且默认情况下使用vfs存储驱动程序会耗尽大量磁盘空间。它类似于Dockerfile,但更优秀的地方是它不需要依赖其余的守护进程,它能支持非Dockerfile的构建文件。
所以,新容器架构运行方式就是这样:Buildah构建容器,Podman运行容器,Skopeo传输容器镜像。这些都是由Github容器组织维护的开源工具(github/containers)
Q4
Docker模型和Podman模型的区别?
一句话回答:C/S(客户端/服务器)模型和fork/exec模型
我们主要对比Docker和Podman的模型区别:
(1)Docker主要使用C/S(客户端/服务器)模型
(2)Podman主要使用fork/exec 模型
那我们想想这两个模型的区别:
(1)fork/exec模型知道某个容器进程到底是谁启动的,因为都是它的子进程啊!
(2)如果我们使用Namespace或者Cgroup对Podman 做一些限制,那么所有创建的容器都会被限制,因为都是它的子进程啊!
(3)可以做一些黑科技,进程通信?进程XX,因为都是它的子进程啊!
好吧,其实区别就是在于C/S(客户端/服务器)模型和fork/exec模型的区别,这个知识点大家都是具体查找其他的资料,总之,我们可以做出各种黑科技。
Q5
怎么从老架构迁移到新架构,有哪些风险?
一句话回答:慎入!!!
这部分我们主要讲给那些使用自建容器编排集群的开发者将讲(因为要排除一些开发者直接使用GKE,EKS之类现成的编排平台,就不好改云平台的底层架构),首先,在使用方面,基础平台之上的使用人员可能感受不是很大,毕竟Podman号称高度匹配Docker命令,所以单纯的替换CRI的话可能是对于资源消耗以及容器启动速度都是有明显加成的,这个是优点。但是,换个角度想,我们要是全部都按照新架构替换的话,这里面的风险就很难预测了。举几个例子:Podman在拉取推送镜像时存在同一镜像digests 改变的情况;使用Docker Compose做部署的时候部署文件怎么修改?特定的指令怎么对接?这些问题都是很需要时间和人力去推动的,所以,在新架构还没有推出稳定的版本之前,最好还是不要迁移,当然,如果你是新进场的云试验者,果断上吧!
Q6
未来的趋势会是怎么样的?
一句话回答:新时代容器是可期的!
未来的趋势,依我个人的观点,新容器的架构会慢慢的蚕食Docker代表的旧架构,原因如下:
(1)Docker本身的设计模式的限制,不能很好的做软件集成;
(2)越来越多的CRI组件推出,在性能上以及资源消耗方面都胜过Docker;
(3)Podman等工具设计出来的时候就是本着服务于K8S的目的,所以他们和K8S贴合的无疑会更紧密,虽然这些工具目前有着这些那些的问题,但是谁说Docker刚推出的时候没有问题了,只是我们入场的早晚罢了。2018是K8S的元年,Google等大厂都开始拥抱K8S,所以未来,新时代容器是可期的!
(2)容器通过四个主要组件工作:名称空间(namespaces),控制组(cgroups),映像(images)和用户空间工具例如Docker。Linux系统上的所有进程都从init进程fork派生。Linux容器的一个主要组件是在新的命名空间下创建一个新的init进程。因此,仅凭名称空间(namespaces),我们就有能力生成一个进程树并操纵一些底层系统资源,而不会影响主机系统。那另一个问题,是什么来阻止新产生的容器过度使用主机的资源呢?使用cgroups,我们可以限制CPU使用率,内存,磁盘等等,这样我们就能够保证我们创建的容器在合理使用的范畴内。最后映像(images)和用户空间工具就是帮助我们更便捷的使用LXC。