目录
介绍
安装Docker
为什么是Docker?
层
Dockerfile
“最新的”不是最好的
不同平台上的进程隔离
使用数据运行容器
架构问题
概括
介绍Docker等容器技术显着简化了软件的依赖管理和可移植性。在本系列文章中,我们探讨了Docker在机器学习(ML)场景中的使用。在本文中,我们将介绍一些适用于ML应用程序的Docker基础知识。
本系列假设您熟悉ML、一般容器化,尤其是Docker。
安装DockerDocker可以在多个平台上运行,包括Intel/AMD处理器上的Windows和macOS Docker Desktop,以及Intel/AMD和ARM处理器上各种Linux发行版的Docker Server。您可以在Docker网站上找到适用于您的平台的综合安装指南。
为什么是Docker?Docker是一种轻量级技术,用于在隔离环境中打包和执行软件组件。这样的包称为“容器镜像”(或简称“镜像”),执行镜像代码的环境称为“容器”。
Docker技术确保完全隔离每个容器的Python和系统依赖项,这超出了虚拟环境所能提供的范围。同时,该技术允许跨运行时环境的最大可移植性。在许多情况下,同一个容器可以在本地工作站或服务器上运行,无论是在本地还是在云中。
为了更好地理解我们将在以下文章中做出的一些设计选择,值得花一些时间在Docker基础上。
层一个Docker镜像由许多只读层组成。每层仅包含当前层和前一层之间的差异。构建镜像时,只会刷新那些已更改的图层以及以下图层。这就是为什么以这样一种方式定义Docker层至关重要,即它们从最静态到最“动态”——最有可能改变。它可以大大减少构建镜像所需的时间。
层数也会影响镜像大小(和构建时间),因此建议使用单个RUN语句执行多个Linux命令(single RUN = single layer)。
DockerfileDockerfile定义了一个镜像。让我们考虑一个非常简单的例子:
FROM python:3.7-slim
RUN apt-get update & apt-get install python3-numpy
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY app /app
WORKDIR app
ENTRYPOINT ["python", "app.py"]
CMD ["--input", "1234"]
上述声明的含义如下:
- FROM以:格式定义基本镜像。如果这样的镜像在本地不可用,Docker将尝试从已知存储库(默认为https://hub.docker.com)中拉取它。
- RUN 执行Linux命令。
- COPY 将本地文件从主机上下文复制到图像。
- WORKDIR 切换当前文件夹(如果需要,创建它)。
- ENTRYPOINT和CMD定义每次容器启动时执行的命令。如果这些语句一起使用,则ENTRYPOINT反映了命令的常量部分。而CMD–是它的参数。
以下语句构建了一个镜像:
$ docker build -t : 。
注意“.” 末尾的(点)表示当前文件夹作为Docker上下文(简而言之,根文件夹的位置,文件复制到容器和Dockerfile)。
“最新的”不是最好的默认情况下,如果没有明确提供标签,Docker会为基础镜像使用“最新”标签。与在为Pip或Conda定义Python依赖项时指定包版本类似,您应该始终将预先确定的标签添加到基础镜像而不是“最新”默认值。它可以为您节省很多痛苦,尤其是在生产中。虽然这并不能确保镜像在每次构建时都100%相同,但它显着降低了引入有害更改的风险。
不同平台上的进程隔离Docker的工作方式因主机操作系统而异。在内部,Docker依赖于四个核心Linux功能:联合文件系统、Linux进程、命名空间和cgroup。
联合文件系统( UnionFS )是一种用于处理图像层的技术。对于Linux上的Docker服务器,所有容器都与主机共享一个内核。
其余三个特性——进程、命名空间和cgroups——确保适当的容器隔离。对于Windows和Mac上的Docker桌面,Linux VM安装在主机上,所有正在运行的容器共享其内核。
考虑到上述情况,很容易理解为什么在Linux服务器上使用默认root用户运行容器是一个非常糟糕的主意。如果只有一个容器在一台专用机器上运行(这通常是云部署的情况),那么这个问题的危险性会稍微降低一些。
无论如何,即使使用Docker Desktop,也不应该以root用户身份运行容器代码。
使用数据运行容器快如闪电的容器执行秘诀在于,当它启动时,不会复制任何数据。只有一个(最初非常薄)读写容器层被添加到只读图像层堆栈中。容器执行期间对文件的所有更改都使用联合文件系统作为“增量”存储在这个新层中。
当一个容器被移除时,这个读写层也随之被删除。这就是为什么您应该始终将容器数据视为临时数据。如果您关心容器处理的数据,则需要一个卷。根据需要和主机环境,它可能由Docker实例持久化或映射到本地或云文件夹。
架构问题Docker并不神奇——它取决于运行它的硬件。这意味着对于Intel/AMD和ARM处理器,您很可能仍需要略有不同的镜像。
概括在本文中,我们介绍了一些Docker基础知识,重点介绍了在处理ML项目时常见的功能。在下面的文章中,我们将运用这些知识。我们将创建一个简单的容器镜像,用于Intel/AMD CPU的实验和训练。
https://www.codeproject.com/Articles/5300724/Containerized-AI-and-Machine-Learning-Overview