问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Docker技术系列文章,第二篇——深入理解 Docker 镜像

创作时间:
作者:
@小白创作中心

Docker技术系列文章,第二篇——深入理解 Docker 镜像

引用
CSDN
1.
https://blog.csdn.net/qq_58611691/article/details/146419430

在 Docker 的生态系统中,镜像是构建和运行容器的基石。深入理解 Docker 镜像的工作原理、构建方式以及管理方法,对于高效使用 Docker 进行应用开发和部署至关重要。本文将带你深入探索 Docker 镜像的奥秘。

Docker 镜像分层机制

什么是镜像分层

Docker 镜像采用分层存储的架构。简单来说,一个镜像由多个只读层叠加而成。当我们创建一个容器时,Docker 会在镜像的最上层添加一个可写层,所有对容器的修改(如创建文件、修改文件等)都发生在这个可写层上。

分层机制的优势

  • 共享资源:多个镜像可以共享相同的基础层。例如,多个基于 Ubuntu 的镜像可以共享 Ubuntu 基础镜像的层,这大大节省了磁盘空间。
  • 提高构建效率:当我们构建一个新的镜像时,如果只对某一层进行了修改,Docker 只需要更新这一层,而不需要重新构建整个镜像。

实例说明

下面通过一个简单的例子来展示镜像分层。我们以一个基于 Ubuntu 的镜像为例,假设这个镜像有三层:

  • 第一层:包含基本的操作系统文件,如内核文件、启动脚本等。
  • 第二层:安装了一些常用的软件包,如vim、curl等。
  • 第三层:配置了一些环境变量和应用程序的初始化脚本。

当我们基于这个镜像创建一个容器时,Docker 会在这三层之上添加一个可写层。如果我们在容器中创建一个新文件,这个文件就会被存储在可写层中。如果我们修改了第二层中的某个文件,Docker 会将修改后的文件复制到可写层中,而不会直接修改原来的只读层。

我们可以通过docker image history命令查看镜像的分层历史。例如,对于ubuntu镜像:

docker image history ubuntu

输出结果类似如下:

这里每一行代表一个镜像层,CREATED BY字段显示了创建该层时执行的命令,SIZE字段显示了该层的大小。

构建自定义镜像

Dockerfile 介绍

Dockerfile 是一个文本文件,其中包含了一系列指令,用于自动化构建镜像。通过编写 Dockerfile,我们可以精确地定义镜像的内容和配置。

Dockerfile 基本语法

  • FROM:指定基础镜像。例如:

    FROM ubuntu:latest
    

    这行指令表示我们的自定义镜像将基于最新版本的 Ubuntu 镜像构建。

  • RUN:在镜像构建过程中执行命令。例如:

    RUN apt-get update && apt-get install -y vim curl
    

    这行指令会在基础镜像上更新软件包索引,并安装vim和curl软件包。注意,这里使用了&&符号,确保只有在apt-get update成功执行后才会执行apt-get install

  • WORKDIR:设置工作目录。例如:

    WORKDIR /app
    

    这行指令将在镜像中创建一个/app目录,并将其设置为工作目录。后续的指令(如COPY、RUN等)如果没有指定绝对路径,将在这个工作目录下执行。

  • COPY:将本地文件复制到镜像中。例如:

    COPY . /app
    

    这行指令会将当前目录下的所有文件(.表示当前目录)复制到镜像的/app目录中。

  • CMD:指定容器启动时要执行的命令。例如:

    CMD ["python", "app.py"]
    

    这行指令表示当基于这个镜像创建的容器启动时,会执行python app.py命令。注意,CMD指令只能在 Dockerfile 中出现一次,如果出现多次,只有最后一次有效。

构建镜像示例

假设我们有一个简单的 Python Flask 应用,目录结构如下:

myapp/
├── app.py
├── requirements.txt
└── templates/
    └── index.html

其中,app.py是应用的主程序,requirements.txt列出了应用所需的依赖包,templates目录包含了 HTML 模板文件。

我们可以编写如下的 Dockerfile 来构建这个应用的镜像:

FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]

在上述 Dockerfile 中:

  • 第一行指定了基础镜像是 Python 3.9 的精简版镜像。
  • 接着设置了工作目录为 /app
  • 然后将 requirements.txt 文件复制到工作目录,并使用 pip 安装依赖包。
  • 再将整个应用目录复制到工作目录。
  • 之后通过 EXPOSE 指令声明容器将在 5000 端口上提供服务。
  • 最后指定容器启动时执行 python app.py 命令来运行 Flask 应用。

编写好 Dockerfile 后,我们可以在包含 Dockerfile 的目录下执行以下命令来构建镜像:

docker build -t myapp:latest .

这里 -t 选项用于指定镜像的标签,格式为 [仓库名]:[标签名]myapp 是仓库名,latest 是标签名,. 表示当前目录,即 Dockerfile 所在的目录。

构建过程中,Docker 会按照 Dockerfile 中的指令依次执行,输出构建日志。当构建完成后,我们可以通过 docker images 命令查看新构建的镜像:

docker images

输出结果中应该会看到 myapp:latest 镜像。

镜像管理

镜像标签

镜像标签用于标识镜像的版本和用途。我们可以使用 docker tag 命令为镜像添加标签。例如,将 myapp:latest 镜像标记为 myapp:v1.0

docker tag myapp:latest myapp:v1.0

这样我们就可以通过不同的标签来管理同一个镜像的不同版本。

推送镜像至仓库

当我们构建好镜像后,可以将其推送到镜像仓库中,以便在其他环境中使用。Docker 官方提供了 Docker Hub 作为公共的镜像仓库,同时我们也可以搭建自己的私有镜像仓库。

要将镜像推送到 Docker Hub,首先需要登录到 Docker Hub:

docker login

输入你的 Docker Hub 账号和密码后,登录成功。然后使用 docker push 命令推送镜像。例如,推送 myapp:latest 镜像:

docker push myapp:latest

如果你的镜像仓库地址不是 Docker Hub,需要在镜像标签中指定完整的仓库地址。例如,将镜像推送到私有仓库 myregistry.com

docker tag myapp:latest myregistry.com/myapp:latest
docker push myregistry.com/myapp:latest

拉取镜像

从镜像仓库拉取镜像的命令是 docker pull。例如,拉取 myapp:latest 镜像:

docker pull myapp:latest

如果镜像仓库需要认证,在拉取之前需要先登录。

以上就是本文的内容了,大体上对 Docker 镜像分层机制、自定义镜像构建以及镜像管理进行了初步的介绍。希望各位读者继续加油,学无止境!

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号