Skip to main content
Version: 1.0.8

Docker 设置

快速入门:安装并运行Docker镜像

首先安装适用于您操作系统的Docker。然后,要获取SynapseML镜像并运行它,打开终端(在Windows上是PowerShell/cmd)并运行

docker run -it -p 8888:8888 mcr.microsoft.com/mmlspark/release

在您的浏览器中,访问 http://localhost:8888/ — 您将看到 Docker 镜像的最终用户许可协议(EULA),一旦您接受它,Jupyter notebook 界面将启动。要跳过此步骤,请在 Docker 命令中添加 -e ACCEPT_EULA=yes

docker run -it -p 8888:8888 -e ACCEPT_EULA=y mcr.microsoft.com/mmlspark/release

您现在可以选择一个示例笔记本并运行它,或者创建您自己的笔记本。

注意:EULA 仅用于运行 SynapseML Docker 镜像;源代码是根据 MIT 许可证发布的(请参阅 LICENSE 文件)。

运行特定版本

在前面的docker命令中,mcr.microsoft.com/mmlspark/release指定了您想要运行的项目和镜像名称。这里还有一个隐含的组件:您想要使用的tsag(=版本)。明确指定它看起来像mcr.microsoft.com/mmlspark/release:1.0.8,用于1.0.8标签。

单独使用 mcr.microsoft.com/mmlspark/release 时,它有一个隐式的 latest 标签,因此它等同于 mcr.microsoft.com/mmlspark/release:latestlatest 标签与最新的稳定版 SynapseML 版本相同。 您可以在我们的 Docker Hub 仓库 上查看当前的 [synapsemltags]

一个更实际的例子

上一节有一个相当简单的命令。你可能想要使用的一个更完整的命令如下所示:

docker run -it --rm \
-p 127.0.0.1:80:8888 \
-v ~/myfiles:/notebooks/myfiles \
mcr.microsoft.com/mmlspark/release:1.0.8

在这个例子中,反斜杠是为了提高可读性;如果你愿意,你可以将命令输入为一行。在PowerShell中,myfiles本地路径和换行看起来有点不同:

docker run -it --rm `
-p 127.0.0.1:80:8888 `
-v C:\myfiles:/notebooks/myfiles `
mcr.microsoft.com/mmlspark/release:1.0.8

让我们分解这个命令并逐一解释每个部分的含义:

  • -it

    此命令结合使用了-i-t(也可以指定为--interactive --tty)。结合这两个标志意味着镜像以交互方式运行,在此示例中意味着您可以看到服务器发出的消息,并且还可以使用Ctrl+C来关闭Jupyter笔记本服务器。

  • --rm

    当 Docker 运行任何镜像时,它会创建一个容器来保存创建或修改的文件的所有进一步文件系统数据。如果你运行了上面的快速启动命令,你可以通过docker container list -a看到留下的容器。你可以通过`docker container rm

    `回收这些容器,或者通过`docker container prune`回收所有停止运行的容器,甚至更一般地,通过`docker system prune`回收所有未使用的 Docker 资源。

    回到--rm:这个标志告诉 Docker 在镜像退出时丢弃镜像,这意味着在运行镜像时创建的任何数据在运行完成后都会被丢弃。但请参阅-v标志的描述。

  • -e ACCEPT_EULA=y

    -e 标志用于在运行的容器中设置环境变量。 在这种情况下,我们使用它来绕过 EULA 检查。可以添加更多标志来设置其他变量,例如,您可以添加一个 -e MMLSPARK_JUPYTER_PORT=80 来更改 Jupyter 服务器监听的端口。

  • -p 127.0.0.1:80:8888

    SynapseML 镜像中的 Jupyter 服务器监听端口 8888,但这通常与实际网络隔离。之前,我们使用 -p 8888:8888 来表示我们希望将实际机器上的端口 8888(左侧)映射到容器中的端口 8888(右侧)。这样做的一个问题是 8888 可能难以记住,但更严重的问题是,现在你的机器向网络上的任何人提供 Jupyter 界面。

    这个更完整的示例解决了这些问题:我们将 8888:8888 替换为 80:8888,以便 HTTP 端口 80 连接到容器中运行的 Jupyter(只需访问 http://localhost/ 即可工作);我们还添加了 127.0.0.1: 前缀,使 Jupyter 界面仅在你的机器上可用,而不是整个网络。

    你可以重复使用此标志以类似方式转发其他端口。例如,你可以暴露一些 Spark 端口,例如:-p 127.0.0.1:4040:4040

  • -v ~/myfiles:/notebooks/myfiles

    如前所述,我们使用--rm在运行退出时移除容器,这通常是可以的,因为从这些容器中提取文件可能会有点复杂。相反,我们使用-v标志将您机器上的一个目录(左侧的~/myfiles)映射到运行容器中可用的目录。Docker镜像对此目录所做的任何修改都会直接在实际目录上执行。

    本地目录遵循本地文件名约定,因此在Windows上,您需要使用类似Windows的路径。在Windows上,您还需要在Docker设置中共享您想要使用的驱动器。

    右侧的路径在容器内部使用,因此它是一个Linux路径。SynapseML镜像在/notebooks目录中运行Jupyter,因此这是一个方便地使您的文件可用的好地方。

    此标志可以多次使用,以使多个目录在运行容器中可用。两个路径都必须是绝对的,因此如果您想相对指定路径,可以使用类似-v $PWD/myfiles:/notebooks/myfiles的东西。

    有了这样的目录共享,您可以创建/编辑笔记本,并且笔记本中的代码可以使用共享目录来存储额外的数据,例如:

    data = spark.read.csv('myfiles/mydata.csv')
    ...
    model.write().overwrite().save('myfiles/myTrainedModel.mml')
  • mcr.microsoft.com/mmlspark/release:1.0.8

    最后,这个参数指定了我们想要运行的镜像的显式版本标签。

将容器作为服务器运行

与使用-it交互式运行Docker镜像的替代方法是以“分离”模式运行它,作为服务器,使用-d(或--detach)标志。这里可能有用的第二个标志是--name,它为运行的镜像提供了一个方便的标签:

docker run -d --name my-synapseml ...flags... mcr.microsoft.com/mmlspark/release

在这种模式下运行时,你可以使用

  • docker stop my-synapseml: 停止镜像

  • docker start my-synapseml: 再次启动它

  • docker logs my-synapseml: 查看它产生的日志输出

在活动容器中运行其他命令

另一个有用的 docker 命令是 exec,它在现有的活动容器的上下文中运行命令。要使用它,您需要指定容器名称和要运行的命令。例如,对于一个已经运行的后台容器,名为 my-synapseml,您可以使用

docker exec -it my-synapseml bash

在服务器的上下文中启动一个shell,大致相当于在Jupyter界面中启动一个终端。

其他常见的Linux可执行文件也可以使用,例如:

docker exec -it my-synapseml top
docker exec my-synapseml ps auxw

(ps 不需要 -it,因为它不是一个交互式命令。)

这些命令也可以用于交互式容器,并且可以使用--name来使它们易于定位。如果你不使用--name,Docker会为容器分配一个随机名称;你可以使用docker ps来查看它。你也可以获取容器ID来使用,而不是名称。

请记住,提供给docker exec的命令是在运行中的容器的上下文中执行的:你只能运行容器中存在的可执行文件,并且运行受到与容器相同的资源限制(文件系统/网络访问等)。SynapseML镜像基于一个相当基础的Ubuntu安装(来自Docker Hub的ubuntu镜像)。

运行其他Spark可执行文件

docker run 可以在镜像名称后接受另一个可选参数,指定一个替代的可执行文件来运行,而不是启动 Jupyter 笔记本服务器的默认启动器。使用这个额外的参数,你可以直接在容器中使用 Spark 环境:

docker run -it ...flags... mcr.microsoft.com/mmlspark/release bash

此命令使用 bash 而不是 Jupyter 启动容器。此环境在其 $PATH 中提供了所有 Spark 可执行文件。您仍然需要指定加载 SynapseML 包的命令行标志,但有一些方便的环境变量保存了所需的包和存储库以供使用:

pyspark --repositories "$MML_M2REPOS" --packages "$MML_PACKAGE" --master "local[*]"

在这种情况下,上面列出的许多标志也很有用,例如使用-v映射工作目录。

更新SynapseML镜像

SynapseML 的新版本会不时发布,并且它们包含一个新的 Docker 镜像。作为镜像使用者,您通常不会注意到这些新版本:docker run 会在本地没有该镜像的副本时下载它,但如果存在,docker run 会盲目地运行它,不会检查是否有新的标签被推送。

因此,您需要明确告诉Docker检查新版本并在存在时拉取它。您可以使用pull命令来执行此操作:

docker pull mcr.microsoft.com/mmlspark/release

由于我们在这里没有指定明确的标签,docker 添加了隐含的 :latest 标签,并在 Docker Hub 上检查带有此标签的可用 mcr.microsoft.com/mmlspark/release 镜像。当它找到带有此标签的不同镜像时,它将获取一个 副本到您的机器上,更改未限定的 mcr.microsoft.com/mmlspark/release 所引用的镜像。

Docker 通常只知道它获取的标签,所以如果你一直使用 mcr.microsoft.com/mmlspark/release 来引用没有明确版本标签的镜像,那么你也不会拥有带有版本标签的镜像。一旦标签更新,之前的版本仍然会在你的系统中,只是没有任何标签。使用 docker images 列出系统中的镜像时,现在会显示两个 mcr.microsoft.com/mmlspark/release 镜像,一个带有 latest 标签,另一个没有标签,显示为 <none>。假设你没有活动的容器(包括分离的容器),docker system prune 将删除这个未标记的镜像,回收使用的空间。

如果你使用了明确的版本标签,那么在新拉取后它仍然会存在,这意味着你可以继续使用这个版本。如果你首先使用了一个未限定的名称,然后使用了一个带版本标签的名称,Docker 将会获取这两个标签。只有第二次获取是快速的,因为它指向已经加载的内容。在这种情况下,当有新版本时执行 pull 将会获取新的 latest 标签并将其含义更改为新版本,但旧版本仍然可以通过其自己的版本标签使用。

最后,如果有这样带有版本标签的旧版本你想删除,你可以使用docker images来检查已安装镜像的列表及其标签,并使用docker rmi <name>:<tag>来删除不需要的镜像。

关于安全的说明

在Docker容器中执行代码可能不安全,如果运行用户是root。因此,SynapseML镜像使用了一个适当的用户名代替。如果你仍然想以root身份运行(例如,如果你想apt install另一个Ubuntu包),那么你应该使用--user root。当与docker exec结合使用时,这种模式可能很有用,可以在镜像继续正常运行的同时执行管理工作。

进一步阅读

本文简要介绍了一些可以使用SynapseML Docker镜像(以及其他一般镜像)完成的有用操作。您可以找到更多的在线文档。