- PVSM.RU - https://www.pvsm.ru -
werf [1] — наша Open Source-утилита для сборки и деплоя приложений. Сегодня мы с радостью сообщаем, что werf научилась работать в распределенном режиме, начиная с версии v1.1.10 (доступна в каналах v1.1 alpha, beta, ea и stable). Для его подключения требуется минимум усилий.
Вот некоторые из примечательных особенностей нового режима:
Заметим, что сборщик Dockerfile также можно использовать в распределенном режиме, однако он пока не поддерживает продвинутое распределенное кэширование слоев.
Однако начнем с рассказа о том, что такое распределенный режим и какие компоненты необходимы для его реализации. Затем покажем, как включить этот режим и как перевести на него (с локального режима) существующие проекты, использующие werf. Наконец, рассмотрим демо-проект [2], который в полной мере задействует механизм распределенной сборки werf.
В werf имеется несколько ключевых концепций, связанных с процессом сборки: стадии, образы, хранилище стадий. В документации [3] стадии и образы определяются следующим образом:
Мы предлагаем разделить сборочный процесс на этапы, каждый с четкими функциями и своим назначением. Каждый этап соответствует промежуточному образу, подобно слоям в Docker. В werf такой этап называется стадией, и конечный образ в итоге состоит из набора собранных стадий. Все стадии хранятся в хранилище стадий (stages storage).
Что за хранилище стадий? До версии v1.1.10 на этот вопрос можно было ответить так: «Это просто локальный сервер Docker». Однако начиная с текущего момента, werf позволяет хранить стадии в реестре Docker-образов. Более того, он поддерживает большинство реализаций [4] Docker Registry, доступных сегодня.
Использование Docker Registry в качестве хранилища стадий позволяет проводить распределенную сборку образов на нескольких хостах. Для сборщика stapel, представляющего собой альтернативу Dockerfile со множеством полезных функций [5], доступно продвинутое кэширование слоев. Для него реализован эффективный и оптимизированный алгоритм выбора стадий и сборки:
Для сборки образов на нескольких хостах можно также использовать и сборщик Dockerfile, однако на данный момент для него не реализовано продвинутое распределенное кэширование слоев (впрочем, это будет сделано [6]).
С появлением распределенного режима werf предлагает два уровня кэширования Docker-образов:
Кроме того, имеются образы, опубликованные в репозитории образов, — назовем их разновидность (3).
Кэши нуждаются в периодической очистке. В werf для этого встроена команда werf cleanup
, удаляющая Docker-образы (2)-го и (3)-го типов.
Локальные Docker-образы (1) пока приходится убирать вручную (только при использовании распределенного режима). Эти образы можно удалять с помощью любых инструментов (например, docker rmi
). Будущие версии werf смогут автоматически удалять эти образы при выполнении связанных со сборкой команд, используя алгоритм LRU, что позволит поддерживать заполненность хранилища на сборочном узле на уровне 80%.
Также следует отметить, что распределенный режим werf использует стадии из хранилища стадий (Docker Registry) и извлекает только те образы, которые необходимы для сборки нового слоя (скачивает только базовый образ). При этом во время холостых сборок (когда образы в действительности не собираются) образы вообще не извлекаются.
Более подробная информация об алгоритме работы сборщика и архитектуре доступна в документации:
Для работы в распределенном режиме werf'у требуется подключение к какому-либо кластеру Kubernetes. Kubernetes будет использоваться для координации множества процессов werf при:
Не имеет значения, используется ли данный кластер Kubernetes для деплоя приложения. Единственное требование — один и тот же экземпляр K8s должен использоваться для всего проекта.
Как именно он используется? werf создает ConfigMap cm/werf-PROJECT_NAME
в пространстве имен werf-synchronization
для каждого проекта. Этот ConfigMap используется для хранения так называемого кэша хранилища стадий [9] и для распределенных блокировок [9]. Для реализации распределенной блокировки в кластере Kubernetes используется Open Source-библиотека lockgate [10], созданная нами специально для werf.
Различные процессы werf, работающие с одним и тем же проектом, должны использовать единое хранилище стадий и один и тот же экземпляр кластера Kubernetes.
Дополнительную информацию о синхронизации можно найти в документации [9].
В werf реализованы новые команды для работы со стадиями:
werf stages sync
[11] — копирует стадии между хранилищами.werf stages switch-from-local
[12] — помогает перевести существующий проект в распределенный режим (подробнее об этом процессе см. ниже).
Для использования распределенного режима достаточно указать параметр --stages-storage=DOCKER_REPO_ADDRESS
для всех команд werf.
Обратите внимание, что DOCKER_REPO_ADDRESS
должен ссылаться на уникальный Docker-репозиторий для данного проекта. Этот репозиторий не может использоваться одновременно для нескольких проектов (хотя один и тот же Docker Registry, конечно, может использоваться несколькими проектами).
Команда werf ci-env
, интегрирующая [13] werf в процесс CI/CD, экспортирует переменную WERF_STAGES_STORAGE
. Она содержит адрес Docker-репозитория, предназначенного для хранения стадий, и это хранилище по умолчанию будет использоваться при всех последующих вызовах werf. Вот пример этой переменной для GitLab CI/CD: WERF_STAGES_STORAGE=CI_REGISTRY_IMAGE/stages
.
Если --stages-storage
определён не :local
, а как адрес Docker Registry (DOCKER_REPO_ADDRESS
), werf автоматически задействует пространство имен Kubernetes werf-synchronization
и текущий контекст из kubeconfig'а по умолчанию для подключения к кластеру. При этом пользователь может явно указать произвольное пространство имен с помощью опции --synchronization=kubernetes://NAMESPACE
. Дополнительная информация доступна в документации [9].
Проект можно переключить в распределенный режим, если он уже использует werf с локальным хранилищем стадий. Новая версия werf поставляется со специальными инструментами, упрощающими этот процесс. Подробная информация об этом доступна в специальном руководстве по миграции [14].
Мы также подготовили демо-проект [15], чтобы продемонстрировать, как с помощью распределенного режима werf можно собрать приложение в публичном GitLab: symfony-demo [2].
Ниже приведены шаги по использованию распределенного режима werf:
1. Подготовьте werf.yaml
:
project: symfony-demo
configVersion: 1
---
image: ~
from: ubuntu:16.04
docker:
WORKDIR: /app
# Non-root user
USER: app
EXPOSE: "80"
ENV:
LC_ALL: en_US.UTF-8
ansible:
beforeInstall:
- name: "Install additional packages"
apt:
state: present
update_cache: yes
pkg:
- locales
- ca-certificates
- name: "Generate en_US.UTF-8 default locale"
locale_gen:
name: en_US.UTF-8
state: present
- name: "Create non-root group for the main application"
group:
name: app
state: present
gid: 242
- name: "Create non-root user for the main application"
user:
name: app
comment: "Create non-root user for the main application"
uid: 242
group: app
shell: /bin/bash
home: /app
- name: Add repository key
apt_key:
keyserver: keyserver.ubuntu.com
id: E5267A6C
- name: "Add PHP apt repository"
apt_repository:
repo: 'deb http://ppa.launchpad.net/ondrej/php/ubuntu xenial main'
update_cache: yes
- name: "Install PHP and modules"
apt:
name: "{{`{{packages}}`}}"
state: present
update_cache: yes
vars:
packages:
- php7.2
- php7.2-sqlite3
- php7.2-xml
- php7.2-zip
- php7.2-mbstring
- php7.2-intl
- name: Install composer
get_url:
url: https://getcomposer.org/download/1.6.5/composer.phar
dest: /usr/local/bin/composer
mode: a+x
install:
- name: "Install app deps"
# NOTICE: Always use `composer install` command in real world environment!
shell: composer update
become: yes
become_user: app
args:
creates: /app/vendor/
chdir: /app/
setup:
- name: "Create start script"
copy:
content: |
#!/bin/bash
php -S 0.0.0.0:8000 -t public/
dest: /app/start.sh
owner: app
group: app
mode: 0755
- raw: echo `date` > /app/version.txt
- raw: chown app:app /app/version.txt
git:
- add: /
to: /app
owner: app
group: app
(файл в репозитории [16])
2. Для распределенного режима werf требуется экземпляр кластера Kubernetes — мы воспользуемся GKE. Подготовьте kube-config для кластера и установите секретную переменную BASE64_KUBECONFIG
:
cat .kube/config | base64 -w0 > /tmp/base64_kubeconfig
# copy /tmp/base64_kubeconfig content and set BASE64_KUBECONFIG variable in CI/CD
3. Подготовьте стадию сборки (build
) в .gitlab-ci.yml
:
stages:
- build
Build:
stage: build
script:
- export KUBECONFIG=$(mktemp -d)/kubeconfig
- echo $BASE64_KUBECONFIG | base64 -d -w0 > $KUBECONFIG
- type multiwerf && source $(multiwerf use 1.1 ea --as-file)
- type werf && source $(werf ci-env gitlab --as-file)
- werf build-and-publish
tags:
- werf-demo-runner
(файл в репозитории [17])
В этом примере мы реализовали только стадию сборки. Для полноценного CI/CD дополнительно понадобятся стадии развертывания (deploy
), очистки (cleanup
) и удаления (dismiss
), однако их реализацию оставим за рамками статьи. С полным примером можно ознакомиться в руководстве по использованию GitLab [18].
4. Убедитесь, что в вашем проекте явно не задан параметр --stages-storage
и не прописана переменная окружения WERF_STAGES_STORAGE
. Команда werf ci-env
установит WERF_STAGES_STORAGE=CI_REGISTRY_IMAGE/stages
(в нашем примере это registry.gitlab.com/distorhead/symfony-demo/stages
).
5. Проверьте реестр контейнеров на соответствующей странице проекта: symfony-demo/container_registry [19]. Здесь показаны собранные стадии проекта в хранилище стадий Docker Registry:
6. Теперь можно попробовать внести изменения в исходники своего приложений (src/Kernel.php
с помощью merge_requests/2 [20]) и пересобрать его. Сборочный процесс (build job [21]) берет существующие стадии из Docker Registry (хранилища стадий) и пересобирает только стадию gitLatestPatch
:
Подобный вывод означает, что все работает правильно!
Распределенный режим — очередная важная веха в развитии проекта werf. Он приносит масштабируемость, требуя при этом минимальных усилий от пользователя.
Распределенный режим доступен с версии werf v1.1.10. В этой статье мы описали, как его включить и как на него перевести существующий проект (уже использующий локальный режим werf). Распределенный режим рекомендуется для систем CI/CD и включается для них по умолчанию.
Попробуйте werf [22], если еще не сделали это! И следите за новостями: скоро мы опубликуем руководство по полной интеграции werf c GitHub Actions.
Читайте также в нашем блоге:
Автор: Timofey Kirillov
Источник [28]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/flant/353598
Ссылки в тексте:
[1] werf: https://werf.io/
[2] демо-проект: https://gitlab.com/distorhead/symfony-demo
[3] документации: https://ru.werf.io/documentation/reference/stages_and_images.html
[4] большинство реализаций: https://ru.werf.io/documentation/reference/working_with_docker_registries.html
[5] полезных функций: https://ru.werf.io/documentation/reference/build_process.html#stapel-%D0%BE%D0%B1%D1%80%D0%B0%D0%B7-%D0%B8-stapel-%D0%B0%D1%80%D1%82%D0%B5%D1%84%D0%B0%D0%BA%D1%82
[6] это будет сделано: https://github.com/flant/werf/issues/2215
[7] стадии (stages): https://ru.werf.io/documentation/reference/stages_and_images.html#stages
[8] хранилище стадий (stages storage): https://ru.werf.io/documentation/reference/stages_and_images.html#stages-storage
[9] кэша хранилища стадий: https://ru.werf.io/documentation/reference/stages_and_images.html#%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B8-%D0%B8-%D0%BA%D0%B5%D1%88-%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D0%BB%D0%B8%D1%89%D0%B0-%D1%81%D1%82%D0%B0%D0%B4%D0%B8%D0%B9
[10] lockgate: https://github.com/flant/lockgate
[11] werf stages sync
: https://ru.werf.io/documentation/reference/stages_and_images.html#%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%B0-sync
[12] werf stages switch-from-local
: https://ru.werf.io/documentation/reference/stages_and_images.html#%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%B0-switch-from-local
[13] интегрирующая: https://ru.werf.io/documentation/reference/plugging_into_cicd/overview.html
[14] руководстве по миграции: https://ru.werf.io/documentation/guides/switch_to_distributed_mode.html
[15] демо-проект: https://ru.werf.io/documentation/guides/advanced_build/first_application.html
[16] файл в репозитории: https://gitlab.com/distorhead/symfony-demo/-/blob/master/werf.yaml
[17] файл в репозитории: https://gitlab.com/distorhead/symfony-demo/-/blob/master/.gitlab-ci.yml
[18] руководстве по использованию GitLab: https://ru.werf.io/documentation/guides/gitlab_ci_cd_integration.html
[19] symfony-demo/container_registry: https://gitlab.com/distorhead/symfony-demo/container_registry
[20] merge_requests/2: https://gitlab.com/distorhead/symfony-demo/-/merge_requests/2
[21] build job: https://gitlab.com/distorhead/symfony-demo/-/jobs/559721685
[22] werf: https://github.com/flant/werf
[23] Полная поддержка популярных реализаций Docker Registry в werf: https://habr.com/ru/company/flant/blog/496992/
[24] Content-based tagging в сборщике werf: зачем и как это работает?: https://habr.com/ru/company/flant/blog/495112/
[25] Релиз werf 1.1: улучшения в сборщике сегодня и планы на будущее: https://habr.com/ru/company/flant/blog/493170/
[26] 3-way merge в werf: деплой в Kubernetes с Helm „на стероидах“: https://habr.com/ru/company/flant/blog/476646/
[27] Использование werf для выката комплексных Helm-чартов: https://habr.com/ru/company/flant/blog/468049/
[28] Источник: https://habr.com/ru/post/504390/?utm_source=habrahabr&utm_medium=rss&utm_campaign=504390
Нажмите здесь для печати.