HELM, который вы должны знать, чтобы играть в K8S

Kubernetes
HELM, который вы должны знать, чтобы играть в K8S

основная концепция

Helm похож на менеджер пакетов в системе Linux, такой как yum/apt и т. д. Он может быстро и легко развернуть ранее упакованный файл yaml в kubernetes, что удобно для управления и обслуживания.

  • helm: клиентский инструмент командной строки, в основном используемый для создания/упаковки/публикации диаграмм приложений kubernetes, создания и управления удаленными хранилищами диаграмм.
  • Tiller: сервер Helm развернут в kubernetes.Tiller принимает запрос helm, создает файл развертывания kubernetes (называемый helm релизом) в соответствии с диаграммой и отправляет его в Kubernetes для создания приложения. Tiller также предоставляет ряд функций, таких как обновление, удаление и откат Release.
  • Диаграмма: пакет helm в формате tar, который содержит все определения образов/зависимостей/ресурсов, необходимых для запуска приложения, а также может содержать определения служб в кластере kubernetes.
  • Релиз: экземпляр Chart, работающий в кластере в kubernetes. В одном и том же кластере Chart можно установить несколько раз, и каждая установка будет генерировать новый выпуск.
  • Репозиторий: репозиторий для публикации и хранения диаграмм.

Проще говоря:

  • Роль helm: Как и команда yum в centos7, управлять программными пакетами, за исключением того, что helm управляет различными контейнерами, установленными на k8s.
  • Роль румпеля: Как и склад программного обеспечения centos7, он просто похож на xxx.repo в каталоге /etc/yum.repos.d.

Двухкомпонентная архитектура

Три принципа работы

3.1 Chart install

  • helm анализирует информацию о структуре диаграммы из указанного каталога или файла tar
  • helm передает структуру диаграммы и информацию о значениях, сформулированную для румпеля, через протокол gRPC.
  • румпель генерирует релиз на основе диаграммы и значений
  • румпель отправляет релиз в kubernetes через json для создания релиза

3.2 Chart update

  • Helm анализирует информацию о структуре диаграммы из указанного каталога или файла tar.
  • Helm передаст структуру диаграммы и информацию о значениях румпелю через протокол gRPC.
  • румпель генерирует релиз и обновляет историю релиза с указанным именем
  • румпель отправляет информацию о выпуске в kubernetes для обновления выпуска

3.3 Chart Rollback

  • helm передаст имя выпуска рулона румпелю
  • румпель находит историю по названию релиза
  • румпель получает предыдущий релиз из истории
  • румпель отправляет последний релиз в kubernetes для замены текущего релиза

3.4 Зависимости обработки диаграммы

Когда Tiller обрабатывает диаграмму, он напрямую объединяет диаграмму и все диаграммы, от которых она зависит, в релиз и одновременно передает ее в Kubernetes. Таким образом, Tiller не отвечает за управление порядком запуска между зависимостями. Приложения в Chart должны иметь возможность самостоятельно обрабатывать зависимости.

Четыре установки и развертывания

Установка версии 4.1 v2

4.1.1 Установка руля

# 在helm客户端主机上,一般为master主机
wget https://get.helm.sh/helm-v2.14.2-linux-amd64.tar.gz
tar xf helm-v2.14.2-linux-amd64.tar.gz
mv helm /usr/local/bin/
helm version

4.1.2 Инициализация румпеля

  • Инициализация румпеля автоматически прочитает~/.kubeкаталог, поэтому вам необходимо убедиться, что файл конфигурации существует и аутентификация прошла успешно.

  • румпель настроить rbac, создать новый rabc-config.yaml и применить его

# 在:https://github.com/helm/helm/blob/master/docs/rbac.md 可以找到rbac-config.yaml

cat > rbac-config.yaml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system
EOF

kubectl apply -f rbac-config.yaml
  • Сделать зеркало
docker pull jessestuart/tiller:v2.14.2

yum install socat

# yum install socat

docker tag jessestuart/tiller:v2.14.2 gcr.io/kubernetes-helm/tiller:v2.14.2

helm init -i gcr.io/kubernetes-helm/tiller:v2.9.0

# 需要注意点参数
–client-only:也就是不安装服务端应用,这在 CI&CD 中可能需要,因为通常你已经在 k8s 集群中安装好应用了,这时只需初始化 helm 客户端即可;
–history-max:最大历史,当你用 helm 安装应用的时候,helm 会在所在的 namespace 中创建一份安装记录,随着更新次数增加,这份记录会越来越多;
–tiller-namespace:默认是 kube-system,你也可以设置为其它 namespace;
  • Изменить изображение
# 由于gfw原因,可以利用此镜像https://hub.docker.com/r/jessestuart/tiller/tags
kubectl edit deployment -n kube-system tiller-deploy

image: jessestuart/tiller:v2.14.0
  • Обработка исключений
Error: Looks like "https://kubernetes-charts.storage.googleapis.com" is not a valid chart repository or cannot be reached: Get https://kubernetes-charts.storage.googleapis.com/index.yaml: read tcp 10.2.8.44:49020->216.58.220.208:443: read: connection reset by peer

解决方案:更换源:helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts

然后在helm init


注意:tiller可能运行在node节点,将tiller镜像下载到node节点并修改tag
  • Посмотреть версию
[root@master ~]# helm version
Client: &version.Version{SemVer:"v2.14.2", GitCommit:"a8b13cc5ab6a7dbef0a58f5061bcc7c0c61598e7", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.14.2+unreleased", GitCommit:"d953c6875cfd4b351a1e8205081ea8aabad7e7d4", GitTreeState:"dirty"}

4.2 Установка и развертывание helm3

Поскольку многие иностранные зеркальные веб-сайты недоступны в Китае, например,gcr.io , рекомендуется использовать Aliyuan,developer.aliyun.com/Hubei.

AppHub — это некоммерческий Helm Hub «China Station», размещенный в общедоступном облаке страны. Его серверная часть разработана тремя инженерами из команды Alibaba Cloud Container Platform, которые используют 20% времени.

Важной обязанностью этого сайта является автоматическая синхронизация всех приложений, размещенных на официальном хабе Helm, с Китаем; в то же время автоматическиgcr.io Подождите, пока все URL-адреса с проблемами доступа к сети будут заменены стабильными URL-адресами внутренних зеркал.

В настоящее время helm3 не зависит от румпеля, и имя релиза можно повторно использовать между разными ns.

4.2.1 Установка руля

Helm3 не нужно устанавливать румпель, просто скачайте бинарный файл Helm и распакуйте его прямо в $PATH, чтобы использовать его.

cd /opt && wget https://cloudnativeapphub.oss-cn-hangzhou.aliyuncs.com/helm-v3.0.0-alpha.1-linux-amd64.tar.gz
tar -xvf helm-v3.0.0-alpha.1-linux-amd64.tar.gz
mv linux-amd64 helm3
mv helm3/helm helm3/helm3
chown root.root helm3 -R
cat > /etc/profile.d/helm3.sh << EOF
export PATH=$PATH:/opt/helm3
EOF
source /etc/profile.d/helm3.sh


[root@master helm3]# helm3 version
version.BuildInfo{Version:"v3.0.0-alpha.1", GitCommit:"b9a54967f838723fe241172a6b94d18caf8bcdca", GitTreeState:"clean"}

4.2.2 Установка приложения с помощью helm3

helm repo add apphub https://apphub.aliyuncs.com
helm search guestbook
helm install guestbook apphub/guestbook

5 использование

5.1 Основные команды

http://hub.kubeapps.com/

completion 	# 为指定的shell生成自动完成脚本(bash或zsh)
create     	# 创建一个具有给定名称的新 chart
delete     	# 从 Kubernetes 删除指定名称的 release
dependency 	# 管理 chart 的依赖关系
fetch      	# 从存储库下载 chart 并(可选)将其解压缩到本地目录中
get        	# 下载一个命名 release
help       	# 列出所有帮助信息
history    	# 获取 release 历史
home       	# 显示 HELM_HOME 的位置
init       	# 在客户端和服务器上初始化Helm
inspect    	# 检查 chart 详细信息
install    	# 安装 chart 存档
lint       	# 对 chart 进行语法检查
list       	# releases 列表
package    	# 将 chart 目录打包成 chart 档案
plugin     	# 添加列表或删除 helm 插件
repo       	# 添加列表删除更新和索引 chart 存储库
reset      	# 从集群中卸载 Tiller
rollback   	# 将版本回滚到以前的版本
search     	# 在 chart 存储库中搜索关键字
serve      	# 启动本地http网络服务器
status     	# 显示指定 release 的状态
template   	# 本地渲染模板
test       	# 测试一个 release
upgrade    	# 升级一个 release
verify     	# 验证给定路径上的 chart 是否已签名且有效
version    	# 打印客户端/服务器版本信息
dep         # 分析 Chart 并下载依赖
  • Укажите value.yaml для развертывания диаграммы
helm install --name els1 -f values.yaml stable/elasticsearch
  • обновить диаграмму
helm upgrade --set mysqlRootPassword=passwd db-mysql stable/mysql

helm upgrade go2cloud-api-doc go2cloud-api-doc/ 
  • Откатить диаграмму
helm rollback db-mysql 1
  • удалить выпуск
helm delete --purge db-mysql
  • Отрисовывается и выводится только шаблон, а не установленный
helm install/upgrade xxx --dry-run --debug

5.2 Организация файла карты

myapp/                               # Chart 目录
├── charts                           # 这个 charts 依赖的其他 charts,始终被安装
├── Chart.yaml                       # 描述这个 Chart 的相关信息、包括名字、描述信息、版本等
├── templates                        # 模板目录
│   ├── deployment.yaml              # deployment 控制器的 Go 模板文件
│   ├── _helpers.tpl                 # 以 _ 开头的文件不会部署到 k8s 上,可用于定制通用信息
│   ├── ingress.yaml                 # ingress 的模板文件
│   ├── NOTES.txt                    # Chart 部署到集群后的一些信息,例如:如何使用、列出缺省值
│   ├── service.yaml                 # service 的 Go 模板文件
│   └── tests
│       └── test-connection.yaml
└── values.yaml                      # 模板的值文件,这些值会在安装时应用到 GO 模板生成部署文件

5.3 Создайте свою собственную диаграмму

  • Создайте свою собственную карту
[root@master mychart]# helm create mychart
Creating mychart
[root@master mychart]# ls
mychart
[root@master mychart]# tree mychart/
mychart/
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml						# 部署相关资源
│   ├── _helpers.tpl							# 模版助手
│   ├── ingress.yaml							# ingress资源
│   ├── NOTES.txt									# chart的帮助文本,运行helm install展示给用户
│   ├── service.yaml							# service端点
│   └── tests
│       └── test-connection.yaml
└── values.yaml

3 directories, 8 files
  • Удалите все файлы в шаблоне и создайте configmap
rm -rf mychart/templates/*
# 我们首先创建一个名为 mychart/templates/configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: mychart-configmap
data:
  myvalue: "Hello World"
  • установочный тест

Так как созданный файл yaml находится под шаблоном, тиллер читает этот файл и отправляет его в kubernetes.

[root@master mychart]# helm install ./mychart/
NAME:   enervated-dolphin
LAST DEPLOYED: Sun Jul 21 09:29:13 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME               DATA  AGE
mychart-configmap  1     0s

[root@master mychart]# kubectl get cm mychart-configmap
NAME                DATA   AGE
mychart-configmap   1      2m6s
[root@master mychart]# kubectl describe cm mychart-configmap
Name:         mychart-configmap
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
myvalue:
----
this is my chart configmap
Events:  <none>


[root@master mychart]# helm get manifest enervated-dolphin

---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mychart-configmap
data:
  myvalue: "this is my chart configmap"

Долженhelm get manifestКоманда получает имя выпуска (enervated-dolphin) и выводит все ресурсы Kubernetes, загруженные на сервер. Каждый файл начинается с---Начинается как начало документа YAML, за которым следует автоматически сгенерированная строка комментария, которая сообщает нам, что этот документ YAML был сгенерирован файлом шаблона.

Оттуда мы видим, что данные YAML — это именно то, что у нас есть в нашемconfigmap.yamlоформлен в файле.

Теперь мы можем удалить наш релиз:helm delete enervated-dolphin.

[root@master mychart]# helm delete enervated-dolphin
release "enervated-dolphin" deleted

5.4 Добавить вызов шаблона

жесткий кодname:Как правило, считается плохой практикой для получения ресурсов. Имя должно быть уникальным для одной версии. Таким образом, мы могли бы захотеть создать поле имя, вставляя имя отпуска.

намекать:имя: Из-за ограничений системы DNS это поле ограничено 63 символами. Поэтому имена выпусков ограничены 53 символами. Kubernetes 1.3 и более ранние версии ограничены 24 символами (т. е. 14-символьными именами).

Измените предыдущую карту конфигурации на следующее содержимое

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"

name:Теперь это значение изменилось на{{.Release.Name}}-configmap.

Директивы шаблона содержатся в{{и}}Блокировать.

директива шаблона{{.Release.Name}}Введите имя выпуска в шаблон. Значение, переданное в шаблон, можно рассматривать как объект пространства имен, где точка (.) разделяет каждый элемент пространства имен.

Первая маленькая точка перед Release означает, что мы начинаем с верхнего пространства имен области действия (мы немного поговорим о области видимости). Таким образом, мы можем понять это.Release.Name:«Начните с пространства имен верхнего уровня, найдите объект Release, затем загляните внутрь дляNameОбъект".

Объект Release — это один из встроенных объектов Helm, который мы рассмотрим более подробно позже. Но пока этого достаточно, чтобы сказать, что это показывает имя выпуска, назначенное нам Тиллером.

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

[root@master mychart]# helm install ./mychart/
NAME:   famous-peahen
LAST DEPLOYED: Sun Jul 21 09:42:05 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME                    DATA  AGE
famous-peahen-confgmap  1     0s


[root@master mychart]# helm get manifest famous-peahen

---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: famous-peahen-confgmap
data:
  myvalue: "this is my chart configmap"

Мы рассмотрели базовые шаблоны: файлы YAML встраивают директивы шаблонов через файлы . В следующей части мы углубимся в шаблоны. Но прежде чем продолжить, вот небольшой прием, позволяющий ускорить создание шаблонов: если вы хотите протестировать отрисовку шаблона, но на самом деле ничего не установлено, используйтеhelm install --debug --dry-run ./mychart. Это отправит диаграмму на сервер Tiller, который отобразит шаблон. Но вместо того, чтобы установить диаграмму, он отобразит шаблон обратно, чтобы можно было увидеть вывод:

5.5 Встроенные объекты

внутренние переменные руля

Объекты передаются в шаблон из механизма шаблонов. Ваш код может передавать объекты (мы объяснимwithиrangeСм. Пример, когда утверждение является утверждением). Есть даже несколько способов создания новых объектов в шаблоне, так же, как мы будем смотреть позже.tupleфункционируют одинаково.

Объекты могут быть такими же простыми, как одно значение. Или они могут содержать другие объекты или функции. Например,ReleaseОбъект содержит несколько объектов (например,Release.NameFilesОбъекты имеют некоторые функции.

В предыдущем разделе мы использовали{{.Release.Name}}Вставьте название выпуска в шаблон.Releaseявляется одним из объектов верхнего уровня, к которым можно получить доступ в шаблонах.

  • Release: Этот объект описывает сам выпуск. В нем есть несколько объектов:
  • Release.Name: название выпуска
  • Release.Time: время выпуска
  • Release.Namespace: пространство имен для выпуска (если не указано в манифесте)
  • Release.Service:имя службы выпуска (всегдаTiller).
  • Release.Revision: номер версии этого выпуска. Он начинается с 1 и каждыйhelm upgradeДобавляйте по одному.
  • Release.IsUpgrade: если текущим действием является обновление или откат, установите для этого параметра значениеtrue.
  • Release.IsInstall: если текущим действием является установка, установите значениеtrue.
  • Values:отvalues.yamlФайлы и файлы, предоставленные пользователем, передаются в значении шаблона. По умолчанию Значения пусты.
  • Chart:Chart.yamlсодержимое файла. Здесь будут доступны любые данные из Chart.yaml. Например, {{.Chart.Name}}-{{.Chart.Version}} распечатает mychart-0.1.0. в руководстве по графикуCharts GuideДоступные поля перечислены
  • Files: Это обеспечивает доступ ко всем неспециальным файлам на диаграмме. Хотя его нельзя использовать для доступа к шаблонам, его можно использовать для доступа к другим файлам на диаграмме. См. раздел «Доступ к файлам».
  • Files.Getэто функция, которая получает файл по имени (.Files.Get config.ini)
  • Files.GetBytes— это функция, которая получает содержимое файла в виде массива байтов, а не строки. Это полезно для таких вещей, как изображения.
  • Capabilities: здесь представлена ​​информация о функциях, поддерживаемых кластером Kubernetes.
  • Capabilities.APIVersionsпредставляет собой набор информации о версии.
  • Capabilities.APIVersions.Has $versionУказывает, включена ли версия в кластере (batch/v1).
  • Capabilities.KubeVersionПредоставляет способ найти версию Kubernetes. Он имеет следующие значения: Major, Minor, GitVersion, GitCommit, GitTreeState, BuildDate, GoVersion, Compiler и Platform.
  • Capabilities.TillerVersionПредоставляет способ найти версию Tiller. Он имеет следующие значения: SemVer, GitCommit и GitTreeState.
  • Template: Содержит информацию о текущем шаблоне выполняется
  • Name: путь к файлу пространства имен текущего шаблона (например,mychart/templates/mytemplate.yaml)
  • BasePath: Путь к пространству имен текущего каталога шаблонов диаграмм (например, mychart/templates).

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

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

5.6 файл значений

В предыдущем разделе мы рассмотрели встроенные объекты, предоставляемые шаблонами Helm. Один из четырех встроенных объектов — Values. Этот объект обеспечивает доступ к значениям, переданным в диаграмму. Его содержание происходит из четырех источников:

  • ДИАГРАММАvalues.yamlдокумент
  • Если это поддиаграмма, из родительской диаграммыvalues.yamlдокумент
  • Файл значений передается с помощью флага -f программы helm install или helm upgrade (helm install -f myvals.yaml ./mychart)
  • пройти через--set(Напримерhelm install --set foo=bar ./mychart)

Приведенный выше список находится в определенном порядке: values.yaml родительской диаграммы может быть переопределен по умолчанию для этого уровня по умолчанию, который, в свою очередь, может быть переопределен предоставленным пользователем файлом значений, который, в свою очередь, может быть переопределен --set переопределяет параметры.

Файлы значений — это простые файлы YAML. мы редактируемmychart/values.yaml, а затем отредактируйте нашConfigMapшаблон.

Удаляем значения по умолчанию.yaml, задаем только один параметр:

# 编辑values.yaml
domain: anchnet.com

# 在模版中引用
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"
  domain: {{.Values.domain}}

Обратите внимание, что мы получаем значение домена в последней строке {{.values.domain}}.

[root@master mychart]# helm install --dry-run --debug ./mychart
'''
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: exciting-manta-confgmap
data:
  myvalue: "this is my chart configmap"
  domain: anchnet.com

  • Вручную используйте --set, чтобы указать

так какdomainпо умолчаниюvalues.yamlфайл установлен наanchnet.com, значение, отображаемое в шаблоне. Мы можем легко добавить--setДобавьте флаги для переопределения:

helm install --dry-run --debug --set domain=51idc.com ./mychart 
'''
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: foppish-mule-confgmap
data:
  myvalue: "this is my chart configmap"
  domain: 51idc.com

так как--setчем по умолчаниюvalues.yamlфайл имеет более высокий приоритет

  • удалить ключ по умолчанию

Если вам нужно удалить ключ из значения по умолчанию, вы можете переопределить значение этого ключа на null, и в этом случае Helm удалит ключ из слияния переопределенных значений.

helm install stable/drupal --set image=my-registry/drupal:0.1.0 --set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt] --set livenessProbe.httpGet=null

5.7 Шаблонные функции и пайпы

  • Функция шаблона

До сих пор мы видели, как помещать информацию в шаблон. Но эта информация помещается в шаблон без изменений. Иногда мы хотим преобразовать эти данные, чтобы они были более полезными для нас.

Начнем с лучшей практики: при вставке строк в шаблоны из объекта .Values ​​мы ссылаемся на эти строки. Мы можем сделать это, вызвав функцию в директиве шаблона цитаты:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"
  drink: {{quote .Values.favorite.drink}}
  food: {{quote .Values.favorite.food}}

Шаблонные функции следуют синтаксисуfunctionName arg1 arg2.... Во фрагменте кода вышеquote .Values.favorite.drinkВызовите функцию цитаты и передайте ей аргумент.

Helm имеет более 60 доступных функций. Некоторые из них работают на языке шаблонов Go.Go template languageопределяется само собой. Большинство других — это библиотеки шаблонов Sprig.Sprig template libraryчасть. Мы многое увидим, когда будем рассматривать пример.

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

  • трубопровод

Одной из мощных возможностей языка шаблонов является его концепция конвейеров. Опираясь на концепцию UNIX, канал — это инструмент для объединения в цепочку ряда шаблонных команд для компактного выражения ряда преобразований. Другими словами, конвейер — это эффективный способ последовательного выполнения нескольких задач. Давайте перепишем приведенный выше пример с трубами.

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"
  drink: {{.Values.favorite.drink | quote}}
  food: {{.Values.favorite.food | quote}}

В этом примере нет вызоваquote ARGUMENT, меняем порядок. Мы используем канал (|) для отправки «параметров» в функцию:.Values.favorite.drink | quote. Используя каналы, мы можем связать несколько функций вместе:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"
  drink: {{.Values.favorite.drink | quote}}
  food: {{.Values.favorite.food | upper | quote}}

Обратный порядок является обычной практикой в ​​​​шаблонах. ты увидишь.val | quoteСравниватьquote .valчаще. Практика тоже.

При оценке шаблон даст следующие результаты:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: trendsetting-p-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"

Обратите внимание, что наш оригиналpizzaтеперь был преобразован в"PIZZA".

При наличии таких параметров конвейера первая оценка (.Values.favorite.drink) будет отправлен в качестве последнего параметра функции. Мы можем изменить приведенный выше пример напитка, чтобы проиллюстрировать функцию с двумя аргументами.repeat COUNT STRING:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"
  drink: {{.Values.favorite.drink | repeat 5 | quote}}
  food: {{.Values.favorite.food | upper | quote}}

Функция повтора будет возвращать заданную строку и указанное количество раз, поэтому мы получим этот вывод:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: melting-porcup-configmap
data:
  myvalue: "Hello World"
  drink: "coffeecoffeecoffeecoffeecoffee"
  food: "PIZZA"
  • Используйте функцию по умолчанию

Часто используется функцияdefault:default DEFAULT_VALUE GIVEN_VALUE. Эта функция позволяет указать значение по умолчанию внутри шаблона, если значение опущено. Давайте используем это, чтобы изменить приведенный выше пример напитка:

drink: {{.Values.favorite.drink | default "tea" | quote}}

Если мы побежим как обычно, мы получим свой кофе:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: virtuous-mink-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"

Теперь удалим настройки любимых напитков из values.yaml:

favorite:
  #drink: coffee
  food: pizza

Повторить сейчасhelm install --dry-run --debug ./mychartсоздаст этот YAML:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: fair-worm-configmap
data:
  myvalue: "Hello World"
  drink: "tea"
  food: "PIZZA"

В реальной диаграмме все статические значения по умолчанию должны существовать в values.yaml и не должны повторяться с командой по умолчанию (иначе они будут избыточными). Однако команда по умолчанию подходит для вычисляемых значений, поскольку вычисляемые значения нельзя объявлять в values.yaml. Например:

drink: {{.Values.favorite.drink | default (printf "%s-tea" (include "fullname" .)) }}

В некоторых местах аifусловия могут быть лучше, чем этоdefaultБолее подходящий. Мы увидим их в следующем разделе.

Шаблонные функции и конвейеры — это мощные способы преобразования информации и вставки ее в YAML. Но иногда вам нужно добавить некоторую логику шаблона, которая немного сложнее, чем вставка строк. В следующем разделе мы рассмотрим управляющие структуры, предоставляемые языками шаблонов.

  • операторная функция

Для шаблонов операторы (eq, ne, lt, gt, and, or и т. д.) представляют собой реализованные функции. В каналах операторы могут быть заключены в круглые скобки ((и)) группировка.

Поместите оператор перед объявлением, а затем его аргументы, как в случае с функцией. Чтобы использовать несколько операторов вместе, разделите каждую функцию круглыми скобками.

{{/* include the body of this if statement when the variable .Values.fooString xists and is set to "foo" */}}
{{if and .Values.fooString (eq .Values.fooString "foo") }}
    {{...}}
{{end}}


{{/* do not include the body of this if statement because unset variables evaluate o false and .Values.setVariable was negated with the not function. */}}
{{if or .Values.anUnsetVariable (not .Values.aSetVariable) }}
   {{...}}
{{end}}

Теперь мы можем перейти от функций и конвейеров к управлению потоком, условиям, циклам и модификаторам области действия.

5.8 Управление технологическим процессом

5.8.1 Управление процессом

Управляющие структуры (называемые «действиями» на языке шаблонов) предоставляют авторам шаблонов возможность контролировать процесс создания шаблонов. Язык шаблонов Helm предоставляет следующие управляющие структуры:

  • if/elseИспользуется для создания условных блоков
  • withуказанный диапазон
  • range, который обеспечивает цикл стиля "для каждого"

Помимо прочего, он предоставляет некоторые операции для объявления и использования именованных разделов шаблона:

  • defineОбъявить новый именованный шаблон в шаблоне
  • templateИмпорт именованного шаблона
  • blockобъявляет специальную заполняемую область шаблона

В этом разделе мы поговорим оif,withиrange. Дополнительный контент описан в разделе «Именованные шаблоны» далее в этом руководстве.

5.8.2 if/else

Первая структура управления, которую мы рассмотрим, предназначена для условного включения блоков текста в шаблоны. Это блок if/else.

Базовая структура условия выглядит следующим образом:

{{if PIPELINE}}
  # Do something
{{else if OTHER PIPELINE}}
  # Do something else
{{else}}
  # Default case
{{end}}

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

Конвейер оценивается как false, если значение выглядит следующим образом.

  • логическое значение false
  • цифра ноль
  • пустая строка
  • Одинnil(пусто или ноль)
  • пустая коллекция(map,slice,tuple,dict,array)

В остальных случаях значение условия равноtrueЭтот конвейер выполняется.

Мы добавляем простое условие в ConfigMap. Если напиток настроен на кофе, мы добавим еще одну настройку:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"
  drink: {{.Values.favorite.drink | default "tea" | quote}}
  food: {{.Values.favorite.food | upper | quote}}
  {{if and .Values.favorite.drink (eq .Values.favorite.drink "coffee") }}mug: true{{ end }}

Уведомление.Values.favorite.drinkДолжен быть определен, иначе будет выдана ошибка при сравнении его с «кофе». Поскольку мы закомментировали в предыдущем примереdrink:coffee, поэтому вывод не должен содержатьmug:trueлоготип. но если мы добавим эту строку обратноvalues.yamlфайл, вывод должен выглядеть так:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: eyewitness-elk-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"
  mug: true

5.8.3 Контрольные пространства

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

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"
  drink: {{.Values.favorite.drink | default "tea" | quote}}
  food: {{.Values.favorite.food | upper | quote}}
  {{if eq .Values.favorite.drink "coffee"}}
    mug: true
  {{end}}

Изначально это выглядело нормально. Но если мы пропустим его через шаблонизатор, то получим неверный результат:

$ helm install --dry-run --debug ./mychart
SERVER: "localhost:44134"
CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart
Error: YAML parse error on mychart/templates/configmap.yaml: error converting YAML to JSON: yaml: line 9: did not find expected key

что случилось? Мы сгенерировали неправильный YAML из-за пробелов выше.

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: eyewitness-elk-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"
    mug: true

Кружка неверно отступает. Давайте просто отступим к линию, а затем запустите:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"
  drink: {{.Values.favorite.drink | default "tea" | quote}}
  food: {{.Values.favorite.food | upper | quote}}
  {{if eq .Values.favorite.drink "coffee"}}
  mug: true
  {{end}}

Когда мы отправляем эту информацию, мы получаем действительный YAML, но он все еще выглядит интересно:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: telling-chimp-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"

  mug: true

Обратите внимание, что мы получили несколько пустых строк в YAML. Зачем? Когда механизм шаблонов запустится, он удалит{{и}}, но оставшиеся пробелы оставьте как есть.

Отступы пробелов в YAML строгие, поэтому управление пробелами становится очень важным. К счастью, в шаблонах Helm есть несколько инструментов, которые могут нам помочь.

Во-первых, синтаксис объявлений шаблонов в фигурных скобках можно изменить с помощью специальных символов, чтобы механизм шаблонов заполнил пробелы.{{-(добавлены тире и пробел) означает, что ячейка должна быть смещена влево, а-}}Означает, что правильный пробел должен быть удален. Уведомление! Новые строки также являются пробелами!

удостовериться-и другие директивы с пробелами.-3означает «удалить левые пробелы и напечатать 3», а-3Означает "печать -3".

Используя этот синтаксис, мы можем изменить наш шаблон, чтобы избавиться от этих новых строк:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"
  drink: {{.Values.favorite.drink | default "tea" | quote}}
  food: {{.Values.favorite.food | upper | quote}}
  {{- if eq .Values.favorite.drink "coffee"}}
  mug: true
  {{- end}}

Чтобы было понятно, давайте подкорректируем сказанное выше, заменив пробелы на*, согласно этому правилу каждый пробел будет удален. один в конце строки*Указывает, что новые строки будут удалены

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"
  drink: {{.Values.favorite.drink | default "tea" | quote}}
  food: {{.Values.favorite.food | upper | quote}}*
**{{- if eq .Values.favorite.drink "coffee"}}
  mug: true*
**{{- end}}

Имея это в виду, мы можем запустить наш шаблон через Helm и посмотреть результаты:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: clunky-cat-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"
  mug: true

Будьте осторожны с модификатором chomping. Это может легко привести к сюрпризам:

  food: {{.Values.favorite.food | upper | quote}}
  {{- if eq .Values.favorite.drink "coffee" -}}
  mug: true
  {{- end -}}

Это даст еду: кружка "ПИЦЦА": правда, так как символы новой строки удалены с обеих сторон.

Подробнее об управлении пробелами в шаблонах см. в официальной документации по шаблонам Go.Official Go template documentation

Наконец, иногда проще указать системе шаблонов, как сделать отступ, чем пытаться уловить расстояние между директивами шаблона. Поэтому иногда можно обнаружить, что использованиеindentфункция({{indent 2 "mug:true"}}) было бы полезно.

5.8.4 Использование with для изменения области действия

Следующей структурой управления, на которую следует обратить внимание, являетсяwith. Он управляет областью видимости переменных. Передумать,.является ссылкой на текущую область. следовательно,.Valuesскажите шаблону, чтобы он смотрел в текущей областиValuesобъект.

Его синтаксис аналогичен простому оператору if:

{{with PIPELINE}}
  # restricted scope
{{end}}

Диапазон можно изменить. with позволяет текущую область (.) к конкретному объекту. Например, мы использовали.Values.favorites. Давайте перепишем нашу ConfigMap, чтобы изменить.диапазон, на который нужно указать.Values.favorites:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"
  {{- with .Values.favorite}}
  drink: {{.drink | default "tea" | quote}}
  food: {{.food | upper | quote}}
  {{- end}}

Обратите внимание, что теперь мы можем ссылаться.drinkи.foodЭто не должно быть квалифицировано. Это потому, чтоwithНастройки заявки.указать на.Values.favorite. существует{{end}}Задний.Сбросить его предыдущий диапазон.

Но будь осторожен! В ограниченной области другие объекты в это время не будут доступны из родительской области. Например, следующее вызовет ошибку:

  {{- with .Values.favorite}}
  drink: {{.drink | default "tea" | quote}}
  food: {{.food | upper | quote}}
  release: {{.Release.Name}}
  {{- end}}

это сгенерирует ошибку, потому что Release.Name не находится в.в пределах. Однако, если мы поменяем местами последние две строки, все будет работать так, как ожидалось, потому что диапазон сбрасывается после .

  {{- with .Values.favorite}}
  drink: {{.drink | default "tea" | quote}}
  food: {{.food | upper | quote}}
  {{- end}}
  release: {{.Release.Name}}

посмотриrange, мы смотрим на переменные шаблона, которые обеспечивают решение вышеупомянутой проблемы области видимости.

5.8.5 Циклыrangeдействие

Многие языки программирования поддерживают использованиеforцикл,foreachПетля или аналогичный функциональный механизм для петли. В языке шаблонов Helm способ перебора коллекции заключается в использованииrangeоператор.

Во-первых, давайте в нашемvalues.yamlДобавьте в файл список начинок для пиццы:

favorite:
  drink: coffee
  food: pizza
pizzaToppings:
  - mushrooms
  - cheese
  - peppers
  - onions

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

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"
  {{- with .Values.favorite}}
  drink: {{.drink | default "tea" | quote}}
  food: {{.food | upper | quote}}
  {{- end}}
  toppings: |-
    {{- range .Values.pizzaToppings}}
    - {{. | title | quote}}
    {{- end}}

Давайте посмотрим поближеtoppings:список. Функция диапазона будет перебирать список PizzaToppings. Но тут случилось кое-что интересное.withобъем наборов.,rangeТо же самое касается операторов. Каждый раз через цикл,.Оба установлены в верхней части текущей пиццы. Это первый раз.Установите грибы. Вторая итерация настроена наcheese,Так далее и тому подобное.

Мы можем отправить прямо в конвейер., поэтому, когда мы делаем{{. | title | quote}}, он отправит.в заголовок (функция регистра заглавий), а затем отправить наquote. Если мы запустим этот шаблон, вывод будет:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: edgy-dragonfly-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"
  toppings: |-
    - "Mushrooms"
    - "Cheese"
    - "Peppers"
    - "Onions"

Теперь, в этом примере, мы попали в кое-что хитрое. Долженtoppings: |-line объявляет многострочную строку. Таким образом, наш список начинок на самом деле не является списком YAML. Это большая струна. Зачем мы это делаем? Из-за данных в ConfigMapsdataСостоит из пар ключ/значение, где и ключ, и значение являются простыми строками. Чтобы понять эту ситуацию, посмотрите наДокументация Kubernetes ConfigMap.. Но для нас эта деталь не важна.

в YAML|-Маркер представляет собой многострочную строку. Это может быть полезным методом для внедрения больших блоков данных в манифесты, как показано здесь.

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

  sizes: |-
    {{- range tuple "small" "medium" "large"}}
    - {{.}}
    {{- end}}
  sizes: |-
    - small
    - medium
    - large

Помимо списка и кортежа,rangeТакже может использоваться для перебора коллекций с ключами и значениями (например,mapилиdict). Мы увидим, как это сделать, когда будем вводить переменные шаблона в следующем разделе.

5.9 Переменные

Теперь, когда мы познакомились с функциями, конвейерами, объектами и управляющими структурами, мы можем найти одно из наиболее фундаментальных применений во многих языках программирования: переменные. В шаблонах они используются реже. Мы увидим, как использовать их, чтобы упростить код и сделать его лучше.withиrange.

В предыдущем примере мы видели, что этот код не сработает:

  {{- with .Values.favorite}}
  drink: {{.drink | default "tea" | quote}}
  food: {{.food | upper | quote}}
  release: {{.Release.Name}}
  {{- end}}

Release.Nameне вwithв пределах блока. Один из способов решить проблему области — присвоить объект переменной, к которой можно получить доступ независимо от текущей области.

В шаблоне Helm переменная — это именованная ссылка на другой объект. следует этой форме$name. Переменным присваивается специальный оператор присваивания::=. Мы можем переопределить Release.Name выше с помощью переменной.

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"
  {{- $relname := .Release.Name -}}
  {{- with .Values.favorite}}
  drink: {{.drink | default "tea" | quote}}
  food: {{.food | upper | quote}}
  release: {{$relname}}
  {{- end}}

Обратите внимание, что прежде чем мы начнемwithПеред блоком присваиваем$relname :=.Выпуск.Имя. сейчас наwithвнутри блока,$relnameПеременная по-прежнему указывает на имя выпуска.

даст что-то вроде этого:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: viable-badger-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"
  release: viable-badger

переменная вrangeОсобенно полезно в циклах. Их можно использовать в объектах, подобных спискам, для захвата как индекса, так и значения:

toppings: |-
    {{- range $index, $topping := .Values.pizzaToppings}}
      {{$index}}: {{ $topping }}
    {{- end}}

Уведомление,rangeСначала переменная, потом оператор присваивания, потом список. Это присваивает целочисленные индексы (начиная с нуля) для$index, значение дается$topping. Запуск даст:

  toppings: |-
      0: mushrooms
      1: cheese
      2: peppers
      3: onions

Для структур данных с ключами и значениями мы можем использоватьrangeчтобы получить оба. Например, мы можем.Values.favoriteПетля так:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name}}-configmap
data:
  myvalue: "Hello World"
  {{- range $key, $val := .Values.favorite}}
  {{$key}}: {{ $val | quote }}
  {{- end}}

Теперь в первой итерации$keyдаdrink,$valдаcoffee,второй раз,$keyеда,$valБудет пицца. Запуск приведенного выше кода сгенерирует следующее:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: eager-rabbit-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "pizza"

Переменные обычно не являются "глобальными". Их область действия — это блок, в котором они находятся. Раньше мы присваивали значения на верхнем уровне шаблона$relname. Эта переменная будет работать в рамках всего шаблона. Но в нашем последнем примере$keyи$valтолько в{{range...}}{{end}}работает в рамках блока.

Однако всегда есть глобальная переменная.$переменная - эта переменная всегда указывает на корневой контекст. Это полезно, когда вы просматриваете область, где вам нужно знать название выпуска диаграммы.

Например:

{{- range .Values.tlsSecrets}}
apiVersion: v1
kind: Secret
metadata:
  name: {{.name}}
  labels:
    # Many helm templates would use `.` below, but that will not work,
    # however `$` will work here
    app.kubernetes.io/name: {{template "fullname" $}}
    # I cannot reference .Chart.Name, but I can do $.Chart.Name
    helm.sh/chart: "{{$.Chart.Name}}-{{ $.Chart.Version }}"
    app.kubernetes.io/instance: "{{$.Release.Name}}"
    app.kubernetes.io/managed-by: "{{$.Release.Service}}"
type: kubernetes.io/tls
data:
  tls.crt: {{.certificate}}
  tls.key: {{.key}}
---
{{- end}}

До сих пор мы рассматривали только один шаблон, объявленный в одном файле. Но одной из замечательных особенностей языка шаблонов Helm является его способность объявлять несколько шаблонов и использовать их вместе. Мы обсудим в следующем разделе.

5.10 Шаблоны имен

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

В разделе «Управление потоком» мы представили три действия для объявления шаблонов и управления ими:define,templateblock. В этом разделе мы введем эти три действия и введемincludeфункция, сtemplateАналогичная функция.

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

Обычное соглашение об именах заключается в добавлении имени диаграммы к каждому определенному шаблону:{{define "mychart.labels"}}. Добавляя префикс с конкретным именем диаграммы, мы можем избежать любых конфликтов, которые могут возникнуть из-за двух разных диаграмм одного и того же шаблона.

5.10.1 частичные и_документ

До сих пор мы использовали один файл, и один файл содержал один шаблон. Но язык шаблонов Helm позволяет создавать специальные встроенные шаблоны, доступные по имени.

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

  • большинство файловtemplates/Рассматривается как содержащий манифесты Kubernetes
  • NOTES.txtявляется исключением
  • Имена подчеркнуты (_) предполагается, что у них нет внутреннего манифеста. Эти файлы не отображают определения объектов Kubernetes, но доступны везде в других шаблонах диаграмм для вызова.

Эти файлы используются для хранения частичных и вспомогательных программ. На самом деле, когда мы впервые создали MyChart, мы увидели файл под названием_helpers.tpl. Этот файл является расположением по умолчанию для частичных шаблонов.

5.10.2 ИспользованиеdefineиtemplateОбъявление и использование шаблонов

Шесть реальных боевых

6.1 Создание диаграмм

  • Go2cloud-api-doc, сделанный с помощью slate, оформляется в чарты с помощью helm, что удобно для последующего развертывания.
helm create go2cloud-api-doc

[root@master go2cloud-api-doc]# tree 
.
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── NOTES.txt
│   ├── service.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

3 directories, 8 files


# 配置 deployment
[root@master go2cloud_api_doc_charts]# egrep "^$|^#" -v go2cloud-api-doc/templates/deployment.yaml  
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "go2cloud-api-doc.fullname" . }}
  labels:
{{ include "go2cloud-api-doc.labels" . | indent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ include "go2cloud-api-doc.name" . }}
      app.kubernetes.io/instance: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ include "go2cloud-api-doc.name" . }}
        app.kubernetes.io/instance: {{ .Release.Name }}
    spec:
      imagePullSecrets: 
        - name: {{ .Values.imagePullSecrets }}
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: {{ .Values.service.port }}
              protocol: TCP
          livenessProbe:
            {{- toYaml .Values.livenessProbe | nindent 12  }}
          readinessProbe:
            {{- toYaml .Values.readinessProbe | nindent 12  }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
      {{- with .Values.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
    {{- with .Values.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
    {{- end }}
    {{- with .Values.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
    {{- end }}


# 配置service
[root@master go2cloud_api_doc_charts]# egrep "^$|^#" -v go2cloud-api-doc/templates/service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: {{ include "go2cloud-api-doc.fullname" . }}
  labels:
{{ include "go2cloud-api-doc.labels" . | indent 4 }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: {{ .Values.service.port }}
      protocol: TCP
      name: http
      nodePort: {{ .Values.service.nodePort }}      
  selector:
    app.kubernetes.io/name: {{ include "go2cloud-api-doc.name" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}


# 配置values
[root@master go2cloud_api_doc_charts]# egrep "^$|^#|^[[:space:]]+#" -v go2cloud-api-doc/values.yaml
replicaCount: 1
image:
  repository: 10.234.2.218/go2cloud/go2cloud-api-doc
  tag: latest
  pullPolicy: Always
imagePullSecrets: registry-secret
nameOverride: ""
fullnameOverride: ""
service:
  type: NodePort
  port: 4567
  nodePort: 30567
ingress:
  enabled: false
  annotations: {}
  hosts:
    - host: chart-example.local
      paths: []
  tls: []
resources: 
  requests:
    cpu: 1000m
    memory: 1280Mi
  limits:
    cpu: 1000m
    memory: 1280Mi
livenessProbe:
  tcpSocket:
    port: 4567
  initialDelaySeconds: 10
  failureThreshold: 2 
  timeoutSeconds: 10
readinessProbe:
  httpGet:
    path: /#introduction
    port: http
  initialDelaySeconds: 5
  failureThreshold: 2 
  timeoutSeconds: 30
nodeSelector: {}
tolerations: []
affinity: {}

[root@master go2cloud_api_doc_charts]# egrep "^$|^#|^[[:space:]]+#" -v go2cloud-api-doc/Chart.yaml 
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: go2cloud-api-doc
version: 0.1.0


# 部署
[root@master go2cloud_api_doc_charts]# helm install -n go2cloud-api-doc -f go2cloud-api-doc/values.yaml go2cloud-api-doc/                  
NAME:   go2cloud-api-doc
LAST DEPLOYED: Wed Jul 31 14:34:21 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME              READY  UP-TO-DATE  AVAILABLE  AGE
go2cloud-api-doc  0/1    1           0          0s

==> v1/Pod(related)
NAME                               READY  STATUS             RESTARTS  AGE
go2cloud-api-doc-7cfb7bb795-clrz8  0/1    ContainerCreating  0         0s

==> v1/Service
NAME              TYPE      CLUSTER-IP     EXTERNAL-IP  PORT(S)         AGE
go2cloud-api-doc  NodePort  10.96.228.251  <none>       4567:30567/TCP  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 go2cloud-api-doc)
  export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
  echo http://$NODE_IP:$NODE_PORT

[root@master go2cloud_api_doc_charts]# helm ls go2cloud-api-doc
NAME                    REVISION        UPDATED                         STATUS          CHART                   APP VERSION     NAMESPACE
go2cloud-api-doc        1               Wed Jul 31 14:34:21 2019        DEPLOYED        go2cloud-api-doc-0.1.0  1.0             default  

[root@master go2cloud_api_doc_charts]# kubectl get deployment go2cloud-api-doc
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
go2cloud-api-doc   0/1     1            0           10m

[root@master go2cloud_api_doc_charts]# kubectl get pods |grep go2cloud-api-doc
go2cloud-api-doc-7cfb7bb795-clrz8                         0/1     CrashLoopBackOff   7          10m

[root@master go2cloud_api_doc_charts]# kubectl get svc go2cloud-api-doc
NAME               TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
go2cloud-api-doc   NodePort   10.96.228.251   <none>        4567:30567/TCP   10m



# 打包
[root@master go2cloud_api_doc_charts]# helm package ./go2cloud-api-doc/
Successfully packaged chart and saved it to: /data/go2cloud_api_doc_charts/go2cloud-api-doc-0.1.0.tgz
[root@master go2cloud_api_doc_charts]# tree 
.
├── go2cloud-api-doc
│   ├── charts
│   ├── Chart.yaml
│   ├── templates
│   │   ├── deployment.yaml
│   │   ├── _helpers.tpl
│   │   ├── NOTES.txt
│   │   ├── service.yaml
│   │   └── tests
│   │       └── test-connection.yaml
│   └── values.yaml
└── go2cloud-api-doc-0.1.0.tgz

4 directories, 8 files


# 升级副本数量
helm upgrade go2cloud-api-doc --set replicaCount=2 go2cloud-api-doc/

6.2 Настройка второстепенного

Сохраните подготовленные графики на minio и разверните minior на k8s

  • Создайте локальный каталог диаграмм
mkdir minio-chart
  • Упакуйте измененный файл диаграммы
helm package redis
  • Скопируйте пакет в созданную локальную директорию диаграммы
cp redis-8.0.5.tgz /root/minio-chart/
  • Обновите индекс индекса в каталоге /root/minio-chart/
helm repo index minio-chart/ --url http://10.234.2.204:31311/minio/common-helm-repo/

  • Загрузите index.yaml и пакет диаграмм в minio
mc cp index.yaml minio/common-helm-repo/
mc cp redis-8.0.5.tgz minio/common-helm-repo/
  • Загрузите созданные графики в minio
helm repo add monocular https://helm.github.io/monocular
helm install -n monocular monocular/monocular

mc cp go2cloud-api-doc-0.1.0.tgz minio/common-helm-repo

допустимый${HOME}/.mc/config.jsonПросмотр информации о ключе ak в формате .

  • проверять

6.3 Загрузка в общедоступный репозиторий helm

Подготовленный пакет чартов можно загрузить в хранилище helm, а можно разместить в собственном собственном личном хранилище Inflow: kubeapps/Monocular/minior и т. д., вы можете использовать команду helm, чтобы установить его одним щелчком мыши.

Загружайте в общедоступные облачные общедоступные репозитории, такие как Apphub, который в настоящее время создается Alibaba в Китае.В современной облачной экосистеме многие зрелые программы с открытым исходным кодом были преобразованы в диаграммы Helm, что делает их очень удобными для загрузки и использования пользователями, такими как Nginx , Apache, Elasticsearch, Redis и другие. Однако до выпуска открытого облачного центра приложений App Hub (Helm Charts China Station) отечественным пользователям было трудно напрямую загружать и использовать эти диаграммы. Теперь AppHub не только синхронизирует все приложения в официальном Helm Hub в режиме реального времени для внутренних пользователей, но и автоматически заменяет все недоступные зеркальные URL-адреса в этих чартах (такие как gcr.io, quay.io и т. д.), наконец, позволяя отечественным разработчикам для прохождения helm установить приложение «установка в один клик» становится возможным.

Для конкретной подачи ваших собственных диаграмм, пожалуйста, обратитесь к:GitHub.com/cloud родной…

Это грифельная диаграмма, которую я загрузил,Slate helps you create beautiful, intelligent, responsive API documentation.

developer.aliyun.com/Hubei/detail?…

Лайки приветствуются.

Семь связанных ссылок