Родительский helm chart для проектов + werf

от автора

В данном методе используется инструмент werf от компании Флант для сборки и доставки приложения и их накопленные знания конфигураций CI/CD и деплоя приложений в K8s.

Фактический результат

Имеем микросервисную архитектуру в k8s, где крутятся и деплоятся сервисы на пхп, го, js … Под каждый микросервис создается отдельный репозиторий, который содержит помимо исходников кода набор кубернетис ресурсов (deployment, configMap, Secret, Job…)

Пример проекта Laravel

Пример проекта Laravel

Проблематика

Выкат и настройка каждого микросервиса становится головной болью, по сути каждый микросервис содержит одинаковые описания ресурсов для k8s (копипаст), нет единого места для изменения ресурсов кубурнетиса для проекта, много лишних знаний об инфроструктуре для программистов, да разработчики бывают разные, кто то может все настроить сам, понимает как это все работает, а кто то нет, по сути такая реализация и была задумана для того чтобы упростить настройку деплоя для разработчиков и девопсов.

Желаемый результат

Иметь единый стандартизированный helm репозиторий (php, go, js …), поддержка семантического версирования чарта, в дочернем проекте иметь только файлы values для определенного окружения с помощью которых настраивать деплой приложения.

Пример дочернего проекта Laravel

Пример дочернего проекта Laravel

Действующие лица

Gitlab, K8s, werf, docker (подразумевается что все доступы к k8s, Gitlab, docker уже имеются)

Поехали!

Werf

Установим werf на сервер Gitlab следуя официальной документации (werf можно использовать без установки на хост запуская image) https://ru.werf.io/documentation/v1.2/index.html?usage=ci&ci=gitlabCiCd&runnerType=hostRunner&os=linux&buildBackend=docker&projectType=simplified&sharedCICD=no&repoType=application

Настроим runner для проекта https://ru.werf.io/documentation/v1.1/guides/gitlab_ci_cd_integration.html

Родительский репозиторий

  1. Создаем новый репозиторий laravel-chart, структура файлов

Структура родительского репозитория

Структура родительского репозитория
  1. .helm/charts/laravel-chart/Chart.yaml

apiVersion: v2 name: laravel-chart description: Laravel chart  version: 1.1.1  appVersion: "1.0.0"
  1. .gitlab-ci.yaml подробное описание инструкций можно посмотреть в статье

stages:   - publish-charts  variables:   REPO_URL: "${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/packages/helm/api/stable/charts"  before_script:   - set -eo pipefail   - type trdl && . $(trdl use werf 1.2 stable)     # Активируем werf для gitlab   - type werf && source $(werf ci-env gitlab --as-file)   - |     werf helm repo update     find . -type f -regex '.*/\(Chart.ya?ml\|requirements.ya?ml\)' -exec \       sh -c 'werf helm dependency build $(dirname "{}") --skip-refresh' \;  "publish charts":   stage: publish-charts   script:     - |       mkdir -p .packages       while read chart; do         echo "[PACKAGING CHART $chart]"         werf helm package "$chart" -d .packages       done < <(find .helm/charts -mindepth 1 -maxdepth 1 -type d)     - |       find .packages -mindepth 1 -maxdepth 1 -type f -name '*.tgz' -exec sh -c 'basename "$0"' '{}' \; | while read package; do         CHART_NAME=$(echo $package | sed -e 's/-[0-9]\.[0-9]\.[0-9]\.tgz$//g')         CHART_VERSION=$(echo $package | sed -e 's/^[a-zA-Z-].*-//g' | sed -e 's/.tgz$//g')         CHART_EXISTS=$(werf helm search repo -l $REPO_NAME/$CHART_NAME | { egrep "$REPO_NAME/$CHART_NAME\s"||true; } | { egrep "$CHART_VERSION\s"||true; } | wc -l)         if [ $CHART_EXISTS = 0 ]; then           curl -sSl --post301 --form "chart=@.packages/$package" --user "$REPO_PUSH:$REPO_PUSH_SECRET" "$REPO_URL"         else           echo "Chart package $package already exists in Helm repo! Skip!"         fi       done   only:     refs:       - master   tags:     - werf

3. Настроим токены для доступа к родительскому репозиторию, Settings -> Repository -> Deploy tokens,создаём новый токен с правами read_package_registry и write_package_registry

Добавим переменные окружения CI/CD

  • REPO_NAME — laravel-chart

  • REPO_PUSH — название нашего токена который создали выше

  • REPO_PUSH_SECRET — секрет нашего токена который создали выше

  1. Заходим на машину где будем запускать наш CI и и регестируем helm repo

werf helm repo add --username $REPO_PUSH --password $REPO_PUSH_SECRET $REPO_NAME ${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/packages/helm/stable werf helm repo update
  1. Коммитим и пушим наш чарт в репозиторий, после пуша наш чарт должен появится в Packages & Registries -> Package Registry нашего репозитория

Дочерний репозиторий

1. Создаем новый репозиторий структура файлов

.helm/Chart.yaml

apiVersion: v2 name: laravel version: 1.0.2 dependencies:   - name: laravel-chart     export-values:       - parent: werf         child: werf     version: ~1.0     repository: "@laravel-chart"

werf.yaml

project: laravel configVersion: 1 --- image: backend dockerfile: deploy.Dockerfile target: backend --- image: frontend dockerfile: deploy.Dockerfile target: frontend

werf-giterminism.yaml (тут мы сознательно отключаем гитерминизм в werf т.к наш чарт не будет находится под гит контролем)

giterminismConfigVersion: 1 helm:   allowUncommittedFiles:     - ".helm/Chart.lock"     - ".helm/charts/*.tgz"

.gitlab-ci.yaml

stages:   - publish-chart   - build   - test   - deploy   - cleanup  variables:   REPO_URL: "${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/packages/helm/api/stable/charts"   HELM_URL: "${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/packages/helm/stable"   MAIN_REPO_NAME: "laravel-chart"   MAIN_HELM_URL: "${CI_SERVER_URL}/api/v4/projects/{id родительского репозитория}/packages/helm/stable"  default:   before_script:     - set -eo pipefail     - type trdl && . $(trdl use werf 1.2 stable)     - type werf && source $(werf ci-env gitlab --as-file)     - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY  Publish Charts:   stage: publish-chart   script: |     werf helm repo add --force-update --username $MAIN_REPO_PULL --password $MAIN_REPO_PULL_SECRET $MAIN_REPO_NAME $MAIN_HELM_URL     werf helm repo update     werf helm dependency update .helm/     find .helm/charts -mindepth 1 -maxdepth 1 -type f -name '*.tgz' -exec sh -c 'basename "$0"' '{}' \; | while read package; do           CHART_NAME=$(echo $package | sed -e 's/-[0-9]\.[0-9]\.[0-9]\.tgz$//g')           CHART_VERSION=$(echo $package | sed -e 's/^[a-zA-Z-].*-//g' | sed -e 's/.tgz$//g')           CHART_EXISTS=$(werf helm search repo $CI_PROJECT_NAME | { egrep "$MAIN_REPO_NAME/$CHART_NAME\s" || true; } | { egrep "$CHART_VERSION\s" || true; } | wc -l)           if [ $CHART_EXISTS = 0 ]; then             curl -sSl --post301 --form "chart=@.helm/charts/$package" --user "$CLIENT_REPO_PUSH:$CLIENT_REPO_PUSH_SECRET" "$REPO_URL"           else             echo "Chart package $package already exists in Helm repo! Skip!"           fi         done     werf helm repo add --username $CLIENT_REPO_PULL --password $CLIENT_REPO_PULL_SECRET $CI_PROJECT_NAME $HELM_URL     werf helm repo update   only:     - development     - staging     - master   tags: [werf]   except: [schedules]  #подготавливаем образы приложения Build and Publish:   stage: build   script:     - werf build   except: [schedules]   tags: [werf]   only:     - development     - staging     - master #запускаем контейнер, запускаем в нем тесты и после прохождения удаляем его Phpunit:   stage: test   script:     - werf helm dependency update .helm/     - werf converge --skip-build --env testing --values .helm/testing/values.yaml     - werf kube-run backend --log-verbose=true --env testing -- vendor/bin/phpunit --colors=never     - werf dismiss --env testing --with-namespace   only:     - development     - staging     - master   environment:     name: ${CI_COMMIT_REF_SLUG}   tags: [werf]   except: [schedules]   dependencies:     - Build and Publish  .base_deploy:   stage: deploy   tags: [werf]   except: [schedules]   dependencies:     - Build and Publish  #деплоим в дев окружение Deploy to development:   extends: .base_deploy   script:     - werf helm dependency update .helm/     - werf converge --skip-build --env development --auto-rollback=true --values .helm/development/values.yaml   only:     - development   environment:     name: development  #деплоим в стаг окружение Deploy to staging:   extends: .base_deploy   script:     - werf helm dependency update .helm/     - werf converge --skip-build --env staging --auto-rollback=true --values .helm/staging/values.yaml   only:     - staging   environment:     name: staging  #деплоим в прод окружение Deploy to production:   extends: .base_deploy   script:     - werf helm dependency update .helm/     - werf converge --skip-build --env production --auto-rollback=true --values .helm/production/values.yaml   only:     - master   environment:     name: production  #запускаем таск для удаления не нужных образов в регистри Cleanup:   stage: cleanup   script:     - werf cr login -u nobody -p ${WERF_IMAGES_CLEANUP_PASSWORD} ${WERF_REPO}     - werf cleanup --repo=${WERF_REPO}   only: [schedules]   tags: [werf] 
  1. Настроим токены для доступа к репозиторию, Settings -> Repository -> Deploy tokens,создаём новые токены

    1. Первый с правами write_package_registry и помещаем полученные значения в переменные окружения дочернего репозитория CLIENT_REPO_PUSH и CLIENT_REPO_PUSH_SECRET

    2. Второй с правами read_package_registry и помещаем полученные значения в переменные окружения дочернего репозиторияCLIENT_REPO_PULL и CLIENT_REPO_PULL_SECRET

    3. Переходим в родительский репозиторий в раздел Settings -> Repository -> Deploy tokens и создаем токен с правами read_package_registry, помещаем полученные значения в переменные окружения дочернего репозитория MAIN_REPO_PULL и MAIN_REPO_PULL_SECRET

В статье не рассматриваются тонкости подготовки образов, настройки CI/CD и деплоя приложения используя werf. Это тема отдельной статьи.

Итог

После всех манипуляций мы имеем возможность настроить наш дочерний репозиторий имея только values в проекте, при запуске CI родительский чарт выкачается и запушится в дочерний package registry, имеем поддержку семантического версирования.


ссылка на оригинал статьи https://habr.com/ru/articles/734922/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *