使用本地 SSH Key 登录 GCP Compute Engine 实例

random-pic-api

前言

因为现在的机场都不太稳定,而且还有 IP 污染这个坑,最近我在用 Claude Code 和 Codex 的时候总觉得有封号风险。折腾来折腾去,我索性在 GCP 买了一台虚拟机,准备自己搭个节点玩玩儿。

这篇记录就是我在 macOS 上配置 GCP 实例 SSH 登录时走的一遍完整流程,目标很简单:不依赖临时密钥,直接用本地固定私钥登录 Compute Engine

为了方便后面复用,我把关键命令和排查点都整理到一篇里,照着走基本可以一次打通。

环境信息

项目
GCP Project ID<your-gcp-project-id>
Zoneus-west1-b
Instance Name<your-instance-name>
External IP<your-instance-external-ip>
本地公钥~/.ssh/dev/gcp.pub
本地私钥~/.ssh/dev/gcp
Google 账号<your-google-account-email>
OS Login 用户名<your-os-login-username>

安装并初始化 gcloud

1) 安装 Google Cloud CLI

1
brew install --cask google-cloud-sdk

安装后检查版本:

1
gcloud --version

如果提示找不到 gcloud,先重新加载 shell 配置:

1
source ~/.zshrc

还不行的话,手动加载 SDK 路径:

1
2
source "$(brew --prefix)/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/path.zsh.inc"
source "$(brew --prefix)/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/completion.zsh.inc"

2) 初始化 gcloud

1
gcloud init

初始化时我选择了已有项目:

1
2
3
4
5
6
7
Pick cloud project to use:
[1] <your-gcp-project-id>
[2] gen-lang-client-0876271165
[3] lunar-mission-483702-a8
[4] Enter a project ID
[5] Create a new project
Please enter numeric choice or text value: 1

也可以手动设置默认项目和区域:

1
2
3
4
gcloud config set project <your-gcp-project-id>
gcloud config set compute/region us-west1
gcloud config set compute/zone us-west1-b
gcloud config list

配置 OS Login 与密钥

1) 添加本地 SSH 公钥到 OS Login

1
2
gcloud compute os-login ssh-keys add \
--key-file=~/.ssh/dev/gcp.pub

成功后会看到类似输出:

1
2
3
4
5
6
7
8
9
10
11
loginProfile:
name: '<your-google-user-id>'
posixAccounts:
- accountId: <your-gcp-project-id>
gid: '<your-posix-id>'
homeDirectory: /home/<your-os-login-username>
name: users/<your-google-account-email>/projects/<your-gcp-project-id>
operatingSystemType: LINUX
primary: true
uid: '<your-posix-id>'
username: <your-os-login-username>

这里最关键的是 username,后面 SSH 登录时要用它作为 Linux 用户名。

2) 查看实例信息

1
gcloud compute instances list

示例输出:

1
2
NAME                      ZONE        MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP      STATUS
<your-instance-name> us-west1-b e2-micro <your-instance-internal-ip> <your-instance-external-ip> RUNNING

开启 OS Login 并授权 IAM

1) 检查实例 metadata

1
2
3
gcloud compute instances describe <your-instance-name> \
--zone=us-west1-b \
--format="get(metadata.items)"

如果只看到 ssh-keys,但没有 enable-oslogin=TRUE,就需要开启 OS Login。

2) 为项目启用 OS Login

1
2
3
gcloud compute project-info add-metadata \
--metadata enable-oslogin=TRUE \
--project=<your-gcp-project-id>

检查是否生效:

1
2
3
gcloud compute project-info describe \
--project=<your-gcp-project-id> \
--format="flattened(commonInstanceMetadata.items[])"

确认输出里存在:

1
enable-oslogin: TRUE

3) 添加 OS Login IAM 权限

普通登录权限:

1
2
3
gcloud projects add-iam-policy-binding <your-gcp-project-id> \
--member="user:<your-google-account-email>" \
--role="roles/compute.osLogin"

需要 sudo 时用管理员权限(我这次用的是这个):

1
2
3
gcloud projects add-iam-policy-binding <your-gcp-project-id> \
--member="user:<your-google-account-email>" \
--role="roles/compute.osAdminLogin"

本地 SSH 配置

编辑 ~/.ssh/config

1
vim ~/.ssh/config

添加以下配置:

1
2
3
4
5
6
7
Host gcp
HostName <your-instance-external-ip>
User <your-os-login-username>
Port 22
IdentityFile ~/.ssh/dev/gcp
IdentitiesOnly yes
PreferredAuthentications publickey

字段说明:

配置项说明
Host gcp本地 SSH 别名
HostNameGCP 实例外网 IP
UserOS Login 返回的 Linux 用户名
PortSSH 端口,默认 22
IdentityFile本地私钥路径
IdentitiesOnly yes强制只使用指定私钥
PreferredAuthentications publickey优先公钥认证

私钥权限建议一起收紧:

1
2
3
4
chmod 700 ~/.ssh
chmod 700 ~/.ssh/dev
chmod 600 ~/.ssh/dev/gcp
chmod 644 ~/.ssh/dev/gcp.pub

登录与验证

直接登录:

1
ssh gcp

等价命令:

1
2
3
ssh -i ~/.ssh/dev/gcp \
-o IdentitiesOnly=yes \
<your-os-login-username>@<your-instance-external-ip>

登录后验证当前用户:

1
whoami

预期输出:

1
<your-os-login-username>

如果想做对照测试,也可以先用:

1
2
3
gcloud compute ssh <your-instance-name> \
--zone=us-west1-b \
--project=<your-gcp-project-id>

常见报错排查

Permission denied (publickey)

错误示例:

1
<your-os-login-username>@<your-instance-external-ip>: Permission denied (publickey).

按这个顺序检查最省时间:

  1. 确认私钥公钥是一对:

    1
    ssh-keygen -y -f ~/.ssh/dev/gcp
  2. 确认 SSH 真的用了目标私钥:

    1
    ssh -vvv gcp

    日志里应出现:

    1
    Offering public key: ~/.ssh/dev/gcp
  3. 确认 OS Login 已开启:

    1
    2
    3
    gcloud compute project-info describe \
    --project=<your-gcp-project-id> \
    --format="flattened(commonInstanceMetadata.items[])"
  4. 确认 IAM 角色已授予:

    1
    2
    3
    4
    gcloud projects get-iam-policy <your-gcp-project-id> \
    --flatten="bindings[].members" \
    --filter="bindings.members:user:<your-google-account-email>" \
    --format="table(bindings.role)"

    至少应包含其一:

    1
    2
    roles/compute.osLogin
    roles/compute.osAdminLogin

命令汇总

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 1. 安装 Google Cloud CLI
brew install --cask google-cloud-sdk

# 2. 初始化 gcloud
gcloud init

# 3. 设置默认项目和区域
gcloud config set project <your-gcp-project-id>
gcloud config set compute/region us-west1
gcloud config set compute/zone us-west1-b

# 4. 添加 SSH 公钥到 OS Login
gcloud compute os-login ssh-keys add \
--key-file=~/.ssh/dev/gcp.pub

# 5. 查看实例
gcloud compute instances list

# 6. 启用项目级 OS Login
gcloud compute project-info add-metadata \
--metadata enable-oslogin=TRUE \
--project=<your-gcp-project-id>

# 7. 添加 OS Login 管理员权限
gcloud projects add-iam-policy-binding <your-gcp-project-id> \
--member="user:<your-google-account-email>" \
--role="roles/compute.osAdminLogin"

# 8. 设置 SSH 私钥权限
chmod 700 ~/.ssh
chmod 700 ~/.ssh/dev
chmod 600 ~/.ssh/dev/gcp
chmod 644 ~/.ssh/dev/gcp.pub

# 9. 登录实例
ssh gcp

排查费用组合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
echo "== Project Billing =="
gcloud billing projects describe <your-gcp-project-id>

echo "\n== Running Instances =="
gcloud compute instances list --filter="status=RUNNING"

echo "\n== Disks =="
gcloud compute disks list

echo "\n== Static IP Addresses =="
gcloud compute addresses list

echo "\n== Snapshots =="
gcloud compute snapshots list

echo "\n== Firewall Rules =="
gcloud compute firewall-rules list