本文档介绍使用 SSH 连接到虚拟机实例时可能会遇到的常见错误、解决错误的方法以及诊断失败的 SSH 连接的方法。
SSH 问题排查工具
使用 SSH 问题排查工具来帮助确定 SSH 连接失败的原因。问题排查工具会执行以下测试,以检查 SSH 连接失败的原因:
- 用户权限测试:检查您是否具有使用 SSH 连接到虚拟机所需的 IAM 权限
- 网络连接测试:检查虚拟机是否已连接到网络
- 虚拟机实例状态测试:检查虚拟机的 CPU 状态,了解虚拟机是否正在运行。
- VPC 设置测试:检查默认 SSH 端口。
运行问题排查工具
您可以使用 Google Cloud 控制台或 Google Cloud CLI 检查可能导致 SSH 连接失败的网络问题和用户权限错误。
控制台
SSH 连接失败后,您可以选择重试连接,或使用浏览器中的 SSH 问题排查工具来诊断连接问题。
要运行问题排查工具,请点击问题排查。
gcloud
使用 gcloud compute ssh
命令运行问题排查工具:
gcloud compute ssh VM_NAME \ --troubleshoot
将 VM_NAME
替换为无法连接的虚拟机的名称。
该工具会提示您提供执行问题排查测试的权限。
查看结果
运行问题排查工具后,请执行以下操作:
- 查看测试结果,了解虚拟机的 SSH 连接无法正常工作的原因。
- 通过执行该工具提供的补救步骤来解决 SSH 连接问题。
尝试重新连接到虚拟机。
如果连接失败,请尝试执行以下操作来手动排查问题:
常见 SSH 错误
以下是使用 SSH 连接到 Compute Engine 虚拟机时可能会遇到的常见错误示例。
SSH-in-Browser 错误
未经授权错误 401
当您从 Google Cloud 控制台使用 SSH-in-browser 连接到虚拟机时,可能会发生以下错误:
Unauthorized Error 401
如果您的用户属于在 Google Workspace 中管理的组织,并且 Workspace 政策中存在有效限制,导致用户无法访问 SSH-in-browser 和 Google Cloud 中的串行控制台,则会发生此错误。
如需解决此问题,请让 Google Workspace 管理员执行以下操作:
-
如果 Google Cloud 被停用,请启用它并重试连接。
-
如果这些服务被停用,请启用它们并重试连接。
如果在 Google Workspace 中启用 Google Cloud 设置后问题仍然存在,请执行以下操作:
从您启动 SSH-in-Browser SSH 连接时开始,以 HTTP 归档格式 (HAR) 文件的形式捕获网络流量。
创建 Cloud Customer Care 支持请求并附上 HAR 文件。
无法连接,正在重试…
启动 SSH 会话时,可能会出现以下错误:
Could not connect, retrying ...
如需解决此问题,请执行以下操作:
虚拟机启动完成后,请重试连接。如果连接不成功,请运行以下命令,验证虚拟机是否未以紧急模式启动:
gcloud compute instances get-serial-port-output VM_NAME \ | grep "emergency mode"
如果虚拟机在紧急模式下启动,请排查虚拟机启动过程,以确定启动过程失败的位置。
在串行控制台中运行以下命令,验证
google-guest-agent.service
服务是否正在运行。systemctl status google-guest-agent.service
如果该服务已停用,请运行以下命令启用并启动该服务:
systemctl enable google-guest-agent.service systemctl start google-guest-agent.service
验证 Linux Google 代理脚本是否已安装并正在运行。如需了解详情,请参阅确定 Google 客服人员状态。如果未安装 Linux Google 代理,请重新安装。
请验证您是否拥有连接到虚拟机所需的角色。如果您的虚拟机使用 OS Login,请参阅分配 OS Login IAM 角色。如果虚拟机没有使用 OS Login,则您需要 Compute Instance Admin 角色或 Service Account User 角色(如果虚拟机设置为以服务账号运行)。您需要具备这些角色才能更新实例或项目 SSH 密钥元数据。
运行以下命令,验证是否存在允许通过 SSH 访问的防火墙规则:
gcloud compute firewall-rules list | grep "tcp:22"
验证是否有通往互联网(或堡垒主机)的默认路由。如需了解详情,请参阅检查路线。
确保根卷没有耗尽磁盘可用空间。如需了解详情,请参阅排查完整磁盘和磁盘大小调整问题。
运行以下命令,确保虚拟机未耗尽内存:
gcloud compute instances get-serial-port-output instance-name \ | grep "Out of memory: Kill process" - e "Kill process" -e "Memory cgroup out of memory" -e "oom"
如果虚拟机出现内存不足问题,请连接到串行控制台进行问题排查。
Linux 错误
权限遭拒(公钥)
在连接到虚拟机时可能会出现以下错误:
USERNAME@VM_EXTERNAL_IP: Permission denied (publickey).
此错误可能是由多种原因造成的。以下是导致此错误的最常见原因:
使用存储在元数据中的 SSH 密钥连接到启用了 OS Login 的虚拟机。如果您的项目启用了 OS Login,则虚拟机不接受存储在元数据中的 SSH 密钥。 如果您不确定是否已启用 OS Login,请参阅检查是否已配置 OS Login。
要解决此问题,请尝试以下方法之一:
- 使用 Google Cloud 控制台或 Google Cloud CLI 连接到您的虚拟机。如需了解详情,请参阅连接到虚拟机。
- 将 SSH 密钥添加到 OS Login。如需了解详情,请参阅将密钥添加到使用 OS Login 的虚拟机。
- 停用 OS Login。如需了解详情,请参阅停用 OS Login。
使用存储在 OS Login 配置文件中的 SSH 密钥连接到未启用 OS Login 的虚拟机。如果您停用了 OS Login,则虚拟机不接受存储在 OS Login 配置文件中的 SSH 密钥。 如果您不确定是否已启用 OS Login,请参阅检查是否已配置 OS Login。
要解决此问题,请尝试以下方法之一:
- 使用 Google Cloud 控制台或 Google Cloud CLI 连接到您的虚拟机。如需了解详情,请参阅连接到虚拟机。
- 启用 OS Login。如需了解详情,请参阅启用 OS Login。
- 将 SSH 密钥添加到元数据。如需了解详情,请参阅将 SSH 密钥添加到使用基于元数据的 SSH 密钥的虚拟机。
虚拟机已启用 OS Login,但您的 IAM 权限不足以使用 OS Login。 如需连接到已启用 OS Login 的虚拟机,您必须具有 OS Login 所需的权限。如果您不确定是否已启用 OS Login,请参阅检查是否已配置 OS Login。
如需解决此问题,请授予必要的 OS Login IAM 角色。
您的密钥已过期,Compute Engine 删除了
~/.ssh/authorized_keys
文件。如果您手动将 SSH 密钥添加到虚拟机,然后使用 Google Cloud 控制台连接到虚拟机,则 Compute Engine 为您的连接创建了新的密钥对。新的密钥对过期后,Compute Engine 删除了虚拟机中的~/.ssh/authorized_keys
文件,其中包含您手动添加的 SSH 密钥。要解决此问题,请尝试以下方法之一:
- 使用 Google Cloud 控制台或 Google Cloud CLI 连接到您的虚拟机。如需了解详情,请参阅连接到虚拟机。
- 将 SSH 密钥重新添加到元数据。如需了解详情,请参阅将 SSH 密钥添加到使用基于元数据的 SSH 密钥的虚拟机。
您使用了第三方工具进行连接,并且 SSH 命令配置有误。如果使用
ssh
命令进行连接,但未指定指向私钥的路径,或者指向私钥的路径不正确,则虚拟机会拒绝连接。要解决此问题,请尝试以下方法之一:
- 运行以下命令:
ssh -i PATH_TO_PRIVATE_KEY USERNAME@EXTERNAL_IP
替换以下内容:PATH_TO_PRIVATE_KEY
:您的 SSH 私钥文件的路径。USERNAME
:连接到该实例的用户的用户名。如果您在元数据中管理 SSH 密钥,则用户名是您在创建 SSH 密钥时指定的名称。对于 OS Login 账号,用户名在 Google 个人资料中定义。EXTERNAL_IP
:您的虚拟机的外部 IP 地址。
- 使用 Google Cloud 控制台或 Google Cloud CLI 连接到您的虚拟机。当您使用这些工具进行连接时,Compute Engine 会为您管理密钥创建。如需了解详情,请参阅连接到虚拟机。
- 运行以下命令:
您的虚拟机客机环境未在运行。如果这是您第一次连接到虚拟机并且客机环境未在运行,则虚拟机可能会拒绝您的 SSH 连接请求。
如需解决此问题,请执行以下操作:
- 重启虚拟机。
- 在 Google Cloud 控制台中,检查串行端口输出中的系统启动日志,以确定客机环境是否正在运行。如需了解详情,请参阅验证客机环境。
- 如果客机环境未运行,请通过克隆虚拟机的启动磁盘并使用启动脚本手动安装客机环境。
OpenSSH 守护程序 (
sshd
) 未运行或配置不正确。sshd
通过 SSH 协议提供对系统的安全远程访问。如果该服务器配置不正确或未运行,您将无法通过 SSH 连接到虚拟机。如需解决此问题,请尝试以下一项或多项操作:
查阅操作系统的用户指南,确保正确设置了
sshd_config
。确保您拥有以下内容的必要所有权和权限设置:
$HOME
和$HOME/.ssh
目录$HOME/.ssh/authorized_keys
文件
负责
客机环境会将已获授权的 SSH 公钥存储在
$HOME/.ssh/authorized_keys
文件中。$HOME
和$HOME/.ssh
目录以及$HOME/.ssh/authorized_keys
文件的所有者必须与连接虚拟机的用户相同。权限
客机环境需要以下 Linux 权限:
路径 权限 /home
0755
$HOME
0700
或0750
或0755
*$HOME/.ssh
0700
$HOME/.ssh/authorized_keys
0600
* 如需了解哪些选项是
$HOME
目录的正确默认权限,请参阅适用于您的特定 Linux 发行版的官方文档。
或者,您也可以基于同一映像创建新虚拟机,并检查
$HOME
的默认权限。通过运行以下命令重启
sshd
:systemctl restart sshd.service
通过运行以下命令检查状态是否存在任何错误:
systemctl status sshd.service
状态输出可能包含退出代码、失败原因等信息。您可以使用这些详细信息进一步进行问题排查。
虚拟机的启动磁盘已满。建立 SSH 连接后,客机环境会将会话的 SSH 公钥添加到
~/.ssh/authorized_keys
文件。如果磁盘已满,则连接会失败。如需解决此问题,请执行以下一项或多项操作:
- 通过使用串行控制台进行调试来发现
no space left errors
,确认启动磁盘已满。 - 调整磁盘大小。
- 如果您知道哪些文件正在使用磁盘可用空间,可创建启动脚本以删除不必要的文件并释放空间。虚拟机启动并且您连接到虚拟机后,请删除
startup-script
元数据。
- 通过使用串行控制台进行调试来发现
$HOME
、$HOME/.ssh
或$HOME/.ssh/authorized_keys
上的权限或所有权有误。负责
客机环境会将已获授权的 SSH 公钥存储在
$HOME/.ssh/authorized_keys
文件中。$HOME
和$HOME/.ssh
目录以及$HOME/.ssh/authorized_keys
文件的所有者必须与连接虚拟机的用户相同。权限
客机环境需要以下 Linux 权限:
路径 权限 /home
0755
$HOME
0700
或0750
或0755
*$HOME/.ssh
0700
$HOME/.ssh/authorized_keys
0600
* 如需了解哪些选项是
$HOME
目录的正确默认权限,请参阅适用于您的特定 Linux 发行版的官方文档。
或者,您也可以基于同一映像创建新虚拟机,并检查
$HOME
的默认权限。
连接失败
从 Google Cloud 控制台、gcloud CLI、堡垒主机或本地客户端连接到虚拟机时,可能会出现以下错误:
Google Cloud 控制台:
Connection Failed We are unable to connect to the VM on port 22.
gcloud CLI:
ERROR: (gcloud.compute.ssh) [/usr/bin/ssh] exited with return code [255].
堡垒主机或本地客户端:
port 22: Connection timed out.
port 22: Connection refused
出现这些错误可能有多种原因。以下是导致这些错误的一些最常见原因:
虚拟机正在启动,而
sshd
尚未运行。在虚拟机运行之前您无法连接到虚拟机。如需解决此问题,请等待虚拟机完成启动,并尝试重新连接。
sshd
在自定义端口上运行。如果您将sshd
配置为在端口 22 以外的端口上运行,您将无法连接到虚拟机。如需解决此问题,请使用以下命令创建自定义防火墙规则,以允许
sshd
运行的端口上的tcp
流量:gcloud compute firewall-rules create FIREWALL_NAME \ --allow tcp:PORT_NUMBER
如需详细了解如何创建防火墙规则,请参阅创建防火墙规则。
SSH 防火墙规则缺失或不允许来自 IAP 或公共互联网的流量。如果防火墙规则不允许来自 IP 范围
0.0.0.0/0
的 IAP 或 TCP 入站流量的连接,则 SSH 连接会被拒绝。如需解决此问题,请执行以下某项操作:
如果您使用 Identity-Aware Proxy (IAP) 进行 TCP 转发,请更新自定义防火墙规则以接受来自 IAP 的流量,然后检查 IAM 权限。
- 更新自定义防火墙规则,以允许来自
35.235.240.0/20
(IAP 用于 TCP 转发的 IP 地址范围)的流量。如需了解详情,请参阅创建防火墙规则。 - 授予使用 IAP TCP 转发的权限(如果您尚未授予权限)。
- 更新自定义防火墙规则,以允许来自
如果您不使用 IAP,请更新自定义防火墙规则以允许入站 SSH 流量。
- 更新自定义防火墙规则以允许到虚拟机的入站 SSH 连接。
升级虚拟机内核后 SSH 连接失败。内核更新后,虚拟机可能会遇到内核崩溃问题,导致虚拟机无法访问。
如需解决此问题,请执行以下操作:
- 将磁盘装载到另一个虚拟机。
- 更新
grub.cfg
文件以使用上一个版本的内核。 - 将磁盘挂接到无响应的虚拟机。
- 使用
gcloud compute instances describe
命令验证虚拟机的状态是否为RUNNING
。 - 重新安装内核。
- 重启虚拟机。
或者,如果您在升级虚拟机之前创建了启动磁盘快照,请使用快照创建虚拟机。
OpenSSH 守护程序 (
sshd
) 未运行或配置不正确。sshd
通过 SSH 协议提供对系统的安全远程访问。如果该服务器配置不正确或未运行,您将无法通过 SSH 连接到虚拟机。如需解决此问题,请尝试以下一项或多项操作:
查阅操作系统的用户指南,确保正确设置了
sshd_config
。确保您拥有以下内容的必要所有权和权限设置:
$HOME
和$HOME/.ssh
目录$HOME/.ssh/authorized_keys
文件
负责
客机环境会将已获授权的 SSH 公钥存储在
$HOME/.ssh/authorized_keys
文件中。$HOME
和$HOME/.ssh
目录以及$HOME/.ssh/authorized_keys
文件的所有者必须与连接虚拟机的用户相同。权限
客机环境需要以下 Linux 权限:
路径 权限 /home
0755
$HOME
0700
或0750
或0755
*$HOME/.ssh
0700
$HOME/.ssh/authorized_keys
0600
* 如需了解哪些选项是
$HOME
目录的正确默认权限,请参阅适用于您的特定 Linux 发行版的官方文档。
或者,您也可以基于同一映像创建新虚拟机,并检查
$HOME
的默认权限。通过运行以下命令重启
sshd
:systemctl restart sshd.service
通过运行以下命令检查状态是否存在任何错误:
systemctl status sshd.service
状态输出可能包含退出代码、失败原因等信息。您可以使用这些详细信息进一步进行问题排查。
虚拟机未启动,因此您无法使用 SSH 或串行控制台进行连接。如果虚拟机无法访问,则您的操作系统可能已损坏。如果启动磁盘未启动,您可以诊断问题。如果您要恢复损坏的虚拟机并检索数据,请参阅恢复损坏的虚拟机或存储空间已满的启动磁盘。
虚拟机正在以维护模式启动。 在维护模式下启动时,虚拟机不接受 SSH 连接,但您可以连接到虚拟机的串行控制台并以根用户身份登录。
如需解决此问题,请执行以下操作:
如果您尚未为虚拟机设置根密码,请在启动期间使用元数据启动脚本运行以下命令:
echo "root:NEW_PASSWORD" | chpasswd
将 NEW_PASSWORD 替换为您选择的密码。
重启虚拟机。
连接到虚拟机的串行控制台,然后以根用户身份登录。
意外错误
尝试连接到 Linux 虚拟机时,可能会出现以下错误:
Connection Failed You cannot connect to the VM instance because of an unexpected error. Wait a few moments and then try again.
此问题可能是由多种原因造成的。以下是导致此错误的一些常见原因:
-
OpenSSH 守护程序 (
sshd
) 未运行或配置不正确。sshd
通过 SSH 协议提供对系统的安全远程访问。如果该服务器配置不正确或未运行,您将无法通过 SSH 连接到虚拟机。如需解决此问题,请尝试以下一项或多项操作:
查阅操作系统的用户指南,确保正确设置了
sshd_config
。确保您拥有以下内容的必要所有权和权限设置:
$HOME
和$HOME/.ssh
目录$HOME/.ssh/authorized_keys
文件
负责
客机环境会将已获授权的 SSH 公钥存储在
$HOME/.ssh/authorized_keys
文件中。$HOME
和$HOME/.ssh
目录以及$HOME/.ssh/authorized_keys
文件的所有者必须与连接虚拟机的用户相同。权限
客机环境需要以下 Linux 权限:
路径 权限 /home
0755
$HOME
0700
或0750
或0755
*$HOME/.ssh
0700
$HOME/.ssh/authorized_keys
0600
* 如需了解哪些选项是
$HOME
目录的正确默认权限,请参阅适用于您的特定 Linux 发行版的官方文档。
或者,您也可以基于同一映像创建新虚拟机,并检查
$HOME
的默认权限。通过运行以下命令重启
sshd
:systemctl restart sshd.service
通过运行以下命令检查状态是否存在任何错误:
systemctl status sshd.service
状态输出可能包含退出代码、失败原因等信息。您可以使用这些详细信息进一步进行问题排查。
未知 SSH 守护程序问题。如需诊断未知 SSH 守护程序问题,请检查串行控制台日志中是否存在错误。
根据串行控制台日志的输出,尝试执行以下操作来救援虚拟机并解决与 SSH 守护程序相关的问题:
无法连接到后端
从 Google Cloud 控制台或 gcloud CLI 连接到虚拟机时,可能会出现以下错误:
Google Cloud 控制台:
-- Connection via Cloud Identity-Aware Proxy Failed -- Code: 4003 -- Reason: failed to connect to backend
gcloud CLI:
ERROR: (gcloud.compute.start-iap-tunnel) Error while connecting [4003: 'failed to connect to backend'].
如果您尝试使用 SSH 连接到没有公共 IP 地址并且未在端口 22 上配置 Identity-Aware Proxy 的虚拟机,则会出现这些错误。
如需解决此问题,请在端口 22 上创建防火墙规则,用于允许来自 Identity-Aware Proxy 的入站流量。
主机密钥不匹配
在连接到虚拟机时可能会出现以下错误:
Host key for server IP_ADDRESS does not match
当 ~/.ssh/known_hosts
文件中的主机密钥与虚拟机的主机密钥不匹配时,将会发生此错误。
如需解决此问题,请从 ~/.ssh/known_hosts
文件中删除主机密钥,然后重试连接。
元数据值过大
如果您尝试向元数据添加新的 SSH 密钥,可能会发生以下错误:
ERROR:"Value for field 'metadata.items[X].value' is too large: maximum size 262144 character(s); actual size NUMBER_OF_CHARACTERS."
元数据值的大小上限为 256 KB。如需缓解此限制,请执行以下操作之一:
- 从项目或实例元数据中删除过期或重复的 SSH 密钥。如需了解详情,请参阅更新正在运行的虚拟机上的元数据。
- 使用 OS Login。
Windows 错误
权限遭拒,请重试
在连接到虚拟机时可能会出现以下错误:
USERNAME@compute.INSTANCE_ID's password: Permission denied, please try again.
此错误表示尝试连接到虚拟机的用户在该虚拟机上不存在。以下是导致此错误的最常见原因:
您的 gcloud CLI 版本已过期
如果 gcloud CLI 已过期,您可能会尝试使用未配置的用户名进行连接。如需解决此问题,请更新 gcloud CLI。
您尝试连接到未启用 SSH 的 Windows 虚拟机。
如需解决此错误,请在项目或实例元数据中将
enable-windows-ssh
键设置为TRUE
。如需详细了解如何设置元数据,请参阅设置自定义元数据。
权限遭拒(公钥、键盘交互式)
当您连接到未启用 SSH 的虚拟机时,可能会发生以下错误:
Permission denied (publickey,keyboard-interactive).
如需解决此错误,请在项目或实例元数据中将 enable-windows-ssh
键设置为 TRUE
。如需详细了解如何设置元数据,请参阅设置自定义元数据。
无法通过 SSH 连接到实例
从 gcloud CLI 连接到虚拟机时,可能会发生以下错误:
ERROR: (gcloud.compute.ssh) Could not SSH into the instance. It is possible that your SSH key has not propagated to the instance yet. Try running this command again. If you still cannot connect, verify that the firewall and instance are set to accept ssh traffic.
此错误可能是由多种原因造成的。以下是导致这些错误的一些最常见原因:
您尝试连接到未安装 SSH 的 Windows 虚拟机。
如需解决此问题,请按照说明在正在运行的虚拟机上启用适用于 Windows 的 SSH。
OpenSSH 服务器 (
sshd
) 未运行或配置不正确。sshd
通过 SSH 协议提供对系统的安全远程访问。如果该服务器配置不正确或未运行,您将无法通过 SSH 连接到虚拟机。如需解决此问题,请查看适用于 Windows Server 和 Windows 的 OpenSSH Server 配置,以确保正确设置
sshd
。
连接超时
SSH 连接超时可能是由以下某种原因造成的:
虚拟机尚未完成启动。虚拟机启动会需要一些时间,请稍等片刻。
如需解决此问题,请等待虚拟机完成启动,并尝试重新连接。
未安装 SSH 软件包。Windows 虚拟机要求您安装
google-compute-engine-ssh
软件包,然后才能使用 SSH 进行连接。如需解决此问题,请安装 SSH 软件包。
诊断失败的 SSH 连接
以下部分介绍了诊断 SSH 连接失败原因的步骤以及修复连接的步骤。
在诊断失败的 SSH 连接之前,请完成以下步骤:
- 安装或更新到 Google Cloud CLI 的最新版本。
- 运行连接性测试。
- 如果您使用的是未运行客机环境的自定义 Linux 映像,请安装 Linux 客机环境。
- 如果您使用 OS Login,请查看排查 OS Login 问题。
Linux 和 Windows 虚拟机的诊断方法
测试连接性
如果存在与防火墙、网络连接或用户账号相关的连接性问题,您可能无法通过 SSH 连接到虚拟机实例。您可以按照本部分中的步骤来确定任何连接性问题。
检查防火墙规则
Compute Engine 为每个项目预配了一组允许 SSH 流量的默认防火墙规则。如果您无法访问实例,请使用 gcloud compute
命令行工具来检查您的防火墙列表并确保存在 default-allow-ssh
规则。
在本地工作站上,请运行以下命令:
gcloud compute firewall-rules list
如果该防火墙规则不存在,请重新添加:
gcloud compute firewall-rules create default-allow-ssh \ --allow tcp:22
如需查看与您的项目中 default-allow-ssh
防火墙规则关联的所有数据,请使用 gcloud compute firewall-rules describe
命令:
gcloud compute firewall-rules describe default-allow-ssh \ --project=project-id
如需详细了解防火墙规则,请参阅 Google Cloud 中的防火墙规则。
测试网络连接
如需确定网络连接是否正常,请测试 TCP 握手:
获取虚拟机的外部
natIP
:gcloud compute instances describe VM_NAME \ --format='get(networkInterfaces[0].accessConfigs[0].natIP)'
将
VM_NAME
替换为无法连接的虚拟机的名称。测试从您的工作站到虚拟机的网络连接:
Linux、Windows 2019/2022 和 macOS
curl -vso /dev/null --connect-timeout 5 EXTERNAL_IP:PORT_NUMBER
替换以下内容:
EXTERNAL_IP
:您在上一步中获得的外部 IP 地址PORT_NUMBER
:端口号
如果 TCP 握手成功,则输出类似于以下内容:
Expire in 0 ms for 6 (transfer 0x558b3289ffb0) Expire in 5000 ms for 2 (transfer 0x558b3289ffb0) Trying 192.168.0.4... TCP_NODELAY set Expire in 200 ms for 4 (transfer 0x558b3289ffb0) Connected to 192.168.0.4 (192.168.0.4) port 443 (#0) > GET / HTTP/1.1 > Host: 192.168.0.4:443 > User-Agent: curl/7.64.0 > Accept: */* > Empty reply from server Connection #0 to host 192.168.0.4 left intact
Connected to
行表示 TCP 握手成功。Windows 2012 和 2016
PS C:> New-Object System.Net.Sockets.TcpClient('EXTERNAL_IP',PORT_NUMBER)
替换以下内容:
EXTERNAL_IP
:您在上一步中获得的外部 IPPORT_NUMBER
:端口号
如果 TCP 握手成功,则输出类似于以下内容:
Available : 0 Client : System.Net.Sockets.Socket Connected : True ExclusiveAddressUse : False ReceiveBufferSize : 131072 SendBufferSize : 131072 ReceiveTimeout : 0 SendTimeout : 0 LingerState : System.Net.Sockets.LingerOption NoDelay : False
Connected: True
行表示 TCP 握手成功。
如果 TCP 握手成功完成,则软件防火墙规则不会阻止连接,操作系统正确转发数据包,并且服务器正在监听目标端口。如果 TCP 握手成功完成,但虚拟机不接受 SSH 连接,则问题可能在于 sshd
守护程序配置错误或无法正常运行。请查看操作系统的用户指南,确保正确设置了 sshd_config
。
如需运行连接测试以分析两个虚拟机之间的 VPC 网络路径配置,并检查编程的配置是否应允许流量,请参阅检查 Google Cloud 中配置有误的防火墙规则。
以其他用户身份连接
导致您无法登录的问题可能仅限于您的用户账号。例如,可能没有为用户正确设置实例上 ~/.ssh/authorized_keys
文件的权限。
您可以使用 gcloud CLI 在 SSH 请求中指定 ANOTHER_USERNAME
,尝试以其他用户身份登录。gcloud CLI 将更新项目的元数据以添加新用户并允许进行 SSH 访问。
gcloud compute ssh ANOTHER_USERNAME@VM_NAME
替换以下内容:
ANOTHER_USERNAME
是不同于您自己的用户名的用户名VM_NAME
是您要连接的虚拟机的名称
使用串行控制台对问题进行调试
我们建议您检查串行控制台中的日志是否存在连接错误。您可以使用浏览器以根用户身份从本地工作站访问串行控制台。如果您无法使用 SSH 登录或者实例没有连接到网络,这种方法非常有用。在这两种情况下,串行控制台仍然可供访问。
如需登录虚拟机的串行控制台并排查虚拟机问题,请按照以下步骤操作:
对于 Linux 虚拟机,请修改根密码,并将以下启动脚本添加到您的虚拟机:
echo root:PASSWORD | chpasswd
将 PASSWORD 替换为您选择的密码。
使用串行控制台连接到您的虚拟机。
对于 Linux 虚拟机,请在完成对所有错误的调试后停用根账号登录:
sudo passwd -l root
Linux 虚拟机的诊断方法
在不关停虚拟机实例的情况下对其进行检查
您可能无法连接某个实例,但该实例可以继续正常处理生产流量。遇到这种情况时,建议您在不中断实例的情况下检查磁盘。
如需检查磁盘并进行问题排查,请执行以下操作:
- 通过创建磁盘快照来备份您的启动磁盘。
- 通过该快照创建一个常规永久性磁盘。
- 创建一个临时实例。
- 将该常规永久性磁盘挂接并装载到新的临时实例。
此过程会创建仅允许通过 SSH 连接的隔离网络,以防止克隆实例干扰生产服务,造成意想不到的后果。
创建新的 VPC 网络以托管您的克隆实例:
gcloud compute networks create debug-network
将
NETWORK_NAME
替换为您想要使用的新网络名称。添加防火墙规则以允许通过 SSH 连接到网络:
gcloud compute firewall-rules create debug-network-allow-ssh \ --network debug-network \ --allow tcp:22
创建启动磁盘的快照。
gcloud compute disks snapshot BOOT_DISK_NAME \ --snapshot-names debug-disk-snapshot
将
BOOT_DISK_NAME
替换为启动磁盘的名称。使用您刚创建的快照创建新磁盘:
gcloud compute disks create example-disk-debugging \ --source-snapshot debug-disk-snapshot
创建没有外部 IP 地址的新调试实例:
gcloud compute instances create debugger \ --network debug-network \ --no-address
将调试磁盘挂接到实例:
gcloud compute instances attach-disk debugger \ --disk example-disk-debugging
按照说明使用堡垒主机连接到虚拟机。
登录调试程序实例后,排查实例问题。例如,您可以查看实例日志:
sudo su -
mkdir /mnt/VM_NAME
mount /dev/disk/by-id/scsi-0Google_PersistentDisk_example-disk-debugging /mnt/VM_NAME
cd /mnt/VM_NAME/var/log
# Identify the issue preventing ssh from working ls
将
VM_NAME
替换为无法连接的虚拟机的名称。
使用启动脚本
如果上述步骤不起作用,您可以创建启动脚本以在实例启动后立即收集信息。按照说明来运行启动脚本。
之后,您还需要使用 gcloud compute instances reset
重置您的实例,然后元数据才会生效。
或者,您也可以运行诊断启动脚本来重新创建您的实例:
运行带有
--keep-disks
标志的gcloud compute instances delete
。gcloud compute instances delete VM_NAME \ --keep-disks boot
将
VM_NAME
替换为无法连接的虚拟机的名称。添加挂接了同一磁盘的新实例并指定您的启动脚本。
gcloud compute instances create NEW_VM_NAME \ --disk name=BOOT_DISK_NAME,boot=yes \ --metadata startup-script-url URL
替换以下内容:
NEW_VM_NAME
是您要创建的新虚拟机的名称BOOT_DISK_NAME
是您无法连接的虚拟机中的启动磁盘的名称URL
是脚本的 Cloud Storage 网址,格式为gs://BUCKET/FILE
或https://storage.googleapis.com/BUCKET/FILE
。
在新实例上使用磁盘
如果您仍需要从永久性启动磁盘恢复数据,则可以分离启动磁盘,然后将该磁盘作为辅助磁盘挂接到新实例上。
删除无法连接的虚拟机并保留其启动磁盘:
gcloud compute instances delete VM_NAME \ --keep-disks=boot
将
VM_NAME
替换为无法连接的虚拟机的名称。使用旧虚拟机的启动磁盘创建新的虚拟机。指定刚刚删除的虚拟机的启动磁盘名称。
使用 SSH 连接到新虚拟机:
gcloud compute ssh NEW_VM_NAME
将
NEW_VM_NAME
替换为新虚拟机的名称。
检查虚拟机启动磁盘是否已满
如果虚拟机启动磁盘已满,则您可能无法访问虚拟机。此情况可能很难进行问题排查,因为虚拟机连接问题是由于启动磁盘已满导致时,这种情况并不总是显而易见。如需详细了解此情况,请参阅排查由于启动磁盘已满而导致无法访问的虚拟机的问题。
Windows 虚拟机的诊断方法
重置 SSH 元数据
如果您无法使用 SSH 连接到 Windows 虚拟机,请尝试取消设置 enable-windows-ssh
元数据键,然后重新启用适用于 Windows 的 SSH。
将
enable-windows-ssh
元数据键设置为FALSE
。如需了解如何设置元数据,请参阅设置自定义元数据。请等待几秒钟,以便更改生效。
使用 RDP 连接到虚拟机
如果您无法诊断导致与 Windows 虚拟机的 SSH 连接失败的原因并解决问题,请使用 RDP 进行连接。
与虚拟机建立连接后,请查看 OpenSSH 日志。
使用 gcpdiag 调试 SSH 问题
gcpdiag
是一种开源工具,不是由官方提供支持的 Google Cloud 产品。您可以使用 gcpdiag
工具来帮助识别和修复 Google Cloud 项目问题。如需了解详情,请参阅 GitHub 上的 gcpdiag 项目。
- 虚拟机健康状况:检查虚拟机是否正在运行以及是否有足够的资源(CPU、内存、磁盘存储空间)。
- 权限:确保您拥有正确的 IAM 权限来配置 SSH 密钥。
- 虚拟机设置:验证 SSH 密钥和其他元数据是否已正确配置。
- 网络规则:查看防火墙规则,确认允许 SSH 流量。
- 客户操作系统:查找可能阻止 SSH 的内部操作系统问题。
Google Cloud 控制台
- 完成然后复制以下命令。
- 打开 Google Cloud 控制台并激活 Cloud Shell。 打开 Cloud 控制台
- 粘贴复制的命令。
- 运行
gcpdiag
命令以下载gcpdiag
Docker 映像,然后执行诊断检查。如果适用,请按照输出说明修复失败的检查。
gcpdiag runbook gce/ssh \
--parameter project_id=PROJECT_ID \
--parameter name=VM_NAME \
--parameter zone=ZONE \
--parameter principal=PRINCIPAL \
--parameter tunnel_through_iap=IAP_ENABLED \
--parameter check_os_login=OS_LOGIN_ENABLED
--parameter local_user=LOCAL_USER \
--parameter check_ssh_in_browser=CHECK_SSH_IN_BROWSER
Docker
您可以使用封装容器运行 gcpdiag
,以在 Docker 容器中启动 gcpdiag
。必须安装 Docker 或 Podman。
- 在本地工作站上复制并运行以下命令。
curl https://gcpdiag.dev/gcpdiag.sh >gcpdiag && chmod +x gcpdiag
- 执行
gcpdiag
命令:./gcpdiag runbook gce/ssh \ --parameter project_id=PROJECT_ID \ --parameter name=VM_NAME \ --parameter zone=ZONE \ --parameter principal=PRINCIPAL \ --parameter tunnel_through_iap=IAP_ENABLED \ --parameter check_os_login=OS_LOGIN_ENABLED --parameter local_user=LOCAL_USER \ --parameter check_ssh_in_browser=CHECK_SSH_IN_BROWSER
查看此 Runbook 的可用参数。
替换以下内容:
- PROJECT_ID:资源所在项目的 ID
- VM_NAME:项目中的目标虚拟机的名称。
- ZONE:目标虚拟机所在的可用区。
- PRINCIPAL:发起 SSH 连接的用户或服务账号正文。对于基于密钥的身份验证,请使用通过 Cloud Shell 命令行工具进行身份验证或已登录 Google Cloud 控制台的用户。对于服务账号模拟,它应为服务账号的电子邮件地址。
- IAP_ENABLED:一个布尔值(true 或 false),指示是否使用 Identity-Aware Proxy 建立 SSH 连接。默认值:
true
- OS_LOGIN_ENABLED:一个布尔值(true 或 false),指示是否使用 OS Login 进行 SSH 身份验证。默认值:
true
- LOCAL_USER:虚拟机上的 Posix 用户。
- CHECK_SSH_IN_BROWSER:一个布尔值,用于检查在浏览器中使用 SSH 是否可行。
实用标志:
--universe-domain
:如果适用,则为托管资源的可信合作伙伴主权云网域--parameter
或-p
:Runbook 参数
如需查看所有 gcpdiag
工具标志的列表和说明,请参阅 gcpdiag
使用说明。
后续步骤
- 了解到 Linux 虚拟机的 SSH 连接在 Compute Engine 上的工作原理。