使用 Docker 容器#
SkyPilot 可以将容器作为任务运行,或作为集群的运行时环境运行。
如果容器镜像可调用 / 具有入口点:将其 作为任务运行。
如果容器镜像将用作运行时环境(例如
ubuntu
、nvcr.io/nvidia/pytorch:23.10-py3
等),并且您需要在容器内运行额外命令:将其 作为运行时环境运行。
注意
在 RunPod 上不支持运行 docker 容器。要在 RunPod 上使用,请将您的 docker 镜像用作运行时环境,或使用 setup
和 run
来配置您的环境。更多信息请参见 GitHub 问题。
将容器作为任务运行#
注意
在 Kubernetes 上,不推荐在 pod 中运行 Docker 运行时。相反,请将您的容器用作运行时环境。
SkyPilot 可以直接将容器化应用作为常规任务运行。SkyPilot 提供的默认虚拟机镜像已预配置 Docker 运行时。
要启动容器化应用,您可以在任务的 run
部分直接调用 docker run
。
例如,要运行 HuggingFace TGI 服务容器
resources:
accelerators: A100:1
run: |
docker run --gpus all --shm-size 1g -v ~/data:/data \
ghcr.io/huggingface/text-generation-inference \
--model-id lmsys/vicuna-13b-v1.5
# NOTE: Uncommon to have any commands after the above.
# `docker run` is blocking, so any commands after it
# will NOT be run inside the container.
私有仓库#
在使用此模式时,要访问托管在私有仓库中的 Docker 镜像,只需在您的任务 YAML 文件中添加 setup
部分以向仓库进行身份验证
resources:
accelerators: A100:1
setup: |
# Authenticate with private registry
docker login -u <username> -p <password> <registry>
run: |
docker run <registry>/<image>:<tag>
远程构建容器#
如果您正在运行容器化应用,也可以在任务的 setup
阶段在集群上远程构建容器镜像。
echo_app
示例 提供了一个如何做到这一点的例子
file_mounts:
/inputs: ./echo_app # Input to application
/echo_app: ./echo_app # Contains the Dockerfile and build context
/outputs: # Output to be written directly to S3 bucket
name: # Set unique bucket name here
store: s3
mode: MOUNT
setup: |
# Build docker image. If pushed to a registry, can also do docker pull here
docker build -t echo:v0 /echo_app
run: |
docker run --rm \
--volume="/inputs:/inputs:ro" \
--volume="/outputs:/outputs:rw" \
echo:v0 \
/inputs/README.md /outputs/output.txt
在这个例子中,Dockerfile 和构建上下文包含在 ./echo_app
中。任务的 setup
阶段构建镜像,run
阶段运行容器。应用的输入使用 file_mounts
复制到 SkyPilot,并通过 docker 卷挂载 (--volume
标志) 挂载到容器内。应用在容器内 /outputs
路径产生的输出也卷挂载到虚拟机的 /outputs
,然后通过存储桶挂载直接写入 S3 存储桶。
我们的 GitHub 仓库有更多示例,包括通过 SkyPilot 在 Docker 容器中运行 Detectron2。
将容器用作运行时环境#
当容器用作运行时环境时,所有事情都在容器内发生
SkyPilot 运行时会自动安装并在容器内启动;
setup
和run
命令在容器中执行;任务创建的任何文件都将存储在容器内。
要将 Docker 镜像用作您的运行时环境,请将任务 YAML 文件中 resources
部分的 image_id
字段设置为 docker:<image_id>
。目前仅支持基于 Debian 的镜像(例如 Ubuntu)。
例如,使用 Docker Hub 的 ubuntu:20.04
镜像
resources:
image_id: docker:ubuntu:20.04
setup: |
# Commands to run inside the container
run: |
# Commands to run inside the container
注意
对于 RunPod 上的 非 root docker 镜像,您必须手动设置 SKYPILOT_RUNPOD_DOCKER_USERNAME
环境变量,使其与 docker 镜像的登录用户匹配(由 Dockerfile 中的最后一条 USER 指令设置)。
您可以在任务 YAML 文件的 envs
部分设置此环境变量
envs:
SKYPILOT_RUNPOD_DOCKER_USERNAME: <ssh-user>
这是为了解决 RunPod 的一个限制,即我们无法获取创建的 pod 的登录用户,甚至 runpodctl 也使用硬编码的 root 进行 SSH 访问。但对于其他云,创建的 docker 容器的登录用户会自动获取并使用。
另一个例子是,如何使用 NVIDIA 的 PyTorch NGC 容器
resources:
image_id: docker:nvcr.io/nvidia/pytorch:23.10-py3
accelerators: T4
setup: |
# Commands to run inside the container
run: |
# Commands to run inside the container
# Since SkyPilot tasks are run inside a fresh conda "(base)" environment,
# deactivate first to access what the Docker image has already installed.
source deactivate
nvidia-smi
python -c 'import torch; print(torch.__version__)'
分配给任务的任何 GPU 都将自动映射到您的 Docker 容器,并且集群内的所有后续任务也将运行在容器内。在多节点场景下,容器将在所有节点上启动,并将相应节点的容器分配用于任务执行。
提示
何时使用此功能?
如果您在 Docker 镜像中设置了预配置的开发环境,使用运行时环境模式会很方便。这对于启动在新虚拟机上难以配置的开发环境特别有用,例如依赖特定版本的 CUDA 或 cuDNN。
注意
由于我们会在启动时在用户指定的容器镜像内执行 pip install skypilot
,用户应确保不会发生依赖冲突。
目前,必须满足以下要求
容器镜像应基于 Debian;
容器镜像必须授予用户无需密码认证的 sudo 权限。拥有 root 用户也是可以接受的。
注意
支持使用带有自定义入口点的容器作为运行时环境,容器的入口点将被 /bin/bash
覆盖。可以在任务 YAML 文件的 setup
和 run
部分执行特定命令。但是,由于 RunPod API 的限制,此方法与 RunPod 不兼容,因此请确保选择一个带有默认入口点(即 /bin/bash
)的容器。
私有仓库#
注意
如果您使用 SkyPilot 在 Kubernetes 集群上启动,这些说明不适用。相反,更多信息请参阅 在 Kubernetes 中使用私有仓库的镜像。
在使用此模式时,要访问托管在私有仓库中的 Docker 镜像,您可以使用任务环境变量提供仓库认证详情
resources:
image_id: docker:<user>/<your-docker-hub-repo>:<tag>
envs:
# Values used in: docker login -u <user> -p <password> <registry server>
# The password should be a personal access token (PAT), see: https://app.docker.com/settings/personal-access-tokens
SKYPILOT_DOCKER_USERNAME: <user>
SKYPILOT_DOCKER_PASSWORD: <password>
SKYPILOT_DOCKER_SERVER: docker.io
resources:
image_id: docker:<your-ecr-repo>:<tag>
envs:
# Values used in: docker login -u <user> -p <password> <registry server>
# Password for ECR can be generated with ``aws ecr get-login-password --region <region>``
SKYPILOT_DOCKER_USERNAME: AWS
SKYPILOT_DOCKER_PASSWORD: <password>
SKYPILOT_DOCKER_SERVER: <your-user-id>.dkr.ecr.<region>.amazonaws.com
或者,您可以使用带有 --env
标志的 sky launch
来传递密码
sky launch sky.yaml \
--env SKYPILOT_DOCKER_PASSWORD="$(aws ecr get-login-password --region us-east-1)"
我们支持使用服务账户密钥的私有 GCP Artifact Registry (GCR)。请参阅 GCP Artifact Registry 认证。请注意,SKYPILOT_DOCKER_USERNAME
需要设置为 _json_key
。
resources:
image_id: docker:<your-gcp-project-id>/<your-registry-repository>/<your-image-name>:<tag>
envs:
SKYPILOT_DOCKER_USERNAME: _json_key
SKYPILOT_DOCKER_PASSWORD: <gcp-service-account-key>
SKYPILOT_DOCKER_SERVER: <location>-docker.pkg.dev
或者,您可以使用带有 --env
标志的 sky launch
来传递服务账户密钥
sky launch sky.yaml \
--env SKYPILOT_DOCKER_PASSWORD="$(cat ~/gcp-key.json)"
注意
如果您的集群在 GCP 上,并且 SKYPILOT_DOCKER_USERNAME
和 SKYPILOT_DOCKER_PASSWORD
设置为空字符串,SkyPilot 将自动使用实例的 IAM 权限向 GCR 进行认证
envs:
SKYPILOT_DOCKER_USERNAME: ""
SKYPILOT_DOCKER_PASSWORD: ""
SKYPILOT_DOCKER_SERVER: <location>-docker.pkg.dev
resources:
image_id: docker:nvidia/pytorch:23.10-py3
envs:
SKYPILOT_DOCKER_USERNAME: $oauthtoken
SKYPILOT_DOCKER_PASSWORD: <NGC_API_KEY>
SKYPILOT_DOCKER_SERVER: nvcr.io
或者,您可以使用带有 --env
标志的 sky launch
来传递 API 密钥
sky launch sky.yaml \
--env SKYPILOT_DOCKER_PASSWORD=<NGC_API_KEY>