# Docker

# Docker和虚拟机

两者架构对比

图片名称

左边是传统虚拟机的架构,右图是docker的架构

  • docker有比虚拟机更少的抽象层,docker不需要hypervisor对硬件资源虚拟化,运行在docker伤的容器直接使用实际物理机的硬件资源,因此在cpu、内存利用率上更有优势
  • docker利用宿主机的内核,而不需要guest os,因此,当创建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核,因而避免了引寻、加载操作系统内核这些过程。docker直接利用宿主机的操作系统,省略了整个过程,因此新建一个docker只需要几秒钟
docker 虚拟机
操作系统 与宿主机共享OS 宿主机上运行虚拟OS
存储大小 镜像小,便于存储 镜像庞大(vmdl、vdi等)
运行性能 几乎无额外性能损失 操作系统额外cpu、内存消耗
移植性 轻便、灵活 笨重
硬件亲和性 面向软件开发 面向硬件运维

# Docker镜像原理

# docker镜像是什么

镜像是一种轻量级、可执行的独立软件包,用来打包运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件

# UnionFS(联合文件系统)

unionFs是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像

特性:一次加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样的文件系统会包含所有底层的文件和目录

# docker镜像加载原理

docker镜像实际上是一层一层文件系统组成,这种层级文件系统称为unionFs

图片名称

bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,linux刚启动时会加载bootfs文件系统,在docker镜像的最底层是bootfs,这一层与典型的linux/unix系统一样,包含boot加载器和内核。当boot加载完成后整个内核就在内存中了,此时内存使用权已经由bootfs转交给内核,此时系统也会卸载bootfs

rootfs,在bootfs之上,包含的就是典型linux系统中的/dev、/proc、/bin、/etc等标准目录和文件。rootfs就是各种不同的操作系统的发行版,比如ubuntu、centos等

刚开始加载第一个镜像的时候会运行一个公共的bootfs,然后加载kernel,当boot加载完后,整个kernel就存在内存中了,此时的使用权交给内核,系统也会卸载bootfs,之后根据操作系统加载roofs

之后再一层一层往上叠加,比如要构建一个tomcat的镜像,就在centos基础上再叠加一个jdk,然后再叠加一个tomcat,它们一起放在一个箱子里,成为一个container

图片名称

这种方式最大的好处就是共享资源

比如,当多个镜像都从相同的base镜像构建而来,那么宿主机只需要在一个磁盘上保存一份base镜像,同时内存中也只需要加载一份base镜像,就可以为所有的容器服务了,而且镜像的每一层都可以被共享

# 容器数据卷

docker的理念:

  • 将运用与运行的环境打包成容器运行,运行可以伴随着容器,但是我们对数据的要求希望是持久化的
  • 容器之间希望有可能共享数据

Docker容器产生新的数据,如果不通过docker commit产生新的镜像,使得数据作为镜像的一部分保存下来,那么当容器删除后,数据自然也就是没有了

为了能保存数据在docker中,我们使用数据卷

# 能干嘛

  • 容器间的继承、数据共享
  • 数据的持久化

# 数据卷

容器内添加两种方法

  1. 直接命令添加
  2. DockerFile添加

运行的时候,添加容器卷,连接两个文件夹,实现两个文件夹共享数据

docker run -it -v 主机文件夹:容器内文件夹 imagename

# 数据卷容器

命名的容器挂载数据卷,其他容器通过挂载这个父容器实现数据共享,挂载数据卷的容器,称之为数据卷容器

实际上就是移动硬盘上挂载移动硬盘,实现数据的传递和共享(硬盘1插在主机上,实现硬盘和主机的共享,之后又有很多硬盘2、硬盘3...插到硬盘1上,实现各个硬盘之间的数据传递)

# 示例

  • 新建一个dc01,里面有两个卷,并在里面新建一个文件
docker run -it --name dc01 imagename
  • 新建一个卷dc02继承dc01,可以看到dc02中的卷继承了dc01
docker run -it --name dc02 --volume-from dc01 yxlian/centos

无论配置多少个,无论有没有被杀死的(无论是不是父容器被杀死),这些容器之间数据都是共享的