Совместное использование Kaniko Cache для многоступенчатых Docker сборок с CloudBuild - PullRequest
1 голос
/ 09 февраля 2020

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

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

1 Ответ

2 голосов
/ 11 февраля 2020

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

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

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

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

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

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

Больше ссылок, которые вы можете счесть полезными (не учитывая, что это не источники Google):

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

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

...