将 SSH 用于 Cloud Run

本页介绍如何使用 SSH 通过 Identity-Aware Proxy (IAP) TCP 转发连接到 Cloud Run 服务。

通过使用 IAP 保护 SSH 连接,您可以在安全的环境中调试各个容器实例。

准备工作

  1. 确保您的 Cloud Run 服务在第二代执行环境中运行,并且包含您在连接后执行命令所需的任何调试工具。如需了解详情,请参阅执行环境。
  2. 如需确保您使用的是最新版本的 Google Cloud CLI,请运行以下命令:

    gcloud components update
    
  3. 在您的项目中启用 Cloud Run API、Cloud Resource Manager API、Cloud OS Login API 和 Identity-Aware Proxy API。

    如需启用 API,请运行以下命令:

    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        oslogin.googleapis.com \
        iap.googleapis.com \
        run.googleapis.com
    

所需的角色

如需获得配置政策和连接到工作负载所需的权限,请让您的管理员为您授予以下 IAM 角色:

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

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

限制

Cloud Run 的 SSH 具有以下限制:

  • 仅支持 Cloud Run 服务和实例。
  • 对于服务,仅支持第二代执行环境。
  • 不支持 Cloud Run 作业。
  • 不支持工作器池。
  • 使用 SSH 时,映像中的主机密钥会被覆盖。在 SSH 会话结束后,密钥仍处于覆盖状态,直到服务重启。
  • Windows:不支持 PuTTY。使用 OpenSSH 客户端。

配置 IAP 授权政策

您可以使用 gcloud CLI 或 IAP REST API 在项目、区域或服务级层管理对 Cloud Run 资源的访问权限。

您可以为以下 Cloud Identity API 标识符配置政策:

  • Cloud Identity:例如,user:EMAIL@example.com
  • 员工身份联合:例如: principal://iam.googleapis.com/locations/global/workforcePools/ <var>POOL_ID</var>/subject/<var>SUBJECT_ATTRIBUTE_VALUE</var>

如需详细了解主账号类型并查看相关示例,请参阅主账号标识符列表。

更新现有 Cloud Run 服务

如需更新服务以启用 SSH,请运行以下命令:

gcloud beta run services update \
    SERVICE_NAME \
    --ssh

将 SERVICE_NAME 替换为您的 Cloud Run 服务的名称。您可以通过向 gcloud beta run deploy 添加 --ssh 来部署 Cloud Run 服务。

授予对项目中所有 Cloud Run 资源的访问权限

如需管理项目中所有资源的访问权限,请在项目级应用 IAM 政策绑定。

gcloud

运行以下命令:

gcloud beta iap tcp add-iam-policy-binding \
    --member='USER' \
    --role='roles/iap.tunnelResourceAccessor' \
    --resource-type=cloud-run

将 USER 替换为用户的主体标识符,例如 user:user@example.com 或 Workforce Identity Federation 主体。

REST API

向项目政策端点发送 POST 请求:

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -d '{
      "policy": {
        "bindings": [
          {
            "role": "roles/iap.tunnelResourceAccessor",
            "members": ["USER"]
          }
        ]
      }
    }' \
    "https://iap.googleapis.com/v1/projects/\
PROJECT_NUMBER/iap_tunnel/cloudRun:setIamPolicy"

替换以下内容:

  • USER:用户的委托人标识符。
  • PROJECT_NUMBER:资源托管所在的 Google Cloud项目编号。

授予对特定位置的所有 Cloud Run 资源的访问权限

如需限制对特定区域(例如 us-central1)内所有资源的访问权限,请在位置级应用政策绑定。

gcloud

运行以下命令:

gcloud beta iap tcp add-iam-policy-binding \
    --member='USER' \
    --role='roles/iap.tunnelResourceAccessor' \
    --resource-type=cloud-run \
    --region=LOCATION

替换以下内容:

  • USER:用户的委托人标识符。
  • LOCATION:部署资源的 Google Cloud 区域(例如 us-central1)。

REST API

向位置政策端点发送 POST 请求:

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -d '{
      "policy": {
        "bindings": [
          {
            "role": "roles/iap.tunnelResourceAccessor",
            "members": ["USER"]
          }
        ]
      }
    }' \
    "https://iap.googleapis.com/v1/projects/\
PROJECT_NUMBER/iap_tunnel/cloudRun/locations/\
LOCATION:setIamPolicy"

替换以下内容:

  • USER:用户的委托人标识符
  • PROJECT_NUMBER: Google Cloud 项目编号
  • LOCATION: Google Cloud 区域

授予对特定 Cloud Run 服务的访问权限

如需限制对项目中单个命名服务的访问权限,请在服务级层应用政策绑定。

gcloud

运行以下命令:

gcloud beta iap tcp add-iam-policy-binding \
    --member='USER' \
    --role='roles/iap.tunnelResourceAccessor' \
    --resource-type=cloud-run \
    --service=SERVICE_NAME \
    --region=LOCATION

替换以下内容:

  • USER:用户的委托人标识符
  • SERVICE_NAME:要连接到的服务逻辑的名称
  • LOCATION:服务部署到的 Google Cloud 区域

REST API

向服务政策端点发送 POST 请求:

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -d '{
      "policy": {
        "bindings": [
          {
            "role": "roles/iap.tunnelResourceAccessor",
            "members": ["USER"]
          }
        ]
      }
    }' \
    "https://iap.googleapis.com/v1/projects/\
    PROJECT_NUMBER/iap_tunnel/cloudRun/locations/\
    LOCATION/services/\
    SERVICE_NAME:setIamPolicy"

替换以下内容:

  • USER:用户的委托人标识符
  • PROJECT_NUMBER: Google Cloud 项目编号
  • LOCATION: Google Cloud 区域
  • SERVICE_NAME:服务的名称

使用 SSH 建立连接

如需建立与 Cloud Run 资源之间的 SSH 隧道,您必须使用 gcloud CLI。

连接到服务

运行以下命令:

gcloud beta run services ssh SERVICE_NAME \
    --region=LOCATION \
    --project=PROJECT_ID

替换以下内容:

  • SERVICE_NAME:要连接的服务的名称
  • LOCATION:服务所在的 Google Cloud 区域
  • PROJECT_ID:您的 Google Cloud项目的 ID

退出会话

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

您对容器所做的任何修改都只会持续到容器保持有效状态为止。退出会话不会自动停止或重启容器。

使用本地 OpenSSH 客户端

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

  1. 如需启动 SSH 隧道并生成必要的证书,请运行以下命令:

    gcloud beta run services ssh SERVICE_NAME \
        --region=LOCATION \
        --project=PROJECT_ID
    

    替换以下内容:

    • SERVICE_NAME:服务的名称
    • LOCATION: Google Cloud 区域
    • PROJECT_ID:您的 Google Cloud 项目 ID
  2. 将以下配置代码添加到本地 ~/.ssh/config 文件中:

    Host cloud-run-ssh
        HostName cloud-run-default
        User root
        IdentityFile ~/.ssh/google_compute_engine
        CertificateFile ~/.ssh/google_compute_engine_cert/PROJECT_ID_LOCATION_SERVICE_NAME-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 ~/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_NAME --region=LOCATION
    

    如果 gcloud 安装路径不同,请更新 ProxyCommand 路径中的前缀。

    替换以下内容:

    • PROJECT_ID:您的 Google Cloud 项目 ID
    • LOCATION: Google Cloud 区域
    • SERVICE_NAME:服务的名称
    • PROJECT_NUMBER:您的 Google Cloud 项目编号
  3. 使用 OpenSSH 连接到服务:

    ssh cloud-run-ssh