Совместное использование кэша Kaniko для многоэтапных сборок Docker с помощью CloudBuild

Я работаю над сценарием 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 представляет собой многоступенчатую сборку с двумя отдельными конечными этапами, которые имеют общую базовую сборку, я хочу разделить кеш между общей частью и двумя другими. Для этого я установил для всех сборок один и тот же репозиторий кеша.- --cache-repo=gcr.io/$PROJECT_ID/<MY_REPO>/cache. До сих пор он работал во всех моих тестах. Однако мне не удалось выяснить, является ли это наилучшей практикой или рекомендуется другой способ кэширования базового образа. Это приемлемая реализация?

Я нашел Kaniko-warmer, но не смог использовать его в своей ситуации.

1 ответ

Прежде чем упоминать какие-либо передовые методы кэширования вашего базового образа, есть несколько передовых методов, позволяющих оптимизировать производительность вашей сборки. Поскольку вы уже используете Kaniko и кэшируете изображение из своего репозитория, я считаю, что ваша реализация соответствует приведенным выше рекомендациям.

Единственное, что я хотел бы сделать, - это использовать Google Cloud Storage для повторного использования результатов из ваших предыдущих сборок. Если сборка занимает много времени, и файлы, созданные не много, и это не займет много времени, чтобы скопировать их из и в Cloud Storage, это ускорит больше вашу сборку.

Кроме того, в следующей статье изложены некоторые передовые практики, касающиеся оптимизации кеша сборки. Я считаю, что самым важным из них является:

"разместите этапы сборки, которые часто меняются, в нижней части файла Docker. Если вы поместите их вверху, Docker не сможет использовать свой кеш сборки для других этапов сборки, которые меняются реже. Поскольку новый образ Docker обычно создается для каждого новую версию исходного кода, добавьте исходный код к изображению как можно позже в Dockerfile".

Наконец, еще одна вещь, которую я хотел бы принять во внимание, - это время истечения срока действия кеша.

Помните, что он должен быть настроен надлежащим образом, чтобы не потерять обновления для зависимостей, но не запускать сборки без использования.

Еще ссылки, которые вы можете счесть полезными (помните, что это не источники Google):

Документация Docker о многоэтапных сборках

Использование многоэтапных сборок для упрощения и стандартизации процессов сборки

Другие вопросы по тегам