【云原生|Docker系列第3篇】Docker镜像的入门实践
欢迎来到Docker入门系列的第三篇博客!在前两篇博客中,我们已经了解了什么是Docker以及如何安装和配置它。本篇博客将重点介绍Docker镜像的概念,以及它们之间的关系。我们还将学习如何拉取、创建、管理和分享Docker镜像,这是使用Docker的重要步骤之一。
Docker镜像是Docker的核心概念之一,它提供了一个可执行的软件包,其中包含了运行应用程序所需的一切:代码、运行时环境、系统工具、库以及依赖项等。
通过学习Docker镜像的概念,您将能够更好地理解Docker的工作原理,并利用Docker提供的强大功能来开发、测试和部署应用程序。接下来,让我们深入探索Docker镜像的世界吧!
1. Docker镜像
Docker镜像是Docker的核心构建块,它是一个轻量级、可执行的软件包,用于构建和运行容器化应用程序。一个Docker镜像包含了运行应用程序所需的一切,包括应用程序的代码、运行时环境、系统工具、库以及依赖项等。
1.1 Docker镜像的特点
- 轻量级:Docker镜像采用了分层存储的机制,不同层之间可以共享相同的文件,从而减少了存储空间的占用。
- 可移植性:Docker镜像具有良好的可移植性,可以在不同的主机和环境中运行,无需关注底层操作系统的差异。
- 版本控制:每个Docker镜像都有唯一的标识符,称为镜像ID,可以用于对镜像进行版本控制和管理。
- 可复用性:可以通过基于已有的Docker镜像构建新的镜像,从而实现镜像的复用和扩展。
1.2 Docker镜像的获取
获取Docker镜像通常有两种方式:拉取公共镜像仓库中的镜像,或者通过构建自定义镜像来创建。
1.2.1 拉取镜像
Docker镜像可以从公共的镜像仓库中拉取,最著名的镜像仓库就是Docker Hub。您可以在Docker Hub上找到数以万计的官方和社区维护的Docker镜像。使用docker pull
命令可以拉取镜像,命令格式如下:
docker pull <镜像名称>:<标签>
例如,要拉取官方的Ubuntu镜像:
docker pull ubuntu:latest
1.2.2 使用Dockerfile构建镜像
1.3 Docker镜像的管理
在使用Docker时,我们可能需要对镜像进行管理,包括查看镜像列表、删除镜像、导出和导入镜像等操作。
1.3.1 查看镜像列表
要查看本地主机上已有的镜像列表,可以使用docker images
命令。该命令将显示镜像的仓库名称、标签、镜像ID、创建时间和大小等信息。
docker images ls
1.3.2 删除镜像
要删除本地主机上的一个或多个镜像,可以使用docker rmi
命令。需要指定要删除的镜像的镜像ID或者仓库名称和标签。
docker rmi <镜像ID或名称>:<标签>
1.3.3 导出和导入镜像
有时候,我们可能需要将一个镜像导出到一个文件中,或者从一个文件中导入一个镜像。可以使用docker save
命令将镜像导出到一个tar文件中,然后使用docker load
命令从tar文件中导入镜像。
导出镜像:
docker save -o <导出文件名.tar> <镜像名称>:<标签>
导入镜像:
docker load -i <导入文件名.tar>
2. 使用Dockerfile定制镜像
2.1 Dockerfile定制镜像
镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
以我们刚刚定制nginx镜像为例子,我们在一个空白目录中,建立一个文本文件,并命名为Dockerfile:
$ mkdir mynginx
$ cd mynginx
$ touch Dockerfile
其内容为:
FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
其中命令我们后面再详细讲述,我们使用它构建镜像,dockerfile构建镜像命令格式如下:
docker build -t <镜像名称>:<标签> <Dockerfile路径>
接下来您可以使用以下命令构建镜像:
docker build -t myimage:latest .
然后我们再运行这个镜像,你可以选择直接命令行运行,也可以直接在docker客户端运行,这里为了方便理解,我用docker客户端运行这个镜像:
随便填个端口:
打开网页访问这个端口:
2.2 Dockerfile指令
2.2.1 COPY 复制文件
格式如下:
COPY [--chown=<user>:<group>] <源路径>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置。比如:
COPY package.json /usr/src/app/
<源路径> 可以是多个,甚至可以是通配符,其通配符规则要满足 Go 的 filepath.Match 规则,如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
2.2.2 FROM 指定基础镜像
所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。就像我们之前运行了一个 nginx 镜像的容器,再进行修改一样,基础镜像是必须指定的。而 FROM 就是指定 基础镜像,因此一个 Dockerfile 中 FROM 是必备的指令,并且必须是第一条指令。
在 Docker Hub 上有非常多的高质量的官方镜像,有可以直接拿来使用的服务类的镜像,如 nginx、redis、mongo、mysql、httpd、php、tomcat 等;也有一些方便开发、构建、运行各种语言应用的镜像,如 node、openjdk、python、ruby、golang 等。可以在其中寻找一个最符合我们最终目标的镜像为基础镜像进行定制。
格式如下:
FROM <镜像名字>
如:
FROM nginx
2.2.3 RUN 执行命令
RUN 指令是用来执行命令行命令的。由于命令行的强大能力,RUN 指令在定制镜像时是最常用的指令之一。其格式有两种:
- shell 格式:RUN <命令>,就像直接在命令行中输入的命令一样。刚才写的 Dockerfile 中的 RUN 指令就是这种格式。
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
- exec 格式:RUN [“可执行文件”, “参数1”, “参数2”],这更像是函数调用中的格式。
2.2.4 ADD 更高级的复制文件
ADD 指令和 COPY 的格式和性质基本一致。但是在 COPY 基础上增加了一些功能。
比如 <源路径> 可以是一个 URL,这种情况下,Docker 引擎会试图去下载这个链接的文件放到 <目标路径> 去。下载后的文件权限自动设置为 600,如果这并不是想要的权限,那么还需要增加额外的一层 RUN 进行权限调整,另外,如果下载的是个压缩包,需要解压缩,也一样还需要额外的一层 RUN 指令进行解压缩。所以不如直接使用 RUN 指令,然后使用 wget 或者 curl 工具下载,处理权限、解压缩、然后清理无用文件更合理。因此,这个功能其实并不实用,而且不推荐使用。
例如:
FROM scratch
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
2.2.5 CMD 容器启动命令
指定容器启动时要执行的命令,可以有多个 CMD,但只有最后一个生效。
CMD ["python", "app.py"]
2.2.6 WORKDIR 设置工作目录
设置工作目录,后续的指令将在该目录下执行。
WORKDIR /app
2.2.7 EXPOSE 暴露端口
声明容器运行时需要监听的端口。
EXPOSE 80
2.2.8 ENV 设置环境变量。
ENV APP_VERSION=1.0
3. Docker镜像的分享和推送
Docker镜像的分享和推送是与团队合作和社区共享的重要环节。您可以将自己创建的镜像分享给其他开发者,也可以将镜像推送到公共的或私有的镜像仓库中。
3.1 分享Docker镜像
要分享一个Docker镜像,可以通过导出和导入的方式进行。首先,使用docker save
命令将镜像导出到一个tar文件中,然后通过邮件、文件共享等方式与其他人共享该文件。
docker save -o <导出文件名.tar> <镜像名称>:<标签>
接收方可以使用docker load
命令从tar文件中导入镜像。
docker load -i <导入文件名.tar>
3.2 推送Docker镜像
如果您希望将镜像推送到Docker Hub或其他镜像仓库中,可以使用docker push
命令。推送镜像之前,您需要先登录到镜像仓库。
docker login
然后,使用docker push
命令将镜像推送到仓库。
docker push <镜像名称>:<标签>
总结
在本篇博客中,我们深入探讨了Docker镜像的概念。我们学习了如何获取和管理Docker镜像,包括拉取镜像、构建自定义镜像以及导出和导入镜像。我们还介绍了如何通过Dockerfile制作镜像以及Dockerfile的指令。最后,我们了解了如何分享和推送Docker镜像,以便与他人共享和合作。
通过学习和掌握Docker镜像的基本概念,您将能够更好地利用Docker来开发、测试和部署应用程序。容器化技术的出现使得应用程序的开发和部署更加灵活、高效,并带来了诸多优势。在接下来的博客中,我们将继续探索Docker的更多功能和应用场景,下一篇文章我们会进入Docker容器的入门实践。
希望本篇博客对您理解Docker镜像起到了很好的指导作用。继续探索Docker的世界,您将发现更多令人兴奋的功能和应用!