GCP#
注意
默认情况下,SkyPilot 会使用您已设置的凭据。在大多数情况下,安装说明 就是您需要做的全部。以下步骤是可选的高级配置选项,主要面向云管理员和高级用户。
服务帐号#
支持GCP 服务帐号。
提示
在您的本地机器上使用服务帐号可以避免定期出现的 google.auth.exceptions.RefreshError: Reauthentication is needed. Please run `gcloud auth application-default login` to reauthenticate.
错误。服务帐号没有有效期,因此是长效的。
设置服务帐号如下
按照说明 创建具有适当角色/权限的服务帐号。
在 IAM & Admin 控制台的“服务帐号”标签页中,点击服务帐号进入其详细页面。点击 KEYS 标签页,然后点击 ADD KEY 添加一个 JSON 密钥。密钥将自动下载。
将环境变量
GOOGLE_APPLICATION_CREDENTIALS
设置为密钥文件的路径,并配置 gcloud CLI 工具$ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json $ gcloud auth activate-service-account --key-file=$GOOGLE_APPLICATION_CREDENTIALS $ gcloud config set project your-project-id
您可能希望将 export 语句添加到您的配置文件(例如
~/.bashrc
,~/.zshrc
)中,以便在所有新的终端会话中自动设置它。
设置权限#
通常,管理员可以在三种权限“级别”中选择,从最宽松且设置工作量最小,到最不宽松且设置工作量更大
中等权限#
授予用户访问您的 GCP 项目而无需 Owner
角色的最简单方法是向用户主体添加以下角色
roles/browser
roles/compute.admin
roles/iam.serviceAccountAdmin
roles/iam.serviceAccountUser
roles/serviceusage.serviceUsageConsumer
roles/storage.admin
roles/iam.securityAdmin
注意
如果 roles/iam.securityAdmin
角色不合意,您可以执行以下操作。首先,包含该角色并让任何用户(例如管理员)成功运行一次 sky launch --cloud gcp
。这是为了创建必要的服务帐号。然后,在上面的列表中将 roles/iam.securityAdmin
角色替换为 roles/iam.roleViewer
。
可选地,要使用 TPU,添加以下角色
roles/tpu.admin
您可以通过 GCP 的 IAM & Admin 控制台授予这些访问权限。
最小权限#
中等权限 将某些 GCP 服务的管理员权限分配给用户。如果您希望在您的组织/项目中为用户授予更精细和更小的权限,您可以按照以下步骤创建自定义角色
转到 GCP 的 IAM & Admin 控制台,然后点击 Create Role(创建角色)。

为角色指定一个描述性名称,例如
minimal-skypilot-role
。点击 Add Permissions(添加权限)并搜索以下权限并将它们添加到角色中
compute.disks.create
compute.disks.list
compute.firewalls.create
compute.firewalls.delete
compute.firewalls.get
compute.instances.create
compute.instances.delete
compute.instances.get
compute.instances.list
compute.instances.setLabels
compute.instances.setMetadata
compute.instances.setServiceAccount
compute.instances.start
compute.instances.stop
compute.networks.get
compute.networks.list
compute.networks.getEffectiveFirewalls
compute.globalOperations.get
compute.subnetworks.use
compute.subnetworks.list
compute.subnetworks.useExternalIp
compute.projects.get
compute.zoneOperations.get
iam.roles.get
iam.serviceAccounts.actAs
iam.serviceAccounts.get
serviceusage.services.enable
serviceusage.services.list
serviceusage.services.use
resourcemanager.projects.get
resourcemanager.projects.getIamPolicy
注意
对于自定义 VPC 用户(在 ~/.sky/config.yaml
中指定了 gcp.vpc_name
,请在此处查看),除非需要通过任务 yaml 中的 resources.ports 开放端口,否则无需 compute.firewalls.create
和 compute.firewalls.delete
权限。
注意
(高级)要进一步限制 iam.serviceAccounts.actAs
权限仅访问 SkyPilot 的服务帐号,您可以从上面的列表中移除该权限,并额外授予组织用户使用管理员创建的服务帐号 skypilot-v1
的能力(参见服务帐号)。可以通过转到 IAM & Admin 控制台 -> 服务帐号 -> skypilot-v1 -> 权限 -> 授予访问权限
并添加具有 roles/iam.serviceAccountUser
角色的用户来实现。这将允许用户使用 SkyPilot 所需的 skypilot-v1
服务帐号。
可选:如果用户需要访问 GCS 存储桶,您可以额外添加以下权限
storage.buckets.create
storage.buckets.get
storage.buckets.delete
storage.objects.create
storage.objects.update
storage.objects.delete
storage.objects.get
storage.objects.list
可选:如果用户需要访问 TPU VM,您可以额外添加以下权限(以下列表可能不详尽,如果您发现任何缺失的权限,请提交问题)
tpu.nodes.create
tpu.nodes.delete
tpu.nodes.list
tpu.nodes.get
tpu.nodes.update
tpu.operations.get
可选:要启用
sky launch --clone-disk-from
,您还需要为该角色拥有以下权限
compute.disks.useReadOnly
compute.images.create
compute.images.get
compute.images.delete
可选:要启用在 GCP 集群上开放端口,您还需要为该角色拥有以下权限
compute.instances.setTags
compute.firewalls.list
compute.firewalls.update
可选:如果用户需要使用自定义机器镜像并结合
sky launch --image-id
,您可以额外添加以下权限
compute.disks.get
compute.disks.resize
compute.images.get
compute.images.useReadOnly
可选:如果您的组织在 ~/.sky/config.yaml 中设置了
gcp.prioritize_reservations
或gcp.specific_reservations
,您可以额外添加以下权限
compute.reservations.list
点击 Create(创建)来创建角色。
回到“IAM”标签页并点击 GRANT ACCESS(授予访问权限)。
在“添加主体”部分填写用户的电子邮件地址,并在“分配角色”部分选择
minimal-skypilot-role
。点击 Save(保存)。

用户应该会收到项目的邀请,并应该能够按照安装中的说明设置 SkyPilot。
SkyPilot 系统的服务帐号#
注意
如果您在“服务帐号”标签下已经有一个电子邮件以 skypilot-v1@
开头的服务帐号,那很可能是 SkyPilot 自动创建的,您可以跳过本节。
在 IAM & Admin 控制台中点击“服务帐号”标签页,然后点击 CREATE SERVICE ACCOUNT(创建服务帐号)。

将服务帐号 ID 设置为
skypilot-v1
并点击 CREATE AND CONTINUE(创建并继续)。

3. 选择上一节中创建的 minimal-skypilot-role
(或您设置的名称)并点击 DONE(完成)。您也可以选择使用前面几节中描述的默认权限或中等权限角色。

防火墙规则#
默认情况下,用户无需设置任何特殊的防火墙规则即可开始使用 SkyPilot。如果默认 VPC 不满足最低要求的规则,将自动创建一个具有足够规则的新 VPC skypilot-vpc
并使用它。
但是,如果您手动设置并指示 SkyPilot 使用自定义 VPC(参见下方),请确保它具有以下必需的防火墙规则
# Allow internal connections between SkyPilot VMs:
#
# controller -> head node of a cluster
# head node of a cluster <-> worker node(s) of a cluster
#
# NOTE: these ports are more relaxed than absolute minimum, but the
# sourceRanges restrict the traffic to internal IPs.
{
"direction": "INGRESS",
"allowed": [
{"IPProtocol": "tcp", "ports": ["0-65535"]},
{"IPProtocol": "udp", "ports": ["0-65535"]},
],
"sourceRanges": ["10.128.0.0/9"],
},
# Allow SSH connections from user machine(s)
#
# NOTE: This can be satisfied using the following relaxed sourceRanges
# (0.0.0.0/0), but you can customize it if you want to restrict to certain
# known public IPs (useful when using internal VPN or proxy solutions).
{
"direction": "INGRESS",
"allowed": [
{"IPProtocol": "tcp", "ports": ["22"]},
],
"sourceRanges": ["0.0.0.0/0"],
},
您可以在 https://console.cloud.google.com/net-security/firewall-manager/firewall-policies/list?project=<your-project-id>
或使用任何 GCP 的 SDK 检查和管理防火墙规则。
使用特定 VPC#
默认情况下,SkyPilot 使用以下行为获取一个 VPC 以供所有 GCP 实例使用
首先,检查项目中所有现有的 VPC 是否满足 SkyPilot 运行所需的最低推荐防火墙规则。如果任何 VPC 满足这些规则,则使用它。
否则,将自动创建一个名为
skypilot-vpc
的新 VPC,该 VPC 具有最低推荐的防火墙规则,并将被使用。它是一个自动模式 VPC,每个区域会自动启动一个子网。
要指示 SkyPilot 使用特定 VPC,您可以使用 SkyPilot 的全局配置文件 ~/.sky/config.yaml
在 gcp.vpc_name
字段中指定 VPC 名称
gcp:
vpc_name: my-vpc-name
详细信息请参见高级配置。示例用例包括使用私有 VPC 或具有精细限制的 VPC,这些 VPC 通常通过 Terraform 或手动创建。
自定义 VPC 应包含必需的防火墙规则。
使用内部 IP#
出于安全原因,用户可能只希望为 SkyPilot 实例使用内部 IP。为此,您可以使用 SkyPilot 的全局配置文件 ~/.sky/config.yaml
来指定 gcp.use_internal_ips
和 gcp.ssh_proxy_command
字段(要查看详细语法,请参阅高级配置)
gcp:
use_internal_ips: true
# VPC with NAT setup, see below
vpc_name: my-vpc-name
ssh_proxy_command: ssh -W %h:%p -o StrictHostKeyChecking=no [email protected]
The gcp.ssh_proxy_command
field is optional. If SkyPilot is run on a machine that can directly access the internal IPs of the instances, it can be omitted. Otherwise, it should be set to a command that can be used to proxy SSH connections to the internal IPs of the instances.
以下是两种启用 SkyPilot 访问这些私有主机的方法
选项 1 – SSH 代理 / 跳板机
选项 2 – IAP 隧道 (Identity‑Aware Proxy) 这通常更简单,因为您无需运行或保护自己的跳板机;Google 在边缘处理隧道。
选择适合您环境的方法。
选项 1:简单的单代理示例#
如果您有一台“跳板机”,可以从运行 SkyPilot 的机器直接访问它,请告诉 SkyPilot 如何通过它建立 SSH 隧道
gcp:
use_internal_ips: true
vpc_name: my-vpc-name
ssh_proxy_command: ssh -W %h:%p -o StrictHostKeyChecking=no [email protected]
当涉及多个区域时,您可以将每个区域映射到其自己的代理(就像之前一样)
gcp:
use_internal_ips: true
vpc_name: my-vpc-name
ssh_proxy_command:
us-west1: ssh -W %h:%p -o StrictHostKeyChecking=no [email protected]
us-east1: ssh -W %h:%p -o StrictHostKeyChecking=no [email protected]
选项 2:IAP 隧道#
IAP TCP 转发会在您的工作站与 GCP VPC 中的任何私有 IP 之间创建一个经过身份验证的隧道——无需公共 IP、VPN 或自行管理的跳板机。SkyPilot 实现了基于 IP(目标组)的模式;尚不支持按实例模式。
设置#
每个项目启用一次 API
$ gcloud services enable iap.googleapis.com
此方法需要 IAP 隧道权限。除了 SkyPilot 所需的其他权限 外,在目标组(或项目范围内)添加内置角色
roles/iap.tunnelResourceAccessor
是最简单的方法。您启动仅内部 VM 的每个区域都必须存在 Cloud NAT 网关,以便它们可以访问互联网进行软件包安装。参见Cloud NAT 设置。
以下脚本可用于在特定的 VPC 区域设置 IAP 隧道
自动化设置脚本(按区域)
#!/usr/bin/env bash
# Set your region and VPC.
REGION=us-east1 # e.g. us-west1, europe-west4, ...
VPC=default # change if using a custom VPC
#######################################################################
# 1. Cloud NAT (if none exists) #
#######################################################################
nat_exists=false
for r in $(gcloud compute routers list --regions="$REGION" \
--format='value(name)'); do
if gcloud compute routers nats list --router="$r" --region="$REGION" \
--format='value(name)' | grep -q .; then
nat_exists=true
fi
done
if [ "$nat_exists" = false ]; then
gcloud compute routers create nat-router --network="$VPC" --region="$REGION"
gcloud compute routers nats create nat-config \
--router=nat-router --router-region="$REGION" \
--nat-all-subnet-ip-ranges --auto-allocate-nat-external-ips
fi
#######################################################################
# 2. IAP destination group covering the subnet CIDR #
#######################################################################
CIDR=$(gcloud compute networks subnets list --network="$VPC" \
--regions="$REGION" --format='value(ipCidrRange)')
gcloud iap tcp dest-groups create "internal-vpc-$VPC" \
--region="$REGION" --ip-range-list="$CIDR"
#######################################################################
# 3. Show the SkyPilot config snippet #
#######################################################################
echo "Update your config.yaml to add the new gcp.ssh_proxy_command.$REGION value:"
echo
cat <<EOF
gcp:
use_internal_ips: true
ssh_proxy_command:
$REGION: gcloud compute start-iap-tunnel %h %p --listen-on-stdin --region=$REGION --network=$VPC --dest-group=internal-vpc-$VPC
EOF
# Automatically do it
read -p 'Automatically update ~/.sky/config.yaml? [y/N] ' choice
if echo "$choice" | grep -xqE '[yY]'; then
yq -Yi ".gcp.use_internal_ips=true | .gcp.ssh_proxy_command[\"$REGION\"]=\"gcloud compute start-iap-tunnel %h %p --listen-on-stdin --region=$REGION --network=$VPC --dest-group=internal-vpc-$VPC\"" ~/.sky/config.yaml
else
echo 'Aborting.'
fi
将打印出的片段粘贴到您的 ~/.sky/config.yaml
中(或者让脚本自动修改)。
创建目标组后,请确保在 SkyPilot 配置中设置 ssh_proxy_command
。例如,如果您有
目标组:
internal-vpc-default
区域:
us-east1
VPC:
default
您可以使用此配置
gcp:
use_internal_ips: true
ssh_proxy_command:
us-east1: gcloud compute start-iap-tunnel %h %p --listen-on-stdin --region=us-east1 --network=default --dest-group=internal-vpc-default
工作原理#
sky launch
创建没有外部 IP 的 VM。连接到实例时,
ssh
使用上面显示的 IAP 代理命令。gcloud compute start-iap-tunnel
通过 Google 的边缘透明地将连接转发到 VM 的私有地址。SSH 数据包通过经过身份验证的 IAP 隧道传输——不会暴露任何公共入口。
故障排除#
打开隧道时出现 Permission denied / 403 → 调用者缺少目标组上的
roles/iap.tunnelResourceAccessor
权限(或等效的自定义角色)。VM 无法访问互联网 → 确保 Cloud NAT 网关与子网位于同一区域,并且
--nat-all-subnet-ip-ranges
已启用。多个子网或 VPC → 为每个 区域 × CIDR 创建一个目标组,并在
ssh_proxy_command
中将每个区域映射到正确的组。
Cloud NAT 设置#
默认情况下,在 GCP 上仅使用内部 IP 创建的实例无法访问公共互联网。为确保 SkyPilot 可以在实例上正确安装依赖项,需要为 VPC 设置 Cloud NAT(有关详细信息,请参阅GCP 的文档)。
Cloud NAT 是区域资源,因此需要在 SkyPilot 将要使用的每个区域中创建它。

要将 SkyPilot 限制为仅使用某些特定区域,您可以将 gcp.ssh_proxy_command
指定为一个字典,将区域映射到该区域的 SSH 代理命令(详细信息请参阅高级配置)
gcp:
use_internal_ips: true
vpc_name: my-vpc-name
ssh_proxy_command:
us-west1: ssh -W %h:%p -o StrictHostKeyChecking=no [email protected]
us-east1: ssh -W %h:%p -o StrictHostKeyChecking=no [email protected]
如果不需要代理,但需要限制区域,您可以将 gcp.ssh_proxy_command
设置为一个字典,将区域映射到 null
gcp:
use_internal_ips: true
vpc_name: my-vpc-name
ssh_proxy_command:
us-west1: null
us-east1: null
强制启用外部 IP#
对于需要访问公共互联网但位于 VPC 中并通过其内部 IP 进行通信的实例,除了设置 Cloud NAT 之外,另一种替代方法是强制创建它们时包含外部 IP 地址。
gcp:
use_internal_ips: true
vpc_name: my-vpc-name
force_enable_external_ips: true