通过 SSH 排查 Cloud Run 问题

借助 SSH,您可以与正在运行的容器实例建立安全的互动式 shell 连接。这样一来,您就可以直接访问容器的文件系统和运行时环境,从而检查系统资源、验证配置和排查问题。

Cloud Run 的 SSH 使用以下服务来保护连接安全:

  • Identity-Aware Proxy TCP 转发会代理 SSH 连接,因此请求必须通过身份验证和授权检查才能到达您的容器。您可以利用情境感知访问权限来扩展 IAP 访问权限政策,以根据 IP 地址和最终用户设备等属性限制访问权限。
  • OS Login 使用 SSH 证书身份验证对用户进行身份验证。当您连接时,gcloud CLI 会为您生成一个有效期为 5 分钟的短期 SSH 证书。证书在容器内进行验证。对于每次登录尝试,Google 都会检查 IAM 权限。

Cloud Run 的 SSH 会自动将所需的 Google 管理的二进制文件(包括 sshd 和验证证书的二进制文件)添加到容器的文件系统中。这些二进制文件仅在 SSH 会话期间可访问,会话结束后即会被移除。Cloud Run SSH 会忽略现有的 SSH 配置(包括 /etc/passwd 条目),而采用 Google 管理的配置。

当在以下路径中建立 SSH 会话时,Google 管理的 SSH 依赖项的第三方开源版权声明会装载到您的容器内:/usr/share/licenses/google_ssh/THIRD_PARTY_NOTICES。

SSH 会话和服务实例

使用 SSH 连接到服务时,请注意以下事项:

  • 如果服务没有正在运行的实例,Cloud Run 会为 SSH 会话启动一个新实例。
  • Cloud Run 旨在让服务实例在整个 SSH 会话期间保持活跃状态。在实例处于活跃状态时,您需要像往常一样为其付费。

限制

SSH 存在以下限制:

  • SSH 会话最长持续 24 小时。24 小时后,会话会断开连接,您必须重新连接。
  • IAP 会在 SSH 会话处于非活跃状态一小时后断开连接。 如需了解详情,请参阅 IAP TCP 转发已知限制。
  • SSH 仅适用于在 Cloud Run 的第二代环境和 Cloud Run 实例中运行的服务。
  • 使用 SSH 时,映像中的主机密钥会被覆盖。 在 SSH 会话结束后,密钥仍处于覆盖状态,直到服务实例重启。
  • Windows:不支持 PuTTY。使用 OpenSSH 客户端。
  • 使用 SSH 时,应格外注意保护容器的安全。考虑采用安全最佳实践,例如以非根用户身份运行应用代码。

准备工作

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud新手,请 创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  5. Verify that billing is enabled for your Google Cloud project.

  6. 启用 Cloud Run Admin API、Cloud Resource Manager API、Identity-Aware Proxy API 和 Cloud OS Login API:
      gcloud services enable run.googleapis.com \
          cloudresourcemanager.googleapis.com \
          iap.googleapis.com \
          oslogin.googleapis.com
      
  7. 安装并初始化 gcloud CLI。
  8. 更新组件:
    gcloud components update
  9. Windows:确保已安装 OpenSSH 客户端。

    OpenSSH 客户端通常默认安装在 Windows 10 及更高版本上。如果未安装,您可以在 PowerShell 中以管理员身份运行以下命令来安装:

    Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

    如需了解详情,请参阅安装 OpenSSH。

  10. 查看 Cloud Run 价格页面。如需根据您的预计使用量来估算费用,请使用价格计算器。 SSH 会针对网络出站流量字节数生成账单。在实例保持活动状态以用于 SSH 会话期间,您还需要照常为该实例付费。
  11. 如果您的项目使用 VPC Service Controls (VPC-SC),请注意,隧道传输过程会检查 iaptunnel.googleapis.com 作为服务名称,而不是 run.googleapis.com。

所需的角色

如需获得完成这些步骤所需的权限,请让您的管理员为您授予以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。

您也可以通过自定义角色或其他预定义角色来获取所需的权限。

如果您不是项目所属组织的成员,Cloud Run 会阻止 SSH 访问。如需获得 SSH 访问权限,请添加 roles/compute.osLoginExternalUser 角色,或使用具有 compute.oslogin.updateExternalUser 权限的自定义角色。

您可以在项目级层授予 IAP-secured Tunnel User 角色,如需针对特定 Cloud Run 服务或实例限制此角色,请运行以下命令:

针对特定服务

gcloud beta iap tcp add-iam-policy-binding \
    --resource-type=cloud-run \
    --service=SERVICE \
    --region=REGION \
    --member=MEMBER \
    --role=roles/iap.tunnelResourceAccessor

替换以下内容:

  • SERVICE:服务的名称。
  • REGION:服务部署所在的区域。
  • MEMBER:要授予访问权限的身份。

对于特定实例

gcloud beta iap tcp add-iam-policy-binding \
    --resource-type=cloud-run \
    --instance=INSTANCE \
    --region=REGION \
    --member=MEMBER \
    --role=roles/iap.tunnelResourceAccessor

替换以下内容:

  • INSTANCE:实例的名称。
  • REGION:服务部署所在的区域。
  • MEMBER:要授予访问权限的身份。

如需在项目和区域级层授予 roles/iap.tunnelResourceAccessor,请参阅配置 IAP 访问权限政策。

将 SSH 与 Cloud Run 服务搭配使用

配置服务级 SSH 访问权限,并使用 SSH 连接到服务。

配置服务级 SSH 访问权限

您可以使用 gcloud CLI 或 YAML 允许对特定服务进行检查访问:

gcloud

如需在现有服务上启用访问权限,请使用以下命令:

gcloud beta run services update SERVICE --ssh

您还可以在部署服务时使用 --ssh 标志,以允许对服务进行检查访问。

YAML

  1. 如果您要创建新的服务,请跳过此步骤。如果您要更新现有服务,请下载其 YAML 配置:

    gcloud run services describe SERVICE --format export > service.yaml
  2. 以下示例包含 YAML 配置:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: SERVICE
      labels:
        cloud.googleapis.com/location: REGION
      annotations:
        run.googleapis.com/ssh-enabled: "true"
        run.googleapis.com/launch-stage: BETA
    spec:
      template:
        spec:
          containers:
            image: IMAGE_URL
    

    替换以下内容:

    • SERVICE:Cloud Run 服务的名称。
    • REGION: Google Cloud 区域,例如 us-central1。
    • IMAGE_URL:对容器映像的引用,例如 us-docker.pkg.dev/cloudrun/container/hello:latest。如果您使用 Artifact Registry,则必须预先创建制品库 REPO_NAME。网址采用 LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG 格式
  3. 使用以下命令创建或更新服务:

    gcloud run services replace service.yaml

    gcloud run services replace 命令默认使用 service.yaml 文件(如果存在)。

您可以使用 gcloud CLI 或 YAML 逐个服务地停用 SSH 访问权限:

gcloud

如需停用对服务的访问权限,请使用以下命令:

gcloud beta run services update SERVICE --no-ssh

YAML

  1. 如果您要创建新的服务,请跳过此步骤。如果您要更新现有服务,请下载其 YAML 配置:

    gcloud run services describe SERVICE --format export > service.yaml
  2. 以下示例包含 YAML 配置:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: SERVICE
      labels:
        cloud.googleapis.com/location: REGION
      annotations:
        run.googleapis.com/ssh-enabled: "false"
        run.googleapis.com/launch-stage: BETA
    spec:
      template:
        spec:
          containers:
            image: IMAGE_URL
    

    替换以下内容:

    • SERVICE:Cloud Run 服务的名称。
    • REGION: Google Cloud 区域,例如 us-central1。
    • IMAGE_URL:对容器映像的引用,例如 us-docker.pkg.dev/cloudrun/container/hello:latest。如果您使用 Artifact Registry,则必须预先创建制品库 REPO_NAME。网址采用 LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG 格式
  3. 使用以下命令创建或更新服务:

    gcloud run services replace service.yaml

    gcloud run services replace 命令默认使用 service.yaml 文件(如果存在)。

使用 SSH 连接到服务

如需使用 SSH 连接到服务,请使用 gcloud CLI:

如需使用 SSH 连接到服务,请使用以下 Google Cloud CLI 命令:

  gcloud beta run services ssh SERVICE --region=REGION --project=PROJECT_ID

替换以下内容:

  • SERVICE:服务的名称。
  • REGION:服务部署所在的区域。
  • PROJECT_ID: Google Cloud 项目 ID。

    如果系统提示您输入 SSH 密钥的口令,您可以将其留空。不过,如果您输入了口令,请确保在同一工作区中进行任何后续 SSH 会话时都使用相同的口令。

    SSH 会话成功完成后,Cloud Run 会显示以下消息:

    Project: PROJECT_ID
    Region: REGION
    Service: SERVICE
    Revision: REVISION
    Instance: INSTANCE_ID
    Container: CONTAINER
    Image: IMAGE
    

    如需结束 SSH 会话,请输入 exit。您对容器所做的任何更改都会在容器保持运行状态期间一直存在。退出会话不会重启或终止容器。

指定服务实例

如需使用 SSH 连接到特定服务实例,请使用 Google Cloud CLI。

如需使用 SSH 连接到 Cloud Run 服务实例,请使用以下 Google Cloud CLI 命令:

  gcloud beta run services ssh SERVICE --region=REGION --project=PROJECT_ID --instance=INSTANCE_ID

替换以下内容:

  • SERVICE:服务的名称。
  • REGION:服务部署所在的区域。
  • PROJECT_ID: Google Cloud 项目 ID。
  • INSTANCE_ID:实例 ID。 如需查找服务实例 ID,请前往可观测性部分中的日志页面。实例 ID 位于日志条目的 labels 字段中。如果您在连接到特定实例之前终止该实例,则无法找到该实例的 ID。

指定修订版本

如需使用 SSH 连接到特定修订版本,请使用 Google Cloud CLI。

如需使用 SSH 连接到 Cloud Run 服务修订版本,请使用以下 Google Cloud CLI 命令:

  gcloud beta run services ssh SERVICE --region=REGION --project=PROJECT_ID --revision=REVISION

替换以下内容:

  • SERVICE:服务的名称。
  • REGION:服务部署所在的区域。
  • PROJECT_ID: Google Cloud 项目 ID。
  • REVISION:修订版本的名称。

将 SSH 与 Cloud Run 实例搭配使用

配置实例级 SSH 访问权限,并使用 SSH 连接到实例。

配置实例级 SSH 访问权限

默认情况下,实例已启用 SSH。

您可以使用 gcloud CLI 或 YAML 针对每个实例停用 SSH 访问权限:

gcloud

如需在实例上停用访问权限,请使用以下命令:

gcloud beta run instances update INSTANCE --no-ssh

YAML

  1. 如果您要创建新实例,请跳过此步骤。 如果您要更新现有实例,请下载其 YAML 配置:

    gcloud beta run instances describe INSTANCE --format export > instance.yaml
  2. 以下示例包含 YAML 配置:

    apiVersion: run.googleapis.com/v1
    kind: Instance
    metadata:
      name: INSTANCE
      labels:
        cloud.googleapis.com/location: REGION
      annotations:
        run.googleapis.com/ssh-enabled: "false"
        run.googleapis.com/launch-stage: BETA
    spec:
      containers:
        image: IMAGE_URL
    

    替换以下内容:

    • INSTANCE:Cloud Run 实例的名称。
    • REGION: Google Cloud 区域,例如 us-central1。
    • IMAGE_URL:对容器映像的引用,例如 us-docker.pkg.dev/cloudrun/container/hello:latest。
  3. 使用以下命令创建或更新实例:

    gcloud beta run instances replace instance.yaml

您可以使用 gcloud CLI 或 YAML 允许对特定实例进行检查访问。

gcloud

如需在现有实例上启用访问权限,请使用以下命令:

gcloud beta run instances update INSTANCE --ssh

您还可以在部署实例时使用 --ssh 标志来允许对实例进行检查访问。

YAML

  1. 如果您要创建新实例,请跳过此步骤。 如果您要更新现有实例,请下载其 YAML 配置:

    gcloud beta run instances describe INSTANCE --format export > instance.yaml
  2. 以下示例包含 YAML 配置:

    apiVersion: run.googleapis.com/v1
    kind: Instance
    metadata:
      name: INSTANCE
      labels:
        cloud.googleapis.com/location: REGION
      annotations:
        run.googleapis.com/ssh-enabled: "true"
        run.googleapis.com/launch-stage: BETA
    spec:
      containers:
        image: IMAGE_URL
    

    替换以下内容:

    • INSTANCE:Cloud Run 实例的名称。
    • REGION: Google Cloud 区域,例如 us-central1。
    • IMAGE_URL:对容器映像的引用,例如 us-docker.pkg.dev/cloudrun/container/hello:latest。
  3. 使用以下命令创建或更新实例:

    gcloud beta run instances replace instance.yaml

通过 SSH 连接到实例

如需使用 SSH 连接到实例,请使用以下 Google Cloud CLI 命令:

  gcloud beta run instances ssh INSTANCE --region=REGION --project=PROJECT_ID

替换以下内容:

  • INSTANCE:实例的名称。
  • REGION:服务部署所在的区域。
  • PROJECT_ID: Google Cloud 项目 ID。

如果系统提示您输入 SSH 密钥的口令,您可以将其留空。不过,如果您输入了口令,请确保在同一工作区中进行任何后续 SSH 会话时都使用相同的口令。

SSH 会话成功完成后,Cloud Run 会显示以下消息:

  Project: PROJECT_ID
  Region: REGION
  Instance: INSTANCE
  Revision: REVISION
  Container: CONTAINER
  Image: IMAGE

如需结束 SSH 会话,请输入 exit。

使用 OpenSSH 客户端进行连接

如需使用 OpenSSH 客户端进行连接,请执行以下操作:

  1. 在目标服务上运行 gcloud beta run services ssh 命令。此命令会启动 SSH 隧道并生成证书。
  2. 将以下内容添加到 SSH 配置中:

    Host cloud-run-ssh
        HostName cloud-run-default
        User root
        IdentityFile /Users/USER/.ssh/google_compute_engine
        CertificateFile /Users/USER/.ssh/google_compute_engine_cert/PROJECT_ID_REGION_SERVICE-cert.pub
        CheckHostIP no
        HashKnownHosts no
        HostKeyAlias cloud-run-default
        IdentitiesOnly yes
        StrictHostKeyChecking no
        UserKnownHostsFile /dev/null
        ProxyUseFdpass no
        ProxyCommand /usr/local/bin/python3 -S /Users/USER/google-cloud-sdk/lib/gcloud.py beta run start-iap-tunnel --project_number=PROJECT_NUMBER --project_id=PROJECT_ID --workload_type=service --deployment_name=SERVICE --region=REGION
    

    替换以下内容:

    • USER:本地计算机上的用户名。
    • PROJECT_ID: Google Cloud 项目 ID。
    • PROJECT_NUMBER: Google Cloud 项目编号。
    • REGION:服务部署所在的区域。
    • SERVICE:服务的名称。

    如果 gcloud CLI 安装在其他文件夹中,您可能需要更新最后一行中的位置。

  3. 运行以下命令:

    ssh cloud-run-ssh
    

您的 SSH 证书会在 5 分钟后过期。如果您在 5 分钟后尝试与服务建立 SSH 连接,则必须重新运行 gcloud beta run services ssh 以重新生成证书。

SSH 访问日志

如需捕获 SSH 密钥管理方面的审核日志,您必须为 Cloud OS Login API 启用审核日志。请参阅查看 OS Login 审核日志。 如需访问 Cloud Run 资源的 SSH 日志,您必须有权访问相应项目的 Cloud Audit Logs。

以下示例查询了过去一天内的所有 Cloud Run 服务:

gcloud logging read '
  logName="projects/PROJECT_ID/logs/cloudaudit.googleapis.com%2Fdata_access" AND
  protoPayload.serviceName="oslogin.googleapis.com" AND
  protoPayload.request.instance:"run.googleapis.com"
' --project=PROJECT_ID \
  --freshness=1d \
  --format="table(timestamp, protoPayload.authenticationInfo.principalSubject:label=USER, protoPayload.request.instance:label=CLOUD_RUN_SERVICE)"

保护和控制 SSH 访问权限

您可以控制哪些人可以使用 SSH,以及在您的环境中如何限制 SSH 的使用。

通过组织政策停用 SSH 访问权限

如需设置组织政策以停用 SSH,请使用自定义限制条件来限制在 Cloud Run 服务上启用 SSH 调试访问权限。

后续步骤