下载镜像
安装好docker后我们就可以开始通俗意义上的跑docker了,先下一个centos的镜像。
下载前先看看有没有我们要下的镜像
docker search centos
下载最近更新的镜像
为了区分同一镜像的不同版本更新,我们下载镜像时一般要加上tag,如果不加就默认下载最新版
docker pull centos:latest
查看我们已有的镜像
docker images
镜像不想要了也可以删除
docker rmi centos
镜像分层
docker的镜像就像盖房子一样,我们可以直接拿下载好的镜像来住,也可以把下载的镜像作为地基加上我们自己的配置。也就是说,我们可以在基础镜像之上,一层一层的增加新的功能,最后建起我们自己的高楼大厦,这种结构就叫做分层结构。
分层结构具有很多优势:
- 共享资源
如果我们有多个镜像都是从一个基础镜像中构建得来,那么docker宿主机上只需保存一份基础镜像的文件,内存中也只需加载一份基础镜像,所有容器就都可以使用了,并且镜像的每一层都可以被共享 - 容器层可写
但一个容器启动时,就有一个新的可写层被加载到镜像的顶部,这一层被称作容器层,这一层以下的都叫做镜像层
镜像之中只有容器层可写,镜像层全都是只读的 - copy on write
镜像层数量可能会很多,所有镜像层叠加起来组成一个文件系统,也就是说上层的文件会覆盖住下层的文件
创建一个新文件自不用说,新文件会被创建到此时的容器层中
读取文件时docker会从上往下依次在各镜像层中查找此文件,找到后打开并存入内存
删除文件时docker也是查找此文件,找到后在容器层记录下删除操作
只有在修改文件时,docker会将原文件复制到容器层然后修改。
可见,容器层保存的是镜像的变化,而不是变化后的镜像
创建镜像
了解了镜像机制后我们就可以来创建自己的镜像了
创建镜像有三种方法,分别是:
- 基于修改后的容器
- 基于本地模板
- 基于dockerfile
基于修改后的容器
以我们刚才下载的centos镜像为例
运行一个容器
docker run -it centos:latest /bin/bash
在这个容器中做出一些修改
退出后查看刚才的容器得到它的id
docker ps --all
以此生成新镜像
docker commit 4d484ee4557d centos_1
以这个新镜像来创建容器
docker run -it centos_1:latest /bin/bash
看到了刚才所做的修改
基于本地模板
将镜像保存为本地文件
docker save -o centos.tar centos:latest
ll -h
-rw------- 1 root root 217M 10月 22 14:03 centos.tar
现在我们可以把这个文件发送给其他人,其他人可以将这个景象导入到本地
docker load --input centos.tar
基于Dockerfile
Dockerfile是一个用以配置image的文本文件,其中记录镜像构建的所有步骤。docker会根据Dockerfile文件生成二进制的image。
还是用刚才的例子
编辑一个Dockerfile文件
cat > Dockerflie <<EOF
FROM centos:latest
MAINTAINER freedom
RUN yum -y install vim
EOF
以Dockerfile文件来创建镜像
docker build -t centos_vim
关于Dockerfile文件的编辑有很多格式的要求
FROM 指定基础镜像和其版本,必须是第一条指令,如果不以任何镜像为基础,写法为:
FROM scratch 接下来的指令将作为镜像的第一层
MAINTAINER 镜像作者,后面可以是任意字符串
RUN 运行指定的指令,有两种写法
RUN <command> shell格式,后边直接跟shell命令
RUN ["executable", "param1", "param2"] exec格式,前面是可执行文件,后面是参数
注意,多行命令不要写多个RUN,每一个指令会建立一层镜像,无用的层多了会使镜像臃肿,减慢部署速度。换行符使用\
CMD 容器启动时要执行的命令,后面也是跟shell命令
当一个Dockerfile文件里出现多个CMD指令时,只有最后一个会生效
RUN和CMD的区别主要有:
RUN是构件容器时就运行的命令以及提交运行结果
CMD是容器启动时执行的命令,在构件时并不运行,构件时仅仅指定了这个命令到底是个什么样子
COPY 复制文件到镜像
COPY只能复制与Dockerfile在同一目录下的文件,因此不需要绝对路径
ADD 与CPOY类似,但是会自动解压归档文件
ENV 设置环境变量,可以被后面的命令使用
EXPOSE 指定容器监听某个端口,docker会将该端口暴露出来
VOLUME 将文件或目录声明为卷
WORKDIR 设置镜像中的当前工作目录
ENTRYPOINT 设置容器启动时运行的命令,可以让容器以应用程序或服务的形式运行