最近3天用零散时间借助官网和一些简单教程资料学习了一下docker,稍微谈一下自己的认识和理解。
Docker与虚拟机区别的理解
很多初学人会很难区分docker和虚拟机的区别,因为用起来给人的感觉是一样的,都差不多,但实际上这两者从设计初衷就不一样。学过或者说了解过Linux内核的人都知道,docker是基于内核中的cgroup和namespace这两者对进程进行封装隔离,这是属于操作系统层面的虚拟化技术。之所以称之为容器,因为他是独立于宿主和其他的隔离的进程。传统虚拟机是虚拟出一套硬件后,在上面运行一个完整的操作系统。相对于虚拟机来说,docker使用的是宿主机器的内核,没有虚拟硬件,虚拟机是使用的自己的内核。因此相比来说,这就体现出了docker的轻便指出,也就知道了为什么安装一个虚拟机需要十几个G,而一个docker容器运行起来只有简单的几百M。
引用网上的图例,这里我就不再画了:
虚拟机:
Docker
从图上可以看出,根本的区别在于,docker是用docker的守护进程(docker daemon)来管理容器里面所有的进程,对应的虚拟机的架构是对硬件层面的虚拟化。
镜像和容器的理解
这两者的区别也是在最初学习阶段比较难以区分理解的两个概念。
镜像
首先我们知道操作系统分为内核和用户空间。对于Linux而言,内核启动之后,会挂载root文件系统为其提供用户空间支持。那么一个docker镜像中都有什么,根据上面的我们已知docker是基于namespace来的,镜像中不含有内核,根据官方给出的文档,镜像相当于是一个root文件系统。比如官方给出的Ubuntu:16.04镜像中只有最小系统的root文件系统。
其实docker竟像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
容器
容器和镜像的关系可以用面向对象编程语言中的类和实例一样,类是静态的定义,实例是运行中的实体,放到这里理解,这个例子最合适不过了。容器实际上是进程,可以通过docker top+容器ID或者
docker inspect -f '{{.State.Pid}}' CONTAINERID也可以看得到,再就是通过docker exec进入到容器里面通过cgroup.procs文件。容器的进程与直接在宿主执行的进程不同,因为有自己独立命名空间。因此他有自己的文件系统、网络配置、进程空间、自己的用户ID空间。
以上就是最近学习docker的心得和自己的理解,如有错误还请指正。
参考: