Онлайн-практикум от команды Fevlake*
и Yandex.Cloud
*8 лет обслуживаем IT-инфраструктуры
Администрирование
Kubernetes в Yandex.Cloud
Онлайн-практикум — проходите,
когда вам удобно
Вакансий со знанием k8s
Крупных компаний в мире используют K8s
В топе по росту спроса
Администрирование Kubernetes в Yandex.Cloud
Мы подготовили программу для:
• Введение в Kubernetes и Yandex.Cloud
• Создаем и разбираем архитектуру кластера Kubernetes
• KaaS в Yandex.Cloud
• Базовые ресурсы в Kubernetes
• Настраиваем планировщик в Kubernetes
• Custom Resource Definitions
• Подключаем внешние ресурсы и системы хранения в Yandex.Cloud
• Изучаем и используем хранение секретов приложения в облаке
• Ingress и управление входящими соединениями
• RBAC - настройка безопасности
• Вертикальное и горизонтальное масштабирование, используя инструменты Yandex.Cloud
• Helm. Разбор компонентов Charts
• Мониторинг и логирование в Kubernetes
• CI/CD для Kubernetes в Yandex.Cloud
Легкий KUB-02: Развертывание Kubernetes-кластера
Описание:
Абсолютно логично, что первое задание, которое может быть в любом практикуме, — это установка используемого инструмента. Мы не станем нарушать традицию и начнем с рассмотрения того, как вы можете установить чистый кластер Kubernetes в своей инфраструктуре.
В целом, есть два основных варианта разворачивания кластера:
Ниже приведены критерии, которые следует учитывать при выборе одного из двух представленных вариантов:
По нашему опыту, можем сказать, что самый простой и надежный способ развертывания kubernetes — это использовать облака, поскольку они берут на себя ответственность за многие компоненты системы, о которых вам не придется думать в отличие от self-hosted решений. Основные из них:
Единственный приемлемый вариант, при котором есть смысл развернуть kubernetes локально на своих машинках, — это обучение. Ну и конечно, тестирование. Если вы хотите погонять Kubernetes локально, то доступно достаточно много вариантов:
Minikube
Minikube — это рекомендованный официальный метод для изучения работы Kubernetes. Он позволяет установить однонодовый кластер в виртуальной машине практически с любым поставщиком (virtualbox, kvm, hyperv, vmware), а также позволяет запустить и на хосте при помощи Docker. Данный вариант хорошо подходит для запуска кластера с целью ознакомления, для тестирования новых версий кластера и инструмента для него. Аналогом этого решения можно рассмотреть Minishift, который представляет собой инструмент для запуска кластера OpenShift в манере, подобной Minikube.
Однако это решение ограничено одним хостом, а значит, всю гибкость и возможности Kubernetes вы попросту не сможете увидеть. Более того, не со всеми инструментами получится познакомиться, в чем вы чуть позднее убедитесь.
Итак, давайте запустим minikube на ОС ubuntu. Запускать можно, как используя систему виртуализации, например kvm, так и в docker-контейнерах, но для этого потребуется установить docker-ce на сервер, используя данную инструкцию. После этого можем приступить к установке minikube:
Устанавливаем:
# Устанавливаем minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# Создаем пользователя, под которым будем создавать кластер
useradd -s /bin/bash -m -G docker kub
# Запускаем minikube
su - kub
minikube start
minikube v1.15.1 on Ubuntu 20.04
Automatically selected the docker driver
Starting control plane node minikube in cluster minikube
Pulling base image ...
Downloading Kubernetes v1.19.4 preload ...
> preloaded-images-k8s-v6-v1.19.4-docker-overlay2-amd64.tar.lz4: 256.00 MiB
... skipped ...
По окончании установки можете проверить, какие контейнеры у вас были запущены, используя docker ps.
Теперь совершим обзорную экскурсию по кластеру. Для доступа к кластеру из консоли потребуется утилита kubectl. Эта утилита доступна для всех современных ОС. Инсталляционные пакеты есть на официальном сайте. Но при использовании minikube он может установить ее за нас. Так что давайте выполним несколько команд и посмотрим на наш кластер:
$ minikube kubectl -- cluster-info
Kubernetes master is running at https://192.168.49.2:8443
KubeDNS is running at
https://192.168.49.2:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Также можем посмотреть на ноды, которые подключены к кластеру:
$ minikube kubectl -- get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready master 3m11s v1.19.4
Отлично, теперь на этом кластере можно будет поучиться, но пока перейдем к другим вариантам установки кластера.
Kubernetes с kops
kops — это еще один инструмент CLI, который обеспечивает развертывание кластера Kubernetes с помощью декларативной спецификации, предоставленной пользователем.
В настоящее время единственной поддерживаемой платформой развертывания является Amazon Web Services, но kops предлагает и другие преимущества, включая высокую доступность для ваших кластеров и дополнения для сетей и мониторинга, в том числе Flannel, Calico и Dashboard.
Пользователю не нужно изначально настраивать инфраструктуру, поскольку kops развернули необходимые ресурсы AWS, такие как инстансы EC2, хранилище EBS и сеть VPC.
Kubernetes с kargo
kargo также является CLI-инструментом, используемым для развертывания кластеров Kubernetes, но на нескольких платформах, таких как Amazon Web Services, Google Compute Engine, Microsoft Azure, OpenStack и серверы bare metal.
Он использует Ansible и требует от пользователей дополнительных настроек Ansible (inventory and variable files).
Kubernetes с kubeadm
Возможности CLI kubeadm позволяют настраивать кластеры Kubernetes в виртуальной или физической инфраструктуре
По нашему опыту, kubeadm предоставил более простой способ развертывания Kubernetes по сравнению с kops и cargo.
Kubernetes с kubespray
Kubespray — это набор доступных плейбуков, инвентори и дополнительных инструментов для общих задач управления конфигурацией кластера Kubernetes.
Kubespray обеспечивает:
Rancher
Rancher изначально не умел работать с Kubernetes, а работал с Docker-контейнерами напрямую, но, начиная с ветки версии 2.x, умеет взаимодействовать и разворачивать Kubernetes-кластер через Web UI, работает практически с любым облачным поставщиком, равно как и на железных серверах.
Все с нуля
Вы также можете развернуть свой кластер Kubernetes с нуля, не используя ни один из этих инструментов
Страница документации Kubernetes содержит инструкции о том, как это можно реализовать.
Если ваша цель состоит в том, чтобы получить глубокое понимание Kubernetes, настройка его без помощи вышеуказанных инструментов может быть полезна, и мы настоятельно рекомендуем использовать именно этот метод для развертывания своего первого кластера
Мы также рекомендуем ознакомиться с Kubernetes The Hard Way — учебником от Келси Хайтауэр.
Естественно, этот список не претендует на полноту, но именно эти решения являются наиболее распространенными и удобными для работы с кластерами от однонодовых до многонодовых инсталляций
CNCF Cloud Native Interactive Landscape
Installing Kubernetes with Minikube (official docs)
Getting started (official docs)
MicroK8s - Zero-ops Kubernetes for workstations and edge / IoT
1. После нажатия кнопки «Начать выполнение» для вас будет подготовлено окружение и предоставлены необходимые доступы.
2. Также вам будут выданы переменные, которые в задании указаны в фигурных скобках, — их надо будет подставить при выполнении задания.
3. После выполнения всех пунктов задания нажмите кнопку «Отправить на проверку», и в течение ближайших 3-5 минут скрипт проверит выполнение всех условий и выставит вам оценку.
4. В случае, если вы что-то забыли, можно исправить ошибки и отправить на проверку повторно.
5. Также, если вы успешно сдали задание, но у вас остались вопросы — вы всегда сможете задать их куратору после проверки или в чате в любое удобное для вас время.
1. Установите на подготовленную виртуальную машину minikube.
2. Создайте пользователя kubernetes, из-под которого будет создаваться кластер kubernetes.
3. Установите кластер kubernetes, который будет слушать порт 8443.
4. Найдите в выводе команды kubectl cluster-info адрес, на котором запущен kubernetes master, и сохраните его в файл /tmp/master.txt.
5. Отправьте задание на проверку.
Средний KUB-10: Yandex Managed Service for Kubernetes
Описание:
Общая концепция
Кластер Kubernetes управляется Yandex Managed Service for Kubernetes и состоит из мастера и групп узлов, которые подключаются к мастер-нодам. Яндекс.Облако полностью управляет мастер-нодами, а также следит за группами узлов. Мы можем управлять Kubernetes-кластером как через Web UI, так и через API и Terraform Provider.
Kubernetes-кластер резервирует две подсети — одну для IP-адресов подов, вторую — для IP-адресов сервисов. Эти сети можно посмотреть через yandex cli:
$ yc vpc subnet list
+----------------------+-----------------------------------------------------------+----------------------+----------------------+---------------+-----------------+ | ID | NAME | NETWORK ID | ROUTE TABLE ID | ZONE | RANGE | +----------------------+-----------------------------------------------------------+----------------------+----------------------+---------------+-----------------+ | b0c4lvs0bvoah9us8s3j | internal-c | enp1a6h7uj2r51r95fqm | | ru-central1-c | [10.2.0.0/16] | | b0c7k60lqi78g84kn8qr | default-ru-central1-c | enpnqajtd39am2v829n8 | | ru-central1-c | [10.130.0.0/24] | | e2l2u9vqt29ust5i90tb | default-ru-central1-b | enpnqajtd39am2v829n8 | | ru-central1-b | [10.129.0.0/24] | | e2lfk24tbrg6kbv9360g | internal-b | enp1a6h7uj2r51r95fqm | | ru-central1-b | [10.1.0.0/16] | | e9b0js158d1st3295g4h | k8s-cluster-catcn9mkdf475bj54h3f-pod-cidr-reservation | enp1a6h7uj2r51r95fqm | | ru-central1-a | [10.112.0.0/16] | | e9b2fve252b3n90a6322 | internal-a | enp1a6h7uj2r51r95fqm | | ru-central1-a | [10.0.0.0/16] | | e9bbb1pc4i52mvp450hi | k8s-cluster-catcn9mkdf475bj54h3f-service-cidr-reservation | enp1a6h7uj2r51r95fqm | | ru-central1-a | [10.96.0.0/16] | | e9bf9j1nlpi0vp320ove | default-ru-central1-a | enpnqajtd39am2v829n8 | enpr50okgu4mnormsl5a | ru-central1-a | [10.128.0.0/24] | +----------------------+-----------------------------------------------------------+----------------------+----------------------+---------------+-----------------+
$
Как вы можете увидеть — kubernetes зарезервировал две подсети с адресами 10.112.0.0/16 для подов и 10.96.0.0/16 для сервисов
Также Kubernetes может резервировать внешние IP-адреса для мастера и внешние адреса для групп узлов. Но это необязательно — вы можете запустить приватный кластер, у которого будут доступны только внутренние адреса. Но для полной работоспособности кластера необходимо настроить им доступ в интернет — для скачивания образов контейнеров или для обращения к внешним сервисам из подов. Это можно сделать различными способами:
А для доступа к кластеру вам потребуется, например, VPN-подлючение к внутренней VPC-сети. Этого можно достичь, создав виртуальную машину внутри облака и настроив на ней vpn.
Мастер Kubernetes может быть двух типов — зональный и региональный. Зональный, как следует из названия, будет размещен только в одной зоне доступности — ru-cetral-1a / 1b / 1c. А зональный — во всех, так что ему не страшны падения одной из зон.
Обновление
В облаке существуют три группы релизных каналов, в рамках которых вы можете обновлять мастер и группы узлов. К слову, вы можете создавать группы узлов с отличной от мастера версией, но только в пределах выбранного релизного канала. Итак, какие каналы существуют:
Обновлять кластер можно двумя способами:
Важно отметить! Если версия Kubernetes, которая установлена у вас на мастере, больше не поддерживается, она будет обновлена автоматически, даже если автообновление выключено. Поэтому следите за обновлениями и периодически обновляйтесь.
Также важно отметить, что во время обновления зональный мастер будет недоступен, в то время как региональный мастер будет доступен на протяжении всего времени обновления.
Группы узлов обновляются по следующему принципу — сначала создается новый узел с новой версией, дальше поды со старого узла расселяются согласно настройкам pod disruption budget (который изучим более подробно чуть позже), затем узел удаляется.
Автоматическое масштабирование
Kubernetes в облаке позволяет производить автоматическое масштабирование нод группы узлов. Для этого достаточно создать группу узлов нефиксированного размера, все остальное Yandex Managed Service for Kubernetes возьмет на себя. В случае, если у вас в кластере появится pod со статусом pending из-за недостаточных ресурсов — cluster-autoscaler это увидит и расширит группу узлов автоматически, чтобы под мог спокойно запуститься. Очень красиво эта функция выглядит при использовании HorizontalPodAutoscaler.
Права доступа
В будущих заданиях мы будем более детально изучать работу Role Based Access Control, но важно понимать, что пользователи, которых вы добавляете в Yandex.Cloud, также могут подключаться к кластеру Kubernetes и выполнять некоторые действия.
Чтобы выдать пользователю доступ к kubernetes, необходимо выставить ему роль:
Также вы можете пойти по более гибкому пути и создать пользователя, например, сервисный аккаунт с правами viewer, а дальше внутри kubernetes кластера назначить ему более расширенные права, используя его username.
Кстати, помните, когда мы создавали кластер, мы добавляли нодам сервисный аккаунт, который обладает правами pull & push в container registry? Это необходимо для того, чтобы ноды кластера напрямую ходили в Yandex Cloud Container Registry, используя аутентификацию сервисного аккаунта. Таким образом вам не придется создавать секреты для аутентификации в registry, как это описано в задании 19.
1. После нажатия кнопки «Начать выполнение» вы увидите текст задания, которое необходимо выполнить на вашем кластере Kubernetes.
2. Также вам будут выданы переменные (если они будут нужны), которые в задании указаны в фигурных скобках, — их надо будет подставить при выполнении задания.
3. После выполнения всех пунктов задания нажмите кнопку «Отправить на проверку», и в течение ближайших 3-5 минут скрипт проверит выполнение всех условий и выставит вам оценку.
4. В случае, если вы что-то забыли, можно исправить ошибки и отправить на проверку повторно.
5. Также, если вы успешно сдали задание, но у вас остались вопросы — вы всегда сможете задать их куратору после проверки или в чате в любое удобное для вас время.
Сложно KUB-30: Углубленная настройка Helm
Описание:
Helm также предоставляет hooks-механизм, позволяющий выполнять необходимые действия при установке/удалении/обновлении или откате чарта. Например, указанные hooks можно использовать для решения следующих задач:
Доступные Hooks:
В Helm существует механизм для подключения других чартов как зависимостей по аналогии с тем, как пакеты в дистрибутивах Linux могут требовать установки других пакетов.
Существует 2 метода определения зависимостей:
Разница в методах определения появилась с приходом Helm версии 3. То, где должны храниться зависимости,определяется тем, какая apiVersion выставлена в chart.yaml в Helm Chart. Первая версия актуальна со времен Helm 2 и хранила зависимости именно в requirements.yaml. Helm 3 поддерживает работу с apiVersion=1, поэтому логика работы должна быть одинакова с любой версией Helm.
Давайте рассмотрим, как выглядит определение зависимостей:
dependencies: - name: kube-state-metrics version: 2.4.* repository: https://kubernetes-charts.storage.googleapis.com/ alias: kubestatemetrics condition: kubeStateMetrics.enabled tags: - monitoring
Как видно, зависимостей может быть несколько, так как это массив. Теперь пройдемся по полям зависимости:
Важное замечание — если по condition или по tags чарт должен быть установлен, то он будет установлен, даже в случае разночтения значений (скажем, tag — false, но связанный condition — true).
При помощи Values в чарте можно устанавливать значения и для зависимых чартов.
Так, предположим, у нас есть чарт с именем sub1, у которого следующий values.yaml:
sub1_password: qwerty subblock: enabled: true
Для того чтобы установить значения для subchart в values.yaml нашего чарта, требуется описать его следующим образом:
db_password: ytrewq sub1: sub1_password: ytrewq subblock: enabled: false
Раз уж мы начали разбираться, зачем нужны зависимости, стоит рассказать, зачем в tempates/_helpers.tpl у нас есть шаблоны для CHART.name, CHART.fullname и так далее. Они нужны для того, чтобы в случае множественной установки одного и того же чарта с разными значениями у нас создавались не захардкорженные значения, а значения, связанные именно с релизом, а не чартом (скажем, имена Deployment). В противном же случае установка той же базы данных приводила бы к созданию манифестов с одинаковыми именами, из-за чего она и проваливалась бы.
Хорошо, зависимости мы описали, но как ими пользоваться? Есть явный и неявный путь.
После деплоя чарта helm собирает сгенерированные манифесты и сохраняет их в storage backend. По умолчанию, вся информация хранится в виде ConfigMap — для каждой версии релиза создается своя.
Далее при каждом апгрейде релиза helm сравнивает информацию сгенерированных манифестов с теми, что хранятся в storage backend (последней DELOYED версии релиза), и применяет разницу.
Указанную информацию можно получить при помощи следующей команды:
kubectl get cm
Историю релиза можно получить с помощью команды —
helm history chart_name
Helm rollback предоставляет возможность откатиться на конкретную версию релиза из истории.
Полное удаление релиза, включая всю метаинформацию о нем, из кластера возможно при помощи ключа --purge для команды helm delete.
Helm является очень вариативным инструментом с огромным множеством возможностей. В этом обзоре будет приведено лишь небольшое количество хитростей, которые можно использовать в работе с ним, да и список, приведенный в официальной документации, не полон. Однако, если вы хотите лучше понять этот инструмент и делать множество вещей наиболее элегантным, с технической точки зрения, образом, то эта информация послужит хорошим фундаментом.
hash templating
Очень часто передаваемые изменения в чарте при обновлении затрагивают такие элементы, как ConfigMap/Secrets. При этом сами Deployments, которые используют конфигурации из ConfigMap/Secret, остаются неизменными. Это может привести к тому, что при обновлении ресурсов поды продолжат работать на старых конфигах, так как они не были перезапущены.
Чтобы избежать этой проблемы, вы можете использовать sha256sum для определения изменения ресурсов и при их изменении обновлять связанные ресурсы. Подробнее можно почитать тут.
Golang magic
При использовании шаблонизатора Golang вы часто будете сталкиваться с необходимостью более глубокого взаимодействия с инструментом, чем простая подстановка данных из values. Например, можно использовать дополнительную логику с проверкой наличия значения:
value: {{ required "A valid .Values.who entry required!" .Values.who }}
Данный подход позволяет еще на этапе рендеринга конфигурационных файлов выявить проблему в чарте.
Indent-функция определяет количество пробелов от начала вставки, эта опция позволяет легко соблюдать структуру yaml-формата:
{{ include "toYaml" $value | indent 2 }}
Генерация таких элементов, как ImagePullSecret, может быть произведена несколькими путями. Вы можете просто взять и загнать base64 от конфига с авторизационными данными в соответствующий секрет, а можете сгенерировать то же самое, используя tml:
Values.yml: | imageCredentials: registry: quay.io username: someone password: sillyness tpl: | {{- define "imagePullSecret" }} {{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.imageCredentials.registry (printf "%s:%s" .Values.imageCredentials.username .Values.imageCredentials.password | b64enc) | b64enc }} {{- end }} secret.yaml: | data: .dockerconfigjson: {{ template "imagePullSecret" . }}
И множество иных хитростей...
Helm install/upgrade
В процессе организации CI/CD вам необходимо иметь универсальную команду, которая будет устанавливать чарт, если его нет, обновлять, если он уже существует, еще и делать это максимально надежно. Такой командой является
helm upgrade chart_name --install --force ./helm_chart/
Debug
В процессе составления чарта вам может потребоваться наличие дебаг-инструмента. Разумеется, есть Helm lint, но что же еще?
Командой Helm template можно отрендерить ваши конфигурационные файлы, имитируя установку. В выводе, соответственно, будут все сгенерированные манифесты. Для дебага yaml-формата можно использовать утилиту yq ., работая с выводом команды helm template.
1. После нажатия кнопки «Начать выполнение» вы увидите текст задания, которое необходимо выполнить на вашем кластере Kubernetes.
2. Также вам будут выданы переменные (если они будут нужны), которые в задании указаны в фигурных скобках, — их надо будет подставить при выполнении задания.
3. После выполнения всех пунктов задания нажмите кнопку «Отправить на проверку», и в течение ближайших 3-5 минут скрипт проверит выполнение всех условий и выставит вам оценку.
4. В случае, если вы что-то забыли, можно исправить ошибки и отправить на проверку повторно.
5. Также, если вы успешно сдали задание, но у вас остались вопросы — вы всегда сможете задать их куратору после проверки или в чате в любое удобное для вас время.
1. Измените количество реплик до 4 в чарте из предыдущего задания.
2. Задеплойте изменения с помощью helm в `local-chart` в namespace `helm`
3. Откатите релиз `local-chart` до первой ревизии с помощью `helm`
4. Отправьте задание на проверку.