SkyPilot Kubernetes 部署指南:从本地 kind 到 GKE / EKS / 自建集群的完整实战
【免费下载链接】skypilotThe AI Compute Platform for frontier teams. SkyPilot turns fragmented AI compute into one AI supercomputer, so frontier AI teams build custom intelligence faster.项目地址: https://gitcode.com/GitHub_Trending/sk/skypilot
导读
本文基于 SkyPilot 官方部署指南,系统讲解如何在不同环境中为 SkyPilot 搭建 Kubernetes 集群:既包括一条命令即可启动的本地开发集群(sky local up),也覆盖 GKE、EKS 两大托管服务,以及 RKE2、K3s 等自建(on-prem)集群和按需云 VM 上的部署方案。读完本文,你将掌握每个场景下的完整部署命令、GPU 支持配置(驱动安装、节点打标、RuntimeClass)与部署后的验证手段(sky check、sky gpus list --infra k8s),并了解这些命令在 SkyPilot 仓库中的底层实现原理。
一、概览:SkyPilot 的 Kubernetes 部署路径
Kubernetes 是 SkyPilot 支持的核心基础设施之一。官方部署指南将集群的创建方式划分为五类场景,每个场景都配有最小化起步步骤:
| 场景 | 核心方式 | 适用对象 |
|---|---|---|
| 本地开发集群 | sky local up(底层基于 kind) | 笔记本上试用 SkyPilot、无需任何云账号 |
| 托管服务 | Google Cloud GKE / Amazon EKS | 已有云账号、希望使用托管集群 |
| 自建集群 | kubeadm / RKE2 / K3s / Rancher 等 | 私有化 on-prem 环境 |
| 按需云 VM | 仓库提供的launch_k8s.sh脚本 | 快速在云 VM 上部署 k8s 并打通 kubeconfig |
无论选择哪种方式,最终目标都是得到一个 SkyPilot 可用的 kubeconfig 与运行环境,随后通过sky check验证、sky launch运行任务。下面按场景逐一展开。
二、本地开发集群:sky local up一条命令起集群
2.1 原理与前置条件
为了在笔记本上直接体验 SkyPilot(无需任何云访问权限),SkyPilot 提供了sky local up命令。它底层调用 kind(Kubernetes in Docker),把集群跑在一个容器里,因此本地不需要额外安装 Kubernetes 组件。
前置条件只需两步:
- 安装 Docker 与 kind。
- 运行
sky local up启动集群并自动配置 kubeconfig:
$ sky local up命令执行完毕后,SkyPilot 会自动把当前 kubeconfig 切换到新建的 kind 集群 context,并自动运行一次sky check验证 Kubernetes 是否可用。之后即可用常规方式运行任务:
$ sky launch使用完毕后可销毁集群:
$ sky local down该命令会删除本地 Kubernetes 集群,并把 kubeconfig 恢复为原有的 context。
2.2 使用注意事项
- Docker 资源分配:官方建议给 Docker 运行时分配至少 4 个或更多 CPU,否则 kind 可能因资源不足而失败(参见 kind 的构建节点镜像失败已知问题)。
- kind 的能力限制:kind 不支持多节点和 GPU,因此不推荐用于生产环境。若需要私有 on-prem 集群,请参考本文第六节的部署方案。
2.3 源码剖析:sky local up是怎么工作的
从源码结构看,sky local up的完整链路位于 sky/utils/kubernetes/kubernetes_deploy_utils.py:
generate_kind_config()动态生成 kind 集群配置:默认集群名为skypilot(DEFAULT_LOCAL_CLUSTER_NAME),把宿主机的 100 个端口映射到容器内的30000-30099端口段,并通过kubeadmConfigPatches设置service-node-port-range与ingress-ready=true节点标签;若传入gpus=True且宿主机检测到 GPU(check_local_gpus()),还会附加extraMounts把 nvidia 设备挂载进 kind 容器(kubernetes_deploy_utils.py)。deploy_local_cluster()负责落盘配置、调用create_cluster.sh脚本创建集群、运行sky check校验,并在结束时通过kubectl读取节点 CPU/GPU 数给出完成提示;若集群已存在(退出码 100)则提示改用sky local down --name <name>(kubernetes_deploy_utils.py)。teardown_local_cluster()调用delete_cluster.sh完成销毁并恢复 kubeconfig(kubernetes_deploy_utils.py)。
另外,从 sky/client/cli/command.py 中的local_up入口可以看到,sky local up支持--gpus、--name、--port-start、--num-nodes等参数(对应local_up(gpus, name, port_start, num_nodes, async_call)),其中端口范围必须为 100 的倍数,默认集群名skypilot独占30000-30099端口段(kubernetes_deploy_utils.py)。
注:
sky local up仅支持在本地运行 SkyPilot(API Server 部署在本地)时使用,因为该命令会修改本机 kubeconfig(见 sky/client/sdk.py 中的校验逻辑)。
三、部署到 Google Cloud GKE
3.1 创建 GKE 集群并获取 kubeconfig
创建一个至少含 1 个节点的 GKE Standard 集群(官方建议节点至少 4 vCPU)。下方是一个 2 节点、每节点 16 核的完整示例(点击展开查看完整gcloud命令):
示例:创建 2 节点、每节点 16 CPU 的 GKE 集群
PROJECT_ID=$(gcloud config get-value project) CLUSTER_NAME=testcluster gcloud beta container --project "${PROJECT_ID}" clusters create "${CLUSTER_NAME}" --zone "us-central1-c" --no-enable-basic-auth --release-channel "regular" --machine-type "e2-standard-16" --image-type "COS_CONTAINERD" --disk-type "pd-balanced" --disk-size "100" --metadata disable-legacy-endpoints=true --scopes "https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/trace.append" --num-nodes "2" --logging=SYSTEM,WORKLOAD --monitoring=SYSTEM --enable-ip-alias --network "projects/${PROJECT_ID}/global/networks/default" --subnetwork "projects/${PROJECT_ID}/regions/us-central1/subnetworks/default" --no-enable-intra-node-visibility --default-max-pods-per-node "110" --security-posture=standard --workload-vulnerability-scanning=disabled --no-enable-master-authorized-networks --addons HorizontalPodAutoscaling,HttpLoadBalancing,GcePersistentDiskCsiDriver --enable-autoupgrade --enable-autorepair --max-surge-upgrade 1 --max-unavailable-upgrade 0 --enable-managed-prometheus --enable-shielded-nodes --node-locations "us-central1-c"随后获取集群 kubeconfig,该命令会自动把新的 GKE context 写入~/.kube/config:
$ gcloud container clusters get-credentials <cluster-name> --region <region> # 示例: # gcloud container clusters get-credentials testcluster --region us-central1-c3.2 [GPU 场景] 安装 NVIDIA 驱动
- 对于 GKE 版本高于
1.30.1-gke.115600的集群,NVIDIA 驱动已预装,无需额外配置。 - 若使用更老的 GKE 版本,则需要手动安装驱动。根据节点 GPU 型号与操作系统,选择对应的 daemonset 部署:
# 基于 Container Optimized OS (COS) 的节点,GPU 非 Nvidia L4(如 V100、A100 等): $ kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nvidia-driver-installer/cos/daemonset-preloaded.yaml # 基于 COS 的节点,使用 L4 GPU: $ kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nvidia-driver-installer/cos/daemonset-preloaded-latest.yaml # 基于 Ubuntu 的节点,GPU 非 Nvidia L4(如 V100、A100 等): $ kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nvidia-driver-installer/ubuntu/daemonset-preloaded.yaml # 基于 Ubuntu 的节点,使用 L4 GPU: $ kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nvidia-driver-installer/ubuntu/daemonset-preloaded-R525.yaml验证驱动是否就绪:运行
kubectl describe nodes,检查节点的Capacity一节中是否列出nvidia.com/gpu资源。
3.3 验证集群并查看 GPU
运行sky check确认 SkyPilot 已正确识别该 Kubernetes 集群:
$ sky check若使用了 GPU,可用sky gpus list --infra k8s查看集群内可用的 GPU 及实时占用情况:
$ sky gpus list --infra k8s GPU REQUESTABLE_QTY_PER_NODE UTILIZATION L4 1, 2, 4 6 of 8 free A100 1, 2 2 of 4 free Kubernetes per node GPU availability NODE GPU UTILIZATION my-cluster-0 L4 4 of 4 free my-cluster-1 L4 2 of 4 free my-cluster-2 A100 2 of 2 free my-cluster-3 A100 0 of 2 free该命令会实时查询 Kubernetes 集群中各节点的 GPU 资源,展示每种 GPU 的单节点可请求数量(REQUESTABLE_QTY_PER_NODE)与空闲量(UTILIZATION),并列出每个节点的 GPU 空闲情况,方便你据此规划任务调度。
四、在 GKE Autopilot 上使用 SkyPilot
GKE Autopilot 在空闲时会自动缩容到 0,因此 SkyPilot 必须把节点匹配(node-fit)决策交给 Autopilot 自身的调度器。在 SkyPilot 配置文件中做如下设置:
kubernetes: autoscaler: gke provision_timeout: 600其中autoscaler: gke告诉 SkyPilot 该集群由 GKE 自动扩缩容负责放置 Pod;provision_timeout: 600则是资源预配超时时间(秒),因为 Autopilot 的节点拉起通常比标准集群更慢。从源码看,autoscaler配置项在 sky/provision/kubernetes/utils.py 中被读取:一旦配置了autoscaler,SkyPilot 会采用该扩缩容器对应的标签格式并跳过自身的 GPU 预检查逻辑,把节点适配完全交给集群托管。
GKE Autopilot 下的已知限制
- 对象存储挂载(SkyPilot 内置 FUSE):
file_mounts中以MOUNT模式挂载云存储 URI 的功能依赖特权 DaemonSet 与hostPath,Autopilot 会拒绝此类负载。替代方案是通过 SkyPilot 卷(由 GCS FUSE CSI 驱动支撑)挂载 GCS bucket。 - 特权或 host 命名空间特性:Docker-in-Docker、GPUDirect TCPX/TCPXO、BuildKit 镜像构建、RDMA(
IPC_LOCK)、SSH Node Pools 等均不可用。 - 挂载 Kubernetes 节点的目录:通过 SkyPilot 的
k8s-hostpath卷类型或在pod_config中覆盖hostPath的方式访问节点文件系统,在 Autopilot 中不被允许(工作负载无法直接访问节点文件系统)。 - Pod 抢占:Autopilot 可能驱逐 Pod 以整合工作负载。对长时间运行的任务,建议使用
sky jobs launch提交,由 SkyPilot 的托管任务机制在抢占后自动恢复。
五、部署到 Amazon EKS
5.1 创建集群并获取 kubeconfig
创建一个至少含 1 个节点的 EKS 集群(同样建议节点至少 4 vCPU),然后更新本地 kubeconfig:
$ aws eks update-kubeconfig --name <cluster-name> --region <region> # 示例: # aws eks update-kubeconfig --name testcluster --region us-west-25.2 [GPU 场景] 用sky gpus label标记节点 GPU 类型
EKS 集群自带 NVIDIA 驱动,但需要为节点打上 GPU 类型标签,SkyPilot 才能识别并调度 GPU 任务。使用 SkyPilot 的节点打标命令:
$ sky gpus label该命令会在每个节点上创建一个 Job,读取nvidia-smi输出的 GPU 类型,并为节点打上skypilot.co/accelerator标签。当前该命令仅支持 NVIDIA GPU。可通过以下命令查看打标 Job 的状态:
$ kubectl get jobs -n kube-system5.3 源码剖析:GPU 打标的实现细节
sky gpus label的实现位于 sky/utils/kubernetes/gpu_labeler.py:
- 先调用
cleanup()删除旧的打标资源(按job=sky-gpu-labeler标签清理,保证幂等)。 - 通过
get_unlabeled_accelerator_nodes()找出尚未打标的 GPU 节点(节点Capacity中须有nvidia.com/gpu资源)。 - 渲染 RBAC 模板 k8s_gpu_labeler_setup.yaml.j2 并 apply;若集群中存在
nvidiaRuntimeClass(K3s 场景),打标 Job 会设置runtimeClassName: nvidia。 - 为每个节点按节点名 hash 生成
sky-gpu-labeler-<hash>的 Job,通过nodeSelector: kubernetes.io/hostname精确绑定到对应节点,Job 在节点内解析nvidia-smi并把节点标签 patch 为skypilot.co/accelerator: <gpu_name>(gpu_labeler.py)。 - 默认会等待所有 Job 完成(超时 20 分钟);失败时可用
sky gpus label --cleanup清理残留资源,也支持--context指定集群、--async异步执行。
打标完成后,可通过kubectl describe nodes检查节点上是否出现skypilot.co/accelerator格式的标签(对应kubernetes-setup.rst中"手动打标"一节的说明:标签必须是skypilot.co/accelerator: <gpu_name>,其中<gpu_name>为 GPU 型号的小写名称;AMD GPU 不支持自动打标,需手动处理)。
5.4 验证与查看 GPU
$ sky check $ sky gpus list --infra k8s GPU REQUESTABLE_QTY_PER_NODE UTILIZATION A100 1, 2 2 of 2 free Kubernetes per node GPU availability NODE GPU UTILIZATION my-cluster-0 A100 2 of 2 free六、在自建(on-prem)集群上部署
如果你有一批 IP 地址以及对应的 SSH 凭证,可以走 SkyPilot 的使用现有机器指南,直接把 SkyPilot 部署到现有的 on-prem 集群上,无需先装 Kubernetes。
另一种方式是使用现成的 Kubernetes 发行版工具先在 on-prem 环境搭好集群,再接入 SkyPilot:
- kubeadm:Kubernetes 官方生产环境部署工具;
- k3s:轻量级发行版,适合边缘与资源受限环境;
- Rancher:Rancher 集群管理平台。
请按各工具官方指南完成集群部署,再回到sky check验证 SkyPilot 接入。
七、特定发行版的 GPU 支持配置
部分 Kubernetes 发行版需要额外步骤才能启用 GPU 支持,这里给出官方指南重点提示的 RKE2 与 K3s 配置。
7.1 Rancher Kubernetes Engine 2(RKE2)
在 RKE2 上通过 Helm 安装 NVIDIA GPU Operator 时,必须额外设置参数把nvidia设为 containerd 的默认运行时:
$ helm install gpu-operator -n gpu-operator --create-namespace \ nvidia/gpu-operator $HELM_OPTIONS \ --set 'toolkit.env[0].name=CONTAINERD_CONFIG' \ --set 'toolkit.env[0].value=/var/lib/rancher/rke2/agent/etc/containerd/config.toml.tmpl' \ --set 'toolkit.env[1].name=CONTAINERD_SOCKET' \ --set 'toolkit.env[1].value=/run/k3s/containerd/containerd.sock' \ --set 'toolkit.env[2].name=CONTAINERD_RUNTIME_CLASS' \ --set 'toolkit.env[2].value=nvidia' \ --set 'toolkit.env[3].name=CONTAINERD_SET_AS_DEFAULT' \ --set-string 'toolkit.env[3].value=true'详细步骤请参考 NVIDIA 官方文档中关于 RKE2 上通过 Helm 安装 GPU Operator 的说明。
7.2 K3s
K3s 上安装 NVIDIA GPU Operator 与 RKE2 类似,区别在于CONTAINERD_CONFIG需改为 K3s 的路径/var/lib/rancher/k3s/agent/etc/containerd/config.toml。示例命令:
$ helm install gpu-operator -n gpu-operator --create-namespace \ nvidia/gpu-operator $HELM_OPTIONS \ --set 'toolkit.env[0].name=CONTAINERD_CONFIG' \ --set 'toolkit.env[0].value=/var/lib/rancher/k3s/agent/etc/containerd/config.toml' \ --set 'toolkit.env[1].name=CONTAINERD_SOCKET' \ --set 'toolkit.env[1].value=/run/k3s/containerd/containerd.sock' \ --set 'toolkit.env[2].name=CONTAINERD_RUNTIME_CLASS' \ --set 'toolkit.env[2].value=nvidia'安装过程中用以下命令查看进度(安装需数分钟,期间出现部分CrashLoopBackOff属正常现象):
$ kubectl get pods -n gpu-operator排障提示:若 gpu-operator 一直卡在
CrashLoopBackOff,可能是 nvidia-docker 运行时的已知问题,需要在各节点上为ldconfig创建符号链接绕开:$ ln -s /sbin/ldconfig /sbin/ldconfig.real
GPU Operator 安装完成后,还需创建 K3s 所需的nvidiaRuntimeClass。SkyPilot 调度 GPU Pod 时会自动使用该 RuntimeClass:
$ kubectl apply -f - <<EOF apiVersion: node.k8s.io/v1 kind: RuntimeClass metadata: name: nvidia handler: nvidia EOF八、在按需云 VM 上一键部署 Kubernetes
如果既没有现成的 on-prem 集群、也不想手工管理托管服务,SkyPilot 仓库提供了一个在按需云 VM 上部署 Kubernetes 的脚本方案,位于 examples/k8s_cloud_deploy/:
- README.md:完整使用说明;
- cloud_k8s.yaml:SkyPilot 任务定义(VM 资源配置 + 集群安装脚本);
- launch_k8s.sh:一键启动脚本。
8.1 使用步骤
- 安装最新 nightly 版 SkyPilot(需带 kubernetes 与目标云厂商的依赖):
pip install "skypilot-nightly[lambda,kubernetes]"- 使用支持端口开放的云(或在 VM 上手动放行 6443 与 443 端口),因为需要向外部暴露 k8s API Server。
- 编辑 cloud_k8s.yaml,设置工作节点数与每节点 GPU 规格;若使用 GCP/AWS/Azure,取消注释
ports行以放行 Kubernetes API Server 的入站连接:
resources: infra: lambda accelerators: A10:1 # ports: 6443 num_nodes: 2- 运行一键脚本启动集群:
./launch_k8s.shSkyPilot 会自动完成全部工作:预配云 VM、部署 k8s 集群、拉取 kubeconfig 并配置好本地kubectl。
8.2 集群安装脚本要点
从 cloud_k8s.yaml 的run段可以看到完整流程:head 节点通过curl -sfL https://get.k3s.io | K3S_TOKEN=${SKY_K3S_TOKEN} sh -安装 k3s 并复制 kubeconfig;worker 节点通过K3S_URL与共享 token 加入集群;随后安装 helm、部署 NVIDIA GPU Operator(含 K3s 的CONTAINERD_CONFIG参数与ldconfig补丁),最后创建nvidiaRuntimeClass,并用wait_for_gpu_operator_installation轮询等待 GPU 资源就绪——这套步骤正是第七节自建集群配置的自动化版本。
8.3 验证与使用
集群就绪后即可用kubectl与sky命令交互:
$ kubectl get nodes NAME STATUS ROLES AGE VERSION 129-80-133-44 Ready <none> 14m v1.30.4+k3s1 150-230-191-161 Ready control-plane,master 14m v1.30.4+k3s1 $ sky gpus list --cloud kubernetes Kubernetes GPUs GPU REQUESTABLE_QTY_PER_NODE UTILIZATION A10 1 2 of 2 free Kubernetes per node GPU availability NODE GPU UTILIZATION 129-80-133-44 A10 1 of 1 free 150-230-191-161 A10 1 of 1 free后续运行 AI 负载的方式与托管集群一致:
- 交互式开发集群:
sky launch -c mycluster --cloud kubernetes --gpus A10:1; - 提交托管任务:
sky jobs launch --gpus A10:1 --cloud kubernetes -- 'nvidia-smi; sleep 600',资源不足时 SkyPilot 会自动排队; - 观察 SkyPilot 创建的 Pod:
kubectl get pods。
集群使用完毕后,一条命令即可销毁:
sky down k8s九、部署后的通用验证清单
无论选择哪种部署方式,建议按以下清单收尾:
sky check:确认 SkyPilot 已启用 Kubernetes,所有场景的必做步骤;sky gpus list --infra k8s(GPU 集群):确认 GPU 类型、可请求数量与实时占用;kubectl describe nodes:确认节点Capacity中存在nvidia.com/gpu,且节点带有skypilot.co/accelerator标签;kubectl get jobs -n kube-system:EKS 打标场景下确认sky-gpu-labelerJob 已成功完成。
更完整的 Kubernetes 使用指南(端口配置、优先级调度、定价、故障排查等)可继续阅读 docs/source/reference/kubernetes/ 目录下的系列文档,例如 kubernetes-setup.rst、kubernetes-troubleshooting.rst 与 kubernetes-getting-started.rst。本文所述部署方式旨在帮助你把 Kubernetes 基础设施跑起来,后续的日常使用则以sky launch/sky jobs launch等 SkyPilot 命令为准。
【免费下载链接】skypilotThe AI Compute Platform for frontier teams. SkyPilot turns fragmented AI compute into one AI supercomputer, so frontier AI teams build custom intelligence faster.项目地址: https://gitcode.com/GitHub_Trending/sk/skypilot
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考