认识容器,我们从它的历史开始聊起 原 荐

本文分享自华为云社区《认识容器我们从它的历史开始聊起》作者:技术火炬手。

关于容器历史、发展以及技术本质,在互联网上已经有非常多的文章了。这里旨在结合自身的工作经验和理解,通过一系列的文章,讲清楚这项技术。

容器的历史和发docker怎么读

1、前世

讲到容器,就linux常用命令不得不提LXC(Llinux必学的60个命令inux Cdocker是干什么的ontainer),他是Docker的前生,或者说Docker是LXC的使用者。完整的LXC能力在2008年合入Linux主线,所以容器的概念在2008年就基本定型了,并不是后面Docker造出来的。关于LXC的介绍很多,大体都会说“LXC是Linudocker常用命令x内核提linux供的容器技术,能提供轻量级的虚拟化能力,能隔离进程和资源”,但总结起来,docker无外乎就linux系统两大知识点Cgroups(Linux Cdocker常用命令ontrol Group)和Linux Namespace。搞清楚他俩,容器技术就基本掌握了。

  • Cgroups:重点在“限制”。限制资源的使用,包括CPU、内存、磁盘的使用,体现出对资源的管理能力。
  • Namespalinux创建文件ce:重点在“隔离”。隔离进程看到的Linux视图。说大白话就是,容器和容器之间不要相互影响,容器和宿主机之间不要相互影响。

2、少年期起步艰难

2009年,Cloud Foundry基于LXC实现了对容器的操作,该项目取名为Warden。2010年,dotCloud公司同样基于LXC技术,使用Go语言实现了一款容器引擎,也就是现在的Docker。那时,dotCloud公司还是个小公司,出生卑微的Docker没docker容器什么热度,活得相当艰难。

3、 成长为巨无霸

2013年,dotCloud公司决定将Docker开源。开源后,项目突然就火了。从大的说,火的原因就是Docker的这句口号“Build once,Run AnyWhere”。呵呵,是不是似曾相识?对的,和Java的Write Once,Run AnyWhere一个道理linux必学的60个命令。对于一个程序员来说,程序写完后打linux命令包成镜像就可以随处部署和运行,开发、测试和生产docker环境完全一致,这是多么大一个诱惑。程序员再也不用去定位因环境差异导致的各种坑爹问题。

Docker开源项目的异常火爆,直接驱动dotCloud公司docker和虚拟机的区别在2013年更名为Docker公司。Docker也快速成长,干掉了CoreOdockerhubS公司的rkt容器和Googllinux必学的60个命令e的lmctfy容docker菜鸟教程器,直接变成了容器的事实标准。也就有了后来linux常用命令人一提到容器就认为是Docker。

总结起来docker是干什么的,Docklinux是什么操作系统er为什么火,靠的就是Docker镜dockerhub像。他打包了应用程序的所有依赖,彻linux必学的60个命令底解决了环境的一致性问题,重新定义了docker安装部署软件的交付方式,提高了生产效率。

4、 被列强蚕食

Docker在容器领域快速成长,野心自然也变大了。2014年linux系统推出了容器云产品Swarm(K8s的同类产品),想扩张事业版图。同时Docker在开源社区拥有绝对话语权,相当强势。这种走自己的路,让别人无路docker可走的行为,让容器领域的其他大厂玩家很是不爽,docker容器为了不让Dockedockerr一家独大,决定要干他。

2015年6月,在Google、Redhat等大厂的“运作”下,Linux基金会成立了OCI(Open Container Initiative)组织,旨在围绕容器格式和运行时制定一个开放的linux系统工业化标准,也就是我们常说的OCI标linux必学的60个命令准。同时,Docker公司将Lilinux命令bcontainer模块捐给CNCF社区,作为OCI标准的实现,这docker怎么读就是现在的RunC项目。说白了,就是现在这块儿有个标准了,大docker家一起玩儿,不被某个特定项目的绑定。

讲到Dockerlinux,就得说说Google家的Kubernetes,他作为容器云平台的事实标准,如今已被广泛使用,俨然已成为大厂标配。Kubernetes原生支持Docker,让Docker的市场占有率一直居高不下。如图是2019年容器运行时的市场占有率linux重启命令

认识容器,我们从它的历史开始聊起
                                                原
                                                    荐

但在2020年,Kubernetdockeres突然宣布在1linux常用命令.20版本以后,也就是2021年以后,不linux操作系统基础知识再支持Docker作为默认的容器运行时,将在代码主干中去除dockershim。

认识容器,我们从它的历史开始聊起
                                                原
                                                    荐

