Docker详细介绍

一、前言

本文为学习Docker的笔记,本人学识浅薄,有错误之处还请指出。本文主要以概念总结为主,操作就不进行赘述,因为网络上写的好的前辈大有所在。

二、为什么会出现Docker

当一款产品需要从开发到上线,必须得经历开发+部署两个阶段,在这两者之间,我们不得不面对各种各样的问题,比如环境问题,版本迭代后环境的兼容问题。相信有开发经验的小伙伴都能经过要把在windows上的开发好的应用转移到Linux环境下繁琐的步骤。比如一个项目需要MySQL、redis、Tomcat、JDK等等。
就在这个时候docker就出现了,它的出现让运维变得简单起来。试想一下如果我们开发好一个应用,该应用的环境也已经部署好了,我们对应用进行打包,不单单只是代码,而是应用+环境一同打包,当你下载即可运行,运行环境也是配好的,因为我们是一同打包好的。这是一件多么美好的事,而Docker所做的就是这样的事,所谓打好的包,在Docker里称为镜像。接下来我们将继续讨论镜像、容器等概念。

三、什么是Docker

引用百度百科的一段话:

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。

相信大家都使用过虚拟机,当我们使用虚拟机虚拟一个Linux系统时,它需要这一整个系统所有必须的应用、二进制文件和库,大家仔细观察我们所使用的iso文件发现它往往有好几G的大小。
大家可以把Docker想象成一个运行在主机的一个虚拟机,但是它更为轻量级。因为Docker是一种容器,它和我们的宿主机共享硬件资源及操作系统,可以实现资源的动态分配。
当你使用Docker pull一个centos的镜像时,会发现它才200M左右的大小,原因就是它和我们的宿主机共享硬件资源及操作系统。下面是容器和虚拟机比较的图片:

Docker详细介绍
Docker详细介绍
这两张图我们还会继续用到,在这里我们可以清楚得看到Docker的构造,对都docker是什么有了一个比较直观的了解,往下讨论我们将继续更加详细地了解Docker。

三、Docker所使用的容器虚拟技术与虚拟机技术的不同

回到上面的两张图。我们可以看出,docker所使用的容器虚拟技术是基于应用程序层的抽象,将代码和依赖项打包在一起。多个容器可以在同一台计算机上运行,并与其他容器共享操作系统内核,每个容器在用户空间中作为独立进程运行。容器占用的空间小于虚拟机(容器映像的大小通常为数十MB),可以处理更多的应用程序,需要的虚拟机和操作系统更少。
而虚拟机技术是将一台机器器转变为多台机器的物理硬件的抽象。管理程序允许多个虚拟机在一台机器上运行。每个虚拟机都包含一个操作系统、应用程序、必要的二进制文件和库的完整副本,占用了数十个GB。虚拟机的启动速度也很慢。
在Docker引擎上运行的Docker容器的优点:
标准:Docker为容器创建了行业标准,因此它们可以在任何地方进行移植。
轻量级:容器共享机器的操作系统内核,因此每个应用程序不需要操作系统,从而提高服务器效率,降低服务器和许可成本。
安全:应用程序在容器中更安全,Docker提供业界最强的默认隔离功能

四、Docker的镜像、容器、仓库

  1. Image(镜像)
    镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。换言之,如果你有了一个项目的镜像,那么你就有了这个项目的代码,以及运行环境,你只需要通过实例一个容器,即可轻松运行该项目。
    另外,镜像只是可读的,它在被创建之后就不会被改变内容,并且它是多层的,对外暴露只有一层包装在外面的可读层,这里涉及到统一文件系统(Union File System)技术,之后会再讨论它。
    Docker镜像分为基础镜像和父镜像,没有父镜像的镜像被称为基础镜像。用户是基于基础镜像来制作各种不同的应用镜像。这些应用镜像共享同一个基础镜像层,提高了存储效率。
    大可把镜像想象成一个春卷,一层一层地把所需要的东西包装起来,最后面对给用户的就是一个可读层。这个可以pull一个tomcat看看,会发现有几百M大小,这就是因为它里面一层层地包装了起来,想知道里面有什么,就去看它的DockerFile,DockerFile也是非常重要的一部分,我们还会讨论到它。
  2. Container(容器)
    容器就是在镜像之上加了一个可读可写层,意味着你可以运行镜像了,但是如何进行操作都不会影响到镜像,并且,你可以对同一个镜像进行实例,运行多个来自同一个镜像的容器,并且相互之间不影响。
    打个比方,用熟悉的Java来说,镜像就是一个person类,然后我们可以实例化多个Person对象,这些对象就是容器
Person p1 = new Person() ;
Person p2 = new Person() ;
.......
p1.do();
p2.do() ;//互不影响

Docker服务端负责构建、运行和分发 Docker 镜像。 3. Repository(仓库)
Docker的仓库类就是存放镜像的地方。仓库又分为Public(公有仓库)、Private(私有仓库) 。
公有仓库开放给所有用户的,可以在上面pull各种镜像,也可以push自己的镜像。
私有仓库则是自己构建的私人的Docker Registry,不公开,自给自己用。
当你试图从Docker客户端拉取一个镜像的时候,Docker服务端(Host)会负责构建、运行和分发 Docker 镜像。当找不到需要的镜像,服务端就会去中央仓库或者私人仓库拉取(如果你有搭建的话)。往往客户端和服务端是安装在本地的,当然服务端也可以在远程。

五、统一文件系统(Union File System)技术

该部分前大家移步Docker联合文件系统Union File System 这篇文章,只要理解这篇文章不管是对Union File System有了了解,还是对上面所说的镜像和容器都会有更加深入的了解。

六、DockerFile

Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。它们简化了从头到尾的流程并极大的简化了部署工作。Dockerfile从FROM命令开始,紧接着跟随者各种方法,命令和参数。其产出为一个新的可以用于创建容器的镜像。
往往你想知道一个镜像里面到底包了多少层,你看DockerFile就知道了,关于DockerFile的命令就不详细说,网上有很多详细的介绍。
我们可以自己构建一个自己定制的Tomcat为例来深入了解Docker镜像。

#基于centos镜像,因为我们tomcat运行需要一个系统呀
FROM   centos
#作者信息
MAINTAINER   yong<[email protected]>
#把java与tomcat添加到容器中,/usr/local是我们镜像centos的目录,tar包放在和DockerFile相同的目录
ADD jdk-8u201-linux-x64.tar.gz  /usr/local/
ADD apache-tomcat-8.5.39.tar.gz /usr/local/
#给镜像的centos安装一个vim编辑器
RUN yum -y install vim
#设置工作访问时候的WORKDIR路径,登录落脚点
ENV MYPATH  /usr/local
WORKDIR  $MYPATH
#配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_201
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.39
ENV CATALINA_BASE /usr/local/apache-tomcat-8.5.39
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE  8080
#启动时运行tomcat
CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out

只要执行对我们的DockerFile执行build命令即可获得一个我们自己订制的Tomcat。是不是十分方便,如果我们有一个项目,我们其实只需要编写好DockerFile文件就好了,Docker就会一层一层得包装好。以上面为例,它会在拿到centos镜像(当然我们本地是有centos镜像的)包一层,然后一条语句一层,这样下去。直到最后一句结束,这样本地就有了一个我们自己的镜像。