镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件
UnionFS(联合文件系统):Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,Union文件系统是Dokcer镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统加载起来,这样最终的文件系统会包含所有的底层文件和目录
docker的镜像实际上是由一层一层的文件系统构成,这种层级的文件系统UnionFS。
主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的linux/unix系统是一样的,包含boot加载器内核。当boot加载完之后整个内核就都在内存中了,此时内存的使用权已经由bootfs交给内核了,此时系统也会卸载bootfs
平时我们安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M。
对以一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就行,因为底层直接用host和kernel,自己只需要提供rootfs就行。由此可见对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。
以pull为例,在下载的过程中我么可以看到docker的镜像好像是在一层一层的下载
最大一个好处就是——共享资源
比如:有多个镜像都从相同的base镜像构建而来,那么宿主机只需要在磁盘上保存一份base镜像,同时内存中也需要加载一份base镜像,就可以为所有服务器服务了。而且镜像的每一层都可以被共享。
docker镜像都是只读的
当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层通常被称作“容器层”,“容器层”之下都叫“镜像层”
所有的docker镜像都源自于基础镜像层,当我们进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。举一个简单的例子,假如基于Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在新镜像中添加Python包,就会在基础镜像层上创建第二个镜像层;如果继续添加一个安全补丁,就会添加第三个镜像层。如下图:
从下图我们可以看到镜像的信息, 每个标签的含义如下:
标签含义REPOSITORY来自于哪个仓库,比如 ubuntuTAG镜像的标签,TAG 信息用来标记来自同一个仓库的不同镜像,例如 ubuntu 仓库中有多个镜像,通过 TAG 信息来区分发行版本,例如 10.04、12.04、12.10、13.04、14.04 等。IMAGE ID镜像的唯一id,如果镜像的id相同,说明它们实际上是同一镜像。CREATED镜像的创建时间SIZE镜像的大小命令可选项讲解:
参数描述-a, --all显示所有镜像 all可以简写成-a,也就是说 -a ,–all都能显示所有镜像-f, --filter根据所提供的条件过滤输出-q只显示镜像的id可选参数用法:
#显示所有镜像 docker images -a #显示所有镜像,但是只展示镜像id docker images -aq搜索结果如下: 每个标签的含义如下:
NAME #名称 DESCRIPTION #描述 STARS #相当于GitHub的STARS,表示受欢迎程度 OFFICIAL #是否为官方的 AUTOMATED #自动构建,表示该镜像由Docker Hub自动构建流程创建的可选项:
-f, --filter filter 根据所提供的条件过滤输出 #例如:搜索仓库中镜像中mysql STARS大于1000的 docker search mysql --filter=STARS=1000我们可以看到第二句: Using default tag: latest 不加参数,默认为下载最新版本
指定镜像版本下载:
docker pull mysql:5.7 运行效果: [root@iZwz94ro78u8c5qdlixltzZ /]# docker pull mysql:5.7 Trying to pull repository docker.io/library/mysql ... 5.7: Pulling from docker.io/library/mysql 8559a31e96f4: Already exists #共用文件,无需下载,节省资源,得益于docker联合文件系统 d51ce1c2e575: Already exists #共用文件,无需下载 c2344adc4858: Already exists #共用文件,无需下载 fcf3ceff18fc: Already exists #共用文件,无需下载 16da0c38dc5b: Already exists #共用文件,无需下载 b905d1797e97: Already exists #共用文件,无需下载 4b50d1c6b05c: Already exists #共用文件,无需下载 d85174a87144: Pull complete a4ad33703fa8: Pull complete f7a5433ce20d: Pull complete 3dcd2a278b4a: Pull complete Digest: sha256:32f9d9a069f7a735e28fd44ea944d53c61f990ba71460c5c183e610854ca4854 Status: Downloaded newer image for docker.io/mysql:5.7该版本需要在docker仓库中存在,点击传送仓库地址:
查看下载的镜像: mysql镜像下载成功~
例如根据名字删除镜像:
docker rmi 镜像名根据id删除:
#删除指定id的容器 docker rmi imageID #删除指定id的多个容器: docker rmi imageID imageID imageID已经全部删除:
我们有了镜像才能创建容器,接下来我们下载一个CentOS镜像来创建一个容器: 下载镜像:
docker pull centos效果如下:
接下来让我们使用命令试一下:
docker run -it centos /bin/bash #命令解释: docker run 启动 -it 进入容器,并以交互方式运行 centos 镜像名 /bin/bash 进入bash shell以实现交互我们会发现一个问题,应用在后台启动之后,我们通过docker ps查看正在运行的容器,发现没有正在运行的,也就是说,容器停止了.但是我们不是以后台的形式启动了一个吗? 原因: 1、docker容器运行必须有一个前台进程, 如果没有前台进程执行,那么容器会被认为空闲,就会自行退出 2、容器运行的命令如果不是那些一直挂起的命令( 运行top,tail、循环等),就是会自动退出 这种情况一般会发生在容器中没有服务的情况,如果容器中一直运行着tomcat,那么就不会出现这种情况了.
可选参数详解:
参数作用-a显示当前正在运行和曾经运行过的容器-n int显示最近创建的容器,int 为显示个数.-q只显示的id扩展:
docker ps -aq // 查看所有容器ID docker stop $(docker ps -aq) // stop停止所有容器 docker rm $(docker ps -aq) // remove删除所有容器 docker stop $(docker ps -q) & docker rm $(docker ps -aq) //一次性停止删除容器效果如下:
两者区别:
docker exec 进入容器之后,开启一个新的终端, docker attach 进入容器正在执行的终端.此处以tomcat举例: 首先我们下载一个tomcat镜像,
docker pull toncat启动tomcat
docker run -d -p 8080:8080 tomcat测试访问:
发现tomcat中什么都没有,404错误.
但是,我们知道,tomcat Windows版本或者linux版本,是有默认页面的,如下: 其实,docker中tomcat镜像也存在默认页面,我们打开镜像查看目录: 会发现一个名为:webapps.dist的文件夹,此处便是tomcat 的欢迎页在里面.我们将里所有的文件都拷贝到webapps中,重新访问:
发现欢迎页可以打开了,那我们怎么将我们修改过的tomcat制作一个镜像呢?
#容器成为一个新的镜像 docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[tag]查询是否成功:
docker images以后我们想保存容器的状态,可以通过commit来提交,保存为一个新的镜像
附:docker命令思维导图: