Kubernetes (k8s) + Helm + GitLab CI/CD. Деплоим правильно

  • Tutorial
В данной статье я хочу рассказать как деплоить приложения в разные среды. В этом примере, мы будем деплоить в: «Test» и «Production». Разумеется, вы можете добавить любые среды.

Для деплоя приложений я использую HELM. Он позволяет гибко управлять конфигурациями. В чем вы сможете убедится ниже. Предполагается, что у вас уже есть настроенный runner с helm-ом и вы знаете и умеете работать с HELM-ом.

Пример файла: .gitlab-ci.yml

.base_deploy: &base_deploy
  stage: deploy
  script:
  - PROJECT_NAME="${CI_PROJECT_NAME}-${CI_ENVIRONMENT_SLUG}"
  - helm --namespace ${CI_ENVIRONMENT_SLUG} upgrade -i ${PROJECT_NAME} helm --set "global.env=${CI_ENVIRONMENT_SLUG}";

stages:
  - deploy

Deploy to Test:
  <<: *base_deploy
  environment:
    name: test

Deploy to Production:
  <<: *base_deploy
  environment:
    name: production
  when: manual

Здесь стоит обратить внимание на то, что в зависимости от среды мы передаем переменную: «test» или «production».

Имя проекта мы тоже формируем с учетом имени переменной, для того, чтобы helm понимал, что это разные проекты (helm ls).

Далее, мы передаем эту переменную (среду) в HELM как: «global.env».

Для выше указанного примера helm должен находиться в одноименной папке в вашем репозиторие.

Теперь рассмотрим пример, как использовать переменную среды в Chart-ах HELM.

Создадим такой values.yaml:

replicas:
  test: 1
  production: 3

domain:
  test: test.domain.com
  production: production.domain.com

resources:
  requests:
    cpu:
      _default: 50m
      production: 50m
    memory:
      _default: 256Mi
      production: 10Mi
  limits:
    memory:
      _default: 1Gi
      production: 1Gi
    cpu:
      _default: 1000m

Здесь видно, что для разных сред мы указываем разные настройки.
Для удобства можно указывать и default-ные настройки.

Ещё один пример, для ingress.yaml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ .Chart.Name }}
spec:
  rules:
  - host: {{ pluck .Values.global.env .Values.domain | first | default .Values.domain._default }}
    http:
      paths:
      - path: /
        backend:
          serviceName: {{ .Chart.Name }}
          servicePort: 80

Вы всегда можете проверить как собирается ваш Chart, командой:

helm template ./helm --set "global.env=test"
helm template ./helm --set "global.env=production"

Так же вы можете деплоить ваш код на разные ноды в зависимости от среды.

Пример:

{{ if eq .Values.global.env "test" }}
      nodeSelector:
        nodetype: testnodes
{{ else if eq .Values.global.env "production" }}
      nodeSelector:
        nodetype: productionnodes
{{ else }}

Всем спасибо. Деплойте правильно.
Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 10

    0
    Если так правильно, то как деплоить неправильно? Например я разгуливаю через --kube-context, т.к. тестовый и продовый k8s, это разные кластера с разными сертификатами и токенами.
      0
      Слово «правильно» конечно же здесь носит шуточный характер)
      Мне было бы очень интересно посмотреть/почитать о вашей инсталляции.
      0
      -
        +1
        у helm есть опция -i — это позволяет установить релиз, если его нет.

        Предпочитаю иметь свои vars.yml под разные среды, а не плодить кучу if.

        Так же использую у себя конструкцию вида:
        - helm upgrade -i -f chart/vars.yml chart_name
        - kubectl rollout status deploy || helm rollback chart_name 0 && exit 1


        Немного упрощенно, там есть еще несколько шагов, но смысл в ролл бэке. Можно у хэлма использовать опцию wait, но она мне не нравится, так как не наглядна и иногда нужно делать цепочку из rollout status.
          0
          Спасибо, крутое замечание. Поизучаю.
          0
          А Вы можете рассказать, как вы делаете деплой на test, если нужна миграция базы? На каком этапе это осуществляется?
            +1
            Осуществляется джобом с restartPolicy: Never, например так
              0
              А если нужен строгий порядок запуска сущностей?
              Например, сначала такой джоб с миграциями, а потом после его выполнения уже поды-воркеры?
              Хелм умеет выстраиваеть подобную очередность?
          0
          Мы столкнулись с проблемой хостов Ingress'a.
          У него есть большой минус, он не поддерживает wildcards. Мы хотели сделать динамические entrypoint's, а ля username.domain.com, но из-за упрямства разработчиков Ingress так не сделать.
          Т.е. если вы хотите сделать приложение которое реализует схему *.domain.com – так сделать не получится.

          Only users with full accounts can post comments. Log in, please.