Kubernetes入门指南#
先决条件#
要连接并使用Kubernetes集群,SkyPilot需要:
一个现有的运行Kubernetes v1.20或更高版本的Kubernetes集群。
一个包含访问凭证和要使用的命名空间的Kubeconfig文件。
支持的Kubernetes部署:
托管的Kubernetes服务(EKS, GKE)
本地集群(Kubeadm, Rancher, K3s)
本地开发集群(KinD, minikube)
在典型的工作流程中:
集群管理员设置一个Kubernetes集群。请参考不同部署环境(Amazon EKS、Google GKE、本地和本地调试)的Kubernetes集群设置的管理指南。
想要在此集群上运行SkyPilot任务的用户将获得包含其凭据的Kubeconfig文件(kube-context)。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 TOTAL_GPUS TOTAL_FREE_GPUS
L4 1, 2, 4 12 12
H100 1, 2, 4, 8 16 16
Kubernetes per node GPU availability
NODE_NAME GPU_NAME TOTAL_GPUS FREE_GPUS
my-cluster-0 L4 4 4
my-cluster-1 L4 4 4
my-cluster-2 L4 2 2
my-cluster-3 L4 2 2
my-cluster-4 H100 8 8
my-cluster-5 H100 8 8
使用自定义图像#
默认情况下,我们维护并使用两个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依赖项,以便快速启动。
要使用您自己的镜像,请将image_id: docker:添加到任务YAML的resources部分。
resources:
image_id: docker:myrepo/myimage:latest
...
您的图像必须满足以下要求:
镜像必须是基于debian的,并且必须安装apt包管理器。
镜像中的默认用户必须具有root权限或无密码sudo访问权限。
注意
如果你的集群运行在非x86_64架构上(例如,Apple Silicon),你的镜像必须为该架构原生构建。否则,你的任务可能会卡在Start streaming logs ...。更多信息请参见GitHub issue。
使用私有仓库中的镜像#
要从私有仓库(例如,私有 DockerHub、Amazon ECR、Google 容器注册表)使用镜像,请在您的 Kubernetes 集群中创建一个 secret,并编辑您的 ~/.sky/config.yaml 文件以指定 secret,如下所示:
kubernetes:
pod_config:
spec:
imagePullSecrets:
- name: your-secret-here
提示
如果您使用Amazon ECR,您的秘密凭证可能每12小时过期一次。考虑使用k8s-ecr-login-renew来自动刷新您的秘密。
打开端口#
在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 pods#
你可以通过在~/.sky/config.yaml中设置pod_config键来覆盖SkyPilot使用的pod配置。
pod_config的值应该是一个遵循Kubernetes Pod API的字典。这将适用于由SkyPilot创建的所有pod。
例如,要设置自定义环境变量并使用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
同样地,你可以直接将Kubernetes卷(例如,一个NFS卷)附加到你的SkyPilot pods上:
# ~/.sky/config.yaml
kubernetes:
pod_config:
spec:
containers:
- volumeMounts: # Custom volume mounts for the pod
- mountPath: /data
name: nfs-volume
volumes:
- name: nfs-volume
nfs: # Alternatively, use hostPath if your NFS is directly attached to the nodes
server: nfs.example.com
path: /nfs
提示
作为全局设置pod_config的替代方案,你也可以在任务YAML中直接使用config_overrides 字段在每个任务的基础上进行设置。
# task.yaml
run: |
python myscript.py
# Set pod_config for this task
experimental:
config_overrides:
pod_config:
...
常见问题解答#
我可以将多个Kubernetes集群与SkyPilot一起使用吗?
SkyPilot 可以与您的 kubeconfig 文件中设置的多个 Kubernetes 上下文一起工作。默认情况下,SkyPilot 将使用当前活动的上下文。要使用不同的上下文,请使用
kubectl config use-context更改您的当前上下文。如果您希望在故障转移期间无缝使用多个上下文,请查看高级配置中的
allowed_contexts功能。是否支持自动扩展Kubernetes集群?
要在自动扩展集群上运行,请在
~/.sky/config.yaml中将provision_timeout键设置为一个较大的值,以便为集群自动扩展器提供足够的时间来配置新节点。 这将指示SkyPilot在集群扩展之前等待,然后再切换到下一个候选资源(例如,下一个云)。如果您在零扩展设置中使用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 in scale-to-zero setting
SkyPilot 能为我配置一个 Kubernetes 集群吗?SkyPilot 会为我的 Kubernetes 集群添加更多节点吗?
Kubernetes支持的目标是在现有的Kubernetes集群上运行SkyPilot任务。它不会配置任何新的Kubernetes集群,也不会向现有的Kubernetes集群添加新节点。
我的组织中有多个用户共享同一个Kubernetes集群。我如何为他们的SkyPilot工作负载提供隔离?
为了实现隔离,您可以创建单独的Kubernetes命名空间,并将它们设置在分发给用户的kubeconfig中。SkyPilot将使用kubeconfig中设置的命名空间来运行所有任务。
如何查看我在Kubernetes集群上由SkyPilot创建的pods?
您可以使用现有的可观测性工具来过滤带有标签
parent=skypilot的资源 (kubectl get pods -l 'parent=skypilot')。例如,按照 这里 的说明在您的集群上部署 Kubernetes Dashboard。我正在使用自定义镜像。如何加快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