Демо-доступ к консоли управления облаком

Быть в теме

Kubernetes 1.7 – Создание собственного Helm чарта (chart)

08.08.2018 31 минута 335

Итак, вы установили собственный Kubernetes кластер, а также установили Helm. Но как теперь запускать при помощи этой связки свои приложения?

Kubernetes-1.7-Creating-custom-helm-chart-e1502898867389.png

Это руководство проведет вас через процесс создания вашего первого чарта, объяснит, что входит в архивы и инструменты, которые вы будете использовать для их разработки. В конце этого вы будете понимать преимущества использования Helm для доставки ваших собственных приложений в ваш кластер.


Для типичного облачного приложения с трехуровневой архитектурой приведенная ниже диаграмма иллюстрирует, как его можно описать в терминах объектов Kubernetes. В этом примере каждый уровень состоит из объекта развертывания (Deployment и службы (Service, а также может дополнительно определять объекты ConfigMapили Secret. Каждый из этих объектов обычно определяется в отдельном конфигурационном YAML файле, который передается для развертывания или обновления в Kubernetes при помощи kubectl.

Kubernetes-3-Tier-App-e1502899018456.png 

Helm чарт содержит в себе каждое YAML определение каждого объекта вашего приложения, обеспечивает единый механизм конфигурации во время развертывания и позволяет вам определять метаданные и\или документацию, которые могут быть полезны при совместной работе над архивами. Helm может быть полезен в различных сценариях:


  • Поиск и использование популярного программного обеспечения, упакованного как Helm чарт
  • Распространение своего приложения через репозиторий Helm
  • Создание воспроизводимых сборок ваших приложений для Kubernetes
  • Интеллектуальное управление объектами в Kubernetes
  • Управление выпуском архивов Helm

Давайте рассмотрим второй и третий сценарии, создав небольшой Helm чарт.


Герерация Helm чарта

Лучший способ начать работу с новым чартом – это использовать команду helm create, чтобы получить пример-заглушку, на базе которого можно будет построить свое приложение. Используйте эту команду для создания нового чарта с именем my-awsome-chart в новой директории:


$ helm create my-awsome-chart


Helm создаст новую директорию с именем названием my-awsome-chart со структурой, показанной ниже. Давайте рассмотрим наш новый чарт, чтобы разобраться в том, как он работает.

$ tree my-awsome-chart

my-awsome-chart

├── charts

├── Chart.yaml

├── templates

│   ├── deployment.yaml

│   ├── _helpers.tpl

│   ├── ingress.yaml

│   ├── NOTES.txt

│   └── service.yaml

└── values.yaml

Шаблоны (templates)

Самой важной частью созданного чарта является директория templates. В ней Helm ищет YAML описания для ваших сервисов (Services), развертываний (Deployment) и других объектов Kubernetes. Если у вас уже есть определения для ваших приложений, все, что вам нужно сделать, это заменить созданные файлы YAML на ваши собственные. В результате вы получите рабочий чарт, который может быть развернут с помощью команды helm install.


Стоит отметить, что Helm обрабатывает каждый файл в директории templates с помощью механизма рендеринга шаблонов Go. Helm расширяет язык шаблонов, добавляя в него ряд полезных функций для написания чартов. Откройте файл service.yaml, чтобы посмотреть, как это выглядит.


$ cd my-awsome-chart/

$ cat templates/service.yaml

apiVersion: v1

kind: Service

metadata:

name: {{ template "fullname" . }}

labels:

    app: {{ template "name" . }}

    chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}

    release: {{ .Release.Name }}

    heritage: {{ .Release.Service }}

spec:

type: {{ .Values.service.type }}

ports:

    - port: {{ .Values.service.externalPort }}

      targetPort: {{ .Values.service.internalPort }}

      protocol: TCP

     name: {{ .Values.service.name }}

selector:

    app: {{ template "name" . }}

    release: {{ .Release.Name }}


Это базовое определение Сервиса (Service) при помощи шаблона. При деплое этого чарта Helm на основании этого файла сгенерирует описание сервиса, которое будет больше похоже на правильно определенный Сервис. Давайте выполним запуск команды helm install (ключ --dry-run) с включенным режимом отладки (ключ --debug):


$ helm install --dry-run --debug .

...

# Source: my-awsome-chart/templates/service.yaml

apiVersion: v1

kind: Service

metadata:

name: doltish-mink-my-awsome-chart

labels:

    app: my-awsome-chart

    chart: my-awsome-chart-0.1.0

    release: doltish-mink

    heritage: Tiller

spec:

type: ClusterIP

ports:

    - port: 80

      targetPort: 80

      protocol: TCP

      name: nginx

selector:

    app: my-awsome-chart

    release: doltish-mink


Значения (values)

Шаблон service.yaml использует специфичные для Helm объекты: .Chart и .Values. Первый предоставляет собой метаданные о чарте для ваших определений, т.к. имя или версия чарта. Последний объект .Values является ключевым элементом любого чарта Helm и используется для отображения конфигурации, которая должна быть установлена в процессе развертывания чарта. Значения по умолчанию для этого объекта определены в файле values.yaml. Попробуйте изменить значение по умолчанию, например, для service.internalPort и выполните еще один запуск команды Helm с ключами --dry-run и --debug. Вы увидите, что targetPort в Сервисе и containerPort в информации о развертывании изменяется. Значение service.internalPort используется для обеспечения правильной работы объектов Serviceand Deployment. Использование шаблонов таким образом может значительно уменьшить ваши изначальные шаблоны и упростить определения ваших Kubernetes объектов.


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

$ helm install --dry-run --debug . --set service.internalPort=8080

Метаданные (metadata)

Как уже упоминалось ранее, Helm чарт состоит из метаданных, которые используются для описания того, что из себя представляет ваше приложение, определения ограничений на минимальную требуемую версию Kubernetes и\или версию Helm, а также управления версией вашего чарта. Все эти метаданные находятся в файле Chart.yaml. Документация Helm подробно описывает различные опции внутри этого файла.

Деплой вашего Helm чарта

Чарт, сгенерированный на предыдущем шаге, предназначен для запуска сервера nginx, который предоставляется при помощи Cервиса (Service) Kubernetes. По умолчанию чарт создаст сервис типа ClusterIP, поэтому nginx будет доступен только внутри кластера. Чтобы получить доступ к нему извне, нам необходимо будет использовать тип публикации NodePort. Мы также можем установить имя релиза Helm, чтобы было легче к нему обращаться. Давайте развернем наш nginx чарт, используя команду helm install:


$ helm install --name example . --set service.type=NodePort

NAME:   example

LAST DEPLOYED: Mon Aug 14 10:28:48 2017

NAMESPACE: default

STATUS: DEPLOYED

 

RESOURCES:

==> v1/Service

NAME                     CLUSTER-IP      EXTERNAL-IP PORT(S)       AGE

example-my-awsome-chart 10.102.172.137        80:32664/TCP 0s

 

==> v1beta1/Deployment

NAME                     DESIRED CURRENT UP-TO-DATE AVAILABLE AGE

example-my-awsome-chart 1        1        1           0          0s

 

 

NOTES:

1. Get the application URL by running these commands:

export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services example-my-awsome-chart)

export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")

echo http://$NODE_IP:$NODE_PORT


Результат установки Helm чарта показывает полезную сводку состояния релиза, какие объекты были созданы, а также файл NOTES.txt, чтобы подсказать, что делать дальше. Запустите предлагаемые выводом команды, чтобы получить URL-адрес для доступа к службе nginx и проверить установку в своем браузере.

Kubernetes-Helm-example-chart-run-result-e1502898957728.png 


Если все пошло хорошо, вы увидите страницу приветствия nginx, как показано выше. Поздравляю! Вы только что развернули свой первый Helm сервис, упакованный в виде Helm чарта!

Изменение Helm чарта для деплоя произвольного сервиса

Сгенерированный чарт создает объект Deployment, предназначенный для запуска образа, предоставленного значениями по умолчанию. Это означает, что все, что нам нужно сделать для запуска другой службы – это изменить образ по-умолчанию в values.yaml.


Далее мы обновим Helm чарт и запустим приложение списка дел, доступное на Docker Hub. В values.yaml обновите образ так, чтобы ссылаться на образ списка дел:


image:

repository: prydonius/todo

tag: 1.0.0

pullPolicy: IfNotPresent


Когда вы разрабатываете собственный Helm чарт, рекомендуется предварительно запускать его через линтер (linter), чтобы следить за тем, что он соответствует лучшим практиками. Запустите команду helm lint, чтобы увидеть, как работает linter:

$ helm lint .

==> Linting .

[INFO] Chart.yaml: icon is recommended

 

1 chart(s) linted, no failures


Линтер не зафиксировал каких-либо серьезных проблемы с нашим чартом, поэтому мы готовы двигаться дальше. Однако, в качестве примера, вот что может сделать линтер, если вы сделали что-то неправильно (Не повторяйте этот шаг):

$ echo "malformed" > mychart/values.yaml

helm lint ./mychart

==> Linting mychart

[INFO] Chart.yaml: icon is recommended

[ERROR] values.yaml: unable to parse YAML

         error converting YAML to JSON: yaml: line 34: could not find expected ':'

 

Error: 1 chart(s) linted, 1 chart(s) failed


На этот раз линтер сообщает нам, что он не смог правильно проанализировать файл values.yaml, а также подсказывает номер строки, чтобы легко найти и исправить допущенную ошибку.


Когда чарт снова станет валидным, мы можем запустить команду helm install, чтобы развернуть приложение списка дел:

$ helm install --name example2 . --set service.type=NodePort

NAME:   example2

LAST DEPLOYED: Mon Aug 14 11:36:58 2017

NAMESPACE: default

STATUS: DEPLOYED

 

RESOURCES:

==> v1/Service

NAME                      CLUSTER-IP    EXTERNAL-IP PORT(S)       AGE

example2-my-awsome-chart 10.97.10.113        80:31336/TCP 1s

 

==> v1beta1/Deployment

NAME                      DESIRED CURRENT UP-TO-DATE AVAILABLE AGE

example2-my-awsome-chart 1        1        1           0          1s

 

 

NOTES:

1. Get the application URL by running these commands:

export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services example2-my-awsome-chart)

export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")

echo http://$NODE_IP:$NODE_PORT


Как и в прошлый раз вы можете проверить деплой вашего приложения, выполнив подсказываемые вам команды, и открыв полученную ссылку в браузере:


Kubernetes-Helm-todo-app-example-chart-run-result-e1502898902120.png 

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

Упаковка чарта и подготовка к распространению

До сих пор в этой статье мы использовали команду helm install для деплоя локального распакованного чарта. Однако, если вы хотите поделиться своими чртами с вашей командой или сообществом, имейте в виду, что все остальные устанавливают чарты tar архива. Мы можем использовать команду helm package для создания такого архива:

$ cd ..

$ helm package ./my-awsome-chart

Helm создаст архив с именем my-awsome-chart-0.1.0.tgz в нашей рабочей директории, используя имя и версию из метаданных, определенных в файле Chart.yaml. Пользователь может установить ваше приложение из этого архива, передав имя архива в качестве параметра для установки:

$ helm install --name example3 my-awsome-chart-0.1.0.tgz --set service.type=NodePort

Репозитории

Для облегчения обмена архивами Helm имеет встроенную поддержку их установки с HTTP-сервера. Helm читает размещенный на сервере индекс хранилища, который описывает, какие архивы чартов доступны, и где они расположены. Так работает стабильный репозиторий по умолчанию.

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

$ helm serve

Regenerating index. This may take a moment.

Now serving you on 127.0.0.1:8879

Теперь в другой вкладке консоли можно посмотреть на содержимое нашего локального репозитория и попробовать установить только что созданный нами сервис:

$ helm search local

NAME              VERSION DESCRIPTION

local/my-awsome-chart      0.1.0 A Helm chart for Kubernetes

$ helm install --name example4 local/my-awsome-chart --set service.type=NodePort

Если вам интересно, как установить общедоступный Helm репозиторий, воспользуйтесь официальной документацией.

Зависимости

С развитием вашего приложения или сервиса ваш чарт также будет становиться сложнее. В какой-то момент вы обнаружите, что вам нужна дополнительная зависимость, например база данных. Helm позволяет указать суб-чарты (sub-charts), которые будут созданы как часть одной и той же версии. Чтобы определить зависимость, создайте файл requirements.yaml в корневой директории вашего чарта:


$ cat > ./my-awsome-chart/requirements.yaml <<EOF

dependencies:

- name: mariadb

version: 0.6.0

repository: https://kubernetes-charts.storage.googleapis.com

EOF


Так же, как файл с зависимостями python приложения (requirements.txt), файл requirements.yaml позволяет вам управлять зависимостями чарта и их версиями. При обновлении зависимостей создается файл блокировки, так чтобы последующая выборка зависитмостей использовала уже известную версию. Выполните следующую команду, чтобы скачать зависимость MariaDB, которую мы определили:


$ helm dep update ./my-awsome-chart

Hang tight while we grab the latest from your chart repositories...

...Unable to get an update from the "local" chart repository (http://127.0.0.1:8879/charts):

         Get http://127.0.0.1:8879/charts/index.yaml: dial tcp 127.0.0.1:8879: getsockopt: connection refused

...Successfully got an update from the "stable" chart repository

Update Complete. Happy Helming!

Deleting outdated charts

Saving 1 charts

Downloading mariadb from repo https://kubernetes-charts.storage.googleapis.com

 

$ ls ./my-awsome-chart/charts/

mariadb-0.6.0.tgz


Helm нашел подходящую версию в стабильном репозитории и скачал ее в директорию chartsнашего чарта. Теперь давайте установим наш чарт и увидим, что объекты MariaDB также создаются:


$ helm install --name example5 ./my-awsome-chart --set service.type=NodePort

NAME:   example5

LAST DEPLOYED: Mon Aug 14 12:09:05 2017

NAMESPACE: default

STATUS: DEPLOYED

 

RESOURCES:

==> v1beta1/Deployment

NAME                      DESIRED CURRENT UP-TO-DATE AVAILABLE AGE

example5-my-awsome-chart 1        1        1           0          1s

example5-mariadb          1        1        1           0          1s

 

==> v1/Secret

NAME              TYPE    DATA AGE

example5-mariadb Opaque 2     2s

 

==> v1/ConfigMap

NAME              DATA AGE

example5-mariadb 1     2s

 

==> v1/PersistentVolumeClaim

NAME              STATUS   VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE

example5-mariadb Pending 2s

 

==> v1/Service

NAME                      CLUSTER-IP    EXTERNAL-IP PORT(S)       AGE

example5-mariadb          10.100.87.94         3306/TCP      2s

example5-my-awsome-chart 10.106.213.6        80:32379/TCP 1s

 

 

NOTES:

1. Get the application URL by running these commands:

export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services example5-my-awsome-chart)

export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")

echo http://$NODE_IP:$NODE_PORT



Одним из преимуществ Helm является его огромный набор чартов, которые вы можете установить с помощью одной команды. В роли автора такого чарта вы можете помочь создать стабильный репозиторий, улучшив существующие чарты или предоставив новые для общего пользования. Посмотрите на текущий репозиторий приложений на https://kubeapps.com.     

 

Не пропустите самые важные, интересные и полезные статьи недели

Ваш e-mail успешно подписан.

Смотрите так же