通过 SSH 密钥从构建访问 GitHub


本教程演示如何将 Secret Manager 与 Cloud Build 搭配使用,从构建访问私有 GitHub 代码库。Secret Manager 是 Google Cloud 服务,可安全存储 API 密钥、密码和其他敏感数据。

目标

  • 设置 GitHub SSH 密钥。
  • 将 SSH 公钥添加到私有代码库的部署密钥中。
  • 将 SSH 私钥存储在 Secret Manager 中。
  • 提交一个用于从 Secret Manager 访问密钥的构建并使用它访问私有代码库。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

  • Secret Manager
  • Cloud Build

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

准备工作

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  3. 确保您的 Google Cloud 项目已启用结算功能

  4. 启用 Cloud Build and Secret Manager API。

    启用 API

  5. 安装 Google Cloud CLI。
  6. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  7. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  8. 确保您的 Google Cloud 项目已启用结算功能

  9. 启用 Cloud Build and Secret Manager API。

    启用 API

  10. 安装 Google Cloud CLI。
  11. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  12. 可选。完成 Secret Manager 快速入门,熟悉此产品。

创建 SSH 密钥

  1. 打开一个终端窗口。

  2. 创建名为 workingdir 的新目录并导航至该目录:

    mkdir workingdir
    cd workingdir
    
  3. 创建一个新的 GitHub SSH 密钥,其中 github-email是您的 GitHub 电子邮件地址:

    ssh-keygen -t rsa -b 4096 -N '' -f id_github -C github-email
    

    此命令会创建一个不带密码的新 SSH 密钥 workingdir/id_github。如果您的 SSH 密钥受密码保护,则 Cloud Build 无法使用它。

将 SSH 私钥存储在 Secret Manager 中

当您创建 SSH 密钥时,您的环境中会创建一个 id_github 文件。由于任何人都可以使用此文件向您的账号进行身份验证,因此您必须先将文件存储在 Secret Manager 中,然后才能在构建中使用。

  1. 要在 Secret Manager 中存储 SSH 密钥,请执行以下操作:

    1. 进入 Google Cloud 控制台中的 Secret Manager 页面:

      转到 Secret Manager 页面

    2. Secret Manager 页面上,点击创建密钥

    3. 创建密钥页面的名称下,输入密钥的名称。

    4. 密钥值字段中,点击上传并上传您的 workingdir/id_github 文件。

    5. 保持区域部分不变。

    6. 点击创建密钥按钮。

此操作会将您的 id_github 文件上传到 Secret Manager。

将 SSH 公钥添加到您的私有代码库的部署密钥

  1. 登录 GitHub

  2. 在右上角,点击您的个人资料照片,然后点击您的个人资料

  3. 在个人资料页面上,点击代码库,然后点击代码库的名称。

  4. 在代码库中,点击设置

  5. 在边栏中,点击部署密钥,然后点击添加部署密钥

  6. 提供标题,粘贴 workingdir/id_github.pub 中的 SSH 公钥。

  7. 如果您希望此密钥具有代码库的写入权限,请选择允许写入权限。拥有写入权限的部署密钥允许将部署推送到代码库。

  8. 点击添加密钥

  9. 从磁盘中删除 SSH 密钥:

    rm id_github*
    

授予权限

您需要向 Cloud Build 服务账号授予在构建期间访问 Secret Manager 的权限。

  1. 在 Google Cloud 控制台中打开 IAM 页面:

    打开 IAM 页面

  2. 选择您的项目,然后点击打开

  3. 在权限表中,找到以 @cloudbuild.gserviceaccount.com 结尾的电子邮件,然后点击铅笔图标。

  4. 添加 Secret Manager Secret Accessor 角色

  5. 点击保存

将 SSH 公钥添加到已知主机

大多数机器都包含名为 known_hosts 的文件,该文件包含远程主机的已知密钥。首次连接到远程主机时,通常会收集这些密钥,但也可以手动添加。此文件中的密钥用于验证远程主机的身份并防止冒充别人。

要让 Cloud Build 连接到 GitHub,您必须将 SSH 公钥添加到 Cloud Build 构建环境中的 known_hosts 文件。为此,您可以将密钥添加到临时 known_hosts.github 文件中,然后将 known_hosts.github 的内容复制到 Cloud Build 构建环境中的 known_hosts 文件。

workingdir 目录中,创建一个名为 known_hosts.github 的文件,然后将 SSH 公钥添加到此文件中:

ssh-keyscan -t rsa github.com > known_hosts.github

在配置构建的下一部分中,您将在 Cloud Build 配置文件中添加说明,以将 known_hosts.github 的内容复制到 Cloud Build 构建环境中的 known_hosts 文件。

配置构建

要配置构建,请执行以下操作:

  1. 通过两个步骤创建一个名为 cloudbuild.yaml 的构建配置文件:第一步(gcloud 步骤)访问 Secret Manager 中的 SSH 密钥,并将其以及 known_hosts.github 的副本作为 id_rsa 保存在 ssh 的卷中。该卷用于跨构建步骤保存文件。 第二步(git 步骤)使用 id_rsa 中的密钥连接到位于 git@github.com:git-username/git-repository 的代码库。

    # Access the id_github file from Secret Manager, and setup SSH
    steps:
    - name: 'gcr.io/cloud-builders/git'
      secretEnv: ['SSH_KEY']
      entrypoint: 'bash'
      args:
      - -c
      - |
        echo "$$SSH_KEY" >> /root/.ssh/id_rsa
        chmod 400 /root/.ssh/id_rsa
        cp known_hosts.github /root/.ssh/known_hosts
      volumes:
      - name: 'ssh'
        path: /root/.ssh
    
    # Clone the repository
    - name: 'gcr.io/cloud-builders/git'
      args:
      - clone
      - --recurse-submodules
      - git@github.com:GIT_USERNAME/GIT_REPOSITORY
      volumes:
      - name: 'ssh'
        path: /root/.ssh
    
    availableSecrets:
      secretManager:
      - versionName: projects/PROJECT_ID/secrets/SECRET_NAME/versions/latest
        env: 'SSH_KEY'
    

将上述命令中的占位值替换为以下内容:

  • GIT_USERNAME:代码库所有者的 GitHub 用户名。
  • GIT_REPOSITORY:您要访问的 GitHub 代码库的名称。
  • PROJECT_ID:您存储 Secret 的 Google Cloud 项目的 ID。
  • SECRET_NAME:您在 Secret Manager 中创建的 Secret 的名称。

如需了解以上代码段中使用的 YAML 多行字符串,请参阅 YAML 多行

提交构建

要提交构建,请运行以下命令:

gcloud builds submit --config=cloudbuild.yaml .

输出类似于以下内容:

Creating temporary tarball archive of 3 file(s) totalling 4.1 KiB before compression.
Uploading tarball of [.] to [gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/[PROJECT-ID]/builds/871b68bc---].
Logs are available at [https://console.cloud.google.com/cloud-build/builds/871b68bc---?project=[PROJECT-ID]].
----------------------------- REMOTE BUILD OUTPUT ------------------------------
starting build "871b68bc-cefc-4411-856c-2a2b7c7d2487"

FETCHSOURCE
Fetching storage object: gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz#1504288640827178
Copying gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz#1504288640827178...
/ [1 files][  3.9 KiB/  3.9 KiB]
Operation completed over 1 objects/3.9 KiB.
BUILD
Step #0: Already have image (with digest): gcr.io/cloud-builders/gcloud
Starting Step #0
Finished Step #0
Step #1: Already have image (with digest): gcr.io/cloud-builders/git
Starting Step #1
Step #1: # github.com SSH-2.0-libssh_0.7.0
Finished Step #1
Step #2: Already have image (with digest): gcr.io/cloud-builders/git
Starting Step #2
Step #2: Cloning into '[REPOSITORY-NAME]'...
Step #2: Warning: Permanently added the RSA host key for IP address 'XXX.XXX.XXX.XXX' to the list of known hosts.
Finished Step #2
PUSH
DONE
-----------------------------------------------------------------------------------------------------------------

ID                                    CREATE_TIME                DURATION  SOURCE                                                                              IMAGES  STATUS
871b68bc-cefc-4411-856c-2a2b7c7d2487  XXXX-XX-XXT17:57:21+00:00  13S       gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz  -                                 SUCCESS

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

删除项目

若要避免产生费用,最简单的方法是删除您为本教程创建的项目。

如需删除项目,请执行以下操作:

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

从代码库中删除部署密钥

  1. 在 GitHub 上,导航到代码库的主页面。

  2. 在代码库名称下,点击设置

  3. 在左侧边栏中,点击部署密钥

  4. 部署密钥页面上,查找与代码库关联的部署密钥,然后点击删除

后续步骤