如图所示,K8s自身定义了标准的容器运行时接口CRI(Container Runtime Interface),目的是能对接任何实现了CRI接口的容器运行时。在初期,Docker是容器运行时不容置疑的王者,K8s便内置了对Docker的支持docker是干什么的,通过dockersdocker安装部署him来实现标准CRI接口到Docker接口的适配,以此获得更多的用户。随着开源的容器运行时Containerd(实现了CRI接口,同样由docker是干什么的Docker捐给CNCF)的成熟,K8s不再维护dockdocker怎么读ershim,仅负责维护标准的CRI,解除与某特定容器运行时的绑定。当然,也不是K8s不支持Docker了,只是dodockerhubckershim谁维护的问题。 随着K8s态度的变化,预计将会有越来docker是干什么的越多linux命令的开发者选择直接与开源的Colinux常用命令ntlinuxainerlinux必学的60个命令d对接,Docker公司和Docker开源项目(现已改名为moby)未来将会发生什么样的变化,谁也说不好。

认识容器,我们从它的历史开始聊起
                                                原
                                                    荐

讲到这里,不知道大家有没有注意到,Docker公司其实是捐献了Containerd和runC。这俩到底是啥东西。简单的说,runC是OCI标准的实现,也叫OCI运行时,是真正负责操作容器的。Containdocker容器erd对外提dockerfile供接口,管理、控制着runC。所以上面的图,真正应该长这样。

认识容器,我们从它的历史开始聊起
                                                原
                                                    荐

Docker公司是一个典型的小公司因linux创建文件一个爆款项目火起来的案例,不管是技术层面、公司经营层面以及如何跟大厂缠斗,不管是好的方面还是坏的方面,都值得我们去学习和了解其背后的故事。

什么是容器

按国际惯例,在linux介绍一个新概念的时候,都得从大家熟悉的东西说起。幸好容器这个概念还算好理docker是干什么的解,喝水的杯子,洗脚的桶docker,养鱼的缸都是容器。容器技术里面的“容器”也是类似linux操作系统基础知识概念,只是装的东西不同罢了,他装的是应用软件本身以及软件运行起来需要的linux系统安装依赖。用鱼缸来类比,鱼缸这个容器里面装的应用软件就是鱼,装的依赖就是鱼食和水。这样大家就能理解docker的logo了。大海就是宿主机,dodocker怎么读cker就是那条鲸鱼,鲸鱼背上的集装箱就是容器,我们的应用程序就装在集装箱里面。

认识容器,我们从它的历史开始聊起
                                                原
                                                    荐

在讲容器的时候一定绕不开容器镜像,这里先简单的把容器镜像理解为是一个压缩包。压缩包里包含应用的可执行docker是干什么的程序以及程序依赖的文件(例如:配置文件和需要调用的动态库等),接下来通过实际操作来看看容器到底是个啥。

一、宿主机视角看容器:

1、首先,我们启动容器。

docker run -d -linux-name=linux是什么操作系统"aimarlinux创建文件-1-container" euleros_arm:2.0SP8SPC306 /bin/sh -c "while tlinuxrue; do echo aimar-1-container; sleep 1; done"linux系统安装

这是Docker的标准命令。意思是使用euleros_arm:2.0SP8SPC306镜像(镜像名:版本号)创建一个新的名字为"aimar-1-container"的容器,并在容器中执行shell命令:每秒打印docker安装部署一次“aimar-1-container”。

  • 参数说明:

-d:使docker和虚拟机的区别用后台运行模式启动容器,并返回容器ID。docker面试题及答案
--name:为容器指定一个名字。

docker run -d --name="aimar-1-container" elinux创建文件uleros_arm:2.0SP8SPC306 /binlinux/sh -c "whdocker和虚拟机的区别ile true; do echo aimar-1-container; sleep 1; done"
207b7c0cbd811791f7006cd56e17033eb430ec656f05b6cd172c77cf45ad093cdocker容器

从输出中,我们看到一串长字符207b7c0cbd811791f7006cd56e17033eb430ec656f05b6cdlinux创建文件172c77cf45ad093c。他就是容器ID,能唯一标识一个容器。当然在使用的时候,不需要使用全id,直接使用缩写id即可(全id的前几位)。例如下图中,通过docker ps查询到的容器id为207b7c0cbd81

认识容器,我们从它的历史开始聊起
                                                原
                                                    荐

aimar-1-container容器启动成功后,我们在宿主机上使用ps进行查看。这时可以发现刚才启动的容器就是个进程,PID为12280。

认识容器,我们从它的历史开始聊起
                                                原
                                                    荐

我们尝试着再启动2个容器,并再次在宿主机进行查看,你会发现又新增了2个进程,PID分别为20049和21097。

认识容器,我们从它的历史开始聊起
                                                原
                                                    荐

所以,我们可以得到一个结论。从宿主机的视角看,容器就是进程

2、接下来,我们进入这个容器。

docker exec -it 207b7c0cbd81 /bindockerhub/bash

docker exec也是Dlinux必学的60个命令ocker的标准命令,用于进入某个容器。意思是进入容器id为207b7c0cbd81的容器,进入后执行/bin/bash命令,开启命令交互。

  • 参数说明:

-it其实是-i和-t两个参数,意思是容器启动后,要分配一个输入/输出终端,方便我们docker怎么读跟容器进行交互,实现跟容器的“对话”linux是什么操作系统能力。

认识容器,我们从它的历史开始聊起
                                                原
                                                    荐

从hostname从kwephispra09909变化为207b7c0cbd81,说明我们已经进入到容器里面了。在容器中,我们尝试着启动一个新的进程。

[root@207b7c0cbd81 /]# /bin/sh -c "while true; do echo aimar-1-container-embed; sleep 1; done" &

认识容器,我们从它的历史开始聊起
                                                原
                                                    荐

再次回到宿主机进linux命令行ps查看,你会发现不管是直接启动容器,还是在容器中启动新的进程,从宿主dockerfile机的角度看,他们都是进程

二、容器视角看容器:

前面我们已经进入容器里面,并启动了新的进程。但是我们并没有在容器里查看进程的情况。在容器中执行pslinux重启命令,会发现得到的结果和宿主机上执行ps的结果完全不linux常用命令一样。下图是容器中dockerfile的执行结果。

在Container1容器中只能看见刚起docker面试题及答案启动的shell进程(cdocker安装部署ontaindocker常用命令er1和conlinux创建文件tainer1-embed),看不到宿主机上的其他进程,也看不到Container2和linux创建文件Container3里面的进程。这些进程像被关进了一个盒子里面,完全感知不到外界,甚至认为我们执行的container1是1号进程(1号进程也叫init进程,是系统中所有其他用户进程的祖先进程)。所以,从容器的视角,容器觉得“我就是天,我就是地,欢迎来到我的世界”

但尴尬docker容器的是,在宿主机上,他们docker菜鸟教程却是普通得不能再普通的进程。注意linux系统安装,相同的进程,在容器里看到的进程ID和在宿主机上linux系统安装看到的进程ID是不一样的。容器中的进程ID分别是1和docker1859,宿主机上对应的进程ID分别是12280和9775(见上图)。

三、总结

通过上面的实验,对容器的定义就需要再加上一个定语。容器就是进程=>容器是与系统其他linux部分隔离开的进程。这个时docker候我们再看下图就更容易理解,容器是跑在宿主机OS(虚机容器的宿主机OS就是Gdockeruest OS)上的进程,容器间以及容器和宿主机间存在隔离性,例如:进程号的隔离。

在容器内和宿主机上,同一个进程的进程ID不同。例如:Container1在容器内PIDdocker是干什么的是1,在宿主机上是12280。那么该进程真正的PID是什么呢?当然是12280!那为什么会造成在docker怎么读容器内看到的PID是1呢,造成这种幻象的,正是Linux Namespadocker怎么读ce。

Linux Namespalinux系统ce是Linux内核用来隔离资源的方式。linux必学的60个命令每个Namespace下的资源对于其他Namespace都是不透明,不可见的。

Namespace按隔离的资源进行分类:

前面提到的容器内外,看到的进程ID不同,正是使用了PID Namespace。那么这个Namespace在哪呢?在Linux上一linux系统安装切皆文件。是的,这个Namespacdocker常用命令e就在文件里。在宿主机上的proc文件中(/proc/进程号/ns)变记docker怎么读录了某个进程对应的Namespace信息。如下图,其中的数字(例如:pid:[ 4026534312])则linux必学的60个命令docker和虚拟机的区别示一个Namespace。

对于Container1、Container2、Container3这3个容器,我们可以看到docker,他们的PID Namespace是linux系统不一样的。说明他们3个容器中的PID相互隔离,也就是说,这3个容器里面可以同时拥有PID号相同的进程,例如:都有PID=1的进程。

在一个命名空docker面试题及答案间中,那这俩进程就相互可见,只是PID与docker宿主机上看到的不同而已。

至此,我们可以对容器的定义再细linux是什么操作系统化一层。容器是与系统其他部分隔离开的进程=》容器是使用Linux Ndockerhubamespace实现与系统其他部分隔离开的进程