通过 SSH 密钥从构建访问 GitHub

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

创建 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 中,然后才能在构建中使用。

如需在 Secret Manager 中存储 SSH 密钥,请执行以下操作:

  1. 在 Google Cloud 控制台中,前往“Secret Manager”页面:

    转到 Secret Manager 页面

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

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

  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*
    

授予权限

您必须向用于构建的服务账号授予访问 Secret Manager 的权限。

  1. 在 Google Cloud 控制台中,前往 Cloud Build 权限页面:

    前往权限

  2. 从下拉列表中,选择要更改其角色的服务账号。

  3. Secret Manager Secret Accessor 角色的状态设置为启用

将 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