上篇我们说到了容器的基本概念,在最后也有提到两篇非常优秀的关于容器技术的文章。
现在我们来对容器技术的框架做个总结:

可以看到,docker 处于容器技术整个框架中的运行引擎层,是其中的一个环节。我们今天就来学习容器系统中位于运行引擎层中的 docker 以及 Dockerfile 的语法糖。
Docker使用 Google 公司推出的 Go语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。
Docker 包括三个基本概念,镜像、容器、仓库。上篇文章中我们提到过, 一个镜像相当于一个模版,一个容器就像是这个模版生成的具体的运行实例,而仓库就是存放镜像的地方。 所以镜像是 docker 中最重要的一步。接下来,我们来实际上手体验 docker。
一、安装 docker
官方文档中已经对各种环境中的安装步骤已经列举的很清楚了,安装过程中出现的一些问题,网上也可以找到对应的解决办法,我们这里就不再详细说明了,个人建议直接下载 docker desktop。安装成功后,国内从 Docker Hub 拉取镜像有时会遇到困难,不要忘记配置镜像加速。(贴心地放上官方文档)
安装好 docker 之后我们来验证一下是否安装成功:
- 验证 docker 是否安装成功:docker info
- 验证 docker 是否成功配置镜像加速:docker info | grep "Registry Mirrors" -A 5
二、docker 镜像常用命令
我们之前提到过,docker 的镜像可以存放在本地,也可以存放在远程仓库中。这种方式像极了我们熟悉的 git ,docker 的命令也和 git 相似,我们使用起来也更加的方便和熟悉。
我们用nignx镜像来上手体验下 docker 镜像常用的命令
- 首先我们来从仓库中拉取 nginx 最新版本的镜像
# 搜索 nginx 镜像
docker search nginx
# 拉取 nginx 最新版本镜像
docker image pull nignx:latest
- 下载到本地后,查看镜像信息
# 查看本地的镜像
docker images 或 docker image ls
# 查看某个镜像的信息
docker image ls nginx 或 docker images nginx
# 查看某个镜像的详细信息
docker image inspect nginx
- 现在我们把下载到本地的镜像保存起来,然后删除下载的镜像
# 将镜像保存在本地
docker image save -o my-nginx.tar nginx
# 删除下载的 nginx 镜像
docker image rm nginx (-f 强制删除参数)
- 将本地保存的镜像包导入到镜像中(删除完毕之后可以先用 2 去检测下是否删除成功)
# 将本地包导入到镜像中
docker load --input my-nginx.tar
经过对镜像一系列的操作,我们体验了 docker 镜像常用的命令,当然对于镜像的操作命令还有很多我们没有提及到,可以通过 docker image --help 来查看更全面的镜像操作指南。
三、docker 镜像的构建 - Dockerfile
Dockerfile 是一个文本文件,其内容包含了若干指令,用来描述如何生成一个镜像。Dockerfile 中的每句指令执行后,都会生成一个对应的镜像层,即使这个指令没有明显的修改文件,它对应的层也会存在,只不过在外界看来,这个层是空的。
常见的 Dockerfile 指令
-
FROM 基础镜像 (基础镜像是必须被指定的,若想要空白的基础镜像,则使用 FROM scratch )
-
RUN 执行命令
- RUN 命令 (像 Shell 脚本一样)
- RUN ["可执行文件", "参数1", "参数2"]
-
COPY 复制文件,参数可用来改变文件的所属用户及所属组
- COPY [--chown=:] <源路径>... <目标路径>
- COPY [--chown=:] ["<源路径1>",... "<目标路径>"]
-
ADD 更高级的复制文件
- ADD 指令会令镜像构建缓存失效,可能会令镜像构建变得比较慢
- 最适合使用 ADD 的场合,是需要自动解压缩的场合
- 当你在 COPY 和 ADD 中疑惑该选用哪个的时候,可以考虑想要做的操作是什么,需要自动解压缩则使用 ADD,其余的文件复制操作选用 COPY
-
EXPOSE 暴露端口,仅仅是声明容器用的端口号,而不是端口映射
-
ENV 设置环境变量
-
ARG 设置构建环境的环境变量
-
WORKDIR 指定工作目录,之后各层的当前目录
-
USER 指定当前用户
-
VOLUME 挂载数据卷
-
ENTRYPOINT 指定容器启动程序及参数
- 当不指定 ENTRYPOINT 时,Docker 默认的 ENTRYPOINT 为 sh -c
-
CMD 指定容器启动程序及参数
- CMD 的完整命令为 ENTRYPOINT CMD,所以实际的命令会被包装为 sh -c ,主进程实际上是 sh
- CMD 命令 (像 Shell 脚本一样)
- CMD ["可执行文件", "参数1", "参数2"]
附上官网的练手小例子
到这里为止,我们已经可以利用 Dockerfile 来创建属于我们自己的容器镜像了,也可以使用 docker image 的相关命令来操作创建的镜像。那容器镜像又是怎么实现的呢?
之前我们有提到过,可以把镜像看作是一个特殊的文件系统,这个文件系统中不会包含任何动态数据,也就是说当镜像生成后,镜像中的内容不会再做更改,很显然的 容器镜像一定是只读的。容器运行时所需要的所有文件集合、为容器提供隔离后执行环境的文件系统,就是容器镜像。 那容器镜像又是怎么设计和实现的呢?
下篇我们继续~