通过CloudBuild共享Kaniko Cache用于多阶段Docker构建

时间:2020-02-09 15:35:06

标签: docker continuous-integration google-cloud-build kaniko

我正在研究一个CloudBuild脚本,该脚本将构建一个多阶段Docker映像以进行集成测试。为了优化构建脚本,我选择使用Kaniko。 Dockerfile和cloudbuild.yaml文件的相关部分在下面提供。

cloudbuild.yaml

steps:
  # Build BASE image
  - name: gcr.io/kaniko-project/executor:v0.17.1
    id: buildinstaller
    args:
      - --destination=gcr.io/$PROJECT_ID/<MY_REPO>-installer:$BRANCH_NAME
      - --destination=gcr.io/$PROJECT_ID/<MY_REPO>-installer:$SHORT_SHA
      - --cache=true
      - --cache-ttl=24h
      - --cache-repo=gcr.io/$PROJECT_ID/<MY_REPO>/cache
      - --target=installer
  # Build TEST image
  - name: gcr.io/kaniko-project/executor:v0.17.1
    id: buildtest
    args:
      - --destination=gcr.io/$PROJECT_ID/<MY_REPO>-test:$BRANCH_NAME
      - --destination=gcr.io/$PROJECT_ID/<MY_REPO>-test:$SHORT_SHA
      - --cache=true
      - --cache-ttl=24h
      - --cache-repo=gcr.io/$PROJECT_ID/<MY_REPO>/cache
      - --target=test-image
    waitFor:
      - buildinstaller
  # --- REMOVED SOME CODE FOR BREVITY ---
  # Build PRODUCTION image
  - name: gcr.io/kaniko-project/executor:v0.17.1
    id: build
    args:
      - --destination=gcr.io/$PROJECT_ID/<MY_REPO>:$BRANCH_NAME
      - --destination=gcr.io/$PROJECT_ID/<MY_REPO>:$SHORT_SHA
      - --destination=gcr.io/$PROJECT_ID/<MY_REPO>:latest
      - --cache=true
      - --cache-ttl=24h
      - --cache-dir=/cache
      - --target=production-image
    waitFor:
      - test # TODO: This will run after tests which were not included here for brevity
images:
  - gcr.io/$PROJECT_ID/<MY_REPO>

Dockerfile

FROM ruby:2.5-alpine AS installer

# Expose port
EXPOSE 3000

# Set desired port
ENV PORT 3000

# set the app directory var
ENV APP_HOME /app
RUN mkdir -p ${APP_HOME}
WORKDIR ${APP_HOME}

# Install necessary packanges
RUN apk add --update --no-cache \
  build-base curl less libressl-dev zlib-dev git \
  mariadb-dev tzdata imagemagick libxslt-dev \
  bash nodejs

# Copy gemfiles to be able to bundle install
COPY Gemfile* ./

#############################
# STAGE 1.5: Test build #
#############################
FROM installer AS test-image

# Set environment
ENV RAILS_ENV test

# Install gems to /bundle
RUN bundle install --deployment --jobs $(nproc) --without development local_gems 

# Add app files
ADD . .
RUN bundle install --with local_gems

#############################
# STAGE 2: Production build #
#############################
FROM installer AS production-image

# Set environment
ENV RAILS_ENV production

# Install gems to /bundle
RUN bundle install --deployment --jobs $(nproc) --without development test local_gems 

# Add app files
ADD . .
RUN bundle install --with local_gems

# Precompile assets
RUN DB_ADAPTER=nulldb bundle exec rake assets:precompile assets:clean

# Puma start command
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]

由于我的Docker映像是一个多阶段构建,具有2个单独的最终阶段,它们共享一个共同的基本构建,因此我想在共同部分和其他两个部分之间共享缓存。为此,我将所有构建都设置为共享同一缓存存储库- --cache-repo=gcr.io/$PROJECT_ID/<MY_REPO>/cache。到目前为止,它在我的所有测试中都有效。但是,我无法确定这是否是最佳做法,或者是否建议使用其他缓存基本映像的方式。这是可以接受的实现吗?

我遇到过Kaniko-warmer,但无法根据情况使用它。

1 个答案:

答案 0 :(得分:3)

在提及有关如何缓存基本映像的最佳做法之前,有一些最佳做法是为了optimize the performance of your build。由于您已经使用了Kaniko,并且正在从存储库中缓存映像,因此我相信您的实现遵循上述最佳实践。

我唯一的建议是使用Google Cloud Storage重用您以前构建的结果。如果您的构建需要很长时间,并且生成的文件不是很多,并且不需要花费很多时间将它们从 复制到 Cloud Storage,可以加快构建速度。

此外,下一篇文章中还介绍了有关Optimization of your build cache的一些最佳做法。我相信其中最重要的是:

”将经常更改的构建步骤放在Dockerfile的底部。如果将它们放在顶部,则Docker无法将其构建缓存用于其他不经常更改的构建步骤。因为通常使用新的Docker映像为每个新版本的源代码构建,请尽可能晚在Dockerfile中将源代码添加到映像中。”

最后我要考虑的另一件事是the cache expiration time

请记住,必须对其进行适当配置,以免丢失依赖项的任何更新,但不要在没有任何使用的情况下运行构建。

您可能会认为有用的更多链接(请记住,这些链接不是Google来源):

Docker documentation about Multi-stage Builds

Using Multi-Stage Builds to Simplify And Standardize Build Processes

相关问题