zl程序教程

您现在的位置是:首页 >  大数据

当前栏目

虚拟化及云计算硬核技术内幕 (33) —— 你说的这个朋友是不是你自己

计算 自己 这个 虚拟化 内幕 是不是 33 朋友
2023-06-13 09:12:15 时间

上回说到,方老师有一个朋友,写招聘JD不小心把“售前产品经理”打错成“收钱产潘金莲”,而且发出去了。

那么,这种情况在方老师这里是有可能出现的吗?

答案当然是不可能的。

因为,方老师使用的公司招聘系统有JD自动审核功能,如果有美女小姐姐在招聘JD中要求“仅限30岁以下男性,身体精壮”,这一类不瑞雪的招聘要求是会被计算机系统扼杀在摇篮中的。

当然,JD自动审核功能是通过所谓的AI技术,也就是神经网络算法,来识别不瑞雪的招聘要求的。进行神经网络训练方面的开发最常用的框架是tensorflow。为了提升tensorflow的部署速度,工程师们经常使用容器化部署tensorflow:

$ docker run -it -p 172.18.10.100:8888 gcr.io/tensorflow/tensorflow bash

以上的命令就可以在一个docker容器中,启动tensorflow的镜像了。

类似地,我们也可以从docker hub上的官方镜像,快速部署nginx,busybox等通用的应用。如运行这条命令:

docker run -d -p 80:80 --name webserver nginx

启动nginx后,就可以在浏览器上访问localhost:80, 看到nginx的测试页了。

关于docker命令的使用,请大家查阅docker官方网站的文档。

docker是怎么样实现快速地部署运行应用的呢?

原来,在大家运行docker run这条命令时,docker会做以下几个动作:

  1. 首先看本地是否有容器镜像;
  2. 如果本地没有容器镜像,则从互联网上的容器镜像库,或从其他地方的容器镜像库,通过http/https的方式拉取容器镜像;
  3. 解析获取到的容器镜像,在虚拟的文件系统(UnionFS)中,展开容器镜像的文件系统,并执行其中的可执行文件。执行时通过指定其namespace与其他进程隔离,使用单独的网络namespace和文件系统挂载namespace。

也就是说,在运用namespace技术隔离进程,并对进程使用cgroups限制资源配额后,还需要基于容器镜像构建unionfs,才能够运行起用于部署应用的容器实例。

让我们在毛主席在《实践论》指出的“解剖麻雀”的方法论,以tomcat镜像为例,看一看容器镜像里面到底有什么。

容器镜像的结构如下图:

从图中可以看出,容器镜像是一个分层次的结构。

我们知道,Linux操作系统在安装完毕后,其文件系统会有一个/boot 路径,容器的bootfs层复用了Linux操作系统的/boot,仅仅是一个指向/boot的链接,从而避免传输和存储重复的数据;

在bootfs上的一层是rootfs。rootfs中有什么呢?

我们知道,一个Linux操作系统安装完毕后,会在根目录下有/dev, /proc, /bin, /etc, /root等一系列目录,存储Linux操作系统运行所必须的文件。rootfs就包含一组指向这些目录的链接。

我们如果在Linux物理机上部署tomcat,还需要在物理机上安装tomcat本身,以及运行JAVA程序(字节码)所依赖的JDK。这两层都会在rootfs之上,也就是基于rootfs的增量。

以上的bootfs,rootfs,JDK和tomcat这几层,就构成了Tomcat容器镜像的只读层(read only layer)。

容器镜像的最上层为可读写层。容器中执行的程序对unionfs做的任何修改,都会被暂时保存在可读写层中。举一个栗子:

如容器中执行的程序去修改了 /root/bash.rc 文件,docker会将写行为记录在可读写层中。如果没有为容器挂载持久化存储,当容器销毁时,写的行为将被视为没有发生过。

容器存储相关的机制,我们在《云存储硬核技术内幕》系列中阐述过,感兴趣的同学可以直接访问。

回到开头的故事,我们可以通过docker run命令来快速拉起一个容器化的应用实例,那么,如果我们需要批量拉起容器应用实例,或在每个宿主机上都运行一个容器,我们需要手工输入命令,或者自行编写脚本来实现吗?

下期我们将为大家解开谜底。