Skip to content

Instantly share code, notes, and snippets.

@anutator
Last active January 3, 2023 18:47
Show Gist options
  • Save anutator/f5748a6b7ec28ec962c48cacfd16b787 to your computer and use it in GitHub Desktop.
Save anutator/f5748a6b7ec28ec962c48cacfd16b787 to your computer and use it in GitHub Desktop.
Kubernetes

Добавление репозитория helm

Можно добавить свой созданный репозиторий с чартами или репозиторий из Интернет, искать на https://artifacthub.io/ helm repo add bitnami https://charts.bitnami.com/bitnami — добавили репозиторий с локальными именем bitnami, далее указан адрес репозитория helm repo list — список локальныех репозиториев helm repo update — получить (обновить) информацию о доступных чартах из соответствующих репозиториев чартов. Информация кешируется локально, потом может использоваться командой поиска. helm search repo — список всех чартов во всех установленных репозиториях helm search repo -l — список всех чартов во всех установленныx репозиториях, отображать все версии каждого чарта helm search repo nginx — поиск во всех добавленных репозиториях чартов со словом nginx в названии или описании. Регистр букв не учитывается. CHART VERSION — версия самого чарта. APP VERSION — версия приложения (например nginx), которое разворачивает чарт. helm search repo -l nginx или helm search repo --versions nginx — то же, но покажет все возможные версии чартов в репозитории (не только последняя). helm search repo -l "nginx server" — то же, но ищем в по наличию словосочетания «nginx server» в описании чарта.

Пример:

$ helm search repo nginx
NAME                            	CHART VERSION	APP VERSION	DESCRIPTION                                       
bitnami/nginx                   	9.9.3        	1.21.6     	NGINX Open Source is a web server that can be a...
bitnami/nginx-ingress-controller	9.1.11       	1.1.2      	NGINX Ingress Controller is an Ingress controll...
bitnami/nginx-intel             	0.1.5        	0.4.7      	NGINX Open Source for Intel is a lightweight se...
bitnami/kong                    	5.0.2        	2.7.0      	Kong is a scalable, open source API layer (aka ...

helm pull bitnami/nginx — скачать чарт, сохранится в текущем каталоге в виде архива .tgz helm package amq — заархивировать чарт, который находится в текущем каталоге amq. Имя созданного архива будет содержать имя и версию чарта, например amq-0.1.2.tgz,т.к. имя не зависит от названия самого каталога. Все файлы, отмеченные в .helmignore, в чарт не включаются.

Установка и обновление релиза

helm install nginx01 bitnami/nginx — установили новый релиз, дали ему имя nginx01, использовали чарт bitnami/nginx, при установке были использованы переменные по умолчанию из самого чарта, свои переменные не добавляли. helm install bitnami/nginx --generate-name — имя релиза автоматически генерируется. Например в шаблоне чарта у нас имя релиза nginx. Тогда при установке релиза несколько раз будут добавляться уникальные суффиксы, например nginx-165948675 helm install nginx01 -n apps bitnami/nginx --create-namespace — установит релиз nginx01 не в текущем namespace, а в app. Дополнительный флаг можно использовать для автоматического создания namespace, если такого нет (на работе не используем автосоздание namespace). Проверка: kubectl get ns

Обновление релиза происходит при обновлении переменных из файла .yml, при обновлении переменных непосредственно из командной строки, при обновлении или изменении версии чарта: helm upgrade nginx01 --set service.type=NodePort --set service.port=8080 bitnami/nginx — обновили две переменные в релизе nginx01 (через точку указано, что переменные второго уровня, т.е. внутри service). Имя чарта bitnami/nginx. Например были переменные в values.yaml внутри чарта, которые использовались по умолчанию:

service:
  type: LoadBalancer
  port: 80

А мы их перезаписали непосредственно из командной строки.

helm upgrade nginx01 -f values.yaml bitnami/nginx — обновили переменные релиза nginx01 из файла values.yaml, который находится в текущем каталоге. Имя чарта bitami/nginx. helm upgrade -i nginx01 -f values.yaml bitnami/nginx — то же самое. Но обычно мы в Gitlab используем флаг -i (или --install), что позволяет установить релиз, если он ещё не был установлен. helm upgrade -i nginx01 -f values.yaml bitnami/nginx --wait --timeout 10s — обычно добавляем флаг ожидания. По умолчанию ждет 300 секунд (5 минут), пока все поды, PVCs (запрос дисков), сервисы и минимальное число подов для Deployment, StatefulSet или ReplicaSet не будут в статусе готовности, прежде чем сделать релиз успешным. Здесь перезаписали таймаут на 10 секунд, подбирать индивидуально. Флаг ожидания очень важен. Если него нет, состояние релиза будет failed только если API-сервер Kubernetes-а не сможет обработать ошибочные манифесты Helm-a, но даже если под не поднялся, будет deployed, что не даст верной картины. Флаг добавит проверку статус подов и пр., результат проверки повлияет на статус релиза. helm upgrade nginx01 --dry-run -f values.yaml bitnami/nginx — флаг --dry-run позволяет имитировать обновление релиза для тестов, т.е. мы увидим манифесы, которые будут получены в результате, но на самом деле ничего не будет обновлено. helm upgrade nginx01 --version 9.3.5 bitnami/nginx — обновляем релиз nginx01, но меняем саму версию чарта. Причем можем откатиться на более старую версию чарта. По умолчанию, если версия чарта не указана, используется самая свежая. Вместо указания конкретной версии можно указать диапазон, например ^2.0.0 — версия чарта выше 2.0.0. helm upgrade nginx01 --version 9.3.5 --reuse-values bitnami/nginx — сделали «дегрейд» версии чарта на 9.3.5, в ней могут быть свои значения переменных по умолчанию, а мы уже например меняли значения, перезаписывая их. Добавив --reuse-values мы гарантируем, что будут переиспользованы все значения переменных из самого последнего релиза, и они будут совмещены со значениями, которые мы добавляем в командной строке через --set и -f (т.е. значения, добавленные с командной строке, имеют приоритет). При указании параметра --reset-values, параметр --reuse-values буде проигнорирован.

Список релизов , история, откат версий

helm list — список релизов в текущем namespace helm list -n имя_namespace — список релизов в указанном namespace. helm list -A илиhelm list --all-namespaces — список релизов во всех namespace

helm history имя_релиза — история конкретного релиза. Возможные статусы:

  • pending-install — манифесты готовы, но ещё не были отправлены в Kubernetes. Видно при использовании флага --dry-run.
  • deployed — манифесты были отправлены в Kubernetes и были приняты. Ещё не значит, что приложение уже работает.
  • pending-upgrade — манифесты обновления готовы, но ещё не отправлены в Kubernetes.
  • superseded — релиз успешно обновлен.
  • pending-rollback — сгенерированы манифесты отката на одну из предыдущих версий, но ещё не отправлены в Kubernetes.
  • uninstalling — текущий (самый последний и свежий) релиз в процессе удаления.
  • uninstalled — если история сохранена, это статус последнего удаленного релиза.
  • failed — Kubernetes не принимает манифесты, отправленные ему Helm-ом во время любой операции. Смотри также флаг --wait, который более точно позволит проверить реальное состояние деплоя.

helm rollback имя_релиза номер — откат на одну из версий из helm history имя_релиза. Если версию не указывать, то откат на предыдущую.

Удаление релиза: helm uninstall имя_релиза — удаляет релиз из текущего namespace, в котором мы находимся. Имя чарта при удалении не нужно. helm uninstall имя_релиза -n имя_namespace — удаляет релиз из заданного namespace helm uninstall имя_релиза --keep-history — удаляет релиз, но сохраняет helm history. Позволит восстановить удаленный релиз через rollback.

Создание шаблона чарта

При создании шаблона чарта создается чарт nginx. При установке релиза из локального чарта, который находится в каталоге myapp, указывать только имя каталога (ранее указывали имя репозитория, слеш, имя чарта)

$ mkdir mycharts
$ cd mycharts/
~/mycharts$ helm create myapp
Creating myapp

# структура каталога чарта
~/mycharts$ tree myapp
myapp
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── NOTES.txt
│   ├── serviceaccount.yaml
│   ├── service.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

3 directories, 10 files

# установка чарта
$ helm install myapp01 myapp
# если мы находимся в каталоге чарта, вместо имени чарта указать точку
# проверим, какие манифесты создадутся, без реальной установки приложения
$ cd myapp
$ helm install myapp01 --dry-run .

# проверка, смотрим имя пода
$ kubectl get pods
$ kubectl get svc

# для доступа к чарту из браузера по адресы localhost:8080 настроить переадресацию порта
kubectl port-forward имя_пода 8080:80

Обновить значения helm чарта без доступа к исходникам

Из украинского Telegram канала.

Когда необходимо:

  • кто-то поставил кастомный чарт с локальной машины
  • репозиторий где был чарт — протух, а обновить значения надо.

Helm 3 хранит полный чарт в секретах с именами вида sh.helm.release.v1.<<name>>.v<<revision>>. Как это посмотреть:

kubectl get sec -A | grep sh.helm.release

Чтобы посмотреть что именно он хранит, для специально сделанного чарта solid-vulture ревизии 1:

kubectl get secrets sh.helm.release.v1.solid-vulture.v1 -o json | jq -r .data.release | base64 -d | base64 -d | gunzip -c | jq

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

Например:

kubectl get secrets sh.helm.release.v1.solid-vulture.v1 -o json | jq -r .data.release | base64 -d | base64 -d | gunzip -c | jq .chart.templates[0].data -r | base64 -d


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

Кроме этого, секреты можно патчить, чтобы, например, зафиксить залипший rollout или изменить манифесты для rollback когда это необходимо (такое бывает).

Дополнительные инструменты, плагины

https://github.com/turboazot/helm-cache — Helm-cache позволяет снизить зависимость от сторонних репозиториев. Кеширует ваши задеплоенные х helm чарты на диске или Chartmuseum.

indent vs nindent

В старых чартах helm можно часто увидеть функцию indent, позволяющую делать отступ каждой строки на определенное число пробелов. У нас шаблоны для сущностей Kubernetes описаны на языке Yaml, поэтому число пробелов важно. Обычно логически по 2 пробела используется для новых вложенных значений (и так далее). Польза в организиции многострочных списков и пр., здесь например будет отступ каждой строки на 4 пробела:

indent 4 $много_текста

Функция nindent появилась для лаконичности чартов — это то же самое, что и indent, но добавляется новая строка в начале.

nindent 4 $много_текста

Чтобы понять, приведу примеры. Здесь у строки volumeMounts 10 пробелов слева. Список маунтов будет взят из файла values.yaml из переменной volumeMounts, и когда этот список распарсится, впереди будет добавлено по 12 пробелов в каждой строке, список начнется со следующей строки после строки volumeMounts. 12 пробелов — значит список «внутри» volumeMounts.

          volumeMounts:  {{- toYaml .Values.volumeMounts | default "" | nindent 12 }}

Пример побольше. У metadata нет отступа, у name, labels, annotations по 2 отступа (пробела), у того, что включено внутри labels и annotations, отступы по 4 пробела слева:

metadata:
  name: {{ include "common.names.fullname" . }}-crt
  labels: {{- include "common.labels.standard" . | nindent 4 }}
    {{- if .Values.commonLabels }}
    {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }}
    {{- end }}
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}

indent. Вот здесь будут вставлены «одиночные» значения переменных. У первой переменной будет отступ 6 пробелов, у второй и третьей по 8. При этом тут новая строка не нужна — и так каждая переменная указана в шаблоне в двойных фигурных скобках (это всё формат языка Go) в новой строке, поэтому нам совсем не хочется добавлять дополнительные пустые строки.

      backup:
        path: "tmp/backups"   # Relative paths are relative to Rails.root (default: tmp/backups/)
{{ include "gitlab.appConfig.shell" . | indent 6 }}
{{ include "gitlab.appConfig.shell.ssh_port" . | indent 8 }}
{{ include "gitlab.appConfig.shell.secret_file" . | indent 8 }}

Мне было очень неудобно администрировать Kubernetes на работе через kubectl: вход организован через OIDC, который ссылается на внутренний сайт Keycloak с централизованной авторизацией. Что приходилось делать ранее: я подключалась по rdp (из программы Remmina) с своему Windows на работе (виртуальная машина). В этом Windows, чтобы заработал kubectl, надо запускать Docker Desktop и оттуда дополнительно функционал для Kubernetes — куча контейнеров. Чтобы нормально работать в командной строке, можно было использовать несколько вариантов:

  • mobaXterm (он может эмулировать терминал bash)
  • cmder
  • WSL — встроенный функционал Windows, позволяющий запускать виртуальные машины Linux. Ну я поставила виртуалку Ubuntu. Замену, что WSL не дает полноценных виртуальных машин как KVM в Linux
  • командная строка самого Windows

Итого, какие проблемы у меня были:

  • много всего запущено на windows только чтобы заработала команда kubectl
  • сложно было поставить плагины — скачивание из Интернет ограничено, пришлось для установки krew плагина и плагина oidc-login (чтобы авторизироваться в Kubernetes) все это заливать на комп через Telegram protable (фактически подпольно) либо ставить старые версии, файлы которых у нас были в обменнике.
  • экран Windows не умещался целиком на моем экране. Если же ставить подгонку по размеру, то текст был мелкий и плохо читаемый!
  • копировать архивы неудобно: в WSL доступ к каталогам компа через /mnt/c/....
  • не все инструменты Linux можно было поставить, т.к. WSL не дает полноценного Linux
  • трафик (а я пока пользуюсь только мобильным интернетом, потому что нет единого места, где бы я жила) — передаю весь рабочий стол через Интернет вместо команд
  • редактор vim глючил: чтобы сохранялись отступы при вставке кода, приходилось писать :set paste, а настройки .vimrc не помогали (((

Считаю, что я долго мучилась. И наконец сегодня решила проблему. У меня еще есть виртуальная машина с Linux на работе, я специально ее просила, но до сегодняшнего дня использовала её только как ProxyJump для доступа на серверы по ssh или для работы с Git (редактировала пайплайны для Gitlab в проектах программистов). Но то что OIDC требовал ввести свой рабочий логин и пароль в браузере, не позволяло нормально работать с kubectl используя только ssh соединение без графики.

Оказалось, проблема легко решается. В .kube/config надо добавить 2 параметра --grant-type=password --username=мой_логин. И всё. Теперь браузер не надо открывать, сразу в командной строке будет запрос на ввод пароля. Поэтому теперь я начала спокойно работать c helm и kubectl на своей виртуалке по ssh. И почему я не занялась этим вопросом раньше? Теперь на Windows я буду смотреть почту (может и ее локально настрою) и заходить на рабочие сайты (у нас по VPN мало чего доступно — Gitlab, Jira, Confluence и еще несколько). На рабочей виртуалке Linux у меня тоже есть графический интерфейс, но он, что интересно, медленнее Windows работает. Следующий шаг — присобачить VSCode плагин для редактирования в нем манифестов и helm чартов вместо vim, вроде можно через ssh открывать в нем файлы.

kind: Config
preferences: {}
users:
  - name: dev-oidc
    user:
        exec:
            apiVersion: client.authentication.k8s.io/v1beta1
            args:
              - oidc-login
              - get-token
              - --oidc-issuer-url=https://sso.имя_нашего_внутреннего_сайта.tech/auth/realms/имя_реалма
              - --oidc-client-id=kubernetes-dv
              - --oidc-client-secret=тут_секрет
              - --grant-type=password
              - --username=мой_логин
            command: kubectl
            env: null
            interactiveMode: IfAvailable
            provideClusterInfo: false

Не работал websocket.

1 - проверить строки Upgrade и Connection в проксирующем сервере nginx (не на ingress-nginx в Kubernetes):

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

Но появлялась все равно ошибка:

WebSocket connection to 'wss://имя_сайта.ru/hub?id=gog_f..........' failed: Error during WebSocket handshake: Unexpected response code: 200

2 - Надо добавить аннотацию в helm чарт в ingress - строка websocket-services, например:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    meta.helm.sh/release-name: crm-app-dv
    meta.helm.sh/release-namespace: crm
    nginx.org/websocket-services: crm-app-dv

Подробности:

That usually implies, that you are using the https://hub.helm.sh/charts/nginx/nginx-ingress Helm Chart for deploying NGINX Ingress into your cluster. Turns out, that this variant of NGINX causes trouble to some customers. The official Helm Chart, that should be used is https://kubernetes.github.io/ingress-nginx/deploy/#using-helm.

If you still want to use NGINX version, that the https://hub.helm.sh/charts/nginx/nginx-ingress Helm Chart deploys, you need to enable WebSocket support for your Service. To load balance Web Sockets, we have to add the following annotation to the Ingress resource:

nginx.org/websocket-services: "service1[,service2,...]"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment