在 Kubernetes 上开始使用#
快速入门#
有 kubeconfig 文件?只需 3 个命令即可开始使用 SkyPilot
# Install dependencies
$ brew install kubectl socat netcat
# Linux: sudo apt-get install kubectl socat netcat
# With a valid kubeconfig at ~/.kube/config, run:
$ sky check
# Shows "Kubernetes: enabled"
# Launch your SkyPilot cluster
$ sky launch --cpus 2+ -- echo hi
有关详细说明、前提条件和高级功能,请继续阅读。
前提条件#
要连接和使用 Kubernetes 集群,SkyPilot 需要
一个运行 Kubernetes v1.20 或更高版本的现有 Kubernetes 集群。
一个包含访问凭据和要使用的命名空间的 Kubeconfig 文件。
支持的 Kubernetes 部署
托管式 Kubernetes 服务 (EKS, GKE)
本地集群 (Kubeadm, Rancher, K3s)
本地开发集群 (KinD, minikube)
在典型的工作流程中
集群管理员设置 Kubernetes 集群。请参考 Kubernetes 集群设置 的管理员指南,了解不同部署环境(Amazon EKS、Google GKE、本地和本地调试)。
希望在此集群上运行 SkyPilot 任务的用户会获得包含其凭据 (kube-context) 的 Kubeconfig 文件。SkyPilot 读取此 Kubeconfig 文件与集群通信。
启动你的第一个任务#
一旦你的集群管理员 设置好 Kubernetes 集群 并为你提供了 kubeconfig 文件
确保你的本地机器上安装了 kubectl、
socat
和nc
(netcat)。$ # MacOS $ brew install kubectl socat netcat $ # Linux (may have socat already installed) $ sudo apt-get install kubectl socat netcat
将你的 kubeconfig 文件放在
~/.kube/config
。$ mkdir -p ~/.kube $ cp /path/to/kubeconfig ~/.kube/config
通过运行
kubectl get pods
命令,你可以验证你的凭据是否已正确设置。注意
如果你的集群管理员还为你提供了特定的服务账户,请在你的
~/.sky/config.yaml
文件中进行设置。kubernetes: remote_identity: your-service-account-name
运行
sky check
命令并验证 SkyPilot 中是否启用了 Kubernetes。$ sky check Checking credentials to enable clouds for SkyPilot. ... Kubernetes: enabled ...
注意
sky check
还会检查你的集群是否支持 GPU。如果不支持 GPU,它会显示原因。要在集群上设置 GPU 支持,请参考 Kubernetes 集群设置指南。
你现在可以在你的 Kubernetes 集群上运行任何 SkyPilot 任务了。
$ sky launch --cpus 2+ task.yaml == Optimizer == Target: minimizing cost Estimated cost: $0.0 / hour Considered resources (1 node): --------------------------------------------------------------------------------------------------- CLOUD INSTANCE vCPUs Mem(GB) ACCELERATORS REGION/ZONE COST ($) CHOSEN --------------------------------------------------------------------------------------------------- Kubernetes 2CPU--2GB 2 2 - kubernetes 0.00 ✔ AWS m6i.large 2 8 - us-east-1 0.10 Azure Standard_D2s_v5 2 8 - eastus 0.10 GCP n2-standard-2 2 8 - us-central1 0.10 IBM bx2-8x32 8 32 - us-east 0.38 Lambda gpu_1x_a10 30 200 A10:1 us-east-1 0.60 ---------------------------------------------------------------------------------------------------.
注意
SkyPilot 将使用 kubeconfig 文件中 current-context
中设置的集群和命名空间。要管理你的 current-context
:
$ # See current context
$ kubectl config current-context
$ # Switch current-context
$ kubectl config use-context mycontext
$ # Set a specific namespace to be used in the current-context
$ kubectl config set-context --current --namespace=mynamespace
查看集群状态#
要查看 Kubernetes 集群中所有 SkyPilot 资源的状体,请运行 sky status --k8s
命令。
与只列出当前用户启动的 SkyPilot 资源的 sky status
不同,sky status --k8s
会列出 Kubernetes 集群中所有用户的 SkyPilot 资源。
$ sky status --k8s
Kubernetes cluster state (context: mycluster)
SkyPilot clusters
USER NAME LAUNCHED RESOURCES STATUS
alice infer-svc-1 23 hrs ago 1x Kubernetes(cpus=1, mem=1, {'L4': 1}) UP
alice sky-jobs-controller-80b50983 2 days ago 1x Kubernetes(cpus=4, mem=4) UP
alice sky-serve-controller-80b50983 23 hrs ago 1x Kubernetes(cpus=4, mem=4) UP
bob dev 1 day ago 1x Kubernetes(cpus=2, mem=8, {'H100': 1}) UP
bob multinode-dev 1 day ago 2x Kubernetes(cpus=2, mem=2) UP
bob sky-jobs-controller-2ea485ea 2 days ago 1x Kubernetes(cpus=4, mem=4) UP
Managed jobs
In progress tasks: 1 STARTING
USER ID TASK NAME RESOURCES SUBMITTED TOT. DURATION JOB DURATION #RECOVERIES STATUS
alice 1 - eval 1x[CPU:1+] 2 days ago 49s 8s 0 SUCCEEDED
bob 4 - pretrain 1x[H100:4] 1 day ago 1h 1m 11s 1h 14s 0 SUCCEEDED
bob 3 - bigjob 1x[CPU:16] 1 day ago 1d 21h 11m 4s - 0 STARTING
bob 2 - failjob 1x[CPU:1+] 1 day ago 54s 9s 0 FAILED
bob 1 - shortjob 1x[CPU:1+] 2 days ago 1h 1m 19s 1h 16s 0 SUCCEEDED
你还可以使用 sky show-gpus --cloud k8s
命令查看集群上实时的 GPU 使用情况。
$ sky show-gpus --cloud k8s
Kubernetes GPUs
GPU REQUESTABLE_QTY_PER_NODE UTILIZATION
L4 1, 2, 4 12 of 12 free
H100 1, 2, 4, 8 16 of 16 free
Kubernetes per node GPU availability
NODE GPU UTILIZATION
my-cluster-0 L4 4 of 4 free
my-cluster-1 L4 4 of 4 free
my-cluster-2 L4 2 of 2 free
my-cluster-3 L4 2 of 2 free
my-cluster-4 H100 8 of 8 free
my-cluster-5 H100 8 of 8 free
使用自定义镜像#
默认情况下,我们维护并使用两个 SkyPilot 容器镜像用于 Kubernetes 集群:
us-central1-docker.pkg.dev/skypilot-375900/skypilotk8s/skypilot
:用于仅 CPU 集群 (Dockerfile)。us-central1-docker.pkg.dev/skypilot-375900/skypilotk8s/skypilot-gpu
:用于 GPU 集群 (Dockerfile)。
这些镜像已预安装 SkyPilot 依赖项,以加快启动速度。
要使用你自己的镜像,请在你的任务 YAML 的 resources
部分添加 image_id: docker:<your image tag>
。
resources:
image_id: docker:myrepo/myimage:latest
...
你的镜像必须满足以下要求:
镜像必须是 基于 debian 的,并且必须安装 apt 包管理器。
镜像中的默认用户必须具有 root 权限或无密码的 sudo 访问权限。
注意
如果你的集群运行在非 x86_64 架构(例如 Apple Silicon)上,你的镜像必须原生构建以支持该架构。否则,你的作业可能会卡在 Start streaming logs ...
。有关更多信息,请参阅 GitHub 问题。
使用私有仓库中的镜像#
要使用私有仓库(例如 Private DockerHub、Amazon ECR、Google Container Registry)中的镜像,请在你的 Kubernetes 集群中创建一个 secret,并编辑你的 ~/.sky/config.yaml
文件以如下方式指定 secret:
kubernetes:
pod_config:
spec:
imagePullSecrets:
- name: your-secret-here
提示
如果你使用 Amazon ECR,你的 secret 凭据可能每 12 小时过期一次。考虑使用 k8s-ecr-login-renew 自动刷新你的 secrets。
开放端口#
在 Kubernetes 上运行的 SkyPilot 集群支持通过两种模式开放端口:
你的集群必须支持并配置其中一种模式。关于如何进行设置,请参考 在 Kubernetes 上设置端口指南。
提示
在 Google GKE、Amazon EKS 或其他云托管的 Kubernetes 服务中,默认的 LoadBalancer 服务模式开箱即用,无需额外配置。
配置好集群后,通过在任务 YAML 的 resources
部分添加 ports
来启动在端口上暴露服务的任务。
# task.yaml
resources:
ports: 8888
run: |
python -m http.server 8888
使用 sky launch -c myclus task.yaml
启动集群后,你可以使用 sky status --endpoints myclus
命令获取访问该端口的 URL。
# List all ports exposed by the cluster
$ sky status --endpoints myclus
8888: 34.173.13.241:8888
# curl a specific port's endpoint
$ curl $(sky status --endpoint 8888 myclus)
...
提示
要了解更多关于在 SkyPilot 任务中开放端口的信息,请参阅 开放端口。
自定义 SkyPilot Pod#
你可以通过在 ~/.sky/config.yaml
文件中设置 pod_config
键来覆盖 SkyPilot 使用的 pod 配置。 pod_config
的值应该是一个遵循 Kubernetes Pod API 的字典。这将应用于 SkyPilot 创建的所有 pods。
例如,要设置自定义环境变量并使用 GPUDirect RDMA,你可以将以下内容添加到你的 ~/.sky/config.yaml
文件中:
# ~/.sky/config.yaml
kubernetes:
pod_config:
spec:
containers:
- env: # Custom environment variables to set in pod
- name: MY_ENV_VAR
value: MY_ENV_VALUE
resources: # Custom resources for GPUDirect RDMA
requests:
rdma/rdma_shared_device_a: 1
limits:
rdma/rdma_shared_device_a: 1
提示
除了全局设置 pod_config
外,你还可以在任务 YAML 中直接通过 config
字段 按任务设置它。
# task.yaml
run: |
python myscript.py
# Set pod_config for this task
config:
kubernetes:
pod_config:
...
挂载 NFS 和其他卷#
可以使用 pod_config 字段将 Kubernetes 卷 附加到 SkyPilot pods。这对于访问共享存储(如 NFS)或本地高性能存储(如 NVMe 驱动器)非常有用。
有关详细信息和示例,请参阅 设置 NFS 和其他卷。
常见问题#
我可以使用 SkyPilot 连接多个 Kubernetes 集群吗?
SkyPilot 可以通过在
~/.sky/config.yaml
文件中设置allowed_contexts
键来使用 kubeconfig 文件中的多个 Kubernetes context。请参阅 多个 Kubernetes 集群。如果未设置
allowed_contexts
,SkyPilot 将使用当前的活动 context。要使用不同的 context,请使用kubectl config use-context <context-name>
命令更改当前 context。是否支持自动扩缩的 Kubernetes 集群?
要在自动扩缩集群上运行,请在
~/.sky/config.yaml
文件中将provision_timeout
键设置为较大的值,以便为集群自动扩缩器提供足够的时间来调配新节点。这将指示 SkyPilot 等待集群扩容,然后再故障转移到下一个候选资源(例如,下一个云)。如果你在 scale-to-zero 环境中使用 GPU,你还应该将
autoscaler
键设置为你的集群的自动扩缩器类型。更多详细信息请参阅 高级配置。# ~/.sky/config.yaml kubernetes: provision_timeout: 900 # Wait 15 minutes for nodes to get provisioned before failover. Set to -1 to wait indefinitely. autoscaler: gke # [gke, karpenter, generic]; required if using GPUs/TPUs in scale-to-zero setting
SkyPilot 可以为我调配 Kubernetes 集群吗?SkyPilot 会为我的 Kubernetes 集群添加更多节点吗?
Kubernetes 支持的目标是在现有的 Kubernetes 集群上运行 SkyPilot 任务。它不会调配任何新的 Kubernetes 集群,也不会向现有的 Kubernetes 集群添加新节点。
我的组织中有多个用户共享同一个 Kubernetes 集群。如何为他们的 SkyPilot 工作负载提供隔离?
为了实现隔离,你可以创建独立的 Kubernetes 命名空间,并在分发给用户的 kubeconfig 文件中进行设置。SkyPilot 将使用 kubeconfig 文件中设置的命名空间来运行所有任务。
如何查看 SkyPilot 在我的 Kubernetes 集群上创建的 pods?
你可以使用现有的可观测性工具,通过标签
parent=skypilot
(kubectl get pods -l 'parent=skypilot'
) 过滤资源。例如,按照 此处 的说明在你的集群上部署 Kubernetes Dashboard。SkyPilot 支持 GKE 上的 TPU 吗?
SkyPilot 支持 GKE 上的单主机 TPU 拓扑(例如,1x1、2x2、2x4)。要使用 TPU,请将其添加到任务 YAML 的 accelerator 字段中:
resources: accelerators: tpu-v5-lite-podslice:1 # or tpu-v5-lite-device, tpu-v5p-slice
我正在使用自定义镜像。如何加快 pod 启动时间?
你可以在自定义镜像中预安装 SkyPilot 依赖项,以加快 pod 启动时间。只需在 Dockerfile 的末尾添加以下几行即可:
FROM <your base image> # Install system dependencies RUN apt update -y && \ apt install git gcc rsync sudo patch openssh-server pciutils fuse unzip socat netcat-openbsd curl -y && \ rm -rf /var/lib/apt/lists/* # Install conda and other python dependencies RUN curl https://repo.anaconda.com/miniconda/Miniconda3-py310_23.11.0-2-Linux-x86_64.sh -o Miniconda3-Linux-x86_64.sh && \ bash Miniconda3-Linux-x86_64.sh -b && \ eval "$(~/miniconda3/bin/conda shell.bash hook)" && conda init && conda config --set auto_activate_base true && conda activate base && \ grep "# >>> conda initialize >>>" ~/.bashrc || { conda init && source ~/.bashrc; } && \ rm Miniconda3-Linux-x86_64.sh && \ export PIP_DISABLE_PIP_VERSION_CHECK=1 && \ python3 -m venv ~/skypilot-runtime && \ PYTHON_EXEC=$(echo ~/skypilot-runtime)/bin/python && \ $PYTHON_EXEC -m pip install 'skypilot-nightly[remote,kubernetes]' 'ray[default]==2.9.3' 'pycryptodome==3.12.0' && \ $PYTHON_EXEC -m pip uninstall skypilot-nightly -y && \ curl -LO "https://dl.k8s.io/release/v1.28.11/bin/linux/amd64/kubectl" && \ sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl && \ echo 'export PATH="$PATH:$HOME/.local/bin"' >> ~/.bashrc
Kubernetes 支持多节点作业吗?
Kubernetes 支持 多节点作业。启动多节点作业时,SkyPilot 集群中的每个节点都将作为一个单独的 pod 进行调配。
SkyPilot 将尝试将每个 pod 放置在集群中的不同节点上。
SkyPilot 将尝试在给定集群上调度所有 pods。如果 SkyPilot 无法在给定集群上调度所有 pods(即部分或所有 pods 无法调度),SkyPilot 将故障转移到另一个集群或云。