将文件从 Google Cloud Container Builder 传递到 Docker 构建任务
Passing files from Google Cloud Container Builder to Docker build task
上下文
在 Rails 上使用 Container Builder 为 App Engine 构建的应用程序 Ruby。我们要求捆绑器能够使用 SSH 密钥从私有 git 存储库安装依赖项。
SSH 密钥来自安全存储桶,它们通过 KMS 进行解密。这些步骤没问题。但是,使用 Docker 构建容器的最后一步无法访问 SSH 密钥。
我之前没有任何使用 Docker 的丰富经验,所以我认为这是一个简单的问题。
cloudbuild.yml
steps:
# Get and prepare Deploy Key
- name: 'gcr.io/cloud-builders/gsutil'
args: ['cp', 'gs://[PROJECT-BUCKET]/git_id_rsa.enc', '/root/.ssh/git_id_rsa.enc']
volumes:
- name: 'ssh-setup'
path: /root/.ssh
- name: 'gcr.io/cloud-builders/gcloud'
args:
- kms
- decrypt
- --ciphertext-file=/root/.ssh/git_id_rsa.enc
- --plaintext-file=/root/.ssh/git_id_rsa
- --location=global
- --keyring=[KEYRING]
- --key=[KEY]
volumes:
- name: 'ssh-setup'
path: /root/.ssh
- name: 'gcr.io/cloud-builders/gcloud'
entrypoint: /workspace/deploy/git-prepare.sh
volumes:
- name: 'ssh-setup'
path: /root/.ssh
# ... Omitted steps ...
# Docker build
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/[PROJECT-NAME]', '.']
volumes:
- name: 'ssh-setup'
path: /root/.ssh
images: ['gcr.io/$PROJECT_ID/[PROJECT-NAME]']
一些标识符已被省略
deploy/git-prepare.sh —
这会执行一些 shell 命令来让 ssh 目录重新填充必要的信息。
#!/bin/bash
mkdir -p /root/.ssh
touch /root/.ssh/config
ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts
touch /root/.ssh/config
echo -e "\nHost bitbucket.org\n IdentityFile /root/.ssh/git_id_rsa" >> /root/.ssh/config
if [ -f /root/.ssh/git_id_rsa.enc ]; then
rm /root/.ssh/git_id_rsa.enc
fi
Docker文件
# .. OMITTING BOILERPLATE FOR RAILS APP SETUP ...
# Copy the application files.
COPY . /app/
# Copy the SSH keys and config for bundler
VOLUME /root/.ssh
COPY /root/.ssh/known_hosts ~/.ssh/known_hosts
COPY /root/.ssh/config ~/.ssh/config
COPY /root/.ssh/git_id_rsa ~/.ssh/git_id_rsa
问题:
构建任务(运行 使用构建触发器)失败并显示:
...omitted lines above...
Step #5: COPY failed: stat /var/lib/docker/tmp/docker-builderxxxxxxxxx/root/.ssh/known_hosts: no such file or directory
Step #5: Step 7/14 : COPY /root/.ssh/known_hosts ~/.ssh/known_hosts
我感觉我不理解 Container Builder 和 Docker 共享卷和数据的方式。
Dockerfile COPY
可以使用多个 <src>
资源,但是 文件和目录的路径将被解释为相对于构建上下文的源.
这是您当前执行 docker build .
命令的路径。
在您的情况下,如果在 Dockerfile 执行其步骤时挂载了 /root/.ssh,那么一个简单的 RUN cp /root/.ssh/... /destination/path
就足够了。
但是,您无法在 docker build
时装载卷(请参阅 moby issue 14080), so check this solution: a multi-stage build can help。
好的,我设法做了上面的答案和评论中引用的内容。这就是我所做的。请注意,正如问题作者发布的那样,我在 /root/.ssh 卷中有我的 id_rsa 和 known_hosts 文件。我假设他通过阅读这篇文章达到了他的状态:https://cloud.google.com/container-builder/docs/access-private-github-repos
在我的 cloudbuild.yaml 中:
在克隆我的 repo 之后,但在 docker 构建之前,我添加了这一步:
- name: 'gcr.io/cloud-builders/git'
entrypoint: 'bash'
args:
- '-c'
- cp /root/.ssh/{id_rsa,known_hosts} .
volumes:
- name: 'ssh'
path: /root/.ssh
然后,在 Dockerfile 中:
COPY id_rsa /root/.ssh/id_rsa
COPY known_hosts /root/.ssh/known_hosts
RUN eval $(ssh-agent) && \
echo -e "StrictHostKeyChecking no" >> /etc/ssh/ssh_config && \
ssh-add /root/.ssh/id_rsa
请注意,我不担心容器中的密钥,因为我使用的是 multi-stage 构建。
我也不得不处理同样的问题,我没有将 ssh 密钥复制到 Docker 文件并进行清理,而是将存储库克隆到工作区作为云构建步骤。工作区中的内容在构建步骤中保持不变,并且可以在构建期间在docker 文件中使用。
# Clone git repo.
- name: 'gcr.io/cloud-builders/git'
id: git-clone
args:
- clone
- git@github.com:repo.git
- workspace/repo-clone
volumes:
- name: 'ssh'
path: /root/.ssh
然后在 docker 文件中。
COPY workspace/repo-name build/
上下文
在 Rails 上使用 Container Builder 为 App Engine 构建的应用程序 Ruby。我们要求捆绑器能够使用 SSH 密钥从私有 git 存储库安装依赖项。
SSH 密钥来自安全存储桶,它们通过 KMS 进行解密。这些步骤没问题。但是,使用 Docker 构建容器的最后一步无法访问 SSH 密钥。
我之前没有任何使用 Docker 的丰富经验,所以我认为这是一个简单的问题。
cloudbuild.yml
steps:
# Get and prepare Deploy Key
- name: 'gcr.io/cloud-builders/gsutil'
args: ['cp', 'gs://[PROJECT-BUCKET]/git_id_rsa.enc', '/root/.ssh/git_id_rsa.enc']
volumes:
- name: 'ssh-setup'
path: /root/.ssh
- name: 'gcr.io/cloud-builders/gcloud'
args:
- kms
- decrypt
- --ciphertext-file=/root/.ssh/git_id_rsa.enc
- --plaintext-file=/root/.ssh/git_id_rsa
- --location=global
- --keyring=[KEYRING]
- --key=[KEY]
volumes:
- name: 'ssh-setup'
path: /root/.ssh
- name: 'gcr.io/cloud-builders/gcloud'
entrypoint: /workspace/deploy/git-prepare.sh
volumes:
- name: 'ssh-setup'
path: /root/.ssh
# ... Omitted steps ...
# Docker build
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/[PROJECT-NAME]', '.']
volumes:
- name: 'ssh-setup'
path: /root/.ssh
images: ['gcr.io/$PROJECT_ID/[PROJECT-NAME]']
一些标识符已被省略
deploy/git-prepare.sh — 这会执行一些 shell 命令来让 ssh 目录重新填充必要的信息。
#!/bin/bash
mkdir -p /root/.ssh
touch /root/.ssh/config
ssh-keyscan bitbucket.org >> /root/.ssh/known_hosts
touch /root/.ssh/config
echo -e "\nHost bitbucket.org\n IdentityFile /root/.ssh/git_id_rsa" >> /root/.ssh/config
if [ -f /root/.ssh/git_id_rsa.enc ]; then
rm /root/.ssh/git_id_rsa.enc
fi
Docker文件
# .. OMITTING BOILERPLATE FOR RAILS APP SETUP ...
# Copy the application files.
COPY . /app/
# Copy the SSH keys and config for bundler
VOLUME /root/.ssh
COPY /root/.ssh/known_hosts ~/.ssh/known_hosts
COPY /root/.ssh/config ~/.ssh/config
COPY /root/.ssh/git_id_rsa ~/.ssh/git_id_rsa
问题:
构建任务(运行 使用构建触发器)失败并显示:
...omitted lines above...
Step #5: COPY failed: stat /var/lib/docker/tmp/docker-builderxxxxxxxxx/root/.ssh/known_hosts: no such file or directory
Step #5: Step 7/14 : COPY /root/.ssh/known_hosts ~/.ssh/known_hosts
我感觉我不理解 Container Builder 和 Docker 共享卷和数据的方式。
Dockerfile COPY
可以使用多个 <src>
资源,但是 文件和目录的路径将被解释为相对于构建上下文的源.
这是您当前执行 docker build .
命令的路径。
在您的情况下,如果在 Dockerfile 执行其步骤时挂载了 /root/.ssh,那么一个简单的 RUN cp /root/.ssh/... /destination/path
就足够了。
但是,您无法在 docker build
时装载卷(请参阅 moby issue 14080), so check this solution: a multi-stage build can help。
好的,我设法做了上面的答案和评论中引用的内容。这就是我所做的。请注意,正如问题作者发布的那样,我在 /root/.ssh 卷中有我的 id_rsa 和 known_hosts 文件。我假设他通过阅读这篇文章达到了他的状态:https://cloud.google.com/container-builder/docs/access-private-github-repos
在我的 cloudbuild.yaml 中: 在克隆我的 repo 之后,但在 docker 构建之前,我添加了这一步:
- name: 'gcr.io/cloud-builders/git'
entrypoint: 'bash'
args:
- '-c'
- cp /root/.ssh/{id_rsa,known_hosts} .
volumes:
- name: 'ssh'
path: /root/.ssh
然后,在 Dockerfile 中:
COPY id_rsa /root/.ssh/id_rsa
COPY known_hosts /root/.ssh/known_hosts
RUN eval $(ssh-agent) && \
echo -e "StrictHostKeyChecking no" >> /etc/ssh/ssh_config && \
ssh-add /root/.ssh/id_rsa
请注意,我不担心容器中的密钥,因为我使用的是 multi-stage 构建。
我也不得不处理同样的问题,我没有将 ssh 密钥复制到 Docker 文件并进行清理,而是将存储库克隆到工作区作为云构建步骤。工作区中的内容在构建步骤中保持不变,并且可以在构建期间在docker 文件中使用。
# Clone git repo.
- name: 'gcr.io/cloud-builders/git'
id: git-clone
args:
- clone
- git@github.com:repo.git
- workspace/repo-clone
volumes:
- name: 'ssh'
path: /root/.ssh
然后在 docker 文件中。
COPY workspace/repo-name build/