Русский
Русский
English
Статистика
Реклама

HelmWave v0.5.0 GitOps для твоего Kubernetes

preview


Helm, как и Docker стал де-факто стандартом в индустрии. Когда мы обсуждаем Kubernetes (52%). И новость, что Docker is deprecated вызвало волну обсуждений в сообществе. Настолько все привыкли к Docker.


Для Docker есть замечательный по своей простоте docker-compose, в котором мы можем декларативно описать, что мы хотим от Docker.


Для Kubernetes набор yaml-tpl файлов упаковывается в архив. И затем этот архив называется Helm-чартом. Но как это часто бывает приложение не может быть описано лишь одним Helm чартом. Требуется как-то управлять/композить/настраивать/шаблонизировать такие сеты.


Одним из подходов по управлению является Umbrella Chart. Это helm chart который объединяет в себе все другие чарты.


Очевидные минусы данного решения:


  • Требуется поддерживать дополнительный чарт
  • Новый слой согласования имен values переменных.
  • Umbrella-chart это все тот же чарт, поэтому о шаблонизации values и декларативном разделении на контуры (Окружения) не может быть и речи.
  • Когда обновляется саб-чарт, нужно идти в umbrella и обновлять еще версию umbrella чарта.

Helmwave возник, как инструмент для декларативного описания всех чартов в одном yaml.
Этот пост покажет как можно решить основные проблемы (use-cases) с помощью helmwave.


Что такое HelmWave?


  • Это бинарь, который устанавливает helm release из helmwave.yml.
  • Кладешь helmwave.yml в git и применяешь его через CI.
  • Можно шаблонизировать все c помощью (Go template), начиная от helmwave.yml до values.
  • Helmwave понимает какие helm-repositories ему понадобятся для деплоя. И вытесняет лишние.

Порядок комманд



graph TD;    Start(helmwave.yml.tpl) --render--> helmwave.yml;    helmwave.yml --planfile--> .helmwave;    .helmwave --sync--> Finish(Releases have been deployed!)

Быстрый старт


helmwave.yml.tpl имеет следующий вид


project: my-projectversion: 0.5.0repositories:  - name: bitnami    url: https://charts.bitnami.com/bitnami.options: &options  install: true  namespace: my-namespacereleases:  - name: redis-a    chart: bitnami/redis    options:      <<: *options  - name: redis-b    chart: bitnami/redis    options:      <<: *options

$ helmwave deploy

Поздравляю, вы задеплоили с помощью helmwave!


$ helm list -n my-namespaceNAME       NAMESPACE       REVISION     STATUS      CHART             APP VERSIONredis-a    my-namespace    1            deployed    redis-11.2.3      6.0.9      redis-b    my-namespace    1            deployed    redis-11.2.3      6.0.9  $ k get po -n my-namespace                                                                                                                         NAME               READY   STATUS    RESTARTS   AGEredis-a-master-0   1/1     Running   0          64sredis-a-slave-0    1/1     Running   0          31sredis-a-slave-1    1/1     Running   0          62sredis-b-master-0   1/1     Running   0          59sredis-b-slave-0    1/1     Running   0          32sredis-b-slave-1    1/1     Running   0          51s

Переменные окружения


$ helmwave help

  • $HELMWAVE_TPL_FILE отвечает за путь к входному файлу для шаблонизации (helmwave.yml.tpl).
  • $HELMWAVE_FILE указывает путь выходного файла после операции шаблонизации (helmwave.yml).
  • $HELMWAVE_PLAN_DIR указывает путь к папке, в которой хранится или будет хранится план (.helmwave/).
  • $HELMWAVE_TAGS массив строк, на основании которого будет проводится планирование.
  • $HELMWAVE_PARALLEL включает/выключает многопоточность (рекомендуется включать).
  • $HELMWAVE_LOG_FORMAT позволяет выбрать один из предустановленных форматов вывода.
  • $HELMWAVE_LOG_LEVEL позволяет управлять детализацией вывода.
  • $HELMWAVE_LOG_COLOR включает/выключает цвета для вывода.

Use-Cases


Примеры будут производиться, опираясь на gitlab-ci. Но это не помешает вам встроить helmwave в любой другой CI-инструмент.


Чем ниже, тем сложнее будут примеры.


Git tag > Docker tag


Допустим вы написали какой-то helm чарт для нашего приложения. Его values.yaml по умолчанию имеет вид:


image:  repository: registry.gitlab.local/example/app  tag: master

Необходимо чтобы image.tag брался из переменной CI


Приступим, создадим 2 файла.


. helmwave.yml.tpl values.yml

helmwave.yml.tpl


project: my-project # Имя проектаversion: 0.5.0 # Версия helmwavereleases:  - name: my-release    chart: my-chart-repo/my-app    values:      - values.yml    options:      install: true      namespace: my-namespace

values.yml


image:  tag: {{ env "CI_COMMIT_TAG" }}

Git commit --> PodAnnotations


Требуется чтобы deployment обновлялся только если у нас есть новый коммит.


deployment имеет примерно этот вид:


    ...    metadata:        {{- with .Values.podAnnotations }}        annotations:          {{- toYaml . | nindent 8 }}        {{- end }}    ...

Поэтому мы можем легко расширить предыдущий пример values.yml


image:  tag: {{ requiredEnv "CI_COMMIT_TAG" }}podAnnotations:    gitCommit: {{ requiredEnv "CI_COMMIT_SHORT_SHA" | quote }}

Контуры, окружения, environments


Структура каталога


. helmwave.yml.tpl values     _.yml     prod.yml     stage.yml

helmwave.yml.tpl


project: my-project  version: 0.5.0  releases:    - name: my-release      chart: my-chart-repo/my-app      values:        # Default        - values/_.yml        # For specific ENVIRONMENT        - values/{{ env "CI_ENVIRONMENT_NAME" }}.yml      options:        install: true        namespace: {{ env "CI_ENVIRONMENT_NAME" }}

values/_.yml Будет запускаться для любого окружения


image:  tag: {{ requiredEnv "CI_COMMIT_TAG" }}podAnnotations:    gitCommit: {{ requiredEnv "CI_COMMIT_SHORT_SHA" | quote }}

values/prod.yml Будет запускаться только для prod


replicaCount: 6

values/stage.yml Будет запускаться только для stage


replicaCount: 2

Используем внешний yaml и .Release.Store


Store это просто хранилище, которое можно задавать в helmwave.yml и передавать дальше в шаблонизацию values.


Допустим мы хотим связать путь к секрету в vault и путь к проекту в gitlab или вы хотите переопределять путь к image.repository. Это можно удобно сделать через Store.


. helmwave.yml.tpl values    _.yml vars     my-list.yaml

values/_.yml


vault: secret/{{ .Release.Store.path  }}/{{ requiredEnv "CI_ENVIRONMENT_NAME"  }}image:  repository: {{ env "CI_REGISTRY" | default "localhost:5000" }}/{{ .Release.Store.path }}

Добавим произвольный yaml файл.


vars/my-list.yaml


releases:  - name: adm-api    path: main/product/adm/api  - name: api    path: main/product/api

helmwave.yml.tpl


project: my-projectversion: 0.5.0.options: &options  install: true  wait: true  timeout: 5mreleases:  {{- with readFile "vars/my-list.yaml" | fromYaml | get "releases" }}  {{- range $v := . }}  - name: {{ $v | get "name" }}    chart: my-project/{{ $v | get "name" }}    options:      <<: *options    store:      path: {{ $v | get "path" }} # Set .Release.Store.path    tags:      - {{ $v | get "name" }}      - my    values:        # Default        - values/_.yml        # For specific ENVIRONMENT        - values/{{ env "CI_ENVIRONMENT_NAME" }}.yml  {{ end }}  {{- end }}

Запускаем!


$ CI_ENVIRONMENT_NAME=stage helmwave planfile

Появится helmwave.yml и папка .helmwave


$ tree .helmwave.helmwave planfile values     _.yml.adm-api@.plan     _.yml.api@.plan$ cat .helmwave/values/_.yml.api@.plan                            vault: secret/main/product/api/stage                                                               image:  repository: localhost:5000/main/product/api$ cat .helmwave/values/_.yml.adm-api@.plan                                  vault: secret/main/product/adm/api/stageimage:  repository: localhost:5000/main/product/adm/api

helmwave.yml


project: my-projectversion: 0.5.0.options: &options  install: true  wait: true  timeout: 5mreleases:  - name: adm-api    chart: my/adm-api    options:      <<: *options    store:      path: main/product/adm/api    tags:      - adm-api      - my    values:        # Default        - values/_.yml        # For specific ENVIRONMENT        - values/stage.yml  - name: api    chart: my/api    options:      <<: *options    store:      path: main/product/api    tags:      - api      - my    values:        # Default        - values/_.yml        # For specific ENVIRONMENT        - values/stage.yml

Отделяем продукты от инфраструктуры


Структура проекта


Создадим в папке values 2 папки


  • product здесь будут values для продуктов
  • infrastructure здесь будет инфарструктурные values

values/infrastructure


  • adminer веб морда для подключения к базе, полезна в основном только в dev-контурах
  • postgresql база данных
  • ns-ready здесь LimitRange, ResourcseQuota, Secrets, NetworkPolicy, etc
  • rabbitmq общая шина между chat и api

values/product
Приложение состоит из 3 микросервисов


  • api
  • chat
  • frontend

И еще нам понадобятся 2 отдельных файла описывающие массив product и массив infrastructure.


Структура проекта:


. helmwave.yml.tpl values    infrastructure       adminer          _.yml          dev.yml          stage.yml       ns-ready          _.yml       postgresql          _.yml          dev.yml       rabbitmq           _.yml           dev.yml           stage.yml    product        _           _.yml           dev.yml           prod.yml           stage.yml        api           _.yml           dev.yml           prod.yml           stage.yml        chat           _.yml        frontend            _.yml            dev.yml            prod.yml            stage.yml vars     infrastructure.yaml     products.yaml

vars/infrastructure.yaml


releases:  - name: postgresql    repo: bitnami    version: 8.6.13  - name: adminer    repo: cetic    version: 0.1.5  - name: rabbitmq    repo: bitnami    version: 7.6.6  - name: ns-ready    repo: my-project    version: 0.1.1

vars/products.yaml


releases:  - name: adm-api    path: rdw/sbs/adm/api  - name: frontend    path: my-project/internal/frontend  - name: api    path: my-project/internal/api  - name: chat    path: my-project/internal/chat

helmwave.yml.tpl


project: my-projectversion: 0.5.0repositories:  - name: bitnami    url: https://charts.bitnami.com/bitnami  - name: cetic    url: https://cetic.github.io/helm-charts.options: &options  install: true  wait: true  timeout: 5m  atomic: false  maxhistory: 10  namespace: {{ requiredEnv "HELM_NS" }}releases:  {{- with readFile "vars/products.yaml" | fromYaml | get "releases" }}  {{- range $v := . }}  - name: {{ $v | get "name" }}    chart: my-project/{{ $v | get "name" }}    options:      <<: *options    store:      path: {{ $v | get "path" }}    tags:      - {{ $v | get "name" }}      - product    values:      # all products & all envs      - values/product/_/_.yml      # all products & an env      - values/product/_/{{ requiredEnv "CI_ENVIRONMENT" }}.yml      # a product & all envs      - values/product/{{ $v | get "name" }}/_.yml      # a product & an env      - values/product/{{ $v | get "name" }}/{{ requiredEnv "CI_ENVIRONMENT" }}.yml  {{ end }}  {{- end }}  {{- with readFile "vars/infrastructure.yaml" | fromYaml | get "releases" }}  {{- range $v := . }}  - name: {{ $v | get "name" }}    chart: {{ $v | get "repo" }}/{{ $v | get "name" }}    options:      <<: *options      chartpathoptions:        version: {{ $v | get "version" }}    tags:      - {{ $v | get "name" }}      - infrastructure    values:      # a svc & all envs      - values/infrastructure/{{ $v | get "name" }}/_.yml      # a svc & an env      - values/infrastructure/{{ $v | get "name" }}/{{ requiredEnv "CI_ENVIRONMENT" }}.yml  {{ end }}  {{- end }}

Контуры в Store


Допустим у нас есть 2 окружения dev и prod.
И в prod'e нам не нужна база данных


vars/infrastructure.yaml


releases:  - name: rabbitmq    repo: stable    version: 6.18.2    envs:      - _ # all environments    tags:      - queue  - name: postgresql    repo: bitnami    version: 8.6.13    envs:      - dev # only dev    tags:      - db

# vim: set filetype=yaml:{{- $env := requiredEnv "CI_ENVIRONMENT" }} # Look at this firstproject: insiderversion: 0.5.0repositories:  - name: stable    url: https://kubernetes-charts.storage.googleapis.com  - name: bitnami    url: https://charts.bitnami.com/bitnami.options: &options  install: true  wait: true  force: false  timeout: 5m  atomic: false  maxhistory: 10  namespace: {{ requiredEnv "HELM_NS" }}releases:  {{- with readFile "vars/infrastructure.yaml" | fromYaml | get "releases" }}  {{- range $v := . }}  {{- $envs := $v | get "envs" }}  {{- if or (has "_" $envs) (has $env $envs) }}  - name: {{ $v | get "name" }}    chart: {{ $v | get "repo" }}/{{ $v | get "name" }}    options:      <<: *options      chartpathoptions:        version: {{ $v | get "version" }}    tags:      - {{ $v | get "name" }}      - infrastructure      {{- if $v | hasKey "tags" }}      - {{ $v | get "tags" | toYaml }}      {{- end }}    values:      # a svc & all envs      - values/infrastructure/{{ $v | get "name" }}/_.yml      # a svc & an env      - values/infrastructure/{{ $v | get "name" }}/{{ $env }}.yml  {{ end }}  {{- end }}  {{- end }}

База по умолчанию выключена


$ helmwave planfile

Чтобы postgresql включился


$ CI_ENVIRONMENT=dev helmwave planfile

Giltab-CI Pipelines


Рассмотрим шаблон gitlab-ci с использованием helmwave из проекта g-ci


variables:  HELMWAVE_LOG_LEVEL: debug.helmwave-deploy:  stage: deploy  environment:    name: ref/$CI_COMMIT_REF_SLUG  image:    name: diamon/helmwave:0.5.0    entrypoint: [""]  script:    - helmwave deployhelmwave deploy:  extends: .helmwave-deploy

С использованием include


include: https://gitlab.com/g-ci/deploy/-/raw/master/helmwave.ymlhelmwave deploy:  environment:    name: prod

P.S.


Helmwave source: https://github.com/zhilyaev/helmwave/
G-CI: https://gitlab.com/g-ci
Приходите к нам в telegram с любыми вопросами!

Источник: habr.com
К списку статей
Опубликовано: 14.12.2020 22:19:31
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Git

Devops

Kubernetes

Gitops

Helm

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru