# Кластеры Kubernetes — полный текст документации > Полный текст раздела «Кластеры Kubernetes» документации Timeweb Cloud в markdown. Каждая статья начинается с заголовка первого уровня и ссылки на свою каноническую страницу. Индекс: https://timeweb.cloud/docs/k8s/llms.txt Статей: 66 Последнее обновление: 2026-08-12 # Кластеры Kubernetes Source: https://timeweb.cloud/docs/k8s?utm_source=llms_txt&utm_medium=ai [Kubernetes](https://timeweb.cloud/services/k8s) — программное обеспечение с открытым исходным кодом, предназначенное для автоматизированного управления контейнерными приложениями. Kubernetes обеспечит автоматическое развертывание, масштабирование, распределение нагрузки, мониторинг сервисов, обработку ошибок и многое другое. Заказать сервис можно в панели [timeweb.cloud/my](https://timeweb.cloud/my/kubernetes/). ## Возможности Kubernetes Использование Kubernetes дает вам множество преимуществ, и среди основных можно отметить следующие: **Автоматическое развертывание** С помощью Kubernetes вы можете автоматизировать процесс создания новых контейнеров для развертывания, удаления существующих контейнеров и распределения всех их ресурсов в новый контейнер. С Kubernetes развернутые приложения всегда будут работать так, как было запланировано. **Мониторинг сервисов** Kubernetes автоматически обнаружит контейнеры, которые были повреждены и перестали отвечать на запросы, и перезапустит их. Если контейнер не проходит заданную проверку работоспособности, Kubernetes завершит его работу и запустит другой контейнер ему на замену. **Распределение сетевой нагрузки** Kubernetes распределит сетевой трафик таким образом, чтобы сбалансировать нагрузку для стабильного развертывания. При обнаружении контейнера с высоким трафиком Kubernetes перезапустит его для выравнивания нагрузки. **Легкость миграции** Kubernetes позволит запускать приложение в одинаковом окружении в любом месте. Вы сможете легко переносить приложения с локальных машин, где велась разработка, на серверы для последующего развертывания и не беспокоиться о проблемах с совместимостью. **Хранение конфиденциальной информации** Пароли, OAuth-токены и ключи SSH сохраняются конфиденциальными. Вы можете обновлять конфигурацию приложения, не изменяя образы контейнеров и не раскрывая конфиденциальную информацию в конфигурации стека. **Автоматизация обновлений** Как и прочие операции, процесс обновления может быть полностью автоматизирован. Обновления не влияют на текущую работоспособность системы, могут проводиться в удобное для разработки время и не требуют подключения команды инженеров.  **Производительность и отказоустойчивость** Благодаря гибкому управлению нагрузкой и широким возможностям масштабирования кластера, Kubernetes обеспечит высокий уровень производительности и отказоустойчивости системы. С Kubernetes вы сможете сэкономить время, снизить расходы и автоматизировать управление приложениями, максимально используя все возможности архитектуры контейнеризации. # Создание кластера Source: https://timeweb.cloud/docs/k8s/create-cluster?utm_source=llms_txt&utm_medium=ai Создать новый кластер можно в вашей панели управления. 1. Перейдите в раздел «[Kubernetes](https://timeweb.cloud/my/kubernetes)». 2. Кликните «Создать» или «Добавить». 3. Выберите регион создания кластера. 4. Укажите желаемые параметры кластера: **Версия Kubernetes**. В дальнейшем вы сможете [изменить](https://timeweb.cloud/docs/k8s/manage-cluster#smena-versii-kubernetes) версию в настройках кластера на одну из более новых. **Конфигурация мастер-ноды**. Доступны следующие варианты: - **Dev** — поддерживает до 10 воркер-нод. Используется одна мастер-нода с параметрами: 2 CPU, 2 ГБ RAM, 30 ГБ NVMe. - **Base** — поддерживает до 100 воркер-нод. Используется одна мастер-нода с параметрами: 4 CPU, 8 ГБ RAM, 60 ГБ NVMe. - **Custom** — позволяет задать количество мастер-нод: 1 или 3. Также доступна настройка конфигурации мастер-нод: - Минимально допустимая конфигурация: 4 CPU, 8 ГБ RAM, 60 ГБ NVMe - Максимально допустимая конфигурация: 32 CPU, 140 ГБ RAM, 1200 ГБ NVMe **Окно обслуживания кластера.** Вы можете задать [окно обслуживания кластера](https://timeweb.cloud/docs/k8s/manage-cluster#okno-obslujivaniya-klastera) — период, в который разрешается выполнение системных обновлений. Доступны три варианта: - - Никогда - В любое время - В заданное время Во время окна обслуживания могут обновляться сертификаты и устанавливаться обновления безопасности. Изменить окно обслуживания можно после создания кластера — в панели управления, во вкладке «Управление». ![2194c070 9dff 4e7f 821c 8b45d9dfccb1](https://content.timeweb.com/assets/1507d0dc-04d7-498a-90b4-80bdc7a44fe9.png?width=750&height=1199) 5. Настройте конфигурацию воркер-нод: создайте одну или несколько групп нод, выберите количество нод в каждой группе, тарифную линейку и конфигурацию для них. При использовании произвольной конфигурации существуют следующие ограничения: - Минимальная конфигурация: - **CPU**: 2 - **RAM**: 2 ГБ - **Диск**: 30 ГБ - Максимальная конфигурация: - **CPU**: 32 - **RAM**: 256 ГБ - **Диск**: 1200 ГБ ![B5ce5a4d 9aef 4a7f Ae35 46096a8d65e0](https://content.timeweb.com/assets/2916eea1-891b-480a-a5bb-3afa3ce34caa.png?width=761&height=755) На этом же этапе вы можете настроить: - - [Автомасштабирование](https://timeweb.cloud/docs/k8s/kubernetes-autoscaler) - [Автохилинг](https://timeweb.cloud/docs/k8s/manage-cluster#avtohiler) - Лейблы - Тейнты ![49a41a04 Cf2b 41bc A14f 86f8f228fce8](https://content.timeweb.com/assets/0048b3f2-7eef-493d-b557-6ba680d0cebd.png?width=703&height=423) 6. Выберите существующую приватную сеть или создайте новую. При необходимости настройте [плагин CNI](https://timeweb.cloud/docs/k8s/network/network-plugins) — он обеспечивает полную сетевую связность между узлами кластера и влияет на масштабируемость и гибкость настройки сетевых политик. ![Screenshot 05 27 25 18:44:18](https://content.timeweb.com/assets/2d95de96-2625-4678-bb61-cc231be41acd.png?width=419&height=460) 7. При необходимости настройте подключение [OIDC-провайдера](https://timeweb.cloud/docs/k8s/connect-oidc-provider-to-cluster). ![Scr 20250818 Njco](https://content.timeweb.com/assets/8c3e1ed4-682b-45e0-90f3-f7a6b64561c7.png?width=846&height=904) 8. Заполните информацию о кластере (имя, комментарий, проект) и нажмите «Заказать». Создание кластера займет пару минут, после чего вы сможете начать работу. # Управление кластером Source: https://timeweb.cloud/docs/k8s/manage-cluster?utm_source=llms_txt&utm_medium=ai Управление кластерами Kubernetes, созданными в панели Timeweb Cloud: - [Дашборд](https://timeweb.cloud/docs/k8s/manage-cluster/dashboard) - [Связанные сервисы](https://timeweb.cloud/docs/k8s/manage-cluster/external-services)  - [Мастер-ноды](https://timeweb.cloud/docs/k8s/manage-cluster/master-node) - [Воркер-ноды](https://timeweb.cloud/docs/k8s/manage-cluster/worker-node) - [Изменение версии Kubernetes](https://timeweb.cloud/docs/k8s/manage-cluster/version-update) - [Перезагрузка воркер-нод](https://timeweb.cloud/docs/k8s/manage-cluster/rebooting-worker-node) - [Окно обслуживания кластера](https://timeweb.cloud/docs/k8s/manage-cluster/change-maintenance-slot) - [Автохилер](https://timeweb.cloud/docs/k8s/manage-cluster/autohealer) - [История действий](https://timeweb.cloud/docs/k8s/manage-cluster/history) - [Удаление кластера](https://timeweb.cloud/docs/k8s/manage-cluster/deleting-cluster) - [Ранний доступ к фичам](https://timeweb.cloud/docs/k8s/manage-cluster/feature-gates) # Дашборд Source: https://timeweb.cloud/docs/k8s/manage-cluster/dashboard?utm_source=llms_txt&utm_medium=ai Во вкладке «Дашборд» отображаются графики загрузки процессора, использования оперативной памяти, вместимости подов, статусов подов и перезапусков контейнеров. Графики доступны как для мастер-, так и для воркер-нод. Чтобы скачать конфигурационный файл для подключения к кластеру, нажмите на ссылку «скачать файл конфигурации». ![Scr 20251022 Scjn](https://content.timeweb.com/assets/372e2d76-dcaa-4f95-b2dc-b1f1e241fdd7.png?width=1007&height=812) #### Описание графиков: **Загрузка ядер CPU** ![Image1](https://content.timeweb.com/assets/fb15f2e4-650c-435c-94c4-19da3c64a57f.png?width=489&height=269) - **Вместимость**: общее количество процессорных ядер на ноде. Измеряется в ядрах или миллиядрах. - **Выделено**: количество процессорных ядер, доступных для размещения приложений на узле. - **Лимит ресурса**: суммарное количество CPU, установленное как лимит для подов. Это показатель максимального использования CPU, установленный для всех подов на ноде. - **Запрос ресурса**: суммарное количество CPU, которое запрашивают все поды на ноде. **Оперативная память** ![Image3](https://content.timeweb.com/assets/a02e7c2a-686f-4803-ad63-b293e938b537.png?width=492&height=265) - **Вместимость**: общий объем оперативной памяти на ноде. - **Выделено**: объем оперативной памяти, доступный для размещения приложений. - **Лимит ресурса**: суммарное ограничение на использование памяти, установленное для всех подов на ноде. - **Запрос ресурса**: суммарный объем памяти, который запрашивают все поды.  **Вместимость подов** ![Image4](https://content.timeweb.com/assets/51f4e62b-28a8-4f7b-b0e8-ffe3e99f52de.png?width=492&height=255) - **Выделено**: количество подов, которое может быть еще размещено на ноде. - **Запрошено**: количество подов, уже размещенных на ноде. **Статусы подов** ![Screenshot 11 21 24 16:24:41](https://content.timeweb.com/assets/4a1b3fdd-b424-4abc-bd6f-31db0301ea8a.png?width=489&height=262) - **Работает**: под успешно развернут и выполняется. Все контейнеры внутри пода запущены и работают.  - **Ошибка**: произошла ошибка при выполнении одного или нескольких контейнеров в поде. Например, контейнер завершился с ненулевым кодом выхода или произошла проблема с доступом к ресурсам. - **Ожидание**: под еще не запущен, так как Kubernetes планирует его размещение на узле, но еще не удалось выделить ресурсы (например, место на узле, сеть или загрузку образа). Узнать причину можно, выполнив команду `kubectl describe node <имя_ноды>`. - **Неизвестно**: kubernetes не может определить текущий статус пода, возможно, из-за отсутствия связи с узлом, на котором под был запущен. Это может указывать на проблемы с соединением или сбоями в системе. - **Завершен успешно**: все контейнеры пода завершили свою работу успешно. Этот статус характерен для подов с задачами, которые предполагают одноразовое выполнение (например, Job). **Рестарт контейнеров** ![Scr 20251022 Sbvc](https://content.timeweb.com/assets/03ddbe12-bdbd-48c1-b310-d8651ff5f644.png?width=1022&height=570) Отображает число контейнеров, перезапущенных за выбранный промежуток времени. # Связанные сервисы Source: https://timeweb.cloud/docs/k8s/manage-cluster/external-services?utm_source=llms_txt&utm_medium=ai Раздел «Связанные сервисы» позволяет увидеть ресурсы, подключенные к кластеру Kubernetes. Здесь собраны все связанные сервисы, которые были созданы из кластера. ![Scr 20251119 Qbol](https://content.timeweb.com/assets/402ece76-aec4-4552-a09c-6a80b5a77de9.png?width=1041&height=742) Сейчас отображаются следующие типы сервисов: - [базы данных (DBaaS)](https://timeweb.cloud/docs/k8s/addons/dbaas-operator); - [балансировщики нагрузки (LBaaS)](https://timeweb.cloud/docs/k8s/network/kubernetes-load-balancer); - [сетевые диски](https://timeweb.cloud/docs/k8s/network-drives-connection); - [реестры контейнеров (Container Registry)](https://timeweb.cloud/docs/k8s/container-registry#ispolzovanie-reestra-v-klastere-kubernetes). При клике на любой из сервисов откроется его страница в панели управления. > [!NOTE] > Обратите внимание, что балансировщики, сетевые диски и DBaaS в разделе будут отображаться только если созданы после 30 сентября 2025 года. # Мастер-ноды Source: https://timeweb.cloud/docs/k8s/manage-cluster/master-node?utm_source=llms_txt&utm_medium=ai Вы можете изменить конфигурацию мастер-нод после создания кластера. Изменение возможно только в сторону увеличения ресурсов. Для этого перейдите во вкладку «Управление» в панели управления кластером и нажмите кнопку «Выбрать конфигурацию». ![48426e60 08d6 48e1 8a9f 463df7a138f3](https://content.timeweb.com/assets/78ab6d1f-a801-4c68-bf24-ed6fcb76175c.png?width=1536&height=1143) В открывшемся меню выберите подходящую конфигурацию мастер-ноды и нажмите кнопку «Изменить и перезагрузить мастер-ноду». ![9845dc29 Fe0c 462c 978a 41577e2e0c96](https://content.timeweb.com/assets/67b3d287-cef9-49c0-abf4-05b1a32a0477.png?width=1542&height=1071) # Воркер-ноды Source: https://timeweb.cloud/docs/k8s/manage-cluster/worker-node?utm_source=llms_txt&utm_medium=ai Во вкладке «Ресурсы» вы можете увидеть информацию о группах воркер-нод. В одной группе могут находиться только ноды с одинаковой конфигурацией. Конфигурация каждой ноды отображается в строке с соответствующей группой. Развернув группу воркер-нод, вы увидите информацию о локальных и внешних IP-адресах нод, а также о дате их создания. ![Scr 20260319 Ovzb](https://content.timeweb.com/assets/6398ecf7-72c7-48c0-8d2b-c2236ce83faf.png?width=2154&height=1610) Обращение к внешним ресурсам с воркеров выполняется через публичные IP-адреса, выделенные каждой ноде, или [через виртуальный роутер](https://timeweb.cloud/docs/k8s/virtual-routers-in-kubernetes), настроенный для кластера. Также во вкладке можно управлять нодами и группами воркер-нод. ## Управление группой воркер-нод Нажмите на три точки рядом с именем группы. В меню доступны действия: - «Добавить ноды» — позволяет указать количество новых нод, которые нужно добавить в группу. - «Редактировать группу» — открывает окно настройки группы. - «Удалить» — удаляет группу воркер-нод. При выборе пункта «Редактировать группу» откроется окно с настройками группы. ![Scr 20260319 Owrc](https://content.timeweb.com/assets/2c6a0c4c-6e4d-419a-966d-e3eda08aaf7f.png?width=2120&height=1616) В настройках можно: - изменить имя группы нод; - включить или отключить [автомасштабирование](https://timeweb.cloud/docs/k8s/kubernetes-autoscaling); - включить или отключить [автохилинг](https://timeweb.cloud/docs/k8s/manage-cluster/autohealer); - включить или отключить публичные IP-адреса для нод (подробнее в статье [про настройку виртуальных роутеров](https://timeweb.cloud/docs/k8s/virtual-routers-in-kubernetes)); - добавить лейбл в формате `ключ:значение`; - добавить тейнт в формате `ключ:значение:эффект`. Эффект тейнта определяет, как планировщик будет размещать поды на ноде: - `NoSchedule` — новые поды не будут размещаться на ноде, если у них нет соответствующей `toleration`; - `PreferNoSchedule` — планировщик по возможности избегает размещения подов на ноде; - `NoExecute` — поды без `toleration` не только не будут размещаться на ноде, но и будут удалены с неё. После внесения изменений нажмите кнопку «Сохранить». ## Управление отдельной нодой Разверните группу нод и нажмите на три точки рядом с нужной нодой. В меню доступны действия: - «Редактировать ноду»; - «Перезагрузить ноду»; - «Удалить ноду». При выборе пункта «Редактировать ноду» откроется окно настройки. ![Scr 20260319 Owwn](https://content.timeweb.com/assets/542a192a-aacd-4d3b-a4ad-05d74926dde5.png?width=2088&height=1608) В этом окне можно: - добавить лейбл в формате `ключ:значение`; - добавить тейнт в формате `ключ:значение:эффект`, где эффект может быть `NoSchedule`, `PreferNoSchedule` или `NoExecute`. После внесения изменений нажмите кнопку «Сохранить». # Логи кластера Source: https://timeweb.cloud/docs/k8s/manage-cluster/logs?utm_source=llms_txt&utm_medium=ai В разделе «Логи» можно посмотреть системные логи компонентов кластера. Это может быть полезно для диагностики работы кластера и проверки событий, связанных с его сервисами. Вы можете настроить: - **Период отображения логов** — выбрать временной интервал, за который будут показаны записи. - **Фильтр сервисов** — выбрать, логи каких компонентов кластера нужно отобразить. По умолчанию показываются записи всех сервисов, но при необходимости можно оставить только нужные: автоскейлер, хиллер, CCM или Kube API Server. ![Scr 20260521 Qkoo](https://content.timeweb.com/assets/3d7d7c2f-a0da-4ae6-9257-248e6064150d.png?width=2156&height=1664) Обратите внимание: в разделе действует ограничение — одновременно можно просмотреть не более 100 000 строк логов. # Изменение версии Kubernetes Source: https://timeweb.cloud/docs/k8s/manage-cluster/version-update?utm_source=llms_txt&utm_medium=ai В настройках кластера вы можете изменить версию Kubernetes на более новую. Перейти на более старую версию не получится. Для обновления версии: 1. В разделе «Kubernetes» кликните на нужный кластер. 2. На вкладке «Управление» нажмите «Обновить версию». ![Scr 20260119 Pyyh](https://content.timeweb.com/assets/8d942dd9-9ed8-4789-8b22-253d48c95267.png?width=2124&height=1520) 3. В списке доступных версий выберите нужную. 4. Укажите время обновления: - - Немедленно; - В заданное время. 5. Нажмите на кнопку «Обновить» или «Запланировать» — в зависимости от выбранного ранее варианта. ![Scr 20260119 Qaqz](https://content.timeweb.com/assets/0c494769-c153-4768-8ee2-8381d9901bfd.png?width=2140&height=1466) Для отмены запланированного обновления: 1. Откройте вкладку «Управление» и снова нажмите «Обновить версию». 2. Нажмите на крестик рядом с запланированным обновлением. ![Scr 20260119 Qbwf](https://content.timeweb.com/assets/c21b10cd-7aa1-48e6-bcc8-8254b66198ef.png?width=2100&height=1456) # Перезагрузка воркер-нод Source: https://timeweb.cloud/docs/k8s/manage-cluster/rebooting-worker-node?utm_source=llms_txt&utm_medium=ai Вы можете перезагрузить любую воркер-ноду из панели управления. Для этого: 1. На вкладке «Ресурсы» раскройте список нод в группе. 2. Кликните на три точки у нужной ноды и выберите «Перезагрузить ноду». ![Scr 20251022 Pyml](https://content.timeweb.com/assets/a60fb2a8-fb40-4909-aac7-730f49801fd6.png?width=790&height=477) # Окно обслуживания кластера Source: https://timeweb.cloud/docs/k8s/manage-cluster/change-maintenance-slot?utm_source=llms_txt&utm_medium=ai Окно обслуживания кластера — это период, в который разрешается выполнение системных обновлений. Доступны три варианта: - Никогда - В любое время - В заданное время Во время окна обслуживания могут обновляться сертификаты и устанавливаться обновления безопасности. Обновления могут затронуть как мастер-, так и воркер-ноды. На это время действия с кластером будут заблокированы. Возможны кратковременные перерывы в работе, например, при перезапуске нод. Вы можете задать окно обслуживания при создании кластера, а также управлять им в дальнейшем в настройках кластера. Чтобы изменить окно обслуживания: 1. В разделе «Kubernetes» кликните на нужный кластер. 2. На вкладке «Управление» нажмите «Изменить» в блоке «Окно обслуживания кластера». 3. Выберите нужный вариант и сохраните изменения. # Автохилер Source: https://timeweb.cloud/docs/k8s/manage-cluster/autohealer?utm_source=llms_txt&utm_medium=ai Система автоматически проверяет состояние воркер-нод каждые 10 минут. Если нода перестает отвечать, автохилер пытается восстановить ее работу: - выполняется попытка перезапуска ноды (до 2 минут на попытку); - если нода не восстановилась, попытка повторяется; - в течение 14 минут автохилер выполняет повторные попытки перезапуска; - если восстановить ноду не удалось, она будет пересоздана. Автохилинг можно включить или отключить [в настройках группы нод](https://timeweb.cloud/docs/k8s/manage-cluster/worker-node#upravlenie-gruppoj-vorker-nod). Чтобы отключить механизм для конкретной ноды в группе, для которой включен автохилинг, добавьте лейбл: ```bash kube-healer.kubernetes.io/healing-disabled: true ``` Механизм не применяется к нодам с GPU. Одновременно может обрабатываться не более 10 задач автохилинга. # История действий Source: https://timeweb.cloud/docs/k8s/manage-cluster/history?utm_source=llms_txt&utm_medium=ai В панели управления логируются действия с кластером — просмотреть их можно на вкладке «История». ![Scr 20251022 Sega](https://content.timeweb.com/assets/643e8645-3a0f-4c93-8ae4-06fbda0f7540.png?width=767&height=477) В логи записываются следующие события: - Создание кластера - Создание группы в кластере - Удаление группы из кластера - Добавление нод в группу - Удаление нод из группы # Prometheus Exporter Source: https://timeweb.cloud/docs/k8s/manage-cluster/prometheus-exporter?utm_source=llms_txt&utm_medium=ai Prometheus Exporter — это компонент, который собирает метрики кластера Kubernetes и предоставляет их в формате, совместимом с Prometheus. Экспортер позволяет отслеживать состояние кластера, нагрузку на ноды и состояние ресурсов. ## Подключение экспортера Данные для подключения экспортеров доступны в панели управления кластером, в разделе «Дашборд». ![Scr 20260413 Qiur](https://content.timeweb.com/assets/a59eda54-d61d-4cef-a71c-4f0ecd0ec26e.png?width=2166&height=1604) При использовании публичных экспортеров для доступа к метрикам необходима базовая авторизация. Пример запроса к публичному экспортеру: ```bash curl -u admin:'пароль' -s https://k8s-exporter.timeweb.cloud/id_экспортера/service/metrics ``` ## Эндпоинты и метрики Доступны два типа метрик: - `node_exporter` — метрики нод: загрузка CPU, использование памяти, операции с диском, сетевой трафик и другие системные показатели ОС; - `kube_state_exporter` — метрики Kubernetes: состояние подов, деплойментов, реплик, нод и других объектов, полученное из Kubernetes API. Публичные эндпоинты: - Метрики нод: ```shell https://k8s-exporter.timeweb.cloud/id_экспортера/node-exporter/metrics ``` - Метрики Kubernetes: ```shell https://k8s-exporter.timeweb.cloud/id_экспортера/service/metrics ``` `id_экспортера` — уникальный идентификатор экспортера из панели управления. ## Особенности реализации Экспортеры доступны в двух вариантах: - публичный — доступ по HTTPS с базовой авторизацией; - приватный — доступ внутри приватной сети. Порты: - `9100` — `node_exporter`. - `9308` — `kube_state_exporter`. Для кластеров с тремя мастер-нодами сбор метрик необходимо выполнять с каждой ноды отдельно. # Ранний доступ к фичам Source: https://timeweb.cloud/docs/k8s/manage-cluster/feature-gates?utm_source=llms_txt&utm_medium=ai Ранний доступ к фичам (feature gates) позволяет включать или отключать экспериментальные возможности Kubernetes. Функции могут находиться в разных статусах — альфа- и бета-версии. Они отличаются уровнем стабильности и готовности к использованию. Альфа-версии: - выключены по умолчанию; - могут работать нестабильно и содержать ошибки; - могут быть удалены без предупреждения; - API может измениться непредсказуемым образом в следующих версиях; - подходят только для тестирования. Бета-версии: - могут быть включены по умолчанию; - считаются достаточно стабильными и протестированными; - не будут полностью удалены, но могут изменяться; - возможны несовместимые изменения API; - при обновлении может потребоваться изменение или пересоздание ресурсов; - рекомендуется использовать только для кластеров с некритичными нагрузками. Корректная работа кластера гарантируется только при значениях по умолчанию. Некоторые функции раннего доступа включены по умолчанию. Список доступных функций зависит от версии Kubernetes. Полный список и статус для конкретной версии можно посмотреть [в официальной документации](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/#feature-gates-for-alpha-or-beta-features). ## Использование Чтобы настроить ранний доступ к фичам: 1. Перейдите в панель управления кластером. 2. Откройте раздел «Управление». 3. Нажмите «Настроить» напротив строки «Ранний доступ к фичам». ![Scr 20260414 Okso](https://content.timeweb.com/assets/f01941c1-be1e-48c7-a8a2-a9ec23e6058e.png?width=2108&height=1650) В открывшемся окне: - отображается список доступных функций; - указан их статус (альфа или бета); - можно включить или отключить нужные функции. ![Scr 20260414 Okxh](https://content.timeweb.com/assets/ce1af084-a9f0-4e3a-9190-22d606a88c40.png?width=2074&height=1596) После изменения настроек нажмите «Сохранить», чтобы применить изменения. Нажмите «Вернуть параметры по умолчанию», чтобы сбросить настройки. Сброс может понадобиться, чтобы исключить влияние экспериментальных функций на работу кластера. При обновлении Kubernetes значения раннего доступа к функциям автоматически сбрасываются к состоянию по умолчанию, так как в новой версии часть функций может быть изменена или недоступна. # Удаление кластера Source: https://timeweb.cloud/docs/k8s/manage-cluster/deleting-cluster?utm_source=llms_txt&utm_medium=ai Удалить кластер можно: - Со страницы конкретного кластера, кликнув на значок удаления: ![Scr 20251022 Seqs](https://content.timeweb.com/assets/06bf051a-05d0-47d0-9fe8-a47b03274d3c.png?width=1014&height=818) - Из списка кластеров, по клику на три точки у нужного кластера и опции «Удалить кластер»: ![Selection 039](https://content.timeweb.com/assets/3869d9df-74d9-4943-b5d0-3fb3a24967c0.png?width=1141&height=903) В следующем окне введите название удаляемого кластера или код подтверждения, в зависимости от [ваших настроек](https://timeweb.cloud/docs/account-management/notifications#uvedomleniya-pri-udalenii-servisov). # Подключение к кластеру Source: https://timeweb.cloud/docs/k8s/cluster-connection?utm_source=llms_txt&utm_medium=ai Для работы с кластерами Kubernetes вы можете использовать: **Консольные утилиты:** - [kubectl](https://timeweb.cloud/docs/k8s/cluster-connection/kubectl) **GUI-утилиты:** - [Lens](https://timeweb.cloud/docs/k8s/cluster-connection/lens) - [Freelens](https://timeweb.cloud/docs/k8s/cluster-connection/freelens) - [Headlamp](https://timeweb.cloud/docs/k8s/addons/headlamp) - [Kubernetes Dashboard](https://timeweb.cloud/docs/k8s/addons#kubernetes-dashboard) # kubectl Source: https://timeweb.cloud/docs/k8s/cluster-connection/kubectl?utm_source=llms_txt&utm_medium=ai [kubectl](https://kubernetes.io/ru/docs/reference/kubectl/overview/) — консольная утилита для работы с сущностями кластера Kubernetes. При помощи нее можно управлять ресурсами кластера, разворачивать приложения, просматривать логи и выполнять другие задачи администрирования. ## Установка kubectl > [!NOTE] > Обратите внимание, что минорная версия `kubectl` (вторая цифра в версии) может отличаться от версии кластера на +/- 1. При использовании более новых или более старых версий могут возникать проблемы с совместимостью. В инструкции указаны конкретные версии для примера, но вы можете заменить их на нужные вам версии. Linux ### Ручная установка 1. Загрузите бинарный файл `kubectl`: ``` curl -LO "https://storage.googleapis.com/kubernetes-release/release/v1.30.2/bin/linux/amd64/kubectl" ``` 2. Проверьте целостность загруженного файла:  ``` echo "$(curl -sL https://dl.k8s.io/release/v1.30.2/bin/linux/amd64/kubectl.sha256) kubectl" | sha256sum --check ``` 3. Установите `kubectl`:  ``` sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl ``` ### Установка через apt 1. Обновите список пакетов:  ```shell sudo apt update ``` 2. Установите необходимые пакеты:  ```shell sudo apt install -y apt-transport-https ca-certificates curl gnupg ``` 3. Добавьте ключ для репозитория Kubernetes и установите правильные права доступа на ключ:  ```shell curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg && sudo chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg ``` 4. Добавьте репозиторий Kubernetes в список источников APT и установите правильные права доступа на файл списка источников:  ```shell echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list && sudo chmod 644 /etc/apt/sources.list.d/kubernetes.list ``` 5. Обновите список пакетов снова:  ```shell sudo apt update ``` 6. Установите `kubectl`:  ```shell sudo apt install -y kubectl ``` macOS  ### Ручная установка **Для процессоров Intel** 1. Загрузите `kubectl` для процессоров Intel:  ```shell curl -LO "https://dl.k8s.io/release/v1.30.2/bin/darwin/amd64/kubectl" ``` 2. Проверьте целостность загруженного файла:  ```shell echo "$(curl -sL https://dl.k8s.io/release/v1.30.2/bin/darwin/amd64/kubectl.sha256) kubectl" | sha256sum --check ``` **Для процессоров Apple Silicon** 1. Загрузите `kubectl` для процессоров Apple Silicon:  ```shell curl -LO "https://dl.k8s.io/release/v1.30.2/bin/darwin/arm64/kubectl" ``` 2. Проверьте целостность загруженного файла:  ```shell echo "$(curl -sL https://dl.k8s.io/release/v1.30.2/bin/darwin/arm64/kubectl.sha256) kubectl" | sha256sum --check ``` 3. Сделайте файл исполняемым, установите права `644`, переместите его в директорию `/usr/local/bin` и установите владельца `root`:  ```shell chmod +x ./kubectl && chmod 644 ./kubectl && sudo mv ./kubectl /usr/local/bin/kubectl && sudo chown root: /usr/local/bin/kubectl ``` ### Установка через homebrew Установите `kubectl`:  ```shell brew install kubectl@1.30 ``` или Установите весь набор инструментов `Kubernetes CLI`:  ```shell brew install kubernetes-cli@1.30 ``` > [!NOTE] > Версии, доступные для установки через Homebrew, вы можете найти [на официальной странице утилиты](https://formulae.brew.sh/formula/kubernetes-cli#default). Windows ### Установка через Chocolatey Установите `kubectl`, выполнив:  ```shell choco install kubernetes-cli --version=1.30.2 ``` ### Ручная установка 1. В PowerShell выполните следующие команды: ```shell mkdir kubectl cd .\kubectl\ curl.exe -LO "https://dl.k8s.io/release/v1.30.2/bin/windows/amd64/kubectl.exe" ``` 2. Добавьте путь к директории `kubectl` в `PATH`, выполнив следующий скрипт в PowerShell: ```shell $destination="$env:USERPROFILE\kubectl" $currentPath = [System.Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::User) if ($currentPath -notlike "*$destination*") { [System.Environment]::SetEnvironmentVariable("Path", "$currentPath;$destination", [System.EnvironmentVariableTarget]::User) } ``` Или добавьте путь вручную: - - Нажмите правой кнопкой мыши на «Этот компьютер». - Выберите «Свойства». - Перейдите в «О программе». - Нажмите «Дополнительные параметры системы». - Перейдите на вкладку «Дополнительно». - Нажмите «Переменные среды». - В разделе «Системные переменные» найдите переменную `Path` и добавьте путь к директории `kubectl`. 3. Перезапустите PowerShell, чтобы изменения вступили в силу. > [!NOTE] > Docker Desktop for Windows добавляет свою версию `kubectl` в `PATH`. Если у вас установлен Docker Desktop, возможно, вам потребуется разместить запись `PATH` для `kubectl` перед той, которая добавлена установщиком Docker Desktop, или удалить версию `kubectl`, установленную Docker Desktop. Теперь `kubectl` установлен на вашем компьютере. Вы можете проверить установку, выполнив команду:  ```shell kubectl version ``` ## Настройка доступа к кластеру Kubernetes ### Получение конфигурационного файла kubeconfig Файл `config.yaml` используется `kubectl` для определения, к какому кластеру подключаться и какие учетные данные использовать. Он содержит информацию о кластерах, пользователях и контекстах, что позволяет легко переключаться между различными конфигурациями Kubernetes.  Поскольку файл `config.yaml` содержит важные учетные данные, его следует хранить в недоступном для посторонних лиц месте, чтобы предотвратить несанкционированный доступ к кластеру. При получении доступа к этому файлу посторонний человек может управлять кластером и его ресурсами. Чтобы получить конфигурационный файл, перейдите на страницу управления кластером и во вкладке «Дашборд» нажмите ссылку «скачайте файл конфигурации». ![Scr 20251022 Sfnh](https://content.timeweb.com/assets/f8187c7a-675f-4678-af48-2d80b2a22b52.png?width=1003&height=816) ### Размещение kubeconfig в домашнем каталоге После получения файла `config.yaml` необходимо разместить его в правильном каталоге, чтобы `kubectl` мог его использовать. macOS и Linux 1. Создайте директорию `.kube` в вашем домашнем каталоге, если она еще не существует: ```shell mkdir -p ~/.kube ``` 2. Скопируйте файл `config.yaml` в эту директорию и переименуйте его в `config`: ```shell cp ~/Downloads/config.yaml ~/.kube/config ``` После выполнения этих шагов `kubectl` будет автоматически использовать конфигурацию из файла `~/.kube/config`. Windows 1. Откройте PowerShell. 2. Создайте директорию `.kube` в вашем домашнем каталоге, если она еще не существует: ```shell mkdir $env:USERPROFILE\.kube ``` 2. Скопируйте файл `config.yaml` в эту директорию и переименуйте его в `config`: ```shell copy <путь_к_config.yaml> $env:USERPROFILE\.kube\config ``` 3. Запустите PowerShell от имени администратора и выполните: ```shell [Environment]::SetEnvironmentVariable("KUBECONFIG", $HOME + "\.kube\config", [EnvironmentVariableTarget]::Machine) ``` После выполнения этих шагов `kubectl` будет автоматически использовать конфигурацию из файла `$env:USERPROFILE\.kube\config`. ### Использование переменной окружения KUBECONFIG Если вам нужно использовать несколько файлов конфигурации или расположить `config.yaml` в другом месте, вы можете воспользоваться переменной окружения `KUBECONFIG`. macOS и Linux 1. Откройте терминал. 2. Установите переменную окружения `KUBECONFIG`: ```shell export KUBECONFIG= ``` Чтобы эти настройки сохранялись после перезагрузки системы, выполните следующий код (по необходимости изменив `~/.bashrc` на `~/.zshrc` (для MacOS) или `~/.profile`): ```shell echo "export KUBECONFIG=" >> ~/.bashrc ``` Windows 1. Откройте PowerShell. 2. Установите переменную окружения `KUBECONFIG`: ```shell $env:KUBECONFIG = "" ``` ### Использование нескольких конфигурационных файлов Вы можете указать несколько файлов `kubeconfig`, разделяя их пути двоеточиями (на macOS и Linux) или точкой с запятой (на Windows): Windows (PowerShell): ```shell $env:KUBECONFIG=";" ``` macOS и Linux: ```shell export KUBECONFIG=: ``` ## Настройка подключения к кластеру Kubernetes После настройки доступа вам нужно убедиться, что `kubectl` может подключиться к кластеру. Для этого выполните следующую команду: ```shell kubectl cluster-info ``` Эта команда выведет информацию о вашем кластере, включая адреса API и других компонентов. Если команда выполнена успешно, значит, `kubectl` подключен к кластеру. ### Проверка контекста Контексты позволяют переключаться между разными кластерами и учетными данными. Каждый контекст представляет собой комбинацию кластеров, пользователей и пространств имен (`namespaces`). Чтобы увидеть список доступных контекстов и узнать, какой из них активен в данный момент, используйте команду: ```shell kubectl config get-contexts ``` Эта команда выведет таблицу с доступными контекстами и укажет, какой из них активен в данный момент.  ![Image3](https://content.timeweb.com/assets/a5f28b6b-5ee3-45da-b783-d92b4c756135.png?width=810&height=117) Если у вас настроено несколько кластеров и вы хотите переключиться на другой контекст, используйте следующую команду: ```shell kubectl config use-context ``` Замените `` на имя нужного контекста, которое вы получили из предыдущей команды. После выполнения этой команды `kubectl` будет использовать новый контекст для всех последующих команд. ## Настройка автодополнения команд Автодополнение команд помогает ускорить ввод команд и уменьшить количество ошибок, автоматически предлагая возможные варианты по мере набора команды. Это особенно полезно для длинных и сложных команд `kubectl`. #### Установка bash-completion Установите пакет `bash-completion`, если он еще не установлен. Для Ubuntu/Debian: ```shell sudo apt install bash-completion ``` Для CentOS/RHEL: ```shell sudo yum install bash-completion ``` Для macOS через Homebrew: ```shell brew install bash-completion ``` bash (Linux) Включите автодополнение для текущего сеанса: ```shell source <(kubectl completion bash) ``` Чтобы автодополнение было всегда включено, выполните команду: ```shell echo "source <(kubectl completion bash)" >> ~/.bashrc ``` zsh (macOS и Linux) Включите автодополнение для текущего сеанса: ```shell source <(kubectl completion zsh) ``` Чтобы автодополнение было всегда включено, выполните команду: ```shell echo "source <(kubectl completion zsh)" >> ~/.zshrc ``` ## Основные команды kubectl ### Получение информации о кластере Чтобы получить общую информацию о вашем кластере, включая адреса компонентов, используйте команду: ```shell kubectl cluster-info ``` ### Просмотр подов Для получения списка всех подов в текущем пространстве имен используйте команду: ```shell kubectl get pods ``` Если вы хотите увидеть поды в конкретном пространстве имен, добавьте опцию `-n`: ```shell kubectl get pods -n ``` ### Просмотр служб Чтобы увидеть все службы (`services`) в текущем пространстве имен, выполните команду: ```shell kubectl get services ``` Вы также можете указать пространство имен: ```shell kubectl get services -n ``` ### Просмотр конфигурации Чтобы увидеть текущую конфигурацию и активный контекст: ```shell kubectl config view ``` ### Описание ресурсов Для получения детальной информации о любом ресурсе, таком как под или служба: ```shell kubectl describe ``` Например, чтобы получить информацию о поде: ```shell kubectl describe pod ``` ### Удаление ресурсов Для удаления ресурса, такого как под или служба: ```shell kubectl delete ``` Например, чтобы удалить под: ```shell kubectl delete pod ``` # Lens Source: https://timeweb.cloud/docs/k8s/cluster-connection/lens?utm_source=llms_txt&utm_medium=ai В статье мы рассмотрим, как подключить кластер Kubernetes к Lens — рабочему столу для управления кластерами. ## Установка Lens 1. Скачайте инсталлятор для вашей операционной системы с [официального сайта](https://lenshq.io/) и выполните установку на ваше локальное устройство, с которого вы планируете подключаться к созданному кластеру. 2. Запустите установленное приложение. 3. Выберите **New to Lens**, (если у вас еще нет учетной записи Lens ID) ![Lens R Ao Hl Pj Lp2](https://content.timeweb.com/assets/7902d5a1-7373-4067-9471-03dbd1403448.png?width=685&height=744) _Форма регистрации в интерфейсе [Lens](https://lenshq.io/)_ 4. Вас переадресует на форму создания Lens ID. Введите свои данные и нажмите **Continue**. ![Screenshot 06 10 25 15:59:44](https://content.timeweb.com/assets/a904f2df-127c-4d14-a03b-7f9521eb0fe5.png?width=503&height=933) _Форма регистрации в интерфейсе [Lens](https://lenshq.io/)_ 5. Подтвердите указанный емейл, перейдя по ссылке в отправленном вам письме. 6. Откроется форма подтверждения. Введите логин и пароль от Lens ID и нажмите **Login**. После успешной авторизации откроется рабочее меню приложения Lens. ## Подключение к кластеру Lens использует стандартный kubeconfig для подключения к кластеру. Вы можете хранить конфигурационные файлы как в системной директории ~/.kube, так и в любом удобном месте. Скачайте файл конфигурации из панели управления в разделе «Дашборд» созданного кластера. ![Selection 333](https://content.timeweb.com/assets/b291488e-55a7-4504-8916-4a1d20b21474.png?width=1015&height=883) ### Использование стандартной папки Если вы разместите скачанный kubeconfig в директории `~/.kube`, Lens автоматически определит кластер. Разверните раздел «Local Kubeconfig» — кластер будет отображен в списке.  ![Screenshot 06 10 25 17:02:29](https://content.timeweb.com/assets/7787b961-d1c4-493f-acdc-19355e0c19ab.png?width=1436&height=894) _Интерфейс [Lens](https://lenshq.io/)_ ### Пользовательская папка с конфигурацией Если вы хотите использовать отдельную директорию: Создайте папку, например `~/k8s_config` и переместите в него ранее скачанный kubeconfig. В списке кластеров Lens наведите курсор на «Local Kubeconfig», нажмите «+», и выберите пункт «Add kubeconfig from filesystem». ![Selection 335](https://content.timeweb.com/assets/22447d38-c9a4-4a50-87b4-4fcc9e6f6fe8.png?width=1435&height=890) _Настройка кастомной директории в интерфейсе [Lens](https://lenshq.io/)_ Укажите путь к kubeconfig. После добавления нажмите на имя кластера в списке для подключения. ![Screenshot 06 10 25 17:05:20](https://content.timeweb.com/assets/bc6a8009-2ee6-43b9-980a-105cd5e9daa4.png?width=1434&height=893) _Отображение кластера в интерфейсе [Lens](https://lenshq.io/)_ О возможностях управления кластером через IDE Lens можно ознакомиться в [официальной документации](https://docs.k8slens.dev). # Freelens Source: https://timeweb.cloud/docs/k8s/cluster-connection/freelens?utm_source=llms_txt&utm_medium=ai Freelens — это форк популярного инструмента для управления Kubernetes-кластерами [Lens](https://timeweb.cloud/docs/k8s/cluster-connection/lens). В отличие от оригинального Lens, Freelens полностью открытый и не требует регистрации или подключения к облачным сервисам, не содержит проприетарных компонентов.  ## Установка Homebrew Для установки Freelens на macOS используйте Homebrew: ```shell brew install --cask freelens ``` Snap На Linux установка доступна через Snap: ```shell snap install freelens --classic ``` Winget В Windows воспользуйтесь winget: ```shell winget install Freelensapp.Freelens ``` Установка вручную Вы можете загрузить бинарные файлы с [официальной страницы релизов](https://github.com/freelensapp/freelens/releases) на GitHub. ## Подключение к кластеру Freelens использует стандартный kubeconfig для подключения к кластеру. Вы можете хранить конфигурационные файлы как в системной директории `~/.kube`, так и в любом удобном месте. Скачайте файл конфигурации из панели управления в разделе «Дашборд» созданного кластера. ![Selection 333](https://content.timeweb.com/assets/1c323875-1084-441c-91d0-81b65b34c500.png?width=1015&height=883) ### Использование стандартной папки Если вы разместите скачанный kubeconfig в директории `~/.kube`, Freelens автоматически определит кластер. Перейдите в раздел «Catalog» → «Clusters» — кластер будет отображен в списке. Вы также можете перейти к нему с помощью кнопки «Browse Clusters in Catalog» на стартовом экране. ### Пользовательская папка с конфигурацией Если вы хотите использовать отдельную директорию: 1. Создайте папку, например `~/k8s_config` и переместите в него ранее скачанный kubeconfig. 2. В Freelens откройте раздел Clusters, нажмите «+» в правом нижнем углу. ![Selection 332](https://content.timeweb.com/assets/27da55ed-d1c2-450f-9af6-7a059432b31b.png?width=1430&height=892) _Раздел «Clusters» в интерфейсе [Freelens](https://freelensapp.github.io/)_ 3. Укажите путь к файлу или к папке, содержащей один или несколько конфигов. 4. После добавления нажмите на имя кластера в списке для подключения. # Автомасштабирование Source: https://timeweb.cloud/docs/k8s/kubernetes-autoscaling?utm_source=llms_txt&utm_medium=ai - [Автомасштабирование Kubernetes](https://timeweb.cloud/docs/k8s/kubernetes-autoscaling/kubernetes-autoscaler) - [Автомасштабирование до нуля нод](https://timeweb.cloud/docs/k8s/kubernetes-autoscaling/autoscaling-to-zero-nodes) # Автомасштабирование Kubernetes Source: https://timeweb.cloud/docs/k8s/kubernetes-autoscaling/kubernetes-autoscaler?utm_source=llms_txt&utm_medium=ai Автомасштабирование в Kubernetes позволяет гибко управлять ресурсами кластера, автоматически добавляя или удаляя ноды и поды в зависимости от нагрузки. > [!NOTE] > Опция доступна только для кластеров, созданных после **8 ноября 2024 года**. Для кластеров, созданных ранее, данная возможность недоступна, даже при настройке через панель управления. ## Включение автомасштабирования при создании кластера Для включения автомасштабирования на этапе создания кластера, необходимо выбрать опцию «Автомасштабирование» в разделе «Конфигурация воркер-нод». ![Scr 20250820 Kkhn](https://content.timeweb.com/assets/2b0a72e8-9c55-499d-8232-ee4279becfe1.png?width=1024&height=1356) Минимальное количество нод на этапе создания кластера — 1. ## Включение автомасштабирования для существующего кластера Если кластер уже создан, включить автомасштабирование можно следующим образом: 1. Перейдите на вкладку «Ресурсы». 2. Выберите «Редактировать группу». ![Image1](https://content.timeweb.com/assets/9246e715-bd10-4d4a-998c-08178ece5a33.png?width=790&height=340) В появившемся меню включите опцию автомасштабирования для группы. ![Scr 20250820 Kkvg](https://content.timeweb.com/assets/afba6b1e-0097-4125-8c91-c31d9752de28.png?width=1002&height=1654) Минимальное количество нод — 0. ## Принцип работы автомасштабирования Для управления созданием и удалением нод используются следующие параметры: ```bash --scale-down-unneeded-time 5m0s --max-scale-down-parallelism 1 --provisioning-request-max-backoff-time 2m0s --max-inactivity 3m0s --scale-down-delay-after-add 2m0s --max-node-provision-time 10m0s --scan-interval 2m0s --scale-up-from-zero=true --scale-down-unready-enabled=true --scale-down-unready-time=30m0s ``` | **Параметр** | **Описание** | | --- | --- | | `scale-down-unneeded-time` | Время, в течение которого нода должна простаивать перед удалением (5 минут). | | `max-scale-down-parallelism` | Максимальное количество нод, которые могут быть удалены одновременно (1). | | `provisioning-request-max-backoff-time` | Максимальное время ожидания между повторными попытками создания ноды (2 минуты). | | `max-inactivity` | Максимальное время бездействия кластера перед началом уменьшения количества нод (3 минуты). | | `scale-down-delay-after-add` | Минимальное время ожидания после добавления ноды перед возможным уменьшением (2 минуты). | | `max-node-provision-time` | Максимальное время, отводимое на создание новой ноды (10 минут). | | `scan-interval` | Интервал проверки состояния кластера и необходимости масштабирования (2 минуты). | | `scale-up-from-zero` | Разрешает масштабирование группы нод с нулевого количества. | | `scale-down-unready-enabled` | Разрешает удаление нод, находящихся в состоянии `NotReady`. | | `scale-down-unready-time` | Время, после которого нода в состоянии `NotReady` может быть удалена (30 минут). | Эти параметры определяют, как быстро добавляются или удаляются ноды в зависимости от текущей нагрузки. Например, если нагрузка снижается и нода простаивает более 5 минут, она может быть удалена. При этом удаление выполняется постепенно, не более одной ноды одновременно, чтобы избежать резкого сокращения ресурсов. При увеличении нагрузки автоскейлер анализирует состояние кластера с интервалом 2 минуты и может инициировать создание новых нод. На создание ноды отводится до 10 минут, а повторные попытки при ошибках выполняются с увеличивающимся интервалом, но не более 2 минут. Такой подход позволяет поддерживать баланс между доступностью ресурсов и их экономичным использованием. ### Настройка параметров автомасштабирования Для кластеров версии `1.34` и выше доступна настройка параметров автомасштабирования. При создании или редактировании группы нод нажмите кнопку «Расширенные параметры». ![Scr 20260413 Mctx](https://content.timeweb.com/assets/b894b30e-0612-4c7f-b835-d776caddb5c9.png?width=2054&height=1648) В открывшемся списке можно задать параметры: - `ScaleDownUtilizationThreshold` — порог утилизации CPU или памяти, ниже которого нода считается кандидатом на удаление. Значение от `0` до `1`. По умолчанию: `0.5`. - `ScaleDownUnneededDuration` — время, в течение которого нода должна оставаться неиспользуемой перед удалением. Минимальное значение — 5 минут. По умолчанию: 5 минут. - `ScaleDownUnreadyDuration` — время, по истечении которого нода в состоянии NotReady может быть удалена. Если включен автохилер, параметр игнорируется, чтобы избежать конфликтов. По умолчанию: 15 минут. - `MaxNodeProvisionDuration` — максимальное время ожидания создания новой ноды. Если нода не была создана за это время, операция считается неуспешной. По умолчанию: 10 минут. - `ZeroOrMaxNodeScaling` — режим масштабирования группы нод: при включении группа масштабируется сразу до максимального размера или до нуля, при выключении — постепенно, по одной ноде. По умолчанию: выключено. - `IgnoreDaemonSetsUtilization` — учитывать ли ресурсы, занятые DaemonSet, при принятии решения об удалении ноды: включено — не учитывать, выключено — учитывать. По умолчанию: выключено. > [!NOTE] > Параметры применяются в кластере в течение 2 минут после сохранения изменений. Чтобы вернуть значения параметров к исходным, нажмите кнопку «Вернуть значения по умолчанию». ## Требования к кластеру Максимальное количество нод в группе не может превышать максимально допустимое количество воркер-нод в кластере. Например, если для всего кластера установлено ограничение в 100 нод, а одна из групп уже использует 30 нод, для новой группы можно установить максимум 70 нод. ## Настройка ресурсов для подов Автомасштабирование работает только в том случае, если в деплойменте указаны ресурсы `requests` и `limits`. Ниже приведен пример файла деплоймента: ```yml apiVersion: apps/v1 kind: Deployment metadata: name: example-deployment spec: selector: matchLabels: app: example template: metadata: labels: app: example spec: containers: - name: example-container image: example-image resources: requests: cpu: "200m" memory: "256Mi" limits: cpu: "400m" memory: "512Mi" ``` Лимиты CPU измеряются в миллиядрах (`m`), где 1000m равняется одному ядру. Лимиты памяти измеряются в мебибайтах (`Mi`) или гибибайтах (`Gi`). ## Использование nodeSelector и nodeAffinity Если в манифесте пода используется `nodeSelector` или `nodeAffinity`, Kubernetes размещает под только на тех нодах, которые соответствуют указанным условиям. Это влияет и на автомасштабирование: автоскейлер сможет создать новую ноду только в той группе, где такой под может быть запущен. Если подходящей группы нод нет, под останется в состоянии `Pending`, даже если автомасштабирование в кластере включено. ### Пример с nodeSelector `nodeSelector` подходит для простых случаев, когда нужно запускать поды только на нодах с определенным лейблом. Например, если приложение должно работать только в определенной группе нод, можно использовать такой манифест: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: worker-deployment spec: replicas: 1 selector: matchLabels: app: worker template: metadata: labels: app: worker spec: nodeSelector: workload-type: background containers: - name: worker image: busybox command: ["sh", "-c", "sleep infinity"] resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "200m" memory: "256Mi" ``` В этом примере под может быть запущен только на нодах с лейблом `workload-type=background`. Если в кластере нет подходящих нод, автоскейлер сможет добавить новую ноду только в ту группу, где используется такой лейбл. ### Пример с nodeAffinity `nodeAffinity` используется, когда требуется более гибко задать условия размещения подов. В отличие от `nodeSelector`, он позволяет использовать выражения с различными операторами и комбинировать несколько условий. Ниже приведен пример, эквивалентный предыдущему `nodeSelector`, но реализованный через `nodeAffinity`: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: api-deployment spec: replicas: 1 selector: matchLabels: app: api template: metadata: labels: app: api spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: workload-type operator: In values: - api containers: - name: api image: nginx:latest resources: requests: cpu: "200m" memory: "256Mi" limits: cpu: "400m" memory: "512Mi" ``` В этом случае под будет размещаться только на нодах с лейблом `workload-type=api`. В этом примере используется оператор In, который позволяет указать одно или несколько допустимых значений для лейбла. `nodeAffinity` поддерживает и другие операторы, например: - `In` — значение лейбла должно входить в указанный список; - `NotIn` — значение лейбла не должно входить в указанный список; - `Exists` — достаточно наличия лейбла на ноде; - `DoesNotExist` — лейбл должен отсутствовать; - `Gt` — значение лейбла должно быть больше указанного (используется для числовых значений); - `Lt` — значение лейбла должно быть меньше указанного (используется для числовых значений). Операторы позволяют задавать более сложные правила размещения подов, чем при использовании `nodeSelector`. Используйте `nodeSelector`, если достаточно простой привязки по одному или нескольким фиксированным значениям. Если нужны более сложные условия размещения, применяйте `nodeAffinity`. ## Настройка Horizontal Pod Autoscaler (HPA) Horizontal Pod Autoscaler (HPA) используется для динамического изменения количества подов в зависимости от потребления ресурсов, таких как процессор или память. HPA масштабирует поды, чтобы поддерживать заданный уровень использования ресурсов и адаптироваться к изменяющимся условиям нагрузки. Ниже приведен пример манифеста HPA: ```yml apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: example-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: example-deployment minReplicas: 1 maxReplicas: 5 targetCPUUtilizationPercentage: 50 ``` #### Подробное описание параметров HPA - `apiVersion`: Определяет версию API, используемую для создания ресурса. В данном случае это `autoscaling/v1`. - `kind`: Тип создаваемого ресурса, здесь — `HorizontalPodAutoscaler`. - `metadata`: Содержит информацию о метаданных, включая имя HPA (`example-hpa`). - `scaleTargetRef`: Указывает объект, который нужно масштабировать. Здесь задаются: - `apiVersion`: Версия API ресурса, который будет масштабироваться. - `kind`: Тип ресурса, который масштабируется, в данном случае — `Deployment`. - `name`: Имя ресурса, который необходимо масштабировать (`example-deployment`). - `minReplicas`: Минимальное количество реплик подов, которые должны поддерживаться, в данном случае — 1. - `maxReplicas`: Максимальное количество реплик подов, до которого можно масштабироваться, здесь — 5. - `targetCPUUtilizationPercentage`: Процент загрузки процессора, при котором будет изменяться количество реплик. В этом примере установлено значение 50, что означает, что количество реплик будет изменяться для поддержания среднего использования CPU на уровне 50%. ## Практический пример использования автомасштабирования Для практического примера создадим деплоймент Nginx, который будет служить базой для настройки автомасштабирования: **Файл** `deployment.yaml`: ```yml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx resources: requests: cpu: "250m" memory: "512Mi" limits: cpu: "500m" memory: "1Gi" ``` Этот деплоймент создает под Nginx с установленными ограничениями на использование ресурсов, что необходимо для корректной работы HPA. ### Настройка горизонтального автомасштабирования подов на примере Nginx Для демонстрации автомасштабирования подов на примере Nginx необходимо использовать объект `HorizontalPodAutoscaler` (HPA). HPA автоматически регулирует количество реплик подов в зависимости от потребления ресурсов. Пример файла HPA: **Файл** `hpa.yaml`: ```yml apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: nginx-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nginx-deployment minReplicas: 1 maxReplicas: 4 targetCPUUtilizationPercentage: 20 ``` В данном примере HPA регулирует количество реплик пода `nginx-deployment` в зависимости от загрузки процессора, поддерживая ее на уровне 20%. ### Настройка балансировщика нагрузки Для правильного распределения нагрузки между подами рекомендуется использовать объект `Service` с типом `LoadBalancer`. Пример файла конфигурации сервиса: **Файл** `service.yaml`: ```yml apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: LoadBalancer ``` Этот сервис обеспечивает доступ к подам, используя балансировку нагрузки по нескольким портам. ### Применение настроек Для применения YAML-файлов необходимо использовать команды: ```shell kubectl apply -f nginx-deployment.yaml kubectl apply -f nginx-hpa.yaml kubectl apply -f nginx-service.yaml ``` Эти команды применят конфигурации деплоймента, HPA и балансировщика, создавая все необходимые компоненты для работы автомасштабирования. ### Демонстрация увеличения количества нод под нагрузкой Перед тем как приступить к генерации нагрузки, убедитесь, что все ресурсы успешно созданы и находятся в состоянии `Running`. Чтобы увидеть, как работает автомасштабирование, можно сгенерировать нагрузку на наш сервис. Для этого воспользуемся утилитой [hey](https://github.com/rakyll/hey), которая отправляет HTTP-запросы для тестирования производительности: Генерируем нагрузку: ```shell hey -z 10m -c 20 http://ip_балансировщика ``` Этот запрос будет генерировать нагрузку в течение 10 минут с 20 параллельными подключениями к сервису Nginx, что приведет к увеличению использования ресурсов и, как следствие, к масштабированию количества реплик деплоймента и, при необходимости, количества воркер-нод. Спустя некоторое время после запуска утилиты, вы можете увидеть, что количество нод увеличилось. Увидеть это можно в панели управления или выполнив команду: ```shell kubectl get nodes ``` Также количество подов увеличилось до 4, как описано в `hpa.yaml`: ```shell kubectl get pods ``` # Автомасштабирование до нуля нод Source: https://timeweb.cloud/docs/k8s/kubernetes-autoscaling/autoscaling-to-zero-nodes?utm_source=llms_txt&utm_medium=ai Автоматическое масштабирование группы нод до нуля позволяет экономить ресурсы, когда они не используются. Это удобно для разовых задач — например, Job — или стейдж-окружений, которые неактивны ночью. > [!NOTE] > Масштабирование до нуля нод — это частный случай [автомасштабирования](https://timeweb.cloud/docs/k8s/kubernetes-autoscaler). Поэтому принципы работы, ограничения и требования, описанные для обычного автомасштабирования, действуют и здесь. ## Требования Чтобы масштабирование до нуля работало, в кластере должны быть еще как минимум две постоянно активные ноды. Они могут располагаться в разных группах. Эти ноды используются для работы системных компонентов Kubernetes. ## Настройка подов Чтобы автоскейлер мог запускать ноды в нужной группе, укажите в манифесте условие размещения через `nodeSelector` или `nodeAffinity`. В качестве условия можно использовать ID группы воркер-нод или [пользовательский лейбл](https://timeweb.cloud/docs/k8s/kubernetes-autoscaling/kubernetes-autoscaler#ispolzovanie-nodeselector-i-nodeaffinity), заданный для этой группы. Лейблы позволяют гибко управлять размещением подов и не привязываться к конкретным ID. #### Как найти ID группы 1. Перейдите в панель управления кластером. 2. Откройте вкладку «Ресурсы». 3. Нажмите на три точки рядом с нужной группой и выберите «Редактировать группу». ![Scr 20250820 Kpwe](https://content.timeweb.com/assets/c5beeff6-63da-44d0-bbee-d34d62e6f6a7.png?width=2012&height=1112) 4. ID группы будет указан в URL, например: ```shell https://timeweb.cloud/my/kubernetes/1048329/54289/edit ``` Здесь: - `1048329` — ID кластера, - `54289` — ID группы узлов. Пример с `nodeSelector`: ```yaml nodeSelector: k8s.timeweb.cloud/cluster-node-group-id: "54289" ``` Пример с `nodeAffinity`: ```yaml affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: k8s.timeweb.cloud/cluster-node-group-id operator: In values: - "54289" ``` ## Когда масштабирование до нуля не сработает Автоскейлер не сможет удалить последнюю ноду в группе в следующих случаях: - У пода установлена аннотация: `cluster-autoscaler.kubernetes.io/safe-to-evict: "false"` - Поды нельзя переместить на другие узлы из-за ограничений планировщика. - Есть `PodDisruptionBudget`, который не позволяет удалить поды без превышения лимита. - Под не управляется контроллером (`Deployment`, `StatefulSet`, `Job`, `ReplicaSet`). ## Практический пример В этом примере создадим группу узлов с включенным масштабированием до нуля, запустим в ней Job и посмотрим, как кластер автоматически создаст ноду для выполнения задачи и удалит ее после завершения. При создании группы воркер-нод можно сразу задать пользовательские лейблы и использовать их для размещения подов. В этом примере для простоты будем использовать ID группы. ### Предварительные требования Существующий кластер Kubernetes хотя бы с одной группой нод. ### Создание группы нод с масштабированием до нуля 1. Перейдите во вкладку «Ресурсы» в панели управления. 2. Нажмите «Добавить группу». 3. Выберите конфигурацию воркер-нод. 4. Включите переключатель «Автомасштабирование» и установите минимальное количество нод равным 0. ![Scr 20250820 Luzj](https://content.timeweb.com/assets/d1bb381b-2c90-4046-9bc0-93625989f393.png?width=1032&height=1570) После создания группы появится одна нода, которая будет автоматически удалена, если на ней не запущены пользовательские поды. Теперь в кластере есть две группы: - группа с активными нодами, которые не масштабируются в 0; - группа с включенным масштабированием до 0. В нашем примере ее ID — `54289`. ![Scr 20250820 Lxah](https://content.timeweb.com/assets/e7c2d2a7-576c-41cc-8393-441d4df5826c.png?width=1528&height=704) ### Проверка существующих нод Выполните команду: ```bash kubectl get nodes ``` Пример вывода: ```bash NAME STATUS ROLES AGE VERSION worker-192.168.0.25 Ready 21h v1.33.3+k0s worker-192.168.0.8 Ready 22h v1.33.3+k0s ``` ### Создание Job Создайте файл `job.yaml` со следующим содержимым: ```yaml apiVersion: batch/v1 kind: Job metadata: name: hello-job spec: ttlSecondsAfterFinished: 30 template: metadata: name: hello-job spec: restartPolicy: Never nodeSelector: k8s.timeweb.cloud/cluster-node-group-id: "54289" containers: - name: hello image: busybox command: - sh - -c - 'i=0; while [ $i -lt 10 ]; do echo "Hello from job"; sleep 30; i=$((i+1)); done' resources: requests: cpu: "50m" memory: "32Mi" limits: cpu: "100m" memory: "64Mi" ``` Это задание запускает контейнер с образом `busybox`, который выводит сообщение в лог 10 раз с интервалом 30 секунд. **Обратите внимание**: в секции `nodeSelector` указан ID группы нод (`54289`). Примените манифест: ```bash kubectl apply -f job.yaml ``` Проверьте список подов: ```bash kubectl get pod ``` Пример вывода: ```shell NAME READY STATUS RESTARTS AGE hello-job-s7ktd 0/1 Pending 0 4s ``` Под находится в статусе `Pending`, так как в группе пока нет нод. Перейдите в раздел «Ресурсы» панели управления. Вы увидите, что началось создание ноды в группе с автомасштабированием.  ![Scr 20250820 Mugx](https://content.timeweb.com/assets/fb105bee-98cb-4edc-a648-f469b429ab9c.png?width=2010&height=1090) После ее создания проверьте список нод: ```bash kubectl get nodes ``` Пример вывода: ```shell NAME STATUS ROLES AGE VERSION worker-192.168.0.25 Ready 21h v1.33.3+k0s worker-192.168.0.6 Ready 7m v1.33.3+k0s worker-192.168.0.8 Ready 22h v1.33.3+k0s ``` `worker-192.168.0.6` — это новая нода, созданная для Job. Проверьте под снова: ```shell kubectl get pod ``` Пример вывода: ```shell NAME READY STATUS RESTARTS AGE hello-job-s7ktd 1/1 Running 0 5m30s ``` Теперь под запущен. ### Завершение задания и удаление ноды После выполнения Job на ноду, где она запускалась, будет установлен тейнт. Посмотрите его командой: ```bash kubectl describe node worker-192.168.0.6 ``` Найдите строку: ```yml Taints:  DeletionCandidateOfClusterAutoscaler=1755679271:PreferNoSchedule ``` Это означает, что нода помечена на удаление. Через 2 минуты после установки тейнта она будет удалена. Проверьте это: ```shell kubectl get nodes ``` # Доступ и пользователи Source: https://timeweb.cloud/docs/k8s/access?utm_source=llms_txt&utm_medium=ai - [Управление пользователями](https://timeweb.cloud/docs/k8s/access/manage-users) - [Подключение OIDC-провайдера к кластеру](https://timeweb.cloud/docs/k8s/access/connect-oidc-provider-to-cluster) # Управление пользователями Source: https://timeweb.cloud/docs/k8s/access/manage-users?utm_source=llms_txt&utm_medium=ai В кластерах Kubernetes доступ к кластеру настраивается средствами самого Kubernetes. Конфигурационный файл `kubeconfig`, который скачивается из панели управления, содержит административные учетные данные и подходит для первичной настройки кластера. Если с кластером работают несколько сотрудников, не рекомендуется использовать один общий административный `kubeconfig`. Если такой файл попадет к постороннему человеку или останется у сотрудника после увольнения, отозвать доступ только для него не получится. Безопаснее создать отдельную учетную запись для каждого пользователя и выдать необходимые права через RBAC. Рассмотрим настройку персонального доступа через `ServiceAccount`, `RoleBinding` или `ClusterRoleBinding` и отдельный `kubeconfig` с токеном. ## Подготовка Для выполнения действий потребуется кластер Kubernetes, административный `kubeconfig`, скачанный из панели управления, и установленная [утилита kubectl](https://timeweb.cloud/docs/k8s/cluster-connection/kubectl). Чтобы скачать `kubeconfig`, перейдите на страницу управления кластером Kubernetes в панели управления. Во вкладке «Дашборд» нажмите ссылку «скачайте файл конфигурации». Скачанный файл будет иметь имя `twc-имя_кластера.yaml`. Проверьте подключение к кластеру: ```bash kubectl --kubeconfig=twc-имя_кластера.yaml get nodes ``` Если команда возвращает список нод, можно переходить к созданию учетной записи. ## Создание пространства для учетных записей Для управления учетными записями удобно создать отдельный неймспейс, например `kube-users`: ```bash kubectl create namespace kube-users ``` Создадим учетную запись для пользователя `twcuser`: ```bash kubectl create serviceaccount twcuser -n kube-users ``` В дальнейшем имя этой учетной записи будет использоваться при выдаче прав и выпуске токена. ## Выдача прав пользователю Права в Kubernetes выдаются через RBAC. Для этого используются: - `RoleBinding` — выдает права в пределах одного неймспейса; - `ClusterRoleBinding` — выдает права на уровне всего кластера. Выдавайте пользователю только минимально необходимые права. Если достаточно доступа к одному неймспейсу, используйте `RoleBinding` вместо `ClusterRoleBinding`. ### Доступ к одному неймспейсу Если пользователю нужен доступ только к одному неймспейсу, создайте `RoleBinding` в этом неймспейсе. В примере ниже пользователь `twcuser` получает права на изменение ресурсов в неймспейсе `app-prod`: ```bash kubectl create namespace app-prod kubectl create rolebinding twcuser-app-prod-edit \ --namespace app-prod \ --clusterrole edit \ --serviceaccount kube-users:twcuser ``` Вместо роли `edit` можно использовать другую встроенную роль: | **Роль** | **Описание** | | --- | --- | | `view` | Просмотр ресурсов без возможности изменять их. | | `edit` | Создание и изменение большинства ресурсов в неймспейсе. | | `admin` | Управление ресурсами в неймспейсе, включая роли и привязки ролей. | | `cluster-admin` | Полный административный доступ ко всему кластеру. | В таблице перечислены стандартные пользовательские `ClusterRole` Kubernetes. Но также [можно создать собственные ClusterRole](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#kubectl-create-clusterrole) с нужными правилами, если стандартных ролей недостаточно.  Для проверки прав выполните: ```bash kubectl auth can-i create deployments \ --as system:serviceaccount:kube-users:twcuser \ -n app-prod ``` Если доступ выдан корректно, команда вернет: ```shell yes ``` ### Доступ ко всему кластеру Если пользователю нужен полный административный доступ ко всему кластеру, создайте `ClusterRoleBinding`: ```bash kubectl create clusterrolebinding twcuser-cluster-admin \ --clusterrole cluster-admin \ --serviceaccount kube-users:twcuser ``` Используйте роль `cluster-admin` только для администраторов кластера. Для команд разработчиков безопаснее выдавать доступ в пределах нужного неймспейса. ## Создание токена Для подключения через `kubectl` пользователю нужен токен. В Kubernetes можно использовать временный токен или долгоживущий токен, сохраненный в `Secret`. ### Временный токен Временный токен создается командой `kubectl create token`. Например, выпустим токен на 24 часа: ```bash TOKEN=$(kubectl create token twcuser -n kube-users --duration=24h) ``` Посмотреть значение токена можно командой: ```bash echo "${TOKEN}" ``` Временный токен автоматически перестанет работать после окончания срока действия. У временных токенов нет отдельного объекта в кластере, поэтому отозвать один конкретный временный токен до истечения срока действия нельзя. Если нужно срочно закрыть доступ, удалите права пользователя или сам `ServiceAccount`. ### Долгоживущий токен Если нужен токен без заданного срока действия, создайте `Secret` типа `kubernetes.io/service-account-token`. Такой токен можно отозвать удалением `Secret`. Создайте файл `twcuser-token-secret.yaml`: ```yaml apiVersion: v1 kind: Secret metadata: name: twcuser-token namespace: kube-users annotations: kubernetes.io/service-account.name: twcuser type: kubernetes.io/service-account-token ``` Примените манифест: ```bash kubectl apply -f twcuser-token-secret.yaml ``` Получите значение секрета: ```bash TOKEN=$(kubectl get secret twcuser-token \ -n kube-users \ -o jsonpath='{.data.token}' | base64 -d) ``` Долгоживущие токены следует использовать только там, где временного токена недостаточно. Такой токен необходимо хранить как секретные учетные данные. ## Создание kubeconfig для пользователя Создадим отдельный файл `kubeconfig`, в котором будут данные кластера и токен пользователя `twcuser`. Сначала получим параметры текущего кластера из административного `kubeconfig`: ```bash CLUSTER_NAME=$(kubectl config view --minify -o jsonpath='{.clusters[0].name}') CLUSTER_SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}') kubectl config view --raw --minify -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 -d > ca.crt ``` Создайте новый файл конфигурации: ```bash kubectl config --kubeconfig=twcuser.kubeconfig set-cluster "${CLUSTER_NAME}" \ --server="${CLUSTER_SERVER}" \ --certificate-authority=ca.crt \ --embed-certs=true kubectl config --kubeconfig=twcuser.kubeconfig set-credentials twcuser \ --token="${TOKEN}" kubectl config --kubeconfig=twcuser.kubeconfig set-context twcuser-context \ --cluster="${CLUSTER_NAME}" \ --user=twcuser kubectl config --kubeconfig=twcuser.kubeconfig use-context twcuser-context ``` Если пользователь должен работать в конкретном неймспейсе, добавьте его в контекст: ```bash kubectl config --kubeconfig=twcuser.kubeconfig set-context twcuser-context \ --cluster="${CLUSTER_NAME}" \ --user=twcuser \ --namespace=app-prod ``` После этого файл `twcuser.kubeconfig` можно передать пользователю. ### Пример готового kubeconfig Ниже приведен пример пользовательского `kubeconfig` с авторизацией по токену. Значения `certificate-authority-data`, `server` и `token` будут отличаться в вашем кластере. ```yaml apiVersion: v1 clusters: - cluster: certificate-authority-data: server: https://:6443 name: twc-example-cluster contexts: - context: cluster: twc-example-cluster namespace: app-prod user: twcuser name: twcuser-context current-context: twcuser-context kind: Config preferences: {} users: - name: twcuser user: token: ``` В готовом файле не должно быть административного пользователя, клиентского сертификата или приватного ключа из исходного `kubeconfig`. Перед передачей файла пользователю убедитесь, что в секции `users` осталась только учетная запись с токеном пользователя. ## Проверка доступа Проверьте работу нового `kubeconfig`: ```bash kubectl --kubeconfig=twcuser.kubeconfig get pods -n app-prod ``` Если пользователю выдан доступ только к неймспейсу `app-prod`, запросы к другим неймспейсам будут запрещены. Например: ```bash kubectl --kubeconfig=twcuser.kubeconfig get pods -n default ``` В этом случае Kubernetes вернет ошибку доступа: ```bash Error from server (Forbidden): pods is forbidden ``` Для проверки конкретного действия можно использовать команду `kubectl auth can-i`: ```bash kubectl --kubeconfig=twcuser.kubeconfig auth can-i update deployments -n app-prod ``` ## Отзыв доступа Способ отзыва зависит от того, какой доступ нужно отключить. ### Удаление прав пользователя Чтобы запретить пользователю выполнять действия в неймспейсе, удалите соответствующий `RoleBinding`: ```bash kubectl delete rolebinding twcuser-app-prod-edit -n app-prod ``` Если пользователю был выдан доступ на уровне всего кластера, удалите `ClusterRoleBinding`: ```bash kubectl delete clusterrolebinding twcuser-cluster-admin ``` После удаления привязки токен может оставаться технически действительным, но прав на выполнение действий у пользователя уже не будет. ### Отзыв долгоживущего токена Если токен был создан через `Secret`, удалите этот `Secret`: ```bash kubectl delete secret twcuser-token -n kube-users ``` После удаления `Secret` токен перестанет проходить аутентификацию. ### Полное удаление учетной записи Чтобы полностью удалить пользователя, удалите его `ServiceAccount`: ```bash kubectl delete serviceaccount twcuser -n kube-users ``` При удалении `ServiceAccount` выпущенные для него токены перестанут работать. Отзыв может примениться не мгновенно: Kubernetes может кэшировать результаты проверки токенов в течение короткого времени. После удаления учетной записи также удалите связанные `RoleBinding` и `ClusterRoleBinding`, если они больше не нужны. # Подключение OIDC-провайдера к кластеру Source: https://timeweb.cloud/docs/k8s/access/connect-oidc-provider-to-cluster?utm_source=llms_txt&utm_medium=ai OpenID Connect (OIDC) — это протокол аутентификации, работающий на основе OAuth 2.0. С его помощью можно настроить авторизацию пользователей в кластере Kubernetes через сервисы аутентификации, такие как Google, Keycloak, Dex, GitHub и другие. ## Настройка OIDC-провайдера Подключение OIDC-провайдера можно настроить при создании кластера — в разделе «Дополнения»: ![Screenshot 05 27 25 18:34:35](https://content.timeweb.com/assets/b86268c7-3755-41db-a660-d3226e281145.png?width=420&height=623) Или позже — в разделе «Управление» в панели управления уже созданным кластером. Для настройки нажмите кнопку «Подключить». ![Selection 273](https://content.timeweb.com/assets/8b96f033-819c-4f3d-a85f-b0d510dc8c4e.png?width=1915&height=957) При настройке укажите значения: - **Название подключения** (обязательное поле) — имя подключения, отображается только в панели управления и не влияет на работу OIDC. - **Issuer URL** (обязательное поле) — адрес OIDC-провайдера. Обычно это URL вида `https://<домен>/realms/` для Keycloak или `https://accounts.google.com` для Google.  - **Client ID** (обязательное поле) — идентификатор клиента, зарегистрированного у провайдера OIDC. - **Username claim** — имя поля в ID-токене, которое Kubernetes будет использовать в качестве имени пользователя (например, `sub`, `preferred_username` или `email`). - **Groups claim** — имя поля в ID-токене, содержащего список групп пользователя. Используется для настройки доступа через RBAC по группам. После указания необходимых параметров нажмите на кнопку «Сохранить». ## Установка kubelogin Утилита `kubelogin` используется для получения ID-токена от провайдера и передачи его Kubernetes при выполнении команд через `kubectl`. Linux Скачайте архив с последней версией утилиты: ```shell curl -LO https://github.com/int128/kubelogin/releases/latest/download/kubelogin_linux_amd64.zip ``` Распакуйте архив: ```shell unzip kubelogin_linux_amd64.zip ``` Сделайте бинарный файл исполняемым: ```shell chmod +x kubelogin ``` Переместите его в системный путь, чтобы можно было запускать из любой директории: ```shell sudo mv kubelogin /usr/local/bin/ ``` macOS Выполните установку с помощью Homebrew: ```shell brew install kubelogin ``` Windows Установите утилиту через Chocolatey: ```shell choco install kubelogin ``` Krew Если вы используете Krew — менеджер плагинов для `kubectl`, выполните: ```shell kubectl krew install oidc-login ``` ## Получение токена Для получения токена выполните команду: ```shell kubelogin get-token \ --oidc-issuer-url=https://адрес_oidc-провайдера \ --oidc-client-id=id_клиента \ --oidc-client-secret=секрет ``` После запуска откроется окно авторизации. Введите логин и пароль пользователя, которому необходимо выдать доступ. После успешной авторизации будет выведен токен в формате JSON. ```shell {"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"2025-04-24T08:48:30Z","token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ3X3AxNzlsdkkzTnltWW01M09GZEpWeDJGeGJ6cGxoX2s5OHVFcmtjRmY4In0.eyJleHAiOjE3NDU0ODQ1MTAsImlhdCI6MTc0NTQ4NDQ1MSwiYXV0aF90aW1lIjoxNzQ1NDg0NDUwLCJqdGkiOiJkNTVmYjkzMy0zY2NlLTRkODYtYTcxZS1lNzc1ODZkN2E2ZGIiLCJpc3MiOiJodHRwczovL2tleWNsb2FrLm5kb2xnaWtoLnNpdGUvcmVhbG1zL21hc3RlciIsImF1ZCI6InRlc3QiLCJzdWIiOiIyY2U5NDk5Ni0zN2NlLTQ1NDEtOGFiOS00ZTk0MWE2YjhmYW123eXAiOiJJRCIsImF6cCI6InRlc3QiLCJub25jZSI6InhuWGNLMTlIVUprRTB0N3BXbVJ6NXJBWC0ya0h4NFpVaGdhbEJ2OW1QsfaiLCJzZXNzaW9uX3N0YXRlIjoiYjZmOWRmNmMtMjNhMS00OGU4LTkwMDQtOWJlYmFmNzY0OGU4IiwiYXRfaGFzaCI6IldocDAtQkdCTmhWNTUwc082eW9wS2ciLCJhY3IiOiIxIiwic2lkIjoiYjZmOWRmNmMtMjNhMS00OGU4LTkwMDQtOWJlYmFmNzY0OGU4IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoidGVzdCB0ZXN0IiwicHJlZmVycmVkX3VzZXJuYW1lIjoidGVzdEBtYWlsLnJ1IiwiZ2l2ZW5fbmFtZSI6InRlc3QiLCJmYW1pbHlfbmFtZSI6InRlc3QiLCJlbWFpbCI6InRlc3RAbWFpbC5ydSJ9.GQjRT_gTjsdfuVwhPYCW5DlqL_pbXpiYItIxNvOs9G8jUldV-3LyntQa4Zf4OSwzKldiJ4wZDRa-8pGI-BwD3SO1RxhkbYm_yTFxXDguxNdjstrFcCfLaslhBPqelpKC7DbsIqSLRIoixihPynIEMhEZRxvlDwZuYmWwyn7zMztQyGHPam_ujICIddcODBDBHA2Ksw_ZNwMAoU0sdMlI3fjTJst_Mh3jgzQRpFctc7X75JCL37HcZ6HBb6_9SWfmKHGO3ivFGs1pKtX6XDay8zt65DaEKM41iTjCzr-nKQ1Qk16fRypgsUauSJp_UHiGMiAUHSz66hQdvUr1uByg"}} ``` Для просмотра содержимого токена выполните: ```shell echo "token" | cut -d '.' -f2 | base64 -d | jq ``` В результате будет показан объект с полями, например: ```js { "exp": 1745480015, "iat": 1745479955, "auth_time": 1745479955, "jti": "4d9d243a-f62d-4150-94eb-5c535d2c0ea8", "iss": "https://keycloak.timeweb.cloud/realms/master", "aud": "test-user", "sub": "2ce94996-37ce-4541-8ab9-4e941a6b8faa", "typ": "ID", "azp": "test-user", "nonce": "ubNzQ6KRI746Ab1WPGG3Z5tONUPDPx-sSud4aLKDlT4", "session_state": "e0933444-3a04-4e17-885c-1a7f93e0ebb3", "at_hash": "QpL9mrseqRikRIVEhdQrBQ", "acr": "1", "sid": "e0933444-3a04-4e17-885c-1a7f93e0ebb3", "email_verified": false, "name": "Timeweb Cloud", "preferred_username": "test@example.com", "given_name": "test", "family_name": "test", "email": "test@example.com" } ``` Одно из имен этих параметров вы указывали при настройке OIDC-провайдера в панели управления; по умолчанию используется `sub`. ## Настройка RBAC RBAC (Role-Based Access Control) — это механизм в Kubernetes, который управляет правами пользователей. Он используется для определения того, какие ресурсы может просматривать или изменять пользователь. Более полную информацию вы можете найти [в официальной документации Kubernetes](https://kubernetes.io/docs/reference/access-authn-authz/rbac/). Для настройки RBAC создадим манифест `oidc-access.yaml` со следующим содержанием: ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: keycloak-cluster-role rules: - apiGroups: ["*"] resources: ["*"] verbs: ["*"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: keycloak-cluster-role-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: keycloak-cluster-role subjects: - kind: User name: "https://адрес_oidc-провайдера#sub" apiGroup: rbac.authorization.k8s.io ``` Укажите значение поля `sub` из токена в параметре `name`. Это даст полные права (`cluster-admin`) конкретному пользователю, авторизованному через OIDC. Примените манифест: ```shell kubectl apply -f oidc-access.yaml ``` Если вы хотите выдать доступ только на чтение ресурсов, например, подов в неймспейсе default, примените такой манифест: ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: readonly-pods namespace: default rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: readonly-pods-binding namespace: default roleRef: kind: Role name: readonly-pods apiGroup: rbac.authorization.k8s.io subjects: - kind: User name: "https://адрес_oidc-провайдера#sub" apiGroup: rbac.authorization.k8s.io ``` Такой манифест позволит пользователю только просматривать поды в неймспейсе default, не давая доступ к другим ресурсам или пространствам имен. Если при настройке OIDC-провайдера в панели управления вы указали «Username claim» со значением, например, `preferred_username`, то Kubernetes будет использовать его как имя пользователя. В этом случае вы можете упростить `subjects.name` и использовать читаемое имя, например: ```yaml subjects: - kind: User name: "test@example.com" apiGroup: rbac.authorization.k8s.io ``` ## Настройка kubectl для работы с OIDC Для подключения к кластеру через OIDC добавьте пользователя в `kubeconfig`: ```shell kubectl config set-credentials oidc \ --exec-api-version=client.authentication.k8s.io/v1 \ --exec-interactive-mode=IfAvailable \ --exec-command=kubelogin \ --exec-arg=get-token \ --exec-arg=--oidc-issuer-url=https://адрес_oidc-провайдера \ --exec-arg=--oidc-client-id=id_клиента \ --exec-arg=--oidc-client-secret=секрет ``` И назначьте текущий контекст: ```shell kubectl config set-context --current --user=oidc ``` Проверьте, что всё работает, выполнив: ```shell kubectl get pods ``` Откроется окно браузера с запросом на вход. После авторизации команда должна выполниться без ошибок. Если возникает ошибка доступа — убедитесь, что пользователю выданы необходимые права через RBAC. Если все работает корректно, вы можете отключить авторизацию по сертификатам в `kubeconfig`, чтобы использовать только OIDC. Для этого закомментируйте или удалите строки с данными клиента: ```yaml # - name: nt94542-1032513 #   user: # client-certificate-data: LS0tLS1CRUdJTiBD… # client-key-data: LS0tLS1CRUdJ… ``` Это позволит использовать OIDC как единственный механизм аутентификации для выбранного пользователя. ## Отключение OIDC-провайдера Чтобы отключить OIDC-провайдера, перейдите в раздел «Управление» в панели управления кластером. Нажмите кнопку «Изменить» рядом с пунктом «OIDC-провайдер», затем — «Удалить». После отключения провайдера все пользователи, подключенные через него, потеряют доступ к кластеру. При этом созданные правила RBAC сохраняются — их необходимо удалить вручную. Найти связанные привязки ролей можно с помощью команды: ```shell kubectl get rolebindings --all-namespaces -o yaml | grep -B5 https://адрес_oidc-провайдера ``` Удалить объекты можно командой: ```shell kubectl delete clusterrolebinding имя ``` Чтобы восстановить доступ, если в `kubeconfig` была указана OIDC-аутентификация, верните настройки с авторизацией по сертификатами или скачайте `kubeconfig` из панели управления. # Сеть и входящий трафик Source: https://timeweb.cloud/docs/k8s/network?utm_source=llms_txt&utm_medium=ai - [Сетевые плагины](https://timeweb.cloud/docs/k8s/network/network-plugins)  - [Балансировщик нагрузки](https://timeweb.cloud/docs/k8s/network/kubernetes-load-balancer) - [Подключение собственного SSL-сертификата к балансировщику](https://timeweb.cloud/docs/k8s/network/connect-custom-ssl-certificate-to-load-balancer) - [Приватные и публичные сервисы](https://timeweb.cloud/docs/k8s/network/public-private-services) - [Виртуальные роутеры](https://timeweb.cloud/docs/k8s/network/virtual-routers-in-kubernetes) # Сетевые плагины Kubernetes Source: https://timeweb.cloud/docs/k8s/network/network-plugins?utm_source=llms_txt&utm_medium=ai В Kubernetes от Timeweb Cloud можно использовать различные сетевые плагины CNI (Container Network Interface), такие как Calico, Flannel, Kube-router и Cilium. Эти плагины обеспечивают подключение подов к сети, управляют маршрутизацией и поддерживают сетевые политики, обеспечивая надежную и безопасную работу приложений. Каждый из этих плагинов предлагает свой подход к решению сетевых задач в Kubernetes. Calico подходит для высокопроизводительных сетей с расширенными политиками безопасности, Flannel выделяется своей простотой и надежностью для базовых сетевых задач, Kube-router ориентирован на высокопроизводительную маршрутизацию, а Cilium обеспечивает глубокую интеграцию с ядром Linux и продвинутую безопасность. Выбрать плагин можно при создании кластера. Изменить его в дальнейшем нельзя. Рассмотрим особенности каждого плагина, чтобы помочь вам выбрать подходящее решение. ## Calico **Calico** — это высокопроизводительное решение для сети Kubernetes, которое использует маршрутизацию на основе IP для обеспечения связи между подами и внешними сетями. #### Принцип работы Calico использует BGP (Border Gateway Protocol) для обмена маршрутами между узлами кластера. Это позволяет каждому узлу знать, где находятся поды, и маршрутизировать пакеты напрямую, минуя дополнительную обработку, что значительно улучшает производительность. #### Сетевые политики Одним из ключевых преимуществ Calico является поддержка продвинутых сетевых политик. Эти политики позволяют настроить контроль доступа между подами на уровне сетевых пакетов, что важно для безопасности приложений. Например, можно задать, какие поды могут обмениваться данными друг с другом. #### Преимущества - Высокая производительность благодаря маршрутизации без наложений (non-overlay). - Масштабируемость для крупных кластеров. - Поддержка продвинутых сетевых политик для безопасности. ## Flannel **Flannel** — это простой и легкий сетевой плагин, который используется для создания наложенных сетей (overlay networks) в Kubernetes. #### Принцип работы Flannel создает виртуальные сети с помощью протоколов VXLAN или UDP, которые позволяют подам общаться друг с другом. При этом каждому поду назначается IP-адрес из диапазона, зарезервированного для виртуальной сети, и трафик маршрутизируется через туннели между узлами. #### Сетевые политики Flannel не предоставляет продвинутых сетевых политик, как Calico, и не поддерживает маршрутизацию на основе BGP. Это делает его менее сложным, но подходящим для простых сетевых сценариев, особенно в небольших и средних кластерах. #### Преимущества - Простота настройки и эксплуатации. - Подходит для небольших кластеров и случаев, когда не требуются сложные сетевые политики. ## Kube-router **Kube-router** — это легковесный плагин, который фокусируется на маршрутизации третьего уровня сетевой модели (Layer 3) с минимальной задержкой. #### Принцип работы Kube-router использует BGP для маршрутизации трафика между подами на разных узлах. При этом он также предоставляет функции сетевых политик и балансировки нагрузки. Kube-router заменяет стандартный сетевой стек Kubernetes, что снижает сложность и уменьшает накладные расходы на обработку сетевого трафика. #### Сетевые политики Помимо маршрутизации, Kube-router обеспечивает контроль трафика с помощью сетевых политик и балансировку нагрузки для IPVS (IP Virtual Server). #### Преимущества - Высокая производительность и низкая задержка. - Поддержка сетевых политик и балансировки нагрузки. - Легкая интеграция с кластерами с требованиями к высокопроизводительной маршрутизации. ## Cilium **Cilium** — это мощный плагин, который использует eBPF (extended Berkeley Packet Filter) для мониторинга и управления сетевым трафиком на уровне ядра операционной системы. #### Принцип работы Cilium использует eBPF для выполнения сетевых операций прямо в ядре Linux, что позволяет фильтровать, анализировать и контролировать сетевой трафик с высокой точностью и минимальными затратами на обработку. Благодаря этому Cilium обеспечивает глубокий контроль за сетевыми потоками и поддерживает сложные сетевые политики на уровне приложений. #### Сетевые политики Cilium поддерживает стандартные сетевые политики Kubernetes, а также расширенные функции безопасности, такие как фильтрация HTTP-запросов и контроль за взаимодействием на уровне API. #### Преимущества - Поддержка глубокого анализа трафика и политики безопасности на уровне приложений. - Высокая производительность благодаря интеграции с eBPF. - Возможность масштабирования и применения сложных сетевых политик. # Балансировщик нагрузки Kubernetes Source: https://timeweb.cloud/docs/k8s/network/kubernetes-load-balancer?utm_source=llms_txt&utm_medium=ai Для обеспечения устойчивой работы приложений и равномерного распределения трафика между подами в Kubernetes используется балансировщик нагрузки. Он помогает избежать перегрузки отдельных подов, поддерживая высокую доступность и стабильность сервисов. ## Базовая конфигурация балансировщика нагрузки Для создания балансировщика нагрузки в Kubernetes создадим ресурс типа Service с типом LoadBalancer. Пример базового манифеста: ```yml apiVersion: v1 kind: Service metadata: name: example-balancer namespace: kubernetes-dashboard spec: selector: app.kubernetes.io/name: nginx ports: - port: 80 # Внешний порт для доступа к приложению targetPort: 80 # Порт пода, на который перенаправляется трафик      appProtocol: k8s.timeweb.cloud/proto-http   type: LoadBalancer ``` В этом примере балансировщик будет перенаправлять трафик с порта 80 на порт 80 внутри подов, соответствующих селектору `app.kubernetes.io/name: nginx`. Если вам нужно добавить несколько правил для балансировки, обязательно указывайте атрибут `name` для каждого порта: ```yml apiVersion: v1 kind: Service metadata: name: example-balancer namespace: kubernetes-dashboard spec: selector: app.kubernetes.io/name: nginx ports: - port: 80 targetPort: 80      appProtocol: k8s.timeweb.cloud/proto-http       name: http - port: 443 targetPort: 443      appProtocol: k8s.timeweb.cloud/proto-https       name: https type: LoadBalancer ``` Значение атрибута `name` может быть произвольным. Для каждого порта можно указать протокол трафика с помощью атрибута `appProtocol`. Это позволяет явно задать, как будет обрабатываться трафик на стороне балансировщика. По умолчанию используется значение `proto-tcp`. Поддерживаются следующие значения: - `k8s.timeweb.cloud/proto-http` — обычный HTTP-трафик. - `k8s.timeweb.cloud/proto-https` — HTTPS-трафик. - `k8s.timeweb.cloud/proto-tcp` — TCP-трафик. - `k8s.timeweb.cloud/proto-tcp-ssl` — TCP-трафик с поддержкой TLS. - `k8s.timeweb.cloud/proto-http2` - HTTP/2-трафик. После создания балансировщик будет отображаться в панели управления в разделе «[Балансировщики](https://timeweb.cloud/my/balancer)» с лейблом «K8S». ![Scr 20250625 Lyfb](https://content.timeweb.com/assets/6dbaa39c-5fcb-4f2d-8bbb-5f2f6624960f.png?width=2028&height=900) Обратите внимание, что балансировщик, созданный с помощью Kubernetes, нельзя изменить в панели управления или через API — только через `kubectl`. ![Scr 20250625 Llzh](https://content.timeweb.com/assets/134fdea9-bdc8-4bad-b0d0-34ffc7f1c96c.png?width=1514&height=784) ## Дополнительные параметры для настройки балансировщика Для более гибкой настройки балансировщика нагрузки в Kubernetes можно использовать дополнительные параметры. Они указываются в виде аннотаций (`annotations`) в манифесте `Service`. Пример манифеста с параметрами, заданными через аннотации: ```yaml apiVersion: v1 kind: Service metadata: name: example-balancer namespace: kubernetes-dashboard labels: app: nginx annotations: k8s.timeweb.cloud/attached-loadbalancer-algo: "leastconn" k8s.timeweb.cloud/attached-loadbalancer-ddos-guard-external-ip: "true" spec: selector: app.kubernetes.io/name: nginx ports: - port: 80 appProtocol: k8s.timeweb.cloud/proto-http targetPort: 80 type: LoadBalancer ``` В этом примере задаются два дополнительных параметра: - `k8s.timeweb.cloud/attached-loadbalancer-algo`: алгоритм балансировки — `leastconn` (выбирает сервер с наименьшим числом активных подключений). - `k8s.timeweb.cloud/attached-loadbalancer-ddos-guard-external-ip`: выделяет балансировщику внешний IP с защитой от DDoS. > [!NOTE] > Дополнительные параметры также можно задавать с помощью лейблов, но этот способ считается устаревшим. Также, при использовании лейблов некоторые параметры могут применяться некорректно. Поэтому мы рекомендуем использовать аннотации. ## Доступные параметры для балансировщика нагрузки В таблице ниже перечислены доступные параметры для настройки балансировщика нагрузки. Каждый параметр задается в виде аннотации в манифесте Service: | **Параметр** | **Назначение** | | --- | --- | | `k8s.timeweb.cloud/attached-loadbalancer-preset-id: "391"` | Задает конфигурацию балансировщика. По умолчанию выбирается минимальная конфигурация для зоны. Получить id тарифов можно при помощи [API](https://timeweb.cloud/api-docs#tag/Balansirovshiki/operation/getBalancersPresets). | | `k8s.timeweb.cloud/attached-loadbalancer-algo: "roundrobin"` | Алгоритм балансировки: `roundrobin` или `leastconn`. | | `k8s.timeweb.cloud/attached-loadbalancer-healthcheck-check-interval: "10"` | Интервал между проверками доступности (в секундах). | | `k8s.timeweb.cloud/attached-loadbalancer-healthcheck-timeout: "5"` | Таймаут проверки доступности (в секундах). | | `k8s.timeweb.cloud/attached-loadbalancer-healthcheck-error-count: "3"` | Количество неудачных проверок перед отключением апстрима. | | `k8s.timeweb.cloud/attached-loadbalancer-healthcheck-recover-count: "2"` | Количество успешных проверок для восстановления апстрима. | | `k8s.timeweb.cloud/attached-loadbalancer-no-external-ip: "true"` | Отключение внешнего публичного IP для балансировщика. | | `k8s.timeweb.cloud/attached-loadbalancer-ddos-guard-external-ip: "true"` | Выделение внешнего IP с защитой от DDoS. | | `k8s.timeweb.cloud/ignore-timeweb-cloud-loadbalancer: "true"` | Исключает сервис из обработки балансировщиком Timeweb Cloud. Может быть полезно, если используется другой `LoadBalancer`, например, `kube-vip` или `MetalLB`. | | `k8s.timeweb.cloud/attached-loadbalancer-proxy-enable: "true"` | Включает прокси-режим для балансировщика. При использовании этой аннотации принимающее приложение (например, ingress-контроллер или прокси) также должно быть настроено на прием proxy protocol. В противном случае запросы могут завершаться ошибками (например, HTTP 400). Примеры настройки из официальной документации: [Ingress NGINX](https://kubernetes.github.io/ingress-nginx/user-guide/miscellaneous/), [Traefik](https://doc.traefik.io/traefik/master/reference/install-configuration/entrypoints/). | | `k8s.timeweb.cloud/attached-loadbalancer-connect-timeout: "5000"` | Время ожидания установления TCP-подключения с апстримом (в миллисекундах). | | `k8s.timeweb.cloud/attached-loadbalancer-client-timeout: "50000"` | Время ожидания новых TCP-сегментов от клиента (в миллисекундах). | | `k8s.timeweb.cloud/attached-loadbalancer-server-timeout: "50000"` | Таймаут ожидания ответа от бэкенда (в миллисекундах). | | `k8s.timeweb.cloud/attached-loadbalancer-http-request-timeout: "10000"` | Таймаут выполнения HTTP-запроса (в миллисекундах). | | `k8s.timeweb.cloud/attached-loadbalancer-maxconn: "10000"` | Максимальное количество соединений, которое может обрабатывать балансировщик на фронтенде. | | `k8s.timeweb.cloud/attached-loadbalancer-ssl: "true"` | Включение автоматического выпуска SSL-сертификата. Если указано `false`, сертификат будет удален. | | `k8s.timeweb.cloud/attached-loadbalancer-ssl-fqdn: "example.com"` | Домен, на который необходимо выпустить SSL-сертификат. | | `k8s.timeweb.cloud/attached-loadbalancer-ssl-type: "lets_encrypt"` | Тип SSL-сертификата. Доступные значения: `lets_encrypt` или `custom`. | | `k8s.timeweb.cloud/attached-loadbalancer-force-ssl: "true"` | Перенаправление HTTP-запросов на HTTPS с кодом `307`. Работает только вместе с настроенным сертификатом: `attached-loadbalancer-ssl` и `attached-loadbalancer-ssl-fqdn`. | ### Служебные аннотации Помимо пользовательских параметров, система может автоматически добавлять служебные аннотации. Например: ```yaml metadata: annotations: k8s.timeweb.cloud/lb-last-config: "..." ``` Аннотация `k8s.timeweb.cloud/lb-last-config` содержит последнюю примененную конфигурацию балансировщика. Система управления кластером использует ее для сравнения текущей и новой конфигурации, чтобы определить, требуется ли обновление балансировщика. Изменять или добавлять эту аннотацию вручную не требуется. ## Настройка перенаправления на HTTPS Для включения перенаправления на HTTPS добавьте параметр: ```yaml metadata: annotations: k8s.timeweb.cloud/attached-loadbalancer-force-ssl: "true" ``` Перед включением перенаправления HTTP на HTTPS убедитесь, что домен из параметра `k8s.timeweb.cloud/attached-loadbalancer-ssl-fqdn` уже указывает на IP-адрес балансировщика. Это необходимо для выпуска сертификата Let's Encrypt. Параметр `k8s.timeweb.cloud/attached-loadbalancer-force-ssl` включает перенаправление HTTP-запросов на HTTPS с кодом `307`. Если включить `force-ssl` без настроенного сертификата и домена, параметр будет проигнорирован, а балансировщик продолжит принимать обычный HTTP-трафик. В логах появится предупреждение: ```shell force-ssl requested but no SSL certificate configured; ignoring force-ssl ``` Если домен еще не указывает на IP-адрес балансировщика, Let's Encrypt не сможет выпустить сертификат. При этом балансировщик может начать отвечать редиректом на HTTPS, где нет валидного сертификата. В результате клиенты будут получать TLS-ошибку, хотя сервис в Kubernetes может выглядеть исправным. Отключить уже включенное перенаправление значением `k8s.timeweb.cloud/attached-loadbalancer-force-ssl: "false"` нельзя. Чтобы выключить перенаправление, удалите и пересоздайте балансировщик. ## Возможные ошибки ### Не удалось получить IP Если при создании балансировщика не удалось получить внешний IP-адрес, в аннотациях сервиса появится следующая отметка: ```bash k8s.timeweb.cloud/attached-loadbalancer-ensuring-error: true ``` Это означает, что что-то пошло не так при привязке внешнего IP. В таком случае рекомендуем попробовать пересоздать балансировщик или [обратиться в техническую поддержку](https://timeweb.cloud/my/support/help-question). #### Как проверить Найдите все сервисы с типом `LoadBalancer` в кластере: ```bash kubectl get svc --all-namespaces --field-selector spec.type=LoadBalancer ``` Посмотрите аннотации нужного сервиса: ```bash kubectl describe svc <имя-сервиса> -n <неймспейс> ``` Если в выводе будет аннотация `k8s.timeweb.cloud/attached-loadbalancer-ensuring-error: true`, пересоздайте балансировщик или [напишите в поддержку](https://timeweb.cloud/my/support/help-question) и укажите ID кластера. ## Практический пример использования балансировщика Для демонстрации работы балансировщика создадим два деплоймента Nginx, каждый из которых будет отображать свою HTML-страницу. Балансировщик случайным образом распределит запросы между подами, и в зависимости от этого будет показана одна из страниц. ### Подготовка окружения Для удобства управления и быстрого удаления всех ресурсов, связанных с балансировщиком, создадим отдельный неймспейс. Это упростит тестирование и последующее удаление ресурсов, сохраняя основной кластер чистым. Выполните команду для создания неймспейса: ```shell kubectl create namespace test-namespace ``` После создания используем этот неймспейс для всех дальнейших ресурсов, включая балансировщик, деплойменты и `ConfigMap`. Для этого добавьте `namespace: test-namespace` в каждый манифест, связанный с примером. ### Создание ConfigMap для HTML-страниц Начнем с создания `ConfigMap`, в котором будут храниться две HTML-страницы. Под 1 будет отображать страницу с заголовком «Pod 1», а Под 2 — с заголовком «Pod 2». Эти страницы подключаются к Nginx в подах. **Файл `nginx-pages-configmap.yaml`:** ```shell apiVersion: v1 kind: ConfigMap metadata: name: nginx-pages namespace: test-namespace data: index-page1.html: |

Pod 1

This is page served by Pod 1.

index-page2.html: |

Pod 2

This is page served by Pod 2.

``` Здесь мы создаем `ConfigMap` с двумя HTML-файлами: `index-page1.html` и `index-page2.html`. Они будут монтироваться в подах Nginx, позволяя каждому поду отображать свою страницу. Примените `ConfigMap`: ```shell kubectl apply -f nginx-pages-configmap.yaml ``` ### Создание деплойментов Nginx Теперь создадим два деплоймента, каждый из которых будет использовать разные HTML-страницы из `ConfigMap`. Деплойменты используют селектор `app: nginx` — это метка, которую балансировщик будет использовать для выбора подов, участвующих в распределении нагрузки. **Файл `nginx-deployment-pod1.yaml`:** ```yml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-pod1 namespace: test-namespace spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest volumeMounts: - name: nginx-pages mountPath: /usr/share/nginx/html/index.html subPath: index-page1.html ports: - containerPort: 80 volumes: - name: nginx-pages configMap: name: nginx-pages ``` Этот деплоймент создает один под (реплика 1) с образом Nginx, который монтирует страницу `index-page1.html` из `ConfigMap` в директорию `/usr/share/nginx/html/index.html`. Порт 80 открыт для доступа к странице. Примените деплоймент: ```shell kubectl apply -f nginx-deployment-pod1.yaml ``` **Файл `nginx-deployment-pod2.yaml`:** ```yml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-pod2 namespace: test-namespace spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest volumeMounts: - name: nginx-pages mountPath: /usr/share/nginx/html/index.html subPath: index-page2.html ports: - containerPort: 80 volumes: - name: nginx-pages configMap: name: nginx-pages ``` Этот деплоймент также создает под Nginx, но монтирует страницу `index-page2.html`, отличающуюся содержимым. Примените второй деплоймент: ```shell kubectl apply -f nginx-deployment-pod2.yaml ``` ### Настройка балансировщика нагрузки Теперь создадим балансировщик, который будет направлять запросы на поды с меткой `app: nginx`. **Файл `nginx-loadbalancer.yaml`:** ```yml apiVersion: v1 kind: Service metadata: name: nginx-loadbalancer namespace: test-namespace spec: selector: app: nginx ports: - port: 80 targetPort: 80      appProtocol: k8s.timeweb.cloud/proto-http   type: LoadBalancer ``` В этом `Service` указываем `type: LoadBalancer`, что создает балансировщик нагрузки, и `selector: app: nginx`, который направляет запросы на поды Nginx из наших деплойментов. Запросы, поступающие на балансировщик, распределяются между подами при помощи алгоритма `roundrobin`, так как этот алгоритм выбирается по умолчанию. Примените балансировщик: ```shell kubectl apply -f nginx-loadbalancer.yaml ``` ### Проверка работы балансировщика После создания балансировщика его внешний IP-адрес можно увидеть в [панели управления](https://timeweb.cloud/my/balancer) или выполнив команду: ```shell kubectl get services -n test-namespace ``` При доступе по этому IP вы увидите страницу, отображаемую одним из подов. Каждый раз при обновлении страницы трафик может перенаправляться на разные поды, что позволяет балансировщику нагрузки случайным образом переключать отображаемую страницу. ### Удаление ресурсов после проверки После того как вы проверили работу балансировщика, вы можете удалить все созданные поды и ресурсы. Для этого выполните следующие команды: ```shell kubectl delete service nginx-loadbalancer -n test-namespace kubectl delete deployment nginx-pod1 -n test-namespace kubectl delete deployment nginx-pod2 -n test-namespace kubectl delete configmap nginx-pages -n test-namespace ``` Эти команды удалят балансировщик, деплойменты подов и `ConfigMap`, созданные ранее. Либо удалите неймспейс полностью, выполнив: ```shell kubectl delete namespace test-namespace ``` Этот способ автоматически удалит все ресурсы, связанные с тестовым окружением. # Подключение собственного SSL-сертификата к балансировщику Source: https://timeweb.cloud/docs/k8s/network/connect-custom-ssl-certificate-to-load-balancer?utm_source=llms_txt&utm_medium=ai Балансировщик нагрузки поддерживает использование собственного SSL-сертификата, загруженного из Kubernetes-секрета типа `kubernetes.io/tls`. Для настройки необходимо создать TLS-секрет с сертификатом и приватным ключом, а затем указать его в аннотациях балансировщика. > [!NOTE] > При настройке сертификата через балансировщик нельзя использовать самоподписанные сертификаты. Необходимо использовать сертификат, выпущенный доверенным центром сертификации. ## Создание секрета Скачайте файлы сертификата. Создайте TLS-секрет в том же неймспейсе, где находится балансировщик: ```bash kubectl -n create secret tls my-app-tls \ --cert=crt.crt \ --key=key.key ``` Проверить тип секрета можно командой: ```bash kubectl -n get secret my-app-tls -o yaml ``` В выводе должно присутствовать: ```bash type: kubernetes.io/tls ``` ## Настройка сервиса Добавьте аннотации для использования собственного сертификата в манифесте балансировщика: ```bash apiVersion: v1 kind: Service metadata: name: my-app annotations: k8s.timeweb.cloud/attached-loadbalancer-ssl: "true" k8s.timeweb.cloud/attached-loadbalancer-ssl-type: "custom" k8s.timeweb.cloud/attached-loadbalancer-ssl-fqdn: "example.com" k8s.timeweb.cloud/attached-loadbalancer-ssl-secret-name: "my-app-tls" spec: type: LoadBalancer selector: app: my-app ports: - name: https port: 443 targetPort: 80 appProtocol: k8s.timeweb.cloud/proto-https ``` Параметры: - `k8s.timeweb.cloud/attached-loadbalancer-ssl` — включает использование SSL-сертификата. - `k8s.timeweb.cloud/attached-loadbalancer-ssl-type` — определяет тип сертификата. Для собственного сертификата используйте значение `custom`. - `k8s.timeweb.cloud/attached-loadbalancer-ssl-fqdn` — доменное имя, для которого выпущен сертификат. - `k8s.timeweb.cloud/attached-loadbalancer-ssl-secret-name` — имя TLS-секрета, содержащего сертификат и приватный ключ. Примените изменения: ```bash kubectl apply -f service.yaml ``` ## Проверка сертификата Проверить сертификат, который использует балансировщик, можно командой: ```bash echo | openssl s_client \ -connect example.com:443 \ -servername example.com \ 2>/dev/null | openssl x509 -noout -subject -issuer -dates ``` Пример успешного результата: ```bash subject=CN=example.com issuer=C=BE, O=GlobalSign nv-sa, CN=GlobalSign GCC R6 AlphaSSL CA 2025 ``` Также можно проверить HTTPS-соединение через `curl`: ```bash curl -kv https://example.com ``` В выводе должно присутствовать: ```bash SSL certificate verify ok. ``` Также в выводе должна быть информация о вашем сертификате: ```bash subject: CN=example.com ``` Если вместо этого отображается сертификат вида: ```bash subject: CN=empty ``` — значит, балансировщик не смог применить указанный сертификат и использует сертификат по умолчанию. ## Обновление сертификата Для замены сертификата обновите существующий секрет: ```bash kubectl -n create secret tls my-app-tls \ --cert=new.crt \ --key=new.key \ --dry-run=client -o yaml | kubectl apply -f - ``` После обновления секрета необходимо запустить повторную настройку балансировщика, изменив любую аннотацию сервиса: ```bash kubectl -n annotate svc my-app \ k8s.timeweb.cloud/rotate-ts="$(date +%s)" \ --overwrite ``` После этого CCM повторно прочитает сертификат и обновит его на балансировщике. ## Практический пример В этом примере настроим собственный SSL-сертификат для тестового приложения Nginx. Перед началом убедитесь, что у вас есть домен и выпущенный для него сертификат от доверенного центра сертификации. ### Создание неймспейса Создайте отдельный неймспейс для тестирования: ```bash kubectl create namespace test-namespace ``` ### Создание тестового приложения Создайте файл `nginx-deployment.yaml`: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx namespace: test-namespace spec: replicas: 1 selector: matchLabels: app: nginx-custom-cert-test template: metadata: labels: app: nginx-custom-cert-test spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 ``` Примените манифест: ```bash kubectl apply -f nginx-deployment.yaml ``` Убедитесь, что под успешно запущен: ```bash kubectl get pods -n test-namespace ``` ### Создание балансировщика нагрузки Создайте файл `nginx-loadbalancer.yaml`: ```yaml apiVersion: v1 kind: Service metadata: name: nginx-loadbalancer namespace: test-namespace spec: type: LoadBalancer selector: app: nginx-custom-cert-test ports: - name: https port: 443 targetPort: 80 appProtocol: k8s.timeweb.cloud/proto-https ``` Примените манифест: ```bash kubectl apply -f nginx-loadbalancer.yaml ``` Дождитесь появления внешнего IP-адреса: ```bash kubectl get svc nginx-loadbalancer -n test-namespace -w ``` Пример вывода: ```bash NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) nginx-loadbalancer LoadBalancer 10.101.130.253 203.0.113.10 443:31826/TCP ``` ### Настройка DNS-записи Создайте A-запись для домена и направьте ее на внешний IP-адрес балансировщика. Проверьте, что домен указывает на IP-адрес балансировщика: ```bash dig +short example.com ``` Результат должен содержать IP-адрес балансировщика. ### Создание TLS-секрета Создайте TLS-секрет в том же неймспейсе, где находится сервис: ```bash kubectl -n test-namespace create secret tls my-app-tls \ --cert=crt.crt \ --key=key.key ``` Проверьте, что секрет создан корректно: ```bash kubectl -n test-namespace get secret my-app-tls -o yaml ``` В выводе должно присутствовать: ```shell type: kubernetes.io/tls ``` При необходимости можно проверить сертификат непосредственно из секрета: ```bash kubectl -n test-namespace get secret my-app-tls \ -o jsonpath='{.data.tls\.crt}' \ | base64 -d \ | openssl x509 -noout -subject -issuer -dates ``` ### Подключение сертификата к балансировщику Добавьте аннотации для использования собственного сертификата в манифест сервиса `nginx-loadbalancer.yaml`: ```yaml apiVersion: v1 kind: Service metadata: name: nginx-loadbalancer namespace: test-namespace annotations: k8s.timeweb.cloud/attached-loadbalancer-ssl: "true" k8s.timeweb.cloud/attached-loadbalancer-ssl-type: "custom" k8s.timeweb.cloud/attached-loadbalancer-ssl-fqdn: "example.com" k8s.timeweb.cloud/attached-loadbalancer-ssl-secret-name: "my-app-tls" spec: type: LoadBalancer selector: app: nginx-custom-cert-test ports: - name: https port: 443 targetPort: 80 appProtocol: k8s.timeweb.cloud/proto-https ``` Примените обновленный манифест: ```bash kubectl apply -f nginx-loadbalancer.yaml ``` Проверьте настройки сервиса: ```bash kubectl -n test-namespace get svc nginx-loadbalancer -o yaml ``` В аннотациях должны присутствовать: ```yaml k8s.timeweb.cloud/attached-loadbalancer-ssl: "true" k8s.timeweb.cloud/attached-loadbalancer-ssl-type: custom k8s.timeweb.cloud/attached-loadbalancer-ssl-fqdn: example.com k8s.timeweb.cloud/attached-loadbalancer-ssl-secret-name: my-app-tls ``` После успешной обработки сертификата появится служебная аннотация: ```bash k8s.timeweb.cloud/attached-loadbalancer-ssl-cert-hash: ... ``` Это означает, что CCM успешно прочитал сертификат из секрета. ### Проверка работы приложения Обратитесь к домену в браузере. Если сертификат успешно применен, браузер установит защищенное HTTPS-соединение без предупреждений о недоверенном сертификате. Также можно проверить доступность приложения с помощью `curl`: ```bash curl -I https://example.com ``` Успешный ответ означает, что: - сертификат загружен на балансировщик; - HTTPS-соединение устанавливается корректно; - балансировщик передает запросы в приложение, работающее в Kubernetes. ### Удаление тестового окружения После завершения проверки удалите тестовый неймспейс: ```bash kubectl delete namespace test-namespace ``` Будут удалены все созданные ресурсы, включая Deployment, Service и TLS-секрет. # Приватные и публичные сервисы Source: https://timeweb.cloud/docs/k8s/network/public-private-services?utm_source=llms_txt&utm_medium=ai Если в кластере нужно публиковать часть сервисов в интернет, а часть оставлять доступной только из приватной сети, удобнее всего разделить входящий трафик на уровне ingress-контроллеров. Для этого можно развернуть два экземпляра Traefik: один будет обслуживать публичные Ingress, второй — приватные. В этой статье разберем такой сценарий. В качестве основы будем использовать два Helm-релиза Traefik с разными `IngressClass`, а затем покажем, как маршрутизировать запросы к публичным и внутренним сервисам. Идея в том, что в кластере запускаются два независимых экземпляра Traefik: - `traefik-public` — обрабатывает только Ingress с `ingressClassName: public`; - `traefik-private` — обрабатывает только Ingress с `ingressClassName: private`. Каждый экземпляр создает собственный сервис типа `LoadBalancer`, но с разными параметрами: - публичный Traefik получает внешний IP-адрес и принимает трафик из интернета; - приватный Traefik создает внутренний балансировщик без публичного IP и доступен только внутри приватной сети. За счет этого можно использовать один и тот же кластер для внешних и внутренних приложений, не смешивая их точки входа. Перед началом убедитесь, что: - у вас [установлен helm](https://timeweb.cloud/docs/k8s/helm); - кластер Kubernetes развернут; - для проверки приватного ingress у вас есть [доступ в приватную сеть](https://timeweb.cloud/docs/vpc/managing-bgp-networks) кластера, например через отдельный VDS в той же сети. ## Подготовка конфигурации Traefik Оба экземпляра Traefik разворачиваются из одного Helm-чарта, но используют разные values-файлы. ### Конфигурация публичного Traefik Создайте файл `traefik-public-values.yaml` со следующим содержимым: ```yaml fullnameOverride: traefik-public ingressClass: enabled: true isDefaultClass: false name: public service: enabled: true type: LoadBalancer annotations: external-dns.alpha.kubernetes.io/hostname: "example.com" external-dns.alpha.kubernetes.io/ttl: "1200" providers: kubernetesCRD: enabled: true allowCrossNamespace: false ingressClass: public kubernetesIngress: enabled: true ingressClass: public publishedService: enabled: true ``` Этот файл настраивает публичный экземпляр Traefik, который будет обрабатывать ingress-ресурсы класса `public` и создавать обычный `LoadBalancer` с внешним IP. Здесь важно следующее: - `ingressClass.name: public` — задает имя класса, на который будут ссылаться публичные Ingress; - `providers.kubernetesCRD.ingressClass` и `providers.kubernetesIngress.ingressClass` — ограничивают Traefik только ресурсами своего класса; - `publishedService.enabled: true` — позволяет корректно публиковать адрес ingress-сервиса. Аннотации `external-dns.alpha.kubernetes.io/*` нужны только в том случае, если в кластере используется [external-dns](https://timeweb.cloud/docs/k8s/addons/externaldns). В значении `external-dns.alpha.kubernetes.io/hostname` нужно указать реальный домен или поддомен, который вы хотите направить на публичный `ingress`, например `app.example.com`. Если вы используете `external-dns`, DNS-запись будет создаваться автоматически. Если `external-dns` в кластере нет, эти аннотации можно убрать и создать DNS-запись вручную. В нашем примере проверка будет выполняться через `curl --resolve`. В таком случае реальные DNS-записи не обязательны. ### Конфигурация приватного Traefik Создайте файл `traefik-private-values.yaml` со следующим содержимым: ```yaml fullnameOverride: traefik-private ingressClass: enabled: true isDefaultClass: false name: private service: enabled: true type: LoadBalancer annotations: k8s.timeweb.cloud/attached-loadbalancer-no-external-ip: "true" providers: kubernetesCRD: enabled: true allowCrossNamespace: false ingressClass: private kubernetesIngress: enabled: true ingressClass: private publishedService: enabled: true ``` Этот файл настраивает приватный экземпляр Traefik, который будет обрабатывать ingress-ресурсы класса private и создавать внутренний балансировщик без публичного IP. Ключевой параметр здесь — `k8s.timeweb.cloud/attached-loadbalancer-no-external-ip: "true"`. Он указывает, что балансировщик должен быть внутренним и не получать внешний публичный IP. ## Установка двух экземпляров Traefik Сначала добавьте репозиторий Helm: ```bash helm repo add traefik https://helm.traefik.io/traefik helm repo update ``` После этого разверните публичный экземпляр: ```bash helm install traefik-public traefik/traefik \ -n traefik-public --create-namespace \ -f traefik-public-values.yaml ``` Затем разверните приватный экземпляр: ```bash helm install traefik-private traefik/traefik \ -n traefik-private --create-namespace \ -f traefik-private-values.yaml ``` После установки сразу проверьте, что оба сервиса типа LoadBalancer созданы: ```bash kubectl get svc -n traefik-public kubectl get svc -n traefik-private ``` > [!NOTE] > Создание балансировщиков может занимать до 10 минут. Пока ресурс создается, в колонке `EXTERNAL-IP` может отображаться состояние `pending`. Ожидаемое поведение будет разным: - у `traefik-public` должен появиться внешний IP-адрес; - у `traefik-private` внешний IP не появится, так как он использует внутренний балансировщик. Проверить состояние балансировщиков можно не только через `kubectl`, но и в панели управления Timeweb Cloud. Дождитесь завершения создания балансировщиков. На этом же этапе полезно убедиться, что оба класса `ingress` зарегистрированы в кластере: ```bash kubectl get ingressclass ``` В выводе должны быть классы public и private.  ## Публикация публичных и приватных сервисов После развертывания двух экземпляров Traefik достаточно указывать нужный `IngressClass` в манифесте Ingress. Для публичного сервиса: ```yaml spec: ingressClassName: public ``` Для приватного сервиса: ```yaml spec: ingressClassName: private ``` Дальше весь трафик будет маршрутизироваться через соответствующий ingress-контроллер. ## Практический пример Ниже приведен полный набор манифестов для демонстрации. В примере будут: - два публичных сервиса `service1` и `service2`; - один приватный сервис `service3`; - два ingress-ресурса с разными IngressClass. #### ConfigMap с тестовыми HTML-страницами Создайте файл `config-map.yaml`: ```shell apiVersion: v1 kind: ConfigMap metadata: name: service-config namespace: ingress-example data: service1.html: | Service 1

Welcome to Service 1!

service2.html: | Service 2

Welcome to Service 2!

service3.html: | Service 3

Welcome to Service 3!

``` #### Публичный сервис service1 Создайте файл `service1-deployment.yaml`: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: service1 namespace: ingress-example spec: replicas: 2 selector: matchLabels: app: service1 template: metadata: labels: app: service1 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: config-volume mountPath: /usr/share/nginx/html volumes: - name: config-volume configMap: name: service-config items: - key: service1.html path: service1.html --- apiVersion: v1 kind: Service metadata: name: service1 namespace: ingress-example spec: selector: app: service1 ports: - protocol: TCP port: 80 targetPort: 80 ``` #### Публичный сервис service2 Создайте файл `service2-deployment.yaml`: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: service2 namespace: ingress-example spec: replicas: 2 selector: matchLabels: app: service2 template: metadata: labels: app: service2 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: config-volume mountPath: /usr/share/nginx/html volumes: - name: config-volume configMap: name: service-config items: - key: service2.html path: service2.html --- apiVersion: v1 kind: Service metadata: name: service2 namespace: ingress-example spec: selector: app: service2 ports: - protocol: TCP port: 80 targetPort: 80 ``` #### Приватный сервис service3 Создайте файл `service3-deployment.yaml`: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: service3 namespace: ingress-example spec: replicas: 2 selector: matchLabels: app: service3 template: metadata: labels: app: service3 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: config-volume mountPath: /usr/share/nginx/html volumes: - name: config-volume configMap: name: service-config items: - key: service3.html path: index.html --- apiVersion: v1 kind: Service metadata: name: service3 namespace: ingress-example spec: selector: app: service3 ports: - protocol: TCP port: 80 targetPort: 80 ``` #### Публичный ingress Создайте файл `ingress-public.yaml`: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-public-ingress namespace: ingress-example spec: ingressClassName: public rules: - host: ingress1.example.com http: paths: - path: /service1 pathType: Prefix backend: service: name: service1 port: number: 80 - path: /service2 pathType: Prefix backend: service: name: service2 port: number: 80 ``` Обратите внимание, что в `spec.ingressClassName` указано значение `public` — это означает, что Ingress будет обрабатываться публичным ingress-контроллером. #### Приватный ingress Создайте файл `ingress-private.yaml`: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-private-ingress namespace: ingress-example spec: ingressClassName: private rules: - host: ingress2.example.com http: paths: - path: / pathType: Prefix backend: service: name: service3 port: number: 80 ``` В `spec.ingressClassName` указано значение `private`, поэтому `Ingress` будет обрабатываться приватным ingress-контроллером. Создайте неймспейс `ingress-example`: ```bash kubectl create namespace ingress-example ``` После этого примените все манифесты: ```bash kubectl apply -f config-map.yaml kubectl apply -f service1-deployment.yaml kubectl apply -f service2-deployment.yaml kubectl apply -f service3-deployment.yaml kubectl apply -f ingress-public.yaml kubectl apply -f ingress-private.yaml ``` Теперь проверьте, что деплойменты, сервисы и ingress-ресурсы созданы: ```bash kubectl get deploy,svc,ingress -n ingress-example ``` В результате вы должны увидеть три сервиса, три деплоймента и два ingress-ресурса. Если какого-то ресурса нет, значит соответствующий манифест не применился или был изменен. Запросы к `ingress1.example.com/service1...` будут попадать в `service1`, а запросы к `ingress1.example.com/service2...` — в `service2`. Запросы к `ingress2.example.com/` будут попадать в `service3`. Такой сервис будет доступен только из приватной сети, если запрос приходит через внутренний балансировщик Traefik. ## Проверка работы Перед проверкой запросами полезно еще раз посмотреть, какой класс назначен каждому ingress: ```bash kubectl describe ingress example-public-ingress -n ingress-example kubectl describe ingress example-private-ingress -n ingress-example ``` Убедитесь, что у `example-public-ingress` указан `Ingress Class: public`, а у `example-private-ingress` — `Ingress Class: private`. Если класс не совпадает, Traefik не будет обрабатывать такой ресурс. > [!NOTE] > В примере используются имена `ingress1.example.com` и `ingress2.example.com`. Это условные хосты. Для проверки через `curl --resolve` их можно использовать без настройки реального DNS. Если вы хотите открывать публичный `ingress` в браузере, замените `ingress1.example.com` на реальный домен или поддомен и настройте для него DNS-запись. Когда публичный балансировщик получит внешний IP, проверьте маршруты командами: ```bash curl http://ingress1.example.com/service1.html \ --resolve ingress1.example.com:80:PUBLIC_LB_EXTERNAL_IP curl http://ingress1.example.com/service2.html \ --resolve ingress1.example.com:80:PUBLIC_LB_EXTERNAL_IP ``` Где `PUBLIC_LB_EXTERNAL_IP` — публичный IP, выделенный для балансировщика. Если в ответ приходит `404`, проверьте, что вы используете именно хост `ingress1.example.com` и пути `/service1` или `/service2`.  Для приватного сервиса выполните проверку с машины, которая находится в той же приватной сети, что и кластер: ```bash curl http://ingress2.example.com/ \   --resolve ingress2.example.com:80:PRIVATE_LB_IP ``` Где `PRIVATE_LB_IP` — приватный IP балансировщика. В ответ вы должны получить HTML-страницу `service3`. Если приватный маршрут не открывается, проверьте, что запрос идет из приватной сети. Внешний интернет-трафик на такой `ingress` не попадет, даже если сам ресурс в кластере настроен правильно. # Виртуальные роутеры Source: https://timeweb.cloud/docs/k8s/network/virtual-routers-in-kubernetes?utm_source=llms_txt&utm_medium=ai Виртуальный роутер позволяет организовать сетевую архитектуру Kubernetes-кластера без использования публичных IP-адресов на воркер-нодах. В этом случае внешний доступ к сервисам настраивается централизованно — через Ingress или балансировщики нагрузки. Основные преимущества: - Экономия — воркеры не используют публичные IP. - Повышенная безопасность — нет прямого доступа к воркер-нодам из интернета. - Централизованная точка входа — внешний трафик проходит только через балансировщики или Ingress. - Более гибкая архитектура — воркер-ноды не привязаны к внешним IP и могут пересоздаваться без изменения сетевой схемы. При такой конфигурации инфраструктура становится более декларативной: сетевые правила и точки входа описываются на уровне кластера, а сами ноды остаются «эфемерными» ресурсами. ## Ограничения Перед настройкой обратите внимание на ограничения и особенности работы виртуальных роутеров: - Поддержка доступна только в локациях Санкт-Петербург, Москва и Амстердам. - К одному кластеру может быть подключен только один виртуальный роутер. - Один виртуальный роутер может использоваться несколькими Kubernetes-кластерами, если они находятся в одной приватной сети. - Роутер и кластер должны находиться в одной приватной сети. - В настройках виртуального роутера должен быть [включен DHCP для приватной сети](https://timeweb.cloud/docs/virtual-routers/usage-dhcp). - У виртуального роутера должен быть подключен публичный IP и настроен NAT для приватной сети. - Для каждой группы воркер-нод обязательно должен быть выбран один из вариантов сетевого подключения: использование публичных IP или использование виртуального роутера. ## Подключение роутера при создании кластера Вы можете подключить виртуальный роутер на этапе создания нового кластера. Опция «Публичный IP» на этапе конфигурации воркер-нод отключена по умолчанию. Если оставить ее выключенной, на этапе настройки сети появится возможность выбрать существующий виртуальный роутер или создать новый. Если в выбранной приватной сети нет подходящего роутера, он будет создан автоматически. При необходимости вы можете изменить параметры нового роутера, нажав кнопку «Изменить параметры». ![Scr 20260216 Omug](https://content.timeweb.com/assets/744223bc-cff8-488a-8e24-89e05bc7678a.png?width=1120&height=1196) Если при настройке кластера выбран новый роутер, создание кластера может занять немного больше времени — сначала будет создан виртуальный роутер, и только после этого начнется развертывание кластера. ## Подключение роутера к существующему кластеру Чтобы подключить виртуальный роутер к уже созданному кластеру, перейдите во вкладку «Сеть». В строке «Интеграция с роутерами» нажмите кнопку «Подключить». ![Scr 20260216 Onan](https://content.timeweb.com/assets/148e575f-b04f-49a5-b389-48ba637ae2ac.png?width=2086&height=1486) В открывшемся меню можно создать новый виртуальный роутер и сразу привязать его к кластеру либо выбрать уже существующий. В списке будут доступны только те роутеры, которые соответствуют требованиям: к ним подключен публичный IP, они находятся в одной приватной сети с кластером, а для этой сети включен DHCP. После подтверждения настроек роутер будет подключен к кластеру и станет доступен для использования в группах воркер-нод. ![Scr 20260216 Ongh](https://content.timeweb.com/assets/80df61aa-5c2f-4f46-9f89-b3863a4715de.png?width=2568&height=1654) ## Работа с воркер-нодами К кластеру может быть подключен только один виртуальный роутер, но способ сетевого подключения настраивается отдельно для каждой группы воркер-нод. Вы можете выбрать: использовать виртуальный роутер или назначать публичный IP каждому воркеру. Для изменения настроек откройте вкладку «Ресурсы». Начните создание новой группы, нажав «Добавить группы», либо откройте параметры существующей группы — нажмите на три точки рядом с нужной группой и выберите «Редактировать группу». В открывшемся меню доступна настройка «Публичный IP». Если отключить ее, группа будет использовать виртуальный роутер. Если роутер еще не был подключен к кластеру, он создастся автоматически. Если включить «Публичный IP», виртуальный роутер для этой группы использоваться не будет, а каждой воркер-ноде будет назначен собственный публичный адрес. ![Scr 20260219 Murj](https://content.timeweb.com/assets/9cd34a31-e960-4222-a33a-a5edbf09c890.png?width=2070&height=1534) ## Доступ к сервисам через проброс портов Если кластер подключен к приватной сети вместе с виртуальным роутером, можно организовать внешний доступ к сервису без использования Ingress или балансировщика — через проброс портов на роутере. В этом случае входящий трафик из интернета сначала поступает на публичный IP виртуального роутера, затем на указанный на нем порт и перенаправляется на приватный IP одной из воркер-нод. Далее запрос попадает на порт `NodePort`, открытый Kubernetes-сервисом, и обрабатывается приложением. Для такой схемы кластер и виртуальный роутер должны находиться в одной приватной сети, при этом к роутеру должен быть подключен публичный IP и настроен доступ к приватным IP воркер-нод. В кластере должен быть создан сервис с типом `NodePort`, а на самом роутере — правило проброса порта на выбранную ноду и соответствующий порт сервиса. При настройке стоит учитывать, что проброс выполняется на конкретную ноду. Если она станет недоступна, внешний доступ к сервису также перестанет работать. ### Пример использования Рассмотрим пример настройки. Создадим простой сервис и настроим к нему доступ из интернета через виртуальный роутер. Для удобства создадим отдельный namespace, в котором будут находиться все ресурсы: ```bash kubectl create namespace port-forward-example ``` Создадим `ConfigMap` со статической HTML-страницей. Файл `config-map.yaml`: ```yaml apiVersion: v1 kind: ConfigMap metadata: name: service-config namespace: port-forward-example data: index.html: | Demo Page

Hello from Kubernetes!

This is a static page served on port 30000.

``` Далее создадим `DaemonSet` и сервис. Файл `daemon-set.yaml`: ```yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: service namespace: port-forward-example spec: selector: matchLabels: app: service template: metadata: labels: app: service spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: config-volume mountPath: /usr/share/nginx/html volumes: - name: config-volume configMap: name: service-config items: - key: index.html path: index.html --- apiVersion: v1 kind: Service metadata: name: service namespace: port-forward-example spec: selector: app: service ports: - port: 80 targetPort: 80 nodePort: 30000 type: NodePort ``` В этом примере используется `DaemonSet`, чтобы поды запускались на каждой воркер-ноде, а сервис с типом `NodePort` открывает порт `30000` на всех нодах кластера. Применим манифесты: ```bash kubectl apply -f config-map.yaml kubectl apply -f daemon-set.yaml ``` Проверим, что поды успешно запущены: ```bash kubectl get pods -n port-forward-example ``` После этого в панели управления виртуальным роутером настройте проброс порта: 1. Перейдите в раздел «Проброс портов». 2. Выберите публичный IP и укажите внешний порт. 3. В качестве приватного IP укажите IP одной из воркер-нод. 4. Укажите порт `30000` (NodePort сервиса). 5. Сохраните правило. ![Scr 20260323 Oqju](https://content.timeweb.com/assets/3a05ce3d-6802-4352-aa5a-fab75bb5d8ff.png?width=2494&height=1658) После сохранения правило появится в списке, где будут отображаться публичный IP и внешний порт. ![Scr 20260323 Osjr](https://content.timeweb.com/assets/784f6c35-162e-49ea-9d04-e1b49ee549df.png?width=2070&height=1592) Для проверки откройте в браузере указанный IP и порт — должна отобразиться страница с текстом «Hello from Kubernetes!». ## Удаление виртуального роутера Перед удалением виртуального роутера необходимо отвязать его от кластера. Пока роутер используется хотя бы одной группой воркер-нод, возможность удаления в панели управления будет недоступна. Перейдите во вкладку «Ресурсы». Для каждой группы нажмите на три точки рядом с ее названием, выберите «Редактировать группу» и включите параметр «Публичный IP». После этого виртуальный роутер перестанет использоваться выбранной группой. Повторите действие для всех групп воркер-нод, в которых он был задействован. Перейдите во вкладку «Ресурсы». Для удаления нажмите на три точки рядом с нужной группой и выберите «Удалить». Повторите действие для всех групп воркер-нод, использующих виртуальный роутер. Когда роутер больше не используется воркерами, вернитесь во вкладку «Сеть». В строке «Интеграция с роутерами» станет активной кнопка «Отвязать» — нажмите ее, чтобы отключить роутер от кластера. ![Scr 20260216 Olco](https://content.timeweb.com/assets/481fd37c-c9c2-4d7c-90bf-e7e92b77975d.png?width=2112&height=1478) После отвязки откройте раздел «Сети» → «Роутеры», нажмите на три точки рядом с нужным роутером и выберите «Удалить». Кнопка удаления станет доступной сразу после отключения интеграции с кластером. ![Scr 20260216 Olne](https://content.timeweb.com/assets/21fbfaea-8e3b-44a7-9547-04bb8b147484.png?width=2092&height=1478) # Подключение сетевых дисков Source: https://timeweb.cloud/docs/k8s/network-drives-connection?utm_source=llms_txt&utm_medium=ai [Сетевые диски](https://timeweb.cloud/docs/network-drives) удобны для размещения данных, которые должны быть доступны между запусками подов или использовать на разных узлах. Они подходят для баз данных, резервного копирования, масштабирования хранилища по мере необходимости и изоляции данных между приложениями. > [!NOTE] > При использовании сетевых дисков в кластере действуют [те же ограничения](https://timeweb.cloud/docs/network-drives#ogranicheniya-setevyh-diskov), что и при использовании дисков с облачными серверами. Доступность сетевых дисков зависит от региона кластера: в Санкт-Петербурге доступны NVMe- и HDD-диски, в Москве — только NVMe-диски. CSI-драйвер сетевых дисков предназначен для интеграции сетевых дисков с кластером Kubernetes. Этот драйвер состоит из двух ключевых компонентов: 1. **Контроллер**: Отвечает за взаимодействие с API. Его задачи включают создание, удаление и изменение размера сетевых дисков. 2. **Node-агент**: Работает на каждом узле кластера и выполняет задачи, связанные с монтированием и управлением дисками на уровне операционной системы. Это включает запросы к API для монтирования или отмонтирования дисков, их форматирование в файловую систему `ext4` и, при необходимости, изменение размеров. Основные особенности драйвера: 1. Диски автоматически форматируются в `ext4`. 2. Драйвер поддерживает только режим `ReadWriteOnce`. Это означает, что один диск может быть подключен к одной ноде. При этом все поды на ноде будут иметь доступ к диску. Чтобы использовать сетевые диски в кластере, необходимо установить CSI-драйвер. Рассмотрим, как это сделать. ## Установка драйвера CSI Установить CSI-драйвер можно через панель управления кластером в разделе «Дополнения» или вручную — с помощью Helm. Рассмотрим оба варианта установки. > [!NOTE] > Для работы драйвера требуется 250 миллиядер и 250 МБ ОЗУ на каждой воркер-ноде. Кроме того, на одной из нод должно быть доступно еще 450 миллиядер и 626 МБ ОЗУ. Через панель управления В панели управления перейдите в раздел «Дополнения» и нажмите на дополнение «CSI-driver». ![Scr 20250818 Lolf](https://content.timeweb.com/assets/7182bc53-b204-45bf-ab07-8f1a42a79f59.png?width=1982&height=1436) В открывшемся окне нажмите кнопку «Установить». ![Scr 20250818 Lpck](https://content.timeweb.com/assets/57c915e6-ff05-4775-8f23-da0329457a7a.png?width=2006&height=1098) Дождитесь завершения установки. Через Helm Создайте файл `values.yaml` и добавьте следующие параметры: ```yml # Токен с доступом к сетевым дискам + кластерам k8s TW_API_SECRET: "токен" # ID из панели TW_CLUSTER_ID: "1000000" provisionerName: network-drives.csi.timeweb.cloud # plugin container image options image: # image name repository: cr-internal.twcstorage.ru/network-drives-csi/driver   # image tag tag: 2 # image pull policy pullPolicy: Always # Node service options node: # node service log level logLevel: debug # force logs as json logJson: true # Controller service options controller: # controller replica count replicas: 1 # controller node selector nodeSelector: {} # controller toleration options tolerations: [] # RBAC options rbac: createRoles: true createServiceAccounts: true # metrics options metrics: podMonitor: enabled: false port: metrics path: /metrics interval: 60s ``` - `TW_API_SECRET` — токен доступа к API Timeweb Cloud. Получить токен можно в панели управления на странице «[API и Terraform](https://timeweb.cloud/my/api-keys)». - `TW_CLUSTER_ID` — ID Kubernetes-кластера. Это значение можно найти в URL страницы с информацией о вашем кластере в панели управления. ![Selection 141](https://content.timeweb.com/assets/235e7faf-4ff8-49b7-94e8-3f7e0d41d2ba.png?width=1354&height=615) Установите CSI-драйвер при помощи Helm: ```shell helm install csi-tw-helm oci://cr-internal.twcstorage.ru/network-drives-csi/csi-driver-timeweb-cloud \ -f values.yaml \ --namespace csi-driver-timeweb-cloud \ --create-namespace ``` Если необходимо установить конкретную версию драйвера, добавьте параметр `--version`: ```shell helm install csi-tw-helm oci://cr-internal.twcstorage.ru/network-drives-csi/csi-driver-timeweb-cloud \ -f values.yaml \ --namespace csi-driver-timeweb-cloud \ --create-namespace \ --version 1.0.0 ``` После установки убедитесь, что все поды в неймспейсе `csi-driver-timeweb-cloud` работают: ```shell kubectl get pods -n csi-driver-timeweb-cloud ``` Проверьте, что драйвер зарегистрирован: ```shell kubectl get csidrivers ``` Вывод должен быть примерно таким: ```shell NAME ATTACHREQUIRED PODINFOONMOUNT STORAGECAPACITY TOKENREQUESTS REQUIRESREPUBLISH MODES AGE network-drives.csi.timeweb.cloud false true true false Persistent 22h ``` ## Обновление драйвера Способ актуален как при установке драйвера через Helm, так и при установке через панель управления кластером. Для обновления необходимо удалить текущий CSI-драйвер и установить его заново. После обновления подключенные сетевые диски продолжат работать в штатном режиме — повторное подключение не требуется. Если драйвер устанавливался при помощи Helm, выполните удаление с помощью `kubectl`: ```shell kubectl delete -n csi-driver-timeweb-cloud csidriver network-drives.csi.timeweb.cloud ``` Если драйвер устанавливался через панель управления, перейдите в раздел «Дополнения» и кликните по карточке «CSI-driver». После этого нажмите кнопку «Удалить». ![Scr 20250922 Mzuv](https://content.timeweb.com/assets/b40fc15e-b3dc-41fc-a6a3-a593ca32d116.png?width=2000&height=1402) После удаления драйвера [установите его](https://timeweb.cloud/docs/k8s/network-drives-connection#ustanovka-drajvera-csi) заново. Рекомендуем использовать установку через панель управления. ## Создание диска при помощи манифеста Создание диска с использованием CSI-драйвера в Kubernetes начинается с создания `PersistentVolumeClaim` (PVC). Это запрос на предоставление тома с заданными параметрами, такими как размер, режим доступа и класс хранилища. Для начала создайте файл `pvc.yaml`, в котором нужно указать параметры PVC. Пример содержимого файла: ```yml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-nvme namespace: default spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: nvme.network-drives.csi.timeweb.cloud ``` В параметрах `PersistentVolumeClaim` указываются следующие значения: - `name` — имя вашего PVC. - `namespace` — пространство имен, где будет создан запрос. - `storage` — размер диска (минимальный размер — 1 ГБ). - `storageClassName` — класс хранилища: - `nvme.network-drives.csi.timeweb.cloud` — для NVMe-дисков, - `hdd.network-drives.csi.timeweb.cloud` — для HDD. О различиях между типами сетевых дисков вы можете прочитать в [этой статье](https://timeweb.cloud/docs/network-drives#tipy-setevyh-diskov). Учитывайте регион кластера: в Санкт-Петербурге доступны NVMe- и HDD-диски, в Москве — только NVMe-диски. После того, как манифест подготовлен, примените его с помощью команды: ```shell kubectl apply -f pvc.yaml ``` Чтобы расширить диск, измените значение параметра `storage` и повторно примените манифест. Это можно сделать в любой момент. Стоит учесть, что сам диск на этом этапе еще не будет создан. Он будет создан только тогда, когда PVC будет связан с работающим подом. Теперь создадим под, который будет использовать созданный PVC. Рассмотрим пример пода с Nginx, подключающим диск в качестве тома. Для этого создайте файл `nginx-pod.yaml`: ```yml apiVersion: v1 kind: Pod metadata: name: nginx-pvc namespace: default spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: nginx-storage mountPath: /usr/share/nginx/html volumes: - name: nginx-storage persistentVolumeClaim: claimName: pvc-nvme ``` В этом файле описывается под, в котором Nginx использует том для размещения данных: - `volumes` — задается подключение тома через PVC, который был создан ранее. - `claimName` — должно совпадать с именем PVC. - `volumeMounts` — указывается, куда именно в файловой системе контейнера будет подключен том (в данном случае — `/usr/share/nginx/html`). Примените манифест с помощью команды: ```shell kubectl apply -f nginx-pod.yaml ``` Убедитесь, что PVC создан и находится в статусе `Bound`: ```shell kubectl get pvc pvc-nvme ``` Вы должны увидеть подобный вывод: ```shell NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE pvc-nvme Bound pvc-a3a43b9e-6a1a-43e6-b218-3ff7d49b97b5 1Gi RWO nvme.network-drives.csi.timeweb.cloud 11s ``` Проверьте состояние пода: ```shell kubectl get pods nginx-pvc ``` Пример вывода: ```shell NAME READY STATUS RESTARTS AGE nginx-pvc 1/1 Running 0 2m17s ``` Если под или PVC не создаются, проверьте ошибки в `Events`: Для PVC: ```shell kubectl describe pvc pvc-nvme ``` Для пода: ```shell kubectl describe pod nginx-pvc ``` Обратите внимание, что при удалении PVC диск будет удален из панели управления. Если вы хотите предотвратить это, необходимо [создать сетевой диск](https://timeweb.cloud/docs/network-drives#sozdanie-setevogo-diska) в панели управления и подключить его по инструкции ниже. ## Увеличение объема диска Для увеличения объема существующего диска необходимо обновить манифест `PersistentVolumeClaim`. В нашем примере откройте файл `pvc.yaml` и измените значение в поле `spec.resources.requests.storage`. Например, чтобы указать 3 ГБ, манифест должен выглядеть так: ```yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-nvme namespace: default spec: accessModes: - ReadWriteOnce resources: requests: storage: 3Gi storageClassName: nvme.network-drives.csi.timeweb.cloud ``` Сохраните изменения и примените обновленный манифест командой: ```shell kubectl apply -f pvc.yaml ``` ## Подключение существующего диска к кластеру Если у вас уже есть сетевой диск, который нужно подключить к Kubernetes, вам потребуется описать `PersistentVolume` (PV). Это действие связывает диск с кластером и позволяет использовать его в подах. Однако важно учитывать, что если на диске ранее были созданы разделы, они будут удалены. Kubernetes не работает с разделами и использует диск как единое пространство. Создайте файл `pv-existing-disk.yaml` с описанием PV: ```yml apiVersion: v1 kind: PersistentVolume metadata: name: existing-disk-pv spec: capacity: storage: 10Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain csi: driver: network-drives.csi.timeweb.cloud volumeHandle: 0df2e9fc-ad17-414b-9e4c-373bbd0479cb fsType: ext4 storageClassName: nvme.network-drives.csi.timeweb.cloud ``` Что здесь важно: - `storageClassName` — выберите класс хранения, соответствующий типу вашего диска. Для NVMe-дисков используйте `nvme.network-drives.csi.timeweb.cloud`, для HDD — `hdd.network-drives.csi.timeweb.cloud`. - `persistentVolumeReclaimPolicy: Retain` — предотвращает удаление диска, если PVC будет удален. - `fsType` — файловая система, которая будет использоваться. - `volumeHandle` — это идентификатор диска. Чтобы его узнать, откройте раздел «[Сетевые диски](https://timeweb.cloud/my/network-drives)» в панели управления, выберите нужный диск и скопируйте `UUID` из URL страницы.  ![Selection 142](https://content.timeweb.com/assets/7c9c5a50-4bef-4f9c-ba36-b716ad445b8b.png?width=1311&height=688) После описания PV нужно создать PVC, чтобы связать этот диск с подами. Создайте файл `pvc-existing-disk.yaml`: ```yml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: existing-disk-pvc spec: volumeMode: Filesystem accessModes: - ReadWriteOnce resources: requests: storage: 10Gi volumeName: existing-disk-pv storageClassName: nvme.network-drives.csi.timeweb.cloud ``` В этом манифесте обратите внимание на следующие поля: - `volumeName` — должно точно совпадать с именем PV, созданного ранее. - `storageClassName` — должно соответствовать значению, указанному в PV. - `resources.requests.storage` — укажите размер диска, равный значению, указанному в PV. Примените манифесты с помощью команд: ```shell kubectl apply -f pv-existing-disk.yaml kubectl apply -f pvc-existing-disk.yaml ``` Теперь PVC готов к использованию. Чтобы проверить, что диск подключен корректно, создайте тестовый под, который запишет файл на диск. Для этого подготовьте файл `write-file-pod.yaml`: ```yml apiVersion: v1 kind: Pod metadata: name: write-to-existing-disk spec: containers: - name: writer image: busybox command: ["/bin/sh", "-c"] args: ["echo 'Hello, Timeweb Cloud!' > /mnt/data/hello.txt && sleep 3600"] volumeMounts: - name: existing-disk-storage mountPath: /mnt/data volumes: - name: existing-disk-storage persistentVolumeClaim: claimName: existing-disk-pvc ``` Примените манифест пода: ```shell kubectl apply -f write-file-pod.yaml ``` Когда под запустится, проверьте содержимое файла, записанного на диск. Для этого выполните команду: ```shell kubectl exec -it write-to-existing-disk -- cat /mnt/data/hello.txt ``` В выводе вы должны увидеть: ```shell Hello, Timeweb Cloud! ``` Если вы хотите проверить содержимое диска вне Kubernetes, отключите его от кластера через панель управления, подключите к серверу и [примонтируйте диск](https://timeweb.cloud/docs/unix-guides/adding-removing-disk#montirovanie-diska). Убедитесь, что монтируете весь диск, а не его разделы, так как они не создаются при использовании Kubernetes. После монтирования в корне диска вы найдете файл `hello.txt`. # Реестр контейнеров Source: https://timeweb.cloud/docs/k8s/container-registry?utm_source=llms_txt&utm_medium=ai Реестр контейнеров (Container Registry) — это хранилище для Docker-образов и OCI-артефактов. В реестре можно хранить, распространять и использовать образы приложений для Kubernetes и других окружений. - [Создание реестра контейнеров](https://timeweb.cloud/docs/k8s/container-registry/create-registry) - [Интерфейс реестра контейнеров](https://timeweb.cloud/docs/k8s/container-registry/interface) - [Работа с Docker-образами](https://timeweb.cloud/docs/k8s/container-registry/docker-images) - [Использование реестра в Kubernetes](https://timeweb.cloud/docs/k8s/container-registry/kubernetes) - [Управление реестром с помощью regctl](https://timeweb.cloud/docs/k8s/container-registry/regctl) - [Загрузка Helm-чартов и OCI-артефактов](https://timeweb.cloud/docs/k8s/container-registry/helm-charts) # Создание реестра контейнеров Source: https://timeweb.cloud/docs/k8s/container-registry/create-registry?utm_source=llms_txt&utm_medium=ai Реестр контейнеров создается в панели управления. 1. Перейдите в раздел «Kubernetes» во вкладку «Реестры контейнеров». 2. Нажмите «Создать» или «Добавить». 3. Укажите параметры реестра: - - регион размещения; - объем хранилища; - имя реестра; - проект. Имя реестра должно быть уникальным. Используйте строчные латинские буквы, цифры и дефисы. Пробелы в имени не поддерживаются. Объем хранилища можно увеличить после создания реестра. Уменьшить объем нельзя. ![Интерфейс создания реестра контейнеров](https://content.timeweb.com/assets/b20c6a47-ad01-4015-9f45-023f8cb971bc.png?width=2172&height=1834) После создания реестра отобразится токен для авторизации. Токен показывается только один раз, поэтому сохраните его сразу. ![Токен для доступа к реестру контейнеров](https://content.timeweb.com/assets/3ea46d4f-7599-4028-8343-6e3b49563442.png?width=2154&height=1886) При потере токена, выпустите новый в разделе «[API и Terraform](https://timeweb.cloud/my/api-keys)». Токен, созданный при создании реестра, начинается с `registry-`. Обратите внимание: - токен для всех проектов дает доступ ко всем реестрам аккаунта; - токен для конкретного проекта дает доступ ко всем реестрам внутри этого проекта; - если токен был скомпрометирован, удалите его в разделе «[API и Terraform](https://timeweb.cloud/my/api-keys)». # Интерфейс реестра контейнеров Source: https://timeweb.cloud/docs/k8s/container-registry/interface?utm_source=llms_txt&utm_medium=ai После создания реестра в панели управления доступны вкладки «Дашборд», «Репозитории», «Настройки» и «История». ## Дашборд На дашборде отображаются: - занятый объем хранилища; - использование входящего и исходящего трафика; - команда для авторизации в реестре. ![Дашборд реестра контейнеров](https://content.timeweb.com/assets/03f09b5e-9db8-454a-9a80-073fcd7c9e19.png?width=2130&height=1852) ## Репозитории Во вкладке «Репозитории» отображаются: - список всех репозиториев в реестре; - образы внутри каждого репозитория; - теги и хэши образов. ![Scr 20260708 Nyim](https://content.timeweb.com/assets/9cea1d2d-591e-465b-ba61-ba516043b075.png?width=2170&height=1616) При нажатии на три точки рядом с образом или репозиторием можно: - удалить образ; - удалить весь репозиторий. ## Настройки В настройках можно изменить объем хранилища. Для этого нажмите «Изменить размер реестра», выберите новый объем и сохраните изменения. Уменьшить размер реестра нельзя. Также в настройках можно изменить проект, к которому относится реестр. ![Настройка реестра контейнеров](https://content.timeweb.com/assets/26dfb490-5be0-4acb-ac43-e7b6d3a09036.png?width=2172&height=1628) ## История Во вкладке «История» отображаются действия, выполненные с реестром. # Работа с Docker-образами Source: https://timeweb.cloud/docs/k8s/container-registry/docker-images?utm_source=llms_txt&utm_medium=ai В реестр контейнеров можно загружать и скачивать Docker-образы через Docker CLI. ## Авторизация Для авторизации используйте команду, указанную на дашборде реестра: ```bash docker login имя_реестра.registry.twcstorage.ru ``` После выполнения команды: - в качестве имени пользователя укажите любое значение, например имя реестра; - при запросе пароля введите токен, полученный при создании реестра. ## Загрузка образа Перед загрузкой назначьте образу тег, который включает адрес реестра и имя репозитория: ```bash docker tag имя_образа:тег имя_реестра.registry.twcstorage.ru/имя_репозитория/имя_образа:тег ``` Замените: - `имя_образа` — на название локального образа; - `имя_реестра` — на имя, указанное при создании реестра; - `имя_репозитория` — на имя репозитория; - `тег` — на нужный тег, например `v1.0.0` или `latest`. Если указать имя несуществующего репозитория, он будет создан автоматически. После тегирования загрузите образ: ```bash docker push имя_реестра.registry.twcstorage.ru/имя_репозитория/имя_образа:тег ``` ## Скачивание образа Скачать образ можно по тегу: ```bash docker pull имя_реестра.registry.twcstorage.ru/имя_репозитория/имя_образа:тег ``` Или по хешу: ```bash docker pull имя_реестра.registry.twcstorage.ru/имя_репозитория@sha256:хеш ``` # Использование реестра в Kubernetes Source: https://timeweb.cloud/docs/k8s/container-registry/kubernetes?utm_source=llms_txt&utm_medium=ai Чтобы использовать реестр контейнеров в Kubernetes-кластере, создайте секрет с данными для подключения. Это можно сделать через панель управления. ## Подключение реестра к кластеру 1. Откройте кластер в панели управления. 2. Перейдите во вкладку «Управление». 3. Нажмите «Изменить» напротив строки «Нет подключенных реестров». 4. Выберите существующий реестр или создайте новый. 5. Укажите неймспейс, в котором будет размещен секрет. 6. Нажмите «Сохранить». ![Подключение реестра контейнеров к k8s](https://content.timeweb.com/assets/bcf3732f-20e7-4b19-972a-8260f6c5a395.png?width=2792&height=1802) Использовать реестр можно только в том неймспейсе, к которому он подключен. После сохранения в кластере будет создан секрет. Повторно открыв меню подключения реестра, вы увидите имя созданного секрета. ## Проверка секрета Проверьте наличие секрета: ```bash kubectl get secrets -n ``` Где `` — неймспейс, выбранный при подключении реестра. Пример вывода: ```bash NAME TYPE DATA AGE craas-doc kubernetes.io/dockerconfigjson 1 4m19s ``` ## Использование образа в манифесте Чтобы использовать образ из реестра, укажите его в манифесте и добавьте `imagePullSecrets`: ```yaml apiVersion: v1 kind: Pod metadata: name: test-hello-go spec: containers: - name: hello image: doc.registry.twcstorage.ru/go/hello-go:1.0.0 imagePullSecrets: - name: craas-doc ``` # Управление реестром с помощью regctl Source: https://timeweb.cloud/docs/k8s/container-registry/regctl?utm_source=llms_txt&utm_medium=ai Управлять реестром контейнеров можно не только через панель управления, но и с помощью сторонних CLI-утилит. Одна из таких утилит — [regctl](https://github.com/regclient/regclient), кроссплатформенная утилита для работы с реестрами. ## Установка Скачайте бинарный файл: ```bash curl -L https://github.com/regclient/regclient/releases/latest/download/regctl-linux-amd64 -o regctl ``` Сделайте файл исполняемым: ```bash chmod +x regctl ``` Переместите файл в системную директорию: ```bash sudo mv regctl /usr/local/bin/regctl ``` Проверьте установку: ```bash regctl version ``` ## Авторизация Для авторизации выполните команду: ```bash regctl registry login имя_реестра.registry.twcstorage.ru \ --user имя_пользователя \ --pass токен ``` Где: - `имя_реестра` — имя, указанное при создании реестра; - `имя_пользователя` — любое значение; - `токен` — токен, выданный при создании реестра. После выполнения команды данные будут сохранены в `~/.regctl/config.json`, и повторная авторизация не потребуется. ## Команды Получить список всех доступных команд: ```bash regctl ``` Вывести список всех репозиториев: ```bash regctl repo ls имя_реестра.registry.twcstorage.ru ``` Просмотреть теги образа: ```bash regctl tag ls имя_реестра.registry.twcstorage.ru/имя_репозитория/имя_образа ``` Получить информацию об образе: ```bash regctl image inspect имя_реестра.registry.twcstorage.ru/имя_репозитория/имя_образа:тег ``` Удалить образ: ```bash regctl image rm имя_реестра.registry.twcstorage.ru/имя_репозитория/имя_образа:тег ``` # Загрузка Helm-чартов и OCI-артефактов Source: https://timeweb.cloud/docs/k8s/container-registry/helm-charts?utm_source=llms_txt&utm_medium=ai Реестр контейнеров поддерживает спецификацию [OCI (Open Container Initiative)](https://opencontainers.org/). Поэтому в реестре можно хранить не только Docker-образы, но и другие артефакты, например Helm-чарты. Для загрузки Helm-чартов можно использовать [helm](https://timeweb.cloud/docs/k8s/deploy/helm) или стороннюю утилиту [oras](https://oras.land/). ## Через Helm Поддержка работы с OCI-реестрами появилась в Helm начиная с версии `3.8.0` и считается стабильной с `3.9.0`. #### Авторизация Для авторизации используйте команду: ```bash helm registry login имя_реестра.registry.twcstorage.ru -u iam ``` В качестве пароля укажите токен, выданный при создании реестра. #### Упаковка чарта Перед загрузкой упакуйте чарт: ```bash helm package ./имя_чарта ``` В результате будет создан архив, например `mychart-0.1.0.tgz`. Имя файла формируется на основе названия и версии из файла `Chart.yaml`. #### Загрузка чарта Для загрузки чарта используйте команду: ```bash helm push имя_запакованного_чарта oci://имя_реестра.registry.twcstorage.ru/имя_репозитория ``` Helm автоматически определит имя чарта и версию из архива. #### Скачивание чарта Для скачивания чарта выполните: ```bash helm pull oci://имя_реестра.registry.twcstorage.ru/имя_репозитория/имя_чарта --version тег ``` ## Через oras `oras` позволяет загружать любые файлы как OCI-артефакты. #### Установка Перейдите [на страницу релизов](https://github.com/oras-project/oras/releases?roistat_visit=12470716) oras и скачайте архив для нужной операционной системы. Для Linux можно скачать архив через `wget`: ```bash wget https://github.com/oras-project/oras/releases/download/v1.2.3/oras_1.2.3_linux_amd64.tar.gz ``` Распакуйте архив: ```bash tar -xvzf oras_1.2.3_linux_amd64.tar.gz ``` Переместите бинарный файл: ```bash sudo mv oras /usr/local/bin/ ``` Проверьте установку: ```bash oras version ``` #### Авторизация Перед использованием авторизуйтесь в реестре: ```bash oras login имя_реестра.registry.twcstorage.ru ``` После выполнения команды: - в качестве имени пользователя укажите любое значение, например имя реестра; - при запросе пароля введите токен, полученный при создании реестра. #### Загрузка чарта Перед загрузкой упакуйте чарт: ```bash helm package ./имя_чарта ``` Загрузите архив в реестр: ```bash oras push имя_реестра.registry.twcstorage.ru/имя_репозитория/имя_чарта:тег имя_запакованного_чарта ``` Проверьте, что артефакт успешно загружен: ```bash oras manifest fetch имя_реестра.registry.twcstorage.ru/имя_репозитория/имя_чарта:тег ``` Команда выведет OCI-манифест с типом артефакта, размером, хешем и другими метаданными. #### Скачивание Для скачивания артефакта выполните: ```bash oras pull имя_реестра.registry.twcstorage.ru/helm/mychart:1.0 ``` Артефакт будет загружен в текущую директорию. # Развертывание приложений Source: https://timeweb.cloud/docs/k8s/deploy?utm_source=llms_txt&utm_medium=ai - [Использование Helm](https://timeweb.cloud/docs/k8s/deploy/helm) - [Создание Helm-чарта](https://timeweb.cloud/docs/k8s/deploy/helm-chart-creation) # Использование Helm Source: https://timeweb.cloud/docs/k8s/deploy/helm?utm_source=llms_txt&utm_medium=ai Helm — это инструмент для управления Kubernetes-приложениями, упрощающий развертывание, обновление и обслуживание сложных приложений, состоящих из множества Kubernetes-объектов. По своей сути, Helm можно сравнить с пакетным менеджером для Kubernetes, таким как apt или yum в Linux, но адаптированным для работы с Kubernetes-кластерами. Helm решает несколько ключевых задач: #### Упрощение развертывания Приложения могут состоять из десятков или сотен объектов Kubernetes, таких как поды, сервисы, конфигурации и другие. Helm объединяет их в единый пакет, называемый чартом, который можно развернуть одной командой. Этот подход значительно снижает сложность ручной настройки приложений. #### Управление версиями приложений Каждый чарт может иметь несколько версий, что позволяет легко откатываться к предыдущей версии или обновлять приложение. Helm поддерживает управление версиями, отслеживание изменений развернутых приложений (релизов) и позволяет выполнять откаты при необходимости. #### Повторное использование конфигураций Helm использует шаблоны для генерации конфигурационных файлов Kubernetes, что облегчает настройку параметров, таких как количество реплик, настройки сетевого доступа, базы данных и другие переменные. Эти настройки хранятся в специальном конфигурационном файле — values.yaml. Это позволяет использовать один и тот же чарт в разных окружениях (разработка, тестирование, продакшн) с минимальными изменениями. #### Централизованное управление репозиториями Чарты хранятся в репозиториях, которые могут быть как публичными, так и частными. Helm позволяет добавлять различные репозитории, обновлять их и устанавливать приложения напрямую. Например, популярный репозиторий Bitnami содержит множество готовых к использованию чартов для различных сервисов. ## Установка Helm Helm тесно связан с версией Kubernetes, поэтому важно выбрать версию, совместимую с вашей версией кластера. Вы можете ознакомиться с таблицей совместимости версий Helm и Kubernetes в [официальной документации](https://helm.sh/docs/topics/version_skew/#supported-version-skew). Linux Чтобы установить Helm на Linux, можно использовать официальный скрипт для автоматической установки. Скачайте установочный скрипт и измените его права на выполнение: ```bash curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 && chmod 700 get_helm.sh ``` Запустите скрипт для установки последней версии Helm: ```bash ./get_helm.sh ``` Укажите версию Helm, совместимую с вашим Kubernetes-кластером: ```bash ./get_helm.sh -v 3.14.1 ``` #### Установка через репозиторий на Ubuntu Для установки Helm через системный пакетный менеджер на Ubuntu, выполните следующие шаги: Добавьте ключ подписи репозитория Helm: ```bash curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null ``` Установите пакет `apt-transport-https`, если он не был установлен ранее: ```bash sudo apt install apt-transport-https --yes ``` Добавьте репозиторий Helm в список источников APT: ```bash echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list ``` После этого выполните команду: ```bash sudo apt update ``` Теперь, когда все подготовительные шаги выполнены, можно установить Helm: ```bash sudo apt install helm ``` Эта команда устанавливает последнюю доступную версию Helm из репозитория. Укажите версию Helm, совместимую с вашим Kubernetes-кластером: ```bash sudo apt install helm=3.14.2-1 ``` Проверьте корректность установки, выполнив: ```bash helm version ``` ![Image1](https://content.timeweb.com/assets/16019808-4504-4d9a-ba6a-5af1f3af100f.png?width=720&height=87) Windows Чтобы установить Helm на Windows, выполните следующие шаги: Запустите PowerShell от имени администратора. Установите Helm с помощью следующей команды: ```shell winget install Helm.Helm ``` Установите версию Helm, совместимую с вашим Kubernetes-кластером: ```shell winget install Helm.Helm -v 3.14.1 ``` Проверьте версию Helm: ```shell helm version ``` ![Image3](https://content.timeweb.com/assets/fe5a9a18-0fa0-4771-b672-2cf6f8bfc6c7.png?width=1223&height=90) MacOS Чтобы установить Helm на MacOS, можно использовать официальный скрипт для автоматической установки. Скачайте установочный скрипт и измените его права на выполнение: ```bash curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 && chmod 700 get_helm.sh ``` Запустите скрипт для установки последней версии Helm: ```bash ./get_helm.sh ``` Укажите версию Helm, совместимую с вашим Kubernetes-кластером: ```bash ./get_helm.sh -v 3.14.1 ``` #### Установка через Homebrew Если вы используете Homebrew, Helm можно установить с его помощью. Обратите внимание, что в репозиториях Homebrew доступна только последняя версия Helm. Для установки выполните команду: ```bash brew install helm ``` Проверьте версию Helm: ```bash helm version ``` ![Image4](https://content.timeweb.com/assets/3c11a216-3d6c-4f6c-b0eb-2ab9e339ade6.png?width=1018&height=127) ## Настройка репозиториев Helm Helm использует репозитории для размещения и распространения чартов — пакетов приложений, которые можно устанавливать в Kubernetes. Репозитории помогают управлять приложениями из централизованных источников, что упрощает процессы установки, обновления и удаления приложений. ### Добавление репозитория Чтобы установить приложение из удаленного репозитория, его нужно сначала добавить в список доступных источников. Это делается с помощью команды `helm repo add`. Например, для добавления популярного репозитория Bitnami выполните следующую команду: ```bash helm repo add bitnami https://charts.bitnami.com/bitnami ``` Helm поддерживает как публичные, так и частные репозитории. Для работы с частными репозиториями могут потребоваться учетные данные для аутентификации, такие как токен или логин с паролем. ### Обновление репозиториев Иногда чарты в репозиториях обновляются, и чтобы убедиться, что у вас актуальные версии, необходимо периодически обновлять информацию о репозиториях. Для этого используется команда: ```bash helm repo update ``` Эта команда синхронизирует ваш локальный индекс чартов с актуальным содержимым удаленных репозиториев. ### Просмотр доступных репозиториев Вы можете посмотреть список всех подключенных репозиториев с помощью команды: ```bash helm repo list ``` Пример вывода:  ![Image2](https://content.timeweb.com/assets/467f5232-e419-4b30-ac52-7448cc307865.png?width=681&height=188) ### Удаление репозитория Если какой-то репозиторий больше не нужен, его можно удалить с помощью команды `helm repo remove`. Например, чтобы удалить репозиторий Bitnami, выполните: ```bash helm repo remove bitnami ``` Эта команда удаляет репозиторий только из локальной конфигурации Helm. Сами чарты и установленные приложения при этом не затрагиваются. ## Установка приложений с помощью Helm После настройки репозиториев вы можете искать и устанавливать приложения в Kubernetes с помощью Helm. ### Поиск приложений в репозиториях Для поиска нужного чарта в подключенных репозиториях используйте команду: ```bash helm search repo <название_приложения> ``` Например, для поиска NGINX выполните: ```bash helm search repo nginx ``` ### Установка приложения Для установки найденного приложения выполните команду: ```bash helm install <имя_релиза> <репозиторий>/<название_чарта> ``` Например, для установки NGINX из репозитория Bitnami: ```bash helm install my-nginx bitnami/nginx ``` ### Проверка состояния установленного приложения Чтобы проверить состояние приложения, выполните: ```bash kubectl get pods ``` Для получения информации о релизе: ```bash helm status <имя_релиза> ``` ### Переопределение параметров установки Для изменения параметров чарта используйте: ```bash helm install my-nginx bitnami/nginx --set service.type=NodePort ``` ### Удаление приложения Чтобы удалить приложение и его ресурсы: ```bash helm uninstall <имя_релиза> ``` # Создание Helm-чарта Source: https://timeweb.cloud/docs/k8s/deploy/helm-chart-creation?utm_source=llms_txt&utm_medium=ai Helm-чарты позволяют упаковать Kubernetes-приложения в удобный пакет, включающий все необходимые ресурсы для их развертывания и управления. Чарты используются для автоматизации создания, обновления и удаления приложений в Kubernetes, что делает управление ими более простым и гибким. ## Создание нового чарта Для создания нового чарта используйте команду: ```bash helm create <имя_чарта> ``` Helm автоматически сгенерирует базовую структуру директорий и файлов, которые содержат необходимые шаблоны и конфигурации для развертывания приложения в Kubernetes. ## Основные файлы и директории - **Chart.yaml** Главный файл чарта, содержащий метаданные: название, версия, описание и версия приложения. Также может включать информацию о зависимостях, если приложение зависит от других чартов. Пример использования: - Указывает, какое приложение разворачивается, и его версию. - Упрощает управление версиями чарта и отслеживание изменений. - **values.yaml** Файл с параметрами по умолчанию, который используется для задания значений, применяемых к шаблонам чарта для генерации конечных манифестов Kubernetes. Пример использования: - Задает параметры, такие как количество реплик, тип сервиса, образ контейнера. - Позволяет переопределять значения через флаг `--set` или дополнительный файл при установке. - **templates/** В этой директории хранятся шаблоны YAML-файлов Kubernetes, определяющие объекты (поды, деплойменты, сервисы и т.д.), которые будут созданы при установке чарта. Шаблоны используют язык Go для динамической генерации манифестов на основе значений из `values.yaml`. Пример использования: - Шаблоны для создания объектов Kubernetes (например, `deployment.yaml`, `service.yaml`). - Логика для гибкой настройки ресурсов (например, количество реплик или тип сервиса). - **charts/** Директория для зависимостей — других чартов, необходимых для работы вашего приложения. Зависимости могут быть установлены локально или загружены из удаленных репозиториев. Пример использования: - Зависимости загружаются командой `helm dependency update`, если они указаны в `Chart.yaml`. - **.helmignore** Этот файл работает аналогично `.gitignore`, исключая файлы и директории при упаковке чарта в архив. Пример использования: - Исключение ненужных файлов (например, документации или временных файлов), чтобы они не попали в финальный пакет. Теперь, когда мы рассмотрели основную структуру чарта и назначение ключевых файлов, перейдем к практическому примеру. Мы создадим чарт для развертывания NGINX, настроим все необходимые параметры и рассмотрим, как шаблоны используют данные из `values.yaml` для генерации Kubernetes-ресурсов. ## Создание базовой структуры чарта Начните с создания базовой структуры чарта. Введите команду: ```shell helm create nginx-chart ``` Это создаст директорию `nginx-chart/` с базовыми файлами: ```shell nginx-chart ├── charts ├── Chart.yaml ├── templates │ ├── deployment.yaml │ ├── _helpers.tpl │ ├── hpa.yaml │ ├── ingress.yaml │ ├── NOTES.txt │ ├── serviceaccount.yaml │ ├── service.yaml │ └── tests │ └── test-connection.yaml └── values.yaml ``` ## Настройка файла Chart.yaml Файл `Chart.yaml` является ключевым элементом любого Helm-чарта. В этом файле указываются метаданные чарта, такие как его имя, версия, описание, а также информация о зависимостях. Пример содержимого `Chart.yaml` для чарта NGINX: ```yml apiVersion: v2 name: nginx-chart description: A Helm chart for deploying NGINX version: 0.1.0 appVersion: "1.21.0" ``` Ключевые поля: - **apiVersion**: Версия API Helm для данного чарта. Для чартов Helm 3 используйте `v2`. - **name**: Название вашего чарта. Оно должно быть уникальным в вашем репозитории. - **description**: Краткое описание того, что делает этот чарт. - **version**: Версия самого чарта. Каждый раз, когда вы вносите изменения в чарт, необходимо обновлять эту версию. - **appVersion**: Версия приложения (в данном случае NGINX), которая будет развернута. Это поле не влияет на логику Helm, но помогает пользователям видеть, какую версию приложения они устанавливают. ## Настройка файла values.yaml Файл `values.yaml` используется для указания значений по умолчанию для параметров, которые могут быть изменены при установке чарта. Настройте его следующим образом: ```yml replicaCount: 2 image: repository: nginx tag: "1.21.0" pullPolicy: IfNotPresent service: type: ClusterIP port: 80 serviceAccount: create: true name: "" ingress: enabled: false annotations: {} hosts: - host: chart-example.local paths: [] tls: [] autoscaling: enabled: false minReplicas: 1 maxReplicas: 5 targetCPUUtilizationPercentage: 80 resources: {} nodeSelector: {} tolerations: [] affinity: {} ``` Этот файл содержит следующие настройки: - **replicaCount**: Количество реплик приложения. - **image**: Настройки образа контейнера NGINX, включая версию (`tag`). - **service**: Тип сервиса и порт, через который будет доступен NGINX. - **serviceAccount**: Создание учетной записи сервиса для чарта. - **ingress**: Параметры для Ingress (по умолчанию выключено). - **autoscaling**: Параметры для авто-масштабирования (по умолчанию выключено). ## Шаблоны чарта Теперь настроим шаблоны в папке templates, которые будут использовать значения из `values.yaml`. #### templates/service.yaml Шаблон для создания Kubernetes-сервиса: ```yml apiVersion: v1 kind: Service metadata: name: {{ include "nginx-chart.fullname" . }} labels: app: {{ include "nginx-chart.name" . }} spec: type: {{ .Values.service.type }} ports: - port: {{ .Values.service.port }} targetPort: 80 selector: app: {{ include "nginx-chart.name" . }} ``` #### templates/deployment.yaml Шаблон для создания деплоймента NGINX: ```yml apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "nginx-chart.fullname" . }} labels: app: {{ include "nginx-chart.name" . }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app: {{ include "nginx-chart.name" . }} template: metadata: labels: app: {{ include "nginx-chart.name" . }} spec: serviceAccountName: {{ if .Values.serviceAccount.create }}{{ include "nginx-chart.serviceAccountName" . }}{{ else }}{{ .Values.serviceAccount.name }}{{ end }} containers: - name: nginx image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" ports: - containerPort: 80 ``` #### templates/serviceaccount.yaml Шаблон для создания учетной записи сервиса: ```yml {{- if .Values.serviceAccount.create }} apiVersion: v1 kind: ServiceAccount metadata: name: {{ include "nginx-chart.serviceAccountName" . }} {{- end }} ``` ## Проверка и установка чарта Проверьте чарт на наличие ошибок: ```shell helm lint ./nginx-chart ``` Установите чарт: ```shell helm install test-nginx ./nginx-chart ``` Проверьте статус релиза: ```shell helm status test-nginx ``` Проверьте состояние подов: ```shell kubectl get pods ``` ## Удаление чарта Когда приложение больше не нужно, его можно удалить: ```shell helm uninstall test-nginx ``` # Дополнения (аддоны) Source: https://timeweb.cloud/docs/k8s/addons?utm_source=llms_txt&utm_medium=ai В кластере Kubernetes можно использовать различные дополнения (аддоны) для расширения его функциональности. Они помогают управлять трафиком, мониторить сервисы, работать с хранилищем и обеспечивать безопасность. Некоторые дополнения, такие как **Nginx Ingress**, **Kubernetes Dashboard** и **CSI S3**, можно установить как на этапе создания кластера, так и позже. Управлять установкой и удалением аддонов можно во вкладке «Дополнения» в панели управления кластером. Дополнения, которые не представлены в панели управления, можно устанавливать вручную при помощи[Helm](https://timeweb.cloud/docs/k8s/deploy/helm). ## Apache Pulsar Apache Pulsar — это распределенная платформа для обмена сообщениями и потоковой обработки данных. Она используется для построения event-driven-архитектур, очередей, стриминга логов и интеграции микросервисов. #### Принцип работы При установке аддона в кластере автоматически разворачиваются основные компоненты Pulsar: ZooKeeper для координации, BookKeeper для хранения сообщений, Pulsar Broker для обработки и маршрутизации сообщений, Pulsar Proxy для клиентского доступа, Recovery для восстановления реплик данных, а также VictoriaMetrics и Grafana для мониторинга. Для хранения данных используются сетевые диски через CSI-драйвер. Количество реплик основных компонентов можно настраивать в параметрах аддона. #### Основные функции - Развертывание отказоустойчивой платформы обмена сообщениями. - Поддержка очередей, стриминга и event-driven-сценариев. - Масштабирование брокеров, прокси, ZooKeeper и BookKeeper. - Хранение сообщений на сетевых дисках. - Встроенный мониторинг через VictoriaMetrics и Grafana. > [!NOTE] > Подробная инструкция по работе [с Apache Pulsar](https://timeweb.cloud/docs/k8s/addons/apache-pulsar). ## ArgoCD ArgoCD — это инструмент GitOps для Kubernetes, который автоматизирует доставку приложений в кластер на основе состояния, описанного в Git-репозитории. #### Принцип работы ArgoCD отслеживает манифесты Kubernetes, Helm-чарты или Kustomize-конфигурации в Git-репозитории и сравнивает их с фактическим состоянием ресурсов в кластере. Если состояние отличается, ArgoCD показывает расхождение и может синхронизировать кластер с репозиторием вручную или автоматически. Такой подход позволяет хранить конфигурацию приложений в Git, управлять изменениями через pull request и быстро откатываться к предыдущим версиям. #### Основные функции - Доставка приложений в Kubernetes по GitOps-модели. - Синхронизация состояния кластера с Git-репозиторием. - Поддержка Kubernetes-манифестов, Helm и Kustomize. - Визуализация ресурсов приложения и их статуса. - Автоматическая или ручная синхронизация изменений. - Откат к предыдущим версиям конфигурации. ## Capsule Capsule — это дополнение, которое реализует концепцию мультиарендности в Kubernetes, обеспечивая изоляцию и контроль потребления ресурсов между различными группами пользователей. #### Принцип работы Capsule позволяет создавать логические тенанты на основе пространств имен с аннотациями и политиками, предоставляя пользователям возможность управлять своими ресурсами без воздействия на ресурсы других пользователей. #### Основные функции - Изоляция ресурсов между пользователями. - Управление квотами и ограничениями. - Настройка политики безопасности для различных пользователей. ## cert-manager cert-manager — это дополнение для Kubernetes, которое автоматизирует выпуск, обновление и управление TLS-сертификатами. #### Принцип работы cert-manager автоматически запрашивает и обновляет сертификаты, управляя их жизненным циклом с помощью CRD-объектов (CertificateRequest, Issuer, ClusterIssuer). Он поддерживает интеграцию с различными поставщиками сертификатов, такими как Let's Encrypt, HashiCorp Vault и внутренние центры сертификации. #### Основные функции - Автоматический выпуск сертификатов - Обновление сертификатов по истечении срока действия - Поддержка множества поставщиков (ACME, Vault, self-signed) > [!NOTE] > Подробная инструкция по работе [с cert-manager](https://timeweb.cloud/docs/k8s/addons/cert-manager). ## cert-manager Webhook cert-manager Webhook — это дополнение для Kubernetes, которое позволяет cert-manager автоматически создавать DNS-записи при валидации домена методом DNS-01. #### Принцип работы Webhook подключает cert-manager к DNS Timeweb Cloud. При выпуске сертификата cert-manager создает challenge для подтверждения владения доменом, а cert-manager Webhook автоматически добавляет нужную DNS-запись. После успешной проверки Let's Encrypt выпускает сертификат, а cert-manager сохраняет его в Kubernetes Secret. Для работы дополнения домен должен быть делегирован на NS Timeweb Cloud, а в кластере должен быть установлен cert-manager. #### Основные функции - Автоматическое создание DNS-записей для DNS-01-валидации. - Выпуск сертификатов Let's Encrypt через ClusterIssuer. - Поддержка wildcard-сертификатов. - Интеграция с cert-manager и Kubernetes Secret. > [!NOTE] > Подробная инструкция по работе [с cert-manager Webhook](https://timeweb.cloud/docs/k8s/addons/cert-manager-webhook). ## Cluster Proportional Autoscaler Cluster Proportional Autoscaler (CPA) — это контроллер, который автоматически масштабирует выбранный деплоймент в зависимости от количества нод или ядер в кластере. CPA особенно полезен для сервисов, которые должны масштабироваться пропорционально ресурсам кластера, например metrics-server или coredns. #### Принцип работы В отличие от горизонтального автоскейлера, CPA не использует метрики нагрузки. Вместо этого масштабирование происходит по заданным формулам, основанным на количестве нод и/или CPU. Поддерживаются два режима: - Linear — количество реплик рассчитывается по заданной формуле с учетом ядер и нод. - Ladder — количество реплик задается явно в виде таблицы соответствий (например, 2 ноды → 2 пода). #### Основные функции - Масштабирование деплойментов без метрик нагрузки. - Поддержка линейного и табличного (ladder) режима. - Учет как доступных, так и недоступных (unschedulable) нод. - Возможность гибкой настройки масштабирования через Helm. - Поддержка нескольких экземпляров CPA для разных целей. > [!NOTE] > Подробная инструкция по работе [с Cluster Proportional Autoscaler](https://timeweb.cloud/docs/k8s/addons/cpa). ## CSI S3 CSI S3 — это плагин для Container Storage Interface (CSI), который позволяет использовать хранилища данных S3 совместно с Kubernetes. #### Принцип работы CSI S3 предоставляет возможность динамически подключать объектные хранилища, совместимые с S3 (например, Ceph, MinIO, AWS S3), как стандартные персистентные тома для использования в Kubernetes. Это особенно полезно для размещения больших объемов данных в контейнерных приложениях. #### Основные функции - Подключение S3-хранилищ как постоянных томов (Persistent Volumes). - Поддержка динамического создания и удаления томов. - Гибкость в использовании различных S3-совместимых систем хранения данных. > [!NOTE] > Подробная инструкция по работе [с CSI S3](https://timeweb.cloud/docs/k8s/addons/csi-s3). ## CSI-driver CSI-driver — это дополнение для Kubernetes, которое подключает сетевые диски Timeweb Cloud к кластеру и позволяет использовать их как постоянные тома для приложений. #### Принцип работы CSI-драйвер интегрирует сетевые диски с Kubernetes через Container Storage Interface. Он состоит из контроллера и node-агента. Контроллер взаимодействует с API и отвечает за создание, удаление и изменение размера сетевых дисков. Node-агент работает на каждой ноде кластера и управляет монтированием дисков на уровне операционной системы. При создании PersistentVolumeClaim Kubernetes передает запрос драйверу, а драйвер создает сетевой диск и подключает его к нужной ноде. Диски автоматически форматируются в ext4 и используются приложениями как обычные persistent volumes. #### Основные функции - Подключение сетевых дисков к Kubernetes через CSI. - Динамическое создание дисков через PersistentVolumeClaim. - Изменение размера подключенных дисков. - Автоматическое форматирование дисков в ext4. - Поддержка storage-классов для NVMe- и HDD-дисков. - Работа в режиме ReadWriteOnce. > [!NOTE] > Подробная инструкция по работе [с CSI-driver](https://timeweb.cloud/docs/k8s/network-drives-connection). ## Envoy Gateway Envoy Gateway — это контроллер Gateway API для Kubernetes, который использует Envoy Proxy для обработки входящего трафика. Он позволяет публиковать HTTP, HTTPS, gRPC, TCP и UDP-сервисы и управлять маршрутизацией через стандартные ресурсы Kubernetes. #### Принцип работы Gateway API можно рассматривать как развитие Ingress. Вместо одного ресурса Ingress используются несколько объектов с разными зонами ответственности: GatewayClass, Gateway, HTTPRoute, GRPCRoute, TCPRoute, UDPRoute и TLSRoute. Envoy Gateway отслеживает эти ресурсы и на их основе создает Envoy Proxy, который принимает внешний трафик и направляет его к сервисам внутри кластера. #### Основные функции - Публикация HTTP, HTTPS, gRPC, TCP и UDP-сервисов. - Маршрутизация по доменам, путям и другим правилам Gateway API. - Управление TLS-настройками. - Применение политик трафика через Kubernetes-ресурсы. - Использование Envoy Proxy как data plane. > [!NOTE] > Подробная инструкция по работе [с Envoy Gateway](https://timeweb.cloud/docs/k8s/addons/envoy-gateway). ## ExternalDNS ExternalDNS — это инструмент для автоматического управления DNS-записями на основе ресурсов Kubernetes. Он создает и обновляет записи в DNS-провайдере в соответствии с аннотациями, указанными в манифестах сервисов и Ingress-ресурсов. #### Принцип работы ExternalDNS отслеживает изменения в объектах Kubernetes и создает или обновляет DNS-записи, в соответствии с внешними IP-адресами сервисов. Это позволяет автоматически привязывать доменные имена к сервисам в кластере без необходимости ручного управления DNS. #### Основные функции - Автоматическое создание и обновление DNS-записей. - Упрощённое управление доменными именами в Kubernetes. > [!NOTE] > Подробная инструкция по работе [ExternalDNS](https://timeweb.cloud/docs/k8s/addons/externaldns). ## Fluent Operator Fluent Operator — это Kubernetes-оператор для управления Fluentd и Fluent Bit, который автоматизирует сбор, маршрутизацию и обработку логов в кластере. #### Принцип работы Fluent Operator использует CRD для управления конфигурацией Fluentd и Fluent Bit, позволяя направлять контейнерные и системные логи в различные хранилища, такие как Elasticsearch, Loki, Kafka и другие. #### Основные функции - Централизованный сбор и управление логами - Гибкая маршрутизация логов в различные системы хранения - Настройка фильтрации, агрегации и обработки логов > [!NOTE] > Подробная инструкция по работе [с Fluent Operator](https://timeweb.cloud/docs/k8s/addons/fluent-operator). ## Grafana Loki Grafana Loki — это система сбора и просмотра логов, разработанная Grafana Labs. Она используется совместно с Grafana и обеспечивает удобную визуализацию логов Kubernetes. #### Принцип работы В отличие от традиционных стеков логирования (например, ELK), Loki не индексирует содержимое логов, а сохраняет их вместе с метаданными (именем пода, namespace и др.). Это делает систему менее ресурсоемкой. Логи собираются с помощью агента Promtail, установленного на каждой ноде, и отправляются в Loki. Просмотр логов осуществляется в Grafana с использованием языка запросов LogQL. #### Основные функции - Сбор логов с подов Kubernetes. - Хранение логов с привязкой к метаданным. - Просмотр логов в Grafana. - Поддержка запроса и фильтрации через LogQL. - Интеграция с альтернативными агентами (Fluent Bit, Filebeat, Logstash). > [!NOTE] > Подробная инструкция по работе [с Grafana Loki](https://timeweb.cloud/docs/k8s/addons/grafana-loki). ## Headlamp Headlamp — это веб-интерфейс для управления Kubernetes-кластером. Он позволяет просматривать ресурсы кластера, управлять ими и отслеживать состояние приложений без использования kubectl. #### Принцип работы Headlamp устанавливается в кластер и предоставляет графический интерфейс для работы с Kubernetes-ресурсами. После установки интерфейс открывается из панели управления кластером. Для входа используется токен, который можно получить во вкладке «Дашборд». Через Headlamp можно просматривать состояние кластера, рабочие нагрузки, хранилища, сетевые ресурсы, политики безопасности, конфигурации и пользовательские ресурсы. #### Основные функции - Просмотр информации о кластере и его состоянии. - Управление Pods, Deployments, StatefulSet и другими workload-ресурсами. - Работа с PVC, PV, storage-классами, сервисами и Ingress. - Просмотр ресурсов Gateway API. - Управление ролями, сервисными аккаунтами, ConfigMap, Secrets и CRD. - Создание ресурсов через веб-интерфейс. > [!NOTE] > Подробная инструкция по работе [с Headlamp](https://timeweb.cloud/docs/k8s/addons/headlamp). ## Istio Istio — это Service Mesh, которая обеспечивает управление трафиком, безопасность и мониторинг для сервисов в Kubernetes. #### Принцип работы Istio внедряет sidecar-прокси (Envoy) в каждый под, обеспечивая маршрутизацию, аутентификацию и мониторинг запросов внутри сервисной сети. #### Основные функции - Маршрутизация трафика. - Гибкое управление политиками безопасности. - Мониторинг и трассировка запросов. ## Istio Ingress Istio Ingress — это компонент Istio, который управляет внешним трафиком в сервисную сетку. #### Принцип работы Istio Ingress работает как точка входа в Service Mesh, обрабатывая внешние HTTP, HTTPS и TCP-запросы и направляя их к внутренним сервисам через Istio. #### Основные функции - Управление внешним трафиком. - Маршрутизация запросов. - Поддержка TLS и mTLS. ## Jaeger Jaeger — это инструмент трассировки распределенных систем, используемый для мониторинга взаимодействий между микросервисами и анализа их производительности. #### Принцип работы Jaeger собирает данные о запросах между сервисами, регистрируя временные метки и зависимости вызовов. Это позволяет отслеживать цепочку запросов, анализировать задержки и выявлять узкие места в системе. #### Основные функции - Трассировка распределенных запросов. - Анализ времени отклика сервисов. - Поиск узких мест в архитектуре. ## Kiali Kiali — это инструмент для управления и визуализации Service Mesh Istio в Kubernetes. #### Принцип работы Kiali предоставляет графическое представление сетевых взаимодействий между сервисами, отображая их зависимости, метрики и потенциальные проблемы. Он может интегрироваться с Prometheus, собирая данные о трафике, ошибках и производительности, а также упрощает управление конфигурацией Istio. #### Основные функции - Визуализация сервисной сети. - Мониторинг трафика и ошибок. - Управление конфигурацией Istio. ## Kube Prometheus Stack Kube Prometheus Stack — это набор инструментов для мониторинга Kubernetes, включающий Prometheus для сбора метрик, Alertmanager для управления оповещениями и Grafana для визуализации данных. #### Принцип работы Система автоматически собирает метрики из компонентов Kubernetes, подов и узлов, а также из сервисов, поддерживающих экспорт Prometheus-метрик. Данные хранятся в Prometheus, отображаются в Grafana, а Alertmanager отправляет уведомления при превышении заданных порогов. #### Основные функции - Сбор и хранение метрик. - Визуализация данных в Grafana. - Настройка оповещений. ## Kubernetes Dashboard > [!NOTE] > Аддон считается устаревшим и доступен только в кластерах, где он был установлен ранее. Kubernetes Dashboard — это веб-интерфейс для управления и мониторинга Kubernetes-кластера. Для работы плагина необходим Nginx Ingress. Поэтому после включения этого плагина автоматически выберется и Nginx Ingress. #### Принцип работы Dashboard предоставляет пользователям графический интерфейс для взаимодействия с кластером. Он позволяет просматривать информацию о статусе подов, узлов, сервисов и других ресурсов Kubernetes. Также через интерфейс можно создавать, изменять и удалять ресурсы. #### Основные функции - Просмотр состояния кластера (поды, узлы, сервисы, конфигурации). - Управление ресурсами кластера. - Мгновенный доступ к логам подов и информации о запущенных приложениях. - Управление секретами и конфигурациями. #### Вход в Kubernetes Dashboard Если вы включили опцию Kubernetes Dashboard для кластера, вы сможете перейти в Dashboard из панели управления. Для входа вам потребуется токен, который можно скопировать на вкладке «Дашборд». ![Вход в Kubernetes Dashboard](https://content.timeweb.com/assets/cfe952eb-0373-4a86-b082-b8584dbae90e.png?width=1021&height=919) ## MinIO Operator MinIO Operator — это дополнение для Kubernetes, позволяющее развернуть S3-совместимое хранилище на базе MinIO. Оператор упрощает управление пользователями, бакетами и конфигурацией с помощью манифестов Kubernetes. #### Принцип работы Оператор использует CRD-объекты для создания кластеров хранения (тенантов), назначения пользователей и управления конфигурацией. Данные могут храниться на сетевых дисках через CSI-драйвер. Доступ к консоли и S3 API реализуется через Nginx Ingress и TLS-сертификаты от cert-manager. #### Основные функции - Развертывание MinIO-хранилища с помощью CRD. - Управление пользователями и ключами доступа через секреты. - Интеграция с [Nginx Ingress](https://timeweb.cloud/docs/k8s/addons/nginx-ingress) и [cert-manager](https://timeweb.cloud/docs/k8s/addons/cert-manager). - Работа с S3 API и консолью управления. - Поддержка отказоустойчивых конфигураций (от 4 узлов). > [!NOTE] > Подробная инструкция по работе [с MinIO Operator](https://timeweb.cloud/docs/k8s/addons/minio-operator). ## NGINX Gateway Fabric NGINX Gateway Fabric — это контроллер Gateway API для Kubernetes, который использует NGINX для обработки входящего трафика. С его помощью можно публиковать сервисы, управлять маршрутизацией и постепенно переходить от Ingress к Gateway API. #### Принцип работы NGINX Gateway Fabric отслеживает ресурсы Gateway API: GatewayClass, Gateway, HTTPRoute, GRPCRoute, TCPRoute, UDPRoute и TLSRoute. На основе этих ресурсов контроллер создает NGINX data plane: поды NGINX и сервис, через который внешний трафик попадает в кластер и направляется к Kubernetes-сервисам. При стандартной установке создается GatewayClass с именем nginx, который обслуживает создаваемые шлюзы. #### Основные функции - Публикация HTTP, HTTPS, gRPC, TCP и UDP-сервисов. - Маршрутизация по доменам и путям. - Управление TLS. - Работа с ресурсами Gateway API. - Миграция существующих Ingress-ресурсов на Gateway API. > [!NOTE] > Подробная инструкция по работе [с NGINX Gateway Fabric](https://timeweb.cloud/docs/k8s/addons/nginx-gateway-fabric). ## Nginx Ingress Nginx Ingress — это контроллер Ingress, который управляет доступом внешнего трафика к сервисам внутри кластера Kubernetes через HTTP и HTTPS. Он маршрутизирует трафик на основе правил, определенных в ресурсах Ingress. #### Принцип работы Ingress-контроллер отслеживает объекты Ingress в Kubernetes и конфигурирует обратный прокси Nginx, чтобы направлять трафик на нужные сервисы. Это позволяет организовать доступ к различным микросервисам через единый IP-адрес, а также настроить балансировку нагрузки и маршрутизацию на основе доменных имен. #### Основные функции - Маршрутизация HTTP/HTTPS запросов. - Поддержка SSL/TLS. - Балансировка нагрузки. - Управление внешним доступом к сервисам в кластере. > [!NOTE] > Подробная инструкция по работе [с Nginx Ingress](https://timeweb.cloud/docs/k8s/addons/nginx-ingress). ## NVIDIA GPU Operator NVIDIA GPU Operator — это дополнение для Kubernetes, которое автоматизирует подготовку GPU-нод и управление компонентами NVIDIA, необходимыми для запуска нагрузок с использованием GPU. #### Принцип работы Оператор устанавливает и управляет компонентами NVIDIA в кластере: драйверами GPU, container runtime, device plugin, DCGM Exporter и другими сервисами. После установки Kubernetes начинает видеть GPU как выделяемый ресурс, который можно запрашивать в спецификациях подов. Это упрощает запуск ML-, AI-, render- и HPC-нагрузок в Kubernetes: администратору не нужно вручную настраивать каждую GPU-ноду и следить за совместимостью компонентов. #### Основные функции - Автоматическая настройка GPU-нод в Kubernetes. - Установка и управление NVIDIA-драйверами. - Публикация GPU как ресурса Kubernetes. - Поддержка запуска контейнеров с GPU. - Мониторинг состояния GPU через DCGM Exporter. - Упрощение эксплуатации ML-, AI- и HPC-нагрузок. ## OpenFaaS Kubernetes OpenFaaS — это платформа для запуска функций (Function as a Service) в Kubernetes. Она позволяет быстро разворачивать и выполнять контейнеризированные функции по запросу или событию. #### Принцип работы Функции в OpenFaaS упаковываются в Docker-образы и разворачиваются как поды в кластере. Платформа управляет их масштабированием, маршрутизацией запросов и безопасностью. Для работы с OpenFaaS доступны веб-интерфейс и CLI-утилита faas-cli. Есть поддержка популярных языков программирования через шаблоны: Python, Node.js, Go и другие. #### Основные функции - Развертывание функций по модели FaaS в Kubernetes. - Web-интерфейс и CLI для управления функциями. - Поддержка кастомных и встроенных функций. - Интеграция с Docker Hub. - Масштабирование функций в зависимости от нагрузки. > [!NOTE] > Подробная инструкция по работе [с OpenFaaS Kubernetes](https://timeweb.cloud/docs/k8s/addons/openfaas). ## Traefik Traefik — это Ingress-контроллер и балансировщик нагрузки для Kubernetes, обеспечивающий динамическую маршрутизацию трафика и автоматическое управление SSL-сертификатами. #### Принцип работы Автоматически обнаруживает сервисы в кластере и конфигурирует маршрутизацию HTTP/HTTPS трафика. #### Основные функции - Маршрутизация трафика. - Интеграция с Let’s Encrypt. > [!NOTE] > Подробная инструкция по работе [с Traefik](https://timeweb.cloud/docs/k8s/addons/traefik). ## TWC Alert Bot TWC Alert Bot — это дополнение для Kubernetes, которое отправляет уведомления о событиях в кластере в Telegram, Slack или Discord. Помогает оперативно реагировать на сбои и поддерживать стабильность инфраструктуры. #### Принцип работы Alert Bot отслеживает критичные события: рестарты контейнеров, сбои liveness- и readiness-проб, проблемы с нодами, ошибки деплоя и др. Для отправки уведомлений достаточно настроить один из поддерживаемых мессенджеров. Можно указать наблюдаемые неймспейсы, исключения по подам и включить только нужные типы алертов. #### Основные функции - Отправка уведомлений в Telegram, Slack и Discord. - Гибкая фильтрация по неймспейсам и именам подов. - Настройка типов алертов (рестарты, сбои проб, события Warning и др.). - Уведомления о превышении ресурсов и недоступности нод. - Простая установка и конфигурация через панель управления. > [!NOTE] > Подробная инструкция по работе [с TWC Alert Bot.](https://timeweb.cloud/docs/k8s/addons/twc-alert-bot) ## TWC DBaaS Operator TWC DBaaS Operator — это дополнение для Kubernetes, позволяющее создавать и управлять облачными базами данных Timeweb Cloud прямо из кластера с помощью CRD-ресурсов. #### Принцип работы Оператор использует собственные ресурсы (Instance, Database, User) для управления жизненным циклом баз данных. Поддерживаются MySQL, PostgreSQL и Redis. Создание происходит в несколько этапов: сначала инстанс (сервер), затем базы данных и пользователи с доступами. #### Основные функции - Управление базами данных из Kubernetes через CRD. - Поддержка MySQL, PostgreSQL и Redis. - Создание инстансов, баз и пользователей с правами доступа. - Гибкая настройка конфигураций и резервного копирования. - Интеграция с API Timeweb Cloud для выбора конфигурации. > [!NOTE] > Подробная инструкция по работе [с TWC DBaaS Operator.](https://timeweb.cloud/docs/k8s/addons/dbaas-operator) ## TWC Karpenter TWC Karpenter — это контроллер для Kubernetes, который автоматически создает и удаляет воркер-ноды в зависимости от текущей нагрузки в кластере. #### Принцип работы Karpenter отслеживает поды в статусе Pending, анализирует их требования к ресурсам и подбирает подходящую конфигурацию ноды. Затем он создает новую ноду через API и размещает на ней поды. При снижении нагрузки Karpenter может удалять неиспользуемые ноды, консолидировать нагрузку и отключать избыточные или менее эффективные по стоимости узлы. В отличие от классического Cluster Autoscaler, он не опирается только на заранее заданные размеры групп нод, а подбирает конфигурацию под текущую рабочую нагрузку. #### Основные функции - Автоматическое создание нод под поды, которые не удалось разместить. - Подбор конфигурации ноды под требования рабочей нагрузки. - Удаление неиспользуемых нод при снижении нагрузки. - Консолидация подов на меньшем количестве узлов. - Интеграция с группами нод Timeweb Cloud через NodeClass и NodePool. > [!NOTE] > Подробная инструкция по работе [с TWC Karpenter](https://timeweb.cloud/docs/k8s/addons/karpenter). ## Vault Vault — система управления секретами от HashiCorp. Позволяет централизованно хранить токены, пароли, сертификаты и другие чувствительные данные. В Kubernetes используется как внешнее хранилище секретов с возможностью гибкого контроля доступа. #### Принцип работы Vault устанавливается как аддон в кластер и может работать в dev- или HA-режиме. Dev-режим подходит только для разработки. В HA-режиме обеспечивается отказоустойчивость, масштабирование и использование распределенного хранилища (например, [CSI-S3](https://timeweb.cloud/docs/k8s/addons/csi-s3)). #### Основные функции - Централизованное и безопасное хранилище секретов. - Поддержка dev- и HA-режима. - Встроенный UI для управления данными. - Интеграция с Kubernetes: автоматическая подстановка секретов в поды. - Поддержка Raft и внешних CSI-хранилищ. > [!NOTE] > Подробная инструкция по работе [с Vault.](https://timeweb.cloud/docs/k8s/addons/vault) ## Velero Velero — это инструмент для резервного копирования, восстановления и миграции данных в Kubernetes. #### Принцип работы Позволяет делать бэкапы и восстанавливать данные на уровне namespace, ресурсов и PersistentVolume. #### Основные функции - Бэкап и восстановление ресурсов Kubernetes. - Миграция данных и приложений между кластерами. - Поддержка локальных и облачных хранилищ для резервных копий. > [!NOTE] > Подробная инструкция по работе [с Velero](https://timeweb.cloud/docs/k8s/addons/velero). ## VictoriaMetrics Operator VictoriaMetrics Operator — это оператор для Kubernetes, который автоматизирует развертывание и управление компонентами мониторинга на базе VictoriaMetrics. Он позволяет собирать, хранить и визуализировать метрики без необходимости ручной настройки каждого компонента. #### Принцип работы Оператор использует CRD-объекты для управления инфраструктурой мониторинга: - VMSingle — однозадачный экземпляр VictoriaMetrics, подходит для простых или тестовых кластеров. - VMCluster — масштабируемый вариант с несколькими компонентами, предназначенный для продакшена. - VMAgent — собирает метрики из подов и сервисов и передает их в VMSingle или VMCluster. - VMPodScrape — определяет, какие поды нужно опрашивать и как. Сбор метрик производится с помощью VMAgent, а доступ к данным возможен через веб-интерфейс VictoriaMetrics. #### Основные функции - Автоматическая установка компонентов мониторинга. - Сбор метрик из подов, сервисов и сторонних источников. - Гибкая настройка хранения и агрегации метрик. - Масштабируемость и поддержка продакшн-нагрузок. - Интеграция с Ingress для доступа к интерфейсу. > [!NOTE] > Подробная инструкция по работе [с VictoriaMetrics Operator](https://timeweb.cloud/docs/k8s/addons/victoriametrics-operator). ## WordPress WordPress — это CMS для создания сайтов и блогов. В Kubernetes она разворачивается как готовое приложение: аддон создает WordPress, базу данных, хранилище данных и сетевые настройки. #### Принцип работы При установке аддона в кластере создаются приложение WordPress, база данных MariaDB, два сетевых диска для хранения данных, LoadBalancer, объект Ingress и Kubernetes Secrets. Для доступа к сайту можно использовать балансировщик нагрузки или доменное имя через Nginx Ingress. Данные WordPress и MariaDB хранятся в PersistentVolumeClaim, поэтому остаются доступны при пересоздании подов. #### Основные функции - Автоматическое развертывание WordPress в Kubernetes. - Создание MariaDB для хранения данных сайта. - Использование сетевых дисков для WordPress и базы данных. - Настройка доступа через LoadBalancer и Ingress. - Возможность указать логин, пароль, почту администратора, домен и схему доступа. - Поддержка размещения файлов WordPress в S3-бакете при использовании CSI S3. > [!NOTE] > Подробная инструкция по работе [с WordPress](https://timeweb.cloud/docs/k8s/addons/wordpress). # Apache Pulsar Source: https://timeweb.cloud/docs/k8s/addons/apache-pulsar?utm_source=llms_txt&utm_medium=ai Apache Pulsar — это распределенная платформа для обмена сообщениями и потоковой обработки данных. Она используется для построения event-driven-архитектур, очередей, стриминга логов и интеграции микросервисов. В панели управления кластером вы можете развернуть Apache Pulsar как готовый аддон, и в кластере автоматически создадутся все необходимые компоненты: брокеры сообщений, хранилище данных, координаторы, прокси и система мониторинга. ## Установка Перед установкой Apache Pulsar убедитесь, что в кластере установлены: - [CSI-driver](https://timeweb.cloud/docs/k8s/network-drives-connection#ustanovka-drajvera-csi) — обязателен, используется для подключения сетевых дисков к BookKeeper и ZooKeeper. - Достаточное количество воркер-нод — по умолчанию кластер создается как отказоустойчивое решение. Для запуска необходимо не менее 4 воркер-нод с характеристиками: 4 CPU, 8 ГБ RAM, 120 ГБ NVMe. Для установки откройте раздел «Дополнения» в панели управления кластера и выберите «Apache Pulsar». ![Scr 20251229 Kssv](https://content.timeweb.com/assets/e60ea3c2-be67-4352-8d4a-c138f0effd0e.png?width=2166&height=1440) В открывшемся окне вы можете установить переключатель «Продвинутая установка» для редактирования параметров установки. Для тестирования можно оставить значения по умолчанию и нажать «Установить». ![Scr 20251229 Ktar](https://content.timeweb.com/assets/a9a33edd-c06e-414d-9bf9-88943a96f8cf.png?width=2154&height=1512) Для доступа к Grafana в настройках необходимо установить пароль. Укажите его в разделе: ```yaml grafana: enabled: true adminPassword: "password" ``` При использовании параметров по умолчанию будут развернуты: - `ZooKeeper` — координатор кластера; - `BookKeeper` — распределенное хранилище сообщений; - `Pulsar Broker` — обработка и маршрутизация сообщений; - `Pulsar Proxy` — точка входа для клиентов; - `Recovery` — восстановление реплик данных; - `VictoriaMetrics` и `Grafana` — мониторинг кластера. ## Настройка параметров ### Основные компоненты Состав кластера задается в блоке `components`: ```yaml components: zookeeper: true bookkeeper: true broker: true proxy: true autorecovery: true toolset: true ``` Здесь можно включать или отключать отдельные сервисы Pulsar. Например, для тестового окружения можно оставить только `ZooKeeper`, `BookKeeper`, `Broker` и `Proxy`. ### Количество реплик Основные сервисы масштабируются через параметры `replicaCount`: ```yaml zookeeper: replicaCount: 3 bookkeeper: replicaCount: 4 broker: replicaCount: 3 proxy: replicaCount: 3 ``` - `ZooKeeper` отвечает за координацию и должен иметь нечетное количество реплик. - `BookKeeper` хранит данные сообщений и определяет отказоустойчивость кластера. - `Broker` и `Proxy` масштабируются для распределения нагрузки между клиентами. ### Хранилище данных Pulsar использует сетевые диски для размещения всех сообщений. Томами управляют StatefulSet `ZooKeeper` и `BookKeeper`. Пример PVC для BookKeeper: ```yaml volumes: ledgers: size: 50Gi storageClassName: nvme.network-drives.csi.timeweb.cloud ``` Пример PVC для ZooKeeper: ```yaml zookeeper: volumes: data: size: 20Gi datalog: size: 20Gi ``` Все тома создаются с классом `nvme.network-drives.csi.timeweb.cloud`. При необходимости его можно заменить на [другой тип хранилища](https://timeweb.cloud/docs/k8s/network-drives-connection#sozdanie-diska-pri-pomoshchi-manifesta). Сетевые диски появятся в панели управления в разделе «Сетевые диски» и будут использоваться для доступности данных при перезапуске подов. ### Мониторинг Аддон автоматически устанавливает стек мониторинга VictoriaMetrics и Grafana: ```yaml victoria-metrics-k8s-stack: enabled: true grafana: enabled: true ``` В Grafana уже созданы дашборды Pulsar, показывающие: - количество сообщений; - нагрузку на брокеры; - задержки доставки; - использование дисков BookKeeper. ## После установки Проверьте состояние подов: ```bash kubectl get pods -n pulsar ``` В рабочем состоянии вы увидите: - несколько подов `pulsar-zookeeper-*`; - несколько подов `pulsar-bookie-*`; - `pulsar-broker-*` и `pulsar-proxy-*`; - поды мониторинга. Пример вывода: ```bash NAME READY STATUS RESTARTS AGE pulsar-bookie-0 1/1 Running 0 22h pulsar-bookie-1 1/1 Running 0 22h pulsar-bookie-2 1/1 Running 0 22h pulsar-bookie-3 1/1 Running 0 22h pulsar-bookie-init-24vrn 0/1 Completed 1 22h pulsar-broker-0 1/1 Running 0 22h pulsar-broker-1 1/1 Running 0 22h pulsar-broker-2 1/1 Running 0 22h pulsar-grafana-5b6cf7bb7b-vktzm 1/1 Running 0 22h pulsar-kube-state-metrics-55947c98cd-jkk6t 1/1 Running 0 22h pulsar-prometheus-node-exporter-9r8jj 1/1 Running 0 22h pulsar-prometheus-node-exporter-d8s2d 1/1 Running 0 22h pulsar-prometheus-node-exporter-gh895 1/1 Running 0 22h pulsar-prometheus-node-exporter-mhbc4 1/1 Running 0 22h pulsar-proxy-0 1/1 Running 0 22h pulsar-proxy-1 1/1 Running 0 22h pulsar-proxy-2 1/1 Running 0 22h pulsar-pulsar-init-rwlwh 0/1 Completed 0 22h pulsar-recovery-0 1/1 Running 0 22h pulsar-toolset-0 1/1 Running 0 22h pulsar-victoria-metrics-operator-84bd8795f6-fjwrm 1/1 Running 0 22h pulsar-zookeeper-0 1/1 Running 0 22h pulsar-zookeeper-1 1/1 Running 0 22h pulsar-zookeeper-2 1/1 Running 0 22h vmagent-pulsar-victoria-metrics-k8s-stack-5897fbdbdb-dnv9l 2/2 Running 0 22h vmsingle-pulsar-victoria-metrics-k8s-stack-bcdcb4884-fbccc 1/1 Running 0 22h ``` Доступ к Grafana Чтобы открыть Grafana, выполните: ```bash kubectl port-forward -n pulsar svc/pulsar-grafana 3000:80 ``` После этого Grafana будет доступна по адресу `http://localhost:3000`. В разделе «Dashboards» → «Pulsar» можно просматривать состояние кластера и поток сообщений в реальном времени. ![Scr 20251229 Maep](https://content.timeweb.com/assets/84363813-4f81-4089-9b96-86e4711bfa21.png?width=2938&height=1634) _Раздел «Dashboards» → «Pulsar» в интерфейсе [Grafana](https://grafana.com/)_ # cert-manager Source: https://timeweb.cloud/docs/k8s/addons/cert-manager?utm_source=llms_txt&utm_medium=ai cert-manager — это расширение для Kubernetes, которое автоматизирует выпуск и обновление сертификатов. Оно позволяет выпускать сертификаты от Let's Encrypt и других центров сертификации, а также использовать внутренние корневые сертификаты. cert-manager упрощает работу с сертификатами, автоматически продлевая их перед истечением срока действия и обеспечивая безопасное шифрование для сервисов в кластере. Он интегрируется с Ingress-контроллерами и поддерживает различные механизмы проверки домена. Это делает его удобным инструментом для автоматизации управления сертификатами в Kubernetes. ## Установка Для установки cert-manager откройте панель управления кластером, перейдите во вкладку «Дополнения» и выберите cert-manager. ![Selection 173](https://content.timeweb.com/assets/460b0f5d-e883-4746-a303-67b18e847ca8.png?width=1004&height=942) В открывшемся мастере установки нажмите кнопку «Установить» и дождитесь завершения процесса. ![Selection 174](https://content.timeweb.com/assets/3a3ba9d8-c08f-4934-b1ae-48808687154f.png?width=1005&height=787) Проверить корректность установки можно командой: ```shell kubectl get pods -n cert-manager ``` Все поды в неймспейсе `cert-manager` должны иметь статус «Running». ## Использование Чтобы cert-manager мог выпускать сертификаты, необходимо создать объект `ClusterIssuer`, который будет управлять сертификатами на уровне всего кластера. Пример манифеста: ```yml apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: email: email@example.com server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: nginx ``` Здесь: - `email` — ваша почта. Она необходима для создания сертификатов, на нее будут приходить уведомления от Let's Encrypt. - `server` — адрес Let's Encrypt или другого центра сертификации. - `privateKeySecretRef` — секрет, в котором хранится закрытый ключ. - `solvers.http01.ingress.class` — метод подтверждения владения доменом через HTTP, в данном случае с использованием Ingress-контроллера nginx. Если вы используете другой Ingress-контроллер, необходимо заменить `nginx` на нужное значение, например, для Traefik: ```yml solvers: - http01: ingress: class: traefik ``` ## Пример использования cert-manager Рассмотрим использование cert-manager на примере ресурсов, описанных в статье про [Nginx Ingress](https://timeweb.cloud/docs/k8s/addons/nginx-ingress). Если вы следовали той инструкции, у вас уже настроены: - 3 деплоймента - Nginx Ingress - LoadBalancer Сервисы доступны по: - http://ingress1.example.com/service1 - http://ingress1.example.com/service2 - http://ingress2.example.com/ Теперь опишем `ClusterIssuer` в файле `cluster-issuer.yaml`: ```yml apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: email: email@example.com server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: nginx ``` Применим манифест: ```shell kubectl apply -f cluster-issuer.yaml ``` Далее необходимо обновить манифест Ingress, добавив аннотацию для использования cert-manager и секцию `tls`. Обновленный `ingress.yaml`: ```yml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress namespace: ingress-example annotations: nginx.ingress.kubernetes.io/rewrite-target: / cert-manager.io/cluster-issuer: letsencrypt-prod spec: rules: - host: ingress1.example.com http: paths: - path: /service1 pathType: Prefix backend: service: name: service1 port: number: 80 - path: /service2 pathType: Prefix backend: service: name: service2 port: number: 80 tls: - hosts: - ingress1.example.com secretName: ingress-tls ``` Изменения: - Добавлена аннотация `cert-manager.io/cluster-issuer: letsencrypt-prod`, указывающая cert-manager использовать созданный `ClusterIssuer`. - Добавлена секция `tls`, в которой указаны домены, для которых cert-manager должен выпустить сертификаты, и секрет `ingress-tls`, где они будут храниться. Применяем обновленный манифест: ```shell kubectl apply -f ingress.yaml ``` Через некоторое время cert-manager выпустит сертификаты и сохранит их в секрете `ingress-tls`. Проверить наличие сертификатов можно командой: ```shell kubectl get secret ingress-tls -n ingress-example -o yaml ``` Если все прошло успешно, в секрете должны появиться `tls.crt` и `tls.key`. Теперь можно проверить работу HTTPS: ```shell curl -v https://ingress1.example.com/service1 ``` Если запрос проходит без ошибок, значит, сертификаты успешно установлены, и сервисы работают по HTTPS. # cert-manager Webhook Source: https://timeweb.cloud/docs/k8s/addons/cert-manager-webhook?utm_source=llms_txt&utm_medium=ai cert-manager Webhook используется для автоматического создания DNS-записей при валидации домена с помощью метода DNS-01. Для корректной работы дополнения необходимо, чтобы: - домен делегированы [на наши NS](https://timeweb.cloud/docs/domains/dns-records-management#ns-servery); - в кластере установлен [cert-manager.](https://timeweb.cloud/docs/k8s/addons/cert-manager) ## Установка cert-manager Webhook Установите дополнение cert-manager Webhook через панель управления Kubernetes в разделе «Дополнения».  ![Selection 283](https://content.timeweb.com/assets/821186e5-8b5a-4f02-80df-a8f0046c71b7.png?width=1038&height=950) После установки убедитесь, что запущен под, отвечающий за DNS01-валидацию: ```shell kubectl get pods -n cert-manager -l app=cert-manager-webhook-timeweb-cloud ``` У пода должен быть статус `Running`. ## Настройка ClusterIssuer Чтобы cert-manager мог выпускать сертификаты, необходимо создать объект `ClusterIssuer`. Он описывает, каким способом и через какого провайдера cert-manager будет выполнять валидацию доменов и получать сертификаты. Объект `ClusterIssuer` действует на уровне всего кластера и может использоваться из любых namespace'ов. Создайте файл `cluster-issuer.yaml`: ```yaml apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-dns spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: email@example.com # Укажите вашу почту privateKeySecretRef: name: letsencrypt-dns-account-key solvers: - dns01: webhook: groupName: twcloud- # Укажите ID вашего кластера solverName: twcloud-dns ``` Значение `privateKeySecretRef` указывает, где будет храниться ключ учетной записи, с помощью которой cert-manager взаимодействует с Let's Encrypt. Параметр `groupName` обязательно должен содержать ID вашего кластера. Его можно посмотреть в адресной строке браузера при открытии страницы управления кластером. ![Selection 284](https://content.timeweb.com/assets/7f13f3b4-db29-4948-92fe-addfcfb1fef4.png?width=1265&height=1000) Примените манифест: ```shell kubectl apply -f cluster-issuer.yaml ``` ## Выпуск сертификата Создайте файл `certificate.yaml`: ```yaml apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: example-com-tls namespace: default spec: secretName: example-com-tls issuerRef: name: letsencrypt-dns kind: ClusterIssuer dnsNames: - example.com - www.example.com ``` При использовании wildcard-домена обязательно заключайте его в кавычки: ```yaml dnsNames: - "*.example.com" ``` Для корректной работы сертификат должен находиться в том же неймспейсе, что и Ingress. Проверьте, что в манифесте указан нужный неймспейс. Замените домены на свои и примените манифест: ```shell kubectl apply -f certificate.yaml ``` ## Проверка статуса Проверить текущий статус выпуска сертификата можно так: ```shell kubectl get certificaterequests,orders,challenges -n default ``` При успешном выпуске сертификата вы увидите примерно следующее: ```shell NAME APPROVED DENIED READY ISSUER REQUESTER AGE certificaterequest.cert-manager.io/example-com-tls-1 True True letsencrypt-dns system:serviceaccount:cert-manager:cert-manager 91s NAME STATE AGE order.acme.cert-manager.io/example-com-tls-1-1905819700 valid 91s ``` ## Проверка сертификата После успешного выпуска проверьте, что секрет с сертификатом создан: ```shell kubectl get secret example-com-tls -n default -o yaml ``` Секрет будет содержать ключи `tls.crt` и `tls.key`. # Cluster Proportional Autoscaler Source: https://timeweb.cloud/docs/k8s/addons/cpa?utm_source=llms_txt&utm_medium=ai Cluster Proportional Autoscaler (CPA) — это контроллер, который автоматически масштабирует выбранный деплоймент в зависимости от количества нод в кластере. Он полезен в случаях, когда сервис должен быть доступен на каждой ноде или масштабироваться пропорционально объему ресурсов в кластере. CPA не использует метрики нагрузки, а работает на основе пропорциональных формул, которые задаются вручную.  ## Режимы работы CPA поддерживает два режима расчета количества реплик: ### Linear В режиме `linear` количество реплик рассчитывается по следующей формуле: ```shell replicas = max(min, min(max, cores / coresPerReplica, nodes / nodesPerReplica)) ``` Можно использовать оба параметра (`coresPerReplica` и `nodesPerReplica`) или только один. Значения `min` и `max` ограничивают итоговое число реплик. Пример настройки: ```yaml config: linear: coresPerReplica: 2 nodesPerReplica: 1 min: 2 max: 20 preventSinglePointFailure: true includeUnschedulableNodes: true ``` В этом примере: - создается по 1 поду на каждую ноду; - дополнительно создается 1 под на каждые 2 CPU ядра; - всегда минимум 2 пода, максимум 20; - при наличии только одной ноды будет не 1, а 2 пода; - учитываются и те ноды, на которые нельзя запланировать поды. ### Ladder В режиме `ladder` количество реплик задается явно, через таблицу соответствий. Это удобно, когда нужно точное количество подов при конкретных размерах кластера. Пример настройки: ```yaml config: ladder: coresToReplicas: - [ 1, 1 ] - [ 64, 3 ] - [ 512, 5 ] - [ 1024, 7 ] - [ 2048, 10 ] nodesToReplicas: - [ 1, 1 ] - [ 2, 2 ] - [ 5, 3 ] ``` В этом примере: - если в кластере 1 нода — будет 1 под; - при 2 нодах — 2 пода; - при 5 и более нодах — 3 пода; - параллельно будет учитываться количество ядер, например: - при 64 ядрах — 3 пода; - при 2048 — 10 подов. ## Установка через ПУ Для установки Cluster Proportional Autoscaler откройте панель управления кластером, перейдите во вкладку «Дополнения» и выберите Cluster Proportional Autoscaler. ![Selection 330](https://content.timeweb.com/assets/fb827072-f98b-435c-8fee-22e36d032b64.png?width=1007&height=859) В открывшемся мастере вы можете изменить конфигурацию скейлера, отредактировав манифест в блоке «Конфигурация». ![Selection 331](https://content.timeweb.com/assets/46c0dc7e-8240-4a9b-a205-67f7d37f34ee.png?width=1003&height=806) По умолчанию скейлер будет настроен для работы с `metrics-server` в неймспейсе `kube-system`. Он использует линейный режим, создавая один под на каждую ноду: ```yaml config: linear: coresPerReplica: 1 nodesPerReplica: 1 min: 1 max: 100 preventSinglePointFailure: true includeUnschedulableNodes: true options: logToStdErr: true logLevel: 7 namespace: kube-system target: deployment/metrics-server ``` Если вы хотите масштабировать другой сервис — например, nginx в неймспейсе default — достаточно изменить параметры `target` и `namespace` в конфигурации перед установкой. Если вы хотите изменить параметры масштабирования или режим работы, отредактируйте блок `config`. Вы можете, например, раскомментировать параметры для `ladder` и использовать его вместо `linear`. > [!NOTE] > При установке через панель управления можно указать только один объект для масштабирования через параметр `target`. > > Если вы хотите масштабировать несколько ресурсов одновременно — например, `metrics-server` и `coredns` — используйте ручную установку с несколькими экземплярами скейлера. ## Установка вручную Если вы хотите более гибко настроить Cluster Proportional Autoscaler или применить несколько скейлеров для разных сервисов, используйте установку через [Helm](https://timeweb.cloud/docs/k8s/deploy/helm). Сначала добавьте репозиторий чарта: ```shell helm repo add cluster-proportional-autoscaler https://kubernetes-sigs.github.io/cluster-proportional-autoscaler ``` Эта команда добавит внешний источник, из которого будет установлен скейлер. Затем обновите список доступных чартов: ```shell helm repo update ``` Создайте файл `values.yaml` со следующим содержимым: ```yaml config: linear: coresPerReplica: 1 nodesPerReplica: 1 min: 1 max: 100 preventSinglePointFailure: true includeUnschedulableNodes: true options: logToStdErr: true logLevel: 7 namespace: kube-system target: deployment/metrics-server serviceAccount: create: true ``` Эта конфигурация включает линейный режим, при котором создается один под на каждую ноду (`nodesPerReplica: 1`). Параметры `min` и `max` ограничивают количество реплик. Флаг `preventSinglePointFailure` добавляет дополнительную реплику при наличии всего одной ноды, а `includeUnschedulableNodes` учитывает ноды, на которые нельзя запланировать поды. В разделе `options` задаются `namespace` и объект, который будет масштабироваться — в нашем случае это `deployment/metrics-server.` Раздел `serviceAccount` указывает, что Helm должен создать сервис-аккаунт с нужными правами автоматически. Установите скейлер с помощью команды: ```shell helm upgrade --install metrics-autoscaler cluster-proportional-autoscaler/cluster-proportional-autoscaler --values values.yaml ``` После установки убедитесь, что pod запущен: ```shell kubectl get pods -n kube-system ``` При ручной установке вы можете создавать несколько независимых экземпляров скейлера для разных целей. Для этого создайте отдельный файл, например `values-nginx.yaml`, измените в нем параметры `target` и `namespace`, и примените новую установку: ```shell helm upgrade --install nginx-autoscaler cluster-proportional-autoscaler/cluster-proportional-autoscaler --values values-nginx.yaml ``` Такой способ позволяет масштабировать любое количество сервисов с разными настройками. # CSI S3 Source: https://timeweb.cloud/docs/k8s/addons/csi-s3?utm_source=llms_txt&utm_medium=ai Интеграция S3 в Kubernetes позволяет приложениям работать с объектным хранилищем как с обычной файловой системой. В Timeweb Cloud для этого используется CSI S3 (Container Storage Interface), который обеспечивает прозрачное подключение S3-бакетов к подам Kubernetes. Рассмотрим, как настроить использование CSI S3 в кластере Kubernetes. ## Установка CSI S3 Добавьте CSI S3 в существующий кластер следующим образом: 1. Перейдите во вкладку «Дополнения» на странице управления кластером. 2. Нажмите на три точки рядом с дополнением CSI S3 и выберите «Установить». ![Image2](https://content.timeweb.com/assets/5f93da12-34fa-48a9-be6a-3b49b4e7f897.png?width=762&height=387) 3. В появившемся окне выберите существующий S3-бакет, создайте новый или подключите внешний бакет S3. ![Image3](https://content.timeweb.com/assets/2c0b7594-5d24-4168-9744-1806a8aaa97e.png?width=764&height=534) После выбора бакета нажмите «Установить» и дождитесь завершения процесса. После установки бакет будет доступен для использования в кластере, и никаких дополнительных настроек не потребуется. ## Проверка установки Чтобы убедиться, что CSI S3 успешно установлен и подключен, выполните команду для получения списка `StorageClass`: ```shell kubectl get storageclass csi-s3 -o yaml ``` Также вы можете просмотреть данные для подключения S3, выполнив следующую команду: ```shell kubectl get secret csi-s3-secret -n csi-s3 -o yaml ``` Данные будут представлены в секции `data`, в формате `base64`. ## Использование CSI S3 в Kubernetes S3 — это объектное хранилище, и Kubernetes не может напрямую взаимодействовать с ним, так как Kubernetes работает с файловыми системами и блочными устройствами. Для подключения используется `PersistentVolumeClaim` (PVC), который позволяет приложениям запрашивать доступ к S3 через CSI-драйвер. Для монтирования S3-бакета используется FUSE-прослойка `geesefs`, которая обеспечивает доступ к файлам в S3 как к обычной файловой системе. Важно отметить, что CSI S3 не является полноценной POSIX-совместимой файловой системой. Это решение подходит для размещения статических файлов, таких как изображения, CSS, JS, конфигурационные файлы, или другие данные, которые не требуют высокой дисковой активности. Из-за отсутствия полной POSIX-совместимости могут возникнуть проблемы с размещением баз данных или других приложений, которые пытаются изменить права доступа или владельца файлов и папок. Также не поддерживаются частичная перезапись файлов и создание жестких ссылок (hardlinks). PVC выполняет роль «заявки» на хранилище. Это запрос к Kubernetes с просьбой предоставить хранилище с определенными параметрами. В ответ на этот запрос Kubernetes создает соответствующий PersistentVolume (PV), который затем связывается с PVC, обеспечивая доступ к хранилищу. Таким образом, CSI S3 преобразует объектное хранилище в том, который можно монтировать в поды. Ниже представлен пример манифеста `PersistentVolumeClaim` для подключения к S3: ```yml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: csi-s3-pvc namespace: default spec: accessModes: - ReadWriteMany resources: requests: storage: 5Gi storageClassName: csi-s3 ``` #### Основные параметры PVC манифеста: - `apiVersion` и `kind`: Указывают, что данный ресурс является `PersistentVolumeClaim` версии v1. - `metadata`: Содержит имя PVC (`csi-s3-pvc`) и указывает, что он создается в неймспейсе `default`. - `accessModes`: Задает режим доступа к хранилищу. В данном случае используется `ReadWriteMany`, что означает возможность чтения и записи в хранилище несколькими подами одновременно. - `resources.requests.storage`: Указывает, что PVC запрашивает 5 GiB пространства в хранилище. Этот объем может быть использован приложением для размещения файлов. - `storageClassName`: Указывает, что используется StorageClass с именем `csi-s3`.  ## Подключение PVC в Deployment Чтобы приложение могло использовать PVC, его необходимо подключить в манифесте Deployment. Пример ниже демонстрирует, как контейнер с образом Nginx использует подключенный PVC: ```yml apiVersion: apps/v1 kind: Deployment metadata: name: s3-app-deployment namespace: default spec: replicas: 1 selector: matchLabels: app: s3-app template: metadata: labels: app: s3-app spec: containers: - name: s3-app-container image: nginx volumeMounts: - name: s3-storage mountPath: /usr/share/nginx/html volumes: - name: s3-storage persistentVolumeClaim: claimName: csi-s3-pvc ``` #### Основные элементы манифеста Deployment: - `apiVersion` и `kind`: Указывают, что данный ресурс является Deployment версии `apps/v1`. - `metadata`: Содержит имя деплоймента (`s3-app-deployment`) и указывает, что он создается в неймспейсе `default`. - `replicas`: Задает количество реплик (в данном случае — 1), что позволяет масштабировать приложение. - `template`: Содержит спецификацию пода, который будет развернут в составе деплоймента. - `containers`: Описывает контейнеры, входящие в состав пода. В этом примере используется контейнер с образом `nginx`. - `volumeMounts`: Определяет точку монтирования тома в контейнере. В данном случае PVC монтируется в каталог `/usr/share/nginx/html`, чтобы контейнер мог использовать данные, размещенные в S3. - `volumes`: Описывает тома, используемые в поде. Здесь указано, что том `s3-storage` связан с PVC `csi-s3-pvc`. Это значит, что данные из S3 будут доступны контейнерам через этот том. Использование PVC позволяет приложению получить доступ к данным в S3, а также упрощает управление доступом и масштабирование, обеспечивая каждой реплике доступ к общим данным. # DBaaS Operator Source: https://timeweb.cloud/docs/k8s/addons/dbaas-operator?utm_source=llms_txt&utm_medium=ai TWC DBaaS Operator — это дополнение для Kubernetes, которое позволяет создавать и управлять облачными базами данных напрямую из кластера. Поддерживаемые базы данных: - [MySQL](https://timeweb.cloud/docs/dbaas/mysql) - [PostgreSQL](https://timeweb.cloud/docs/dbaas/postgresql) - [Redis](https://timeweb.cloud/docs/dbaas/redis) ## Установка Для установки дополнения перейдите в раздел «Дополнения» в панели управления кластером и выберите «TWC DBaaS Operator». ![Scr 20250806 Njjd](https://content.timeweb.com/assets/2e90274c-ef17-4522-939c-6081c1fcb368.png?width=2012&height=1444) В открывшемся окне нажмите кнопку «Установить» и дождитесь завершения установки. ![Scr 20250806 Njnp](https://content.timeweb.com/assets/9be9e6d3-b25e-436d-bcd8-f98521a69cdb.png?width=2006&height=962) После завершения установки, убедитесь, что все работает корректно. Для этого выполните команду: ```shell kubectl get pod -n tw-dbaas-operator ``` В выводе должен быть под со статусом `Running`: ```shell NAME READY STATUS RESTARTS AGE tw-dbaas-operator-856f97b959-k5jvp 1/1 Running 0 27m ``` Оператор создает три ресурса CustomResourceDefinition (CRD): - `instances.dbaas.timeweb.cloud` — управление инстансами DBaaS. - `databases.dbaas.timeweb.cloud` — управление базами данных внутри инстансов. - `users.dbaas.timeweb.cloud` — управление пользователями баз данных. ## Использование Работу с DBaaS через оператор можно разделить на три шага: 1. Создание инстанса базы данных. 2. Создание базы данных внутри инстанса. 3. Создание пользователей. ### Создание инстанса Сперва необходимо создать инстанс — это сама облачная база данных, с заданным типом, версией, конфигурацией и параметрами резервного копирования. Пример манифеста: ```yaml apiVersion: dbaas.timeweb.cloud/v1 kind: Instance metadata: name: mysqldbaas spec: type: "mysql" # mysql / redis / postgresql name: "k8smysql" # отображаемое имя в панели version: "8.0" pass_hash_type: "sha2" # только для MySQL (sha2 или native) backups: copy_count: 2 period: "day" enabled: true config: auto_increment_increment: "1" replica_count: 1 # количество реплик. Поддерживается только для MySQL и PostgreSQL. Поддерживаемые значения: 1, 3, 5.   no_external_ip: false instance_size: preset_id: 123 ``` Параметры в блоке `config` уникальны для каждого типа базы данных. Список доступных параметров можно найти в отдельных статьях: - [MySQL](https://timeweb.cloud/docs/dbaas/mysql/parameters) - [PostgreSQL](https://timeweb.cloud/docs/dbaas/postgresql/parameters) - [Redis](https://timeweb.cloud/docs/dbaas/redis/parameters) Подходящий `preset_id` можно получить [при помощи запроса к API](https://timeweb.cloud/api-docs#tag/Bazy-dannyh/operation/getDatabasesPresets): ```bash curl -X GET \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TIMEWEB_CLOUD_TOKEN" \ "https://api.timeweb.cloud/api/v2/presets/dbs" ``` Для удобства можно использовать команду с фильтрацией и форматированием: ```bash curl -sS -H "Authorization: Bearer $TIMEWEB_CLOUD_TOKEN" \ "https://api.timeweb.cloud/api/v2/presets/dbs" \ | jq -r '.databases_presets[] | select(.type=="mysql") | [.id, .description_short, .location, .price] | @tsv' \ | column -t ``` ID пресета будет указан в первом столбце. При необходимости измените `type=="mysql"` на нужный тип базы данных. ### Создание базы данных После создания инстанса можно описать базы данных, которые будут в нем размещены. Пример манифеста: ```yaml apiVersion: dbaas.timeweb.cloud/v1 kind: Database metadata: name: database-sample spec: database_list: - name: "default_db" description: "" - name: "db0" description: "new db" dbaas_instance: name: "mysqldbaas" namespace: "default" ``` Поле `dbaas_instance` должно указывать на соответствующий инстанс. ### Включение расширений PostgreSQL Для баз PostgreSQL можно включить расширения. Для этого в манифесте `Database` добавьте поле `extensions` и перечислите в нем нужные расширения. Пример манифеста: ```yaml apiVersion: dbaas.timeweb.cloud/v1 kind: Database metadata: name: postgres-pgvector namespace: default spec: database_list: - name: "default_db" description: "PostgreSQL база с расширениями" dbaas_instance: name: "postgres-instance" namespace: "default" extensions: - "pg_stat_statements" - "timescaledb" - "postgres_fdw" - "postgis" - "uuid-ossp" - "amcheck" - "pg_stat_kcache" - "pg_trgm" - "pgcrypto" - "pgvector" - "citext" - "pgagent" - "postgis_topology" ``` Поле `extensions` поддерживается только для PostgreSQL. Для MySQL и Redis его указывать не нужно. Чтобы отключить расширения, передайте пустой список: ```yaml apiVersion: dbaas.timeweb.cloud/v1 kind: Database metadata: name: postgres-pgvector namespace: default spec: database_list: - name: "default_db" description: "PostgreSQL база с расширениями" dbaas_instance: name: "postgres-instance" namespace: "default" extensions: [] ``` ### Создание пользователя После того как базы данных созданы, можно добавить пользователей и выдать им права доступа. Пользователь привязывается к конкретному инстансу и может иметь разные права для разных баз внутри него. Пример манифеста: ```yaml apiVersion: dbaas.timeweb.cloud/v1 kind: User metadata: name: user-sample spec: user: "user0" passwordSecret: "user0Secret" description: "cool user" host: "192.168.%" permissions: - grants: ["ALTER", "UPDATE", "DELETE", "INSERT"] database: "default_db" - grants: ["SELECT"] database: "db1" dbaas_instance: name: "mysqldbaas" namespace: "default" --- apiVersion: v1 kind: Secret metadata: name: user0Secret type: Opaque data: password: cGFzc3dvcmQxMjM0 ``` Пароль для пользователя хранится в Kubernetes Secret в поле `password`, закодированном в base64. Создать его можно так: `echo -n 'пароль' | base64` В разделе permissions указываются права пользователя на конкретные базы данных. Права задаются в виде списка SQL-грантов для каждой базы. Список доступных привилегий можно найти в статьях: - [MySQL](https://timeweb.cloud/docs/dbaas/mysql/users-and-privileges#dostupnye-privilegii) - [PostgreSQL](https://timeweb.cloud/docs/dbaas/postgresql/users-and-privileges#dostupnye-privilegii) - [Redis](https://timeweb.cloud/docs/dbaas/redis/users-and-privileges#dostupnye-privilegii) # Envoy Gateway Source: https://timeweb.cloud/docs/k8s/addons/envoy-gateway?utm_source=llms_txt&utm_medium=ai Envoy Gateway — это контроллер Gateway API для Kubernetes, который использует Envoy Proxy для обработки входящего трафика. С его помощью можно публиковать HTTP, HTTPS, gRPC, TCP и UDP-сервисы, настраивать маршрутизацию по доменам и путям, управлять TLS и применять политики трафика через стандартные Kubernetes-ресурсы. Gateway API можно рассматривать как развитие Ingress. Вместо одного ресурса Ingress используются несколько объектов с разными зонами ответственности: - `GatewayClass` — указывает, какой контроллер будет обслуживать шлюзы. - `Gateway` — описывает точку входа: порты, протоколы и TLS-настройки. - `HTTPRoute` — задает правила маршрутизации HTTP-трафика к сервисам. - `GRPCRoute`, `TCPRoute`, `UDPRoute`, `TLSRoute` — используются для других типов трафика. Envoy Gateway отслеживает эти ресурсы и на их основе создает Envoy Proxy, который принимает внешний трафик и направляет его к сервисам внутри кластера. ## Установка Для установки Envoy Gateway откройте панель управления кластером, перейдите во вкладку «Дополнения» и выберите Envoy Gateway. В открывшемся мастере установки можно оставить параметры по умолчанию или включить продвинутую установку и изменить `values.yaml`. Для начала работы достаточно настроек по умолчанию. Нажмите «Установить» и дождитесь завершения установки. После этого проверьте, что поды Envoy Gateway запущены: ```bash kubectl get pods -n envoy-gateway-system ``` Все поды должны находиться в статусе `Running`. Также можно проверить, что в кластере появились ресурсы Gateway API: ```shell kubectl api-resources | grep gateway.networking.k8s.io ``` ## Пример использования Рассмотрим пример, в котором Envoy Gateway будет принимать HTTP-трафик на одном внешнем IP-адресе и направлять запросы в два разных сервиса: - `http://app.example.com/service1` — в сервис `service1`; - `http://app.example.com/service2` — в сервис `service2`. Для примера создадим отдельный неймспейс: ```bash kubectl create namespace envoy-example ``` ### Создание ConfigMap Создайте файл `configmap.yaml` с HTML-страницами для двух сервисов: ```shell apiVersion: v1 kind: ConfigMap metadata: name: nginx-pages namespace: envoy-example data: service1.html: | Service 1

Service 1

service2.html: | Service 2

Service 2

``` Примените манифест: ```bash kubectl apply -f configmap.yaml ``` ### Создание Deployment и Service Создайте файл `service1.yaml`: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: service1 namespace: envoy-example spec: replicas: 2 selector: matchLabels: app: service1 template: metadata: labels: app: service1 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html configMap: name: nginx-pages items: - key: service1.html path: index.html --- apiVersion: v1 kind: Service metadata: name: service1 namespace: envoy-example spec: selector: app: service1 ports: - name: http port: 80 targetPort: 80 type: ClusterIP ``` Создайте файл `service2.yaml`: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: service2 namespace: envoy-example spec: replicas: 2 selector: matchLabels: app: service2 template: metadata: labels: app: service2 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html configMap: name: nginx-pages items: - key: service2.html path: index.html --- apiVersion: v1 kind: Service metadata: name: service2 namespace: envoy-example spec: selector: app: service2 ports: - name: http port: 80 targetPort: 80 type: ClusterIP ``` Примените манифесты: ```bash kubectl apply -f service1.yaml kubectl apply -f service2.yaml ``` Проверьте, что поды запущены: ```bash kubectl get pods -n envoy-example ``` ### Создание GatewayClass `GatewayClass` связывает Gateway API с контроллером Envoy Gateway. Создайте файл `gatewayclass.yaml`: ```yaml apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: envoy-gateway spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller ``` Примените манифест: ```bash kubectl apply -f gatewayclass.yaml ``` Проверьте статус: ```bash kubectl get gatewayclass envoy-gateway ``` В колонке `ACCEPTED` должно быть значение `True`. Это означает, что Envoy Gateway принял `GatewayClass` и будет обслуживать связанные с ним ресурсы `Gateway`. ### Создание Gateway Gateway описывает внешний вход в приложение. Создайте файл `gateway.yaml`: ```yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: app-gateway namespace: envoy-example spec: gatewayClassName: envoy-gateway listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: Same ``` Примените манифест: ```bash kubectl apply -f gateway.yaml ``` Когда `Gateway` будет создан, Envoy Gateway развернет Envoy Proxy и балансировщик нагрузки. Создание балансировщика можно отследить [в панели управления](https://timeweb.cloud/my/balancer) или проверить командой: ```bash kubectl get gateway app-gateway -n envoy-example ``` Дождитесь, когда в колонке `PROGRAMMED` появится значение `True`, а в колонке `ADDRESS` — внешний IP-адрес. Также можно посмотреть созданный сервис: ```bash kubectl get svc -n envoy-gateway-system \ -l gateway.envoyproxy.io/owning-gateway-namespace=envoy-example,gateway.envoyproxy.io/owning-gateway-name=app-gateway ``` Envoy Gateway по умолчанию создает балансировщик для каждого `Gateway`. Поэтому отдельный манифест `Service` типа `LoadBalancer`, как в классическом сценарии с Ingress-контроллером, не требуется. ### Создание HTTPRoute HTTPRoute задает правила маршрутизации. Создайте файл `httproute.yaml`: ```yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: app-route namespace: envoy-example spec: parentRefs: - name: app-gateway hostnames: - app.example.com rules: - matches: - path: type: PathPrefix value: /service1 filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefixMatch replacePrefixMatch: / backendRefs: - name: service1 port: 80 - matches: - path: type: PathPrefix value: /service2 filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefixMatch replacePrefixMatch: / backendRefs: - name: service2 port: 80 ``` Примените манифест: ```bash kubectl apply -f httproute.yaml ``` Проверьте, что маршрут принят: ```bash kubectl get httproute app-route -n envoy-example -o yaml ``` В статусе ресурса должно быть: ```bash status: "True" type: Accepted ``` В этом манифесте `HTTPRoute` принимает запросы с доменом `app.example.com` и направляет их в разные сервисы по префиксу пути. Фильтр `URLRewrite` заменяет префиксы `/service1` и `/service2` на `/`, чтобы Nginx внутри каждого сервиса отдавал свою главную страницу. ### Проверка работы Получите внешний IP-адрес Gateway: ```bash kubectl get gateway app-gateway -n envoy-example ``` Пропишите этот IP-адрес в DNS-настройках домена app.example.com в виде A-записи. После обновления DNS проверьте доступность сервисов: ```bash curl http://app.example.com/service1 curl http://app.example.com/service2 ``` Если DNS еще не обновился, можно выполнить проверку по IP-адресу, передав заголовок `Host`: ```bash curl -H "Host: app.example.com" http:///service1 curl -H "Host: app.example.com" http:///service2 ``` В ответе должны отображаться страницы `Service 1` и `Service 2`. ### Удаление примера Чтобы удалить ресурсы, созданные в примере, выполните: ```bash kubectl delete namespace envoy-example kubectl delete gatewayclass envoy-gateway ``` Дополнение Envoy Gateway при этом останется установленным в кластере. Удалить его можно во вкладке «Дополнения» в панели управления кластером. ## Миграция с Nginx Ingress на Envoy Gateway Envoy Gateway можно развернуть рядом с Nginx Ingress и переносить маршруты постепенно. Такой подход позволяет сначала проверить ресурсы Gateway API на отдельном внешнем IP-адресе, а затем переключить DNS-записи или трафик на новый Gateway. Для автоматической конвертации Ingress-ресурсов можно использовать утилиту [ingress2gateway](https://github.com/kubernetes-sigs/ingress2gateway). Она читает существующие Ingress-ресурсы из кластера и выводит эквивалентные ресурсы Gateway API: `Gateway`, `HTTPRoute` и другие объекты. > [!NOTE] > ingress2gateway помогает подготовить миграцию, но не заменяет ручную проверку. Некоторые аннотации Nginx Ingress могут быть не поддержаны или потребовать ручной настройки после конвертации. ### Требования Перед миграцией подготовьте кластер: - установите Envoy Gateway; - [создайте GatewayClass](https://timeweb.cloud/docs/k8s/addons/envoy-gateway#sozdanie-gateway) для Envoy Gateway; - проверьте, что исходные Ingress-ресурсы работают через Nginx Ingress. Проверьте, что в кластере есть нужные классы: ```bash kubectl get ingressclass kubectl get gatewayclass ``` В выводе должны быть: - `IngressClass` с именем `nginx`; - `GatewayClass` с именем `envoy-gateway`. ### Установка ingress2gateway Если на локальной машине установлен Go, установите ingress2gateway командой: ```bash go install github.com/kubernetes-sigs/ingress2gateway@v1.0.0 ``` После установки бинарный файл будет доступен в директории `$(go env GOPATH)/bin`. Убедитесь, что эта директория добавлена в `PATH`. Также можно установить ingress2gateway через Homebrew: ```bash brew install ingress2gateway ``` Или скачать готовый бинарный файл со страницы [релизов проекта](https://github.com/kubernetes-sigs/ingress2gateway/releases). ### Исходный пример В примере ниже миграция выполняется для приложения, которое уже опубликовано через Nginx Ingress. В кластере есть неймспейс `ingress-migration-demo`. В нем находятся: - Ingress `migration-source`; - Service `service1` и `service2`; - два правила маршрутизации для домена `ingress-migration.example.com`: - `/service1` направляет трафик в `service1`; - `/service2` направляет трафик в `service2`. Проверьте исходный Ingress: ```bash kubectl get ingress -n ingress-migration-demo ``` В колонке `CLASS` должно быть значение `nginx`. ### Конвертация Ingress-ресурсов Чтобы сконвертировать этот Ingress в ресурсы Gateway API, выполните: ```bash ingress2gateway print \ --providers=ingress-nginx \ --emitter=envoy-gateway \ --ingress-nginx-ingress-class=nginx \ --namespace=ingress-migration-demo > gateway-migration.yaml ``` В этой команде: - `print` — режим, в котором ingress2gateway выводит сгенерированные ресурсы в стандартный вывод. За счет перенаправления `>` результат сохраняется в файл `gateway-migration.yaml`. - `--providers=ingress-nginx` — указывает тип исходного Ingress-контроллера. В этом примере исходные маршруты обслуживает Nginx Ingress, поэтому используется значение `ingress-nginx`. - `--emitter=envoy-gateway` — указывает, для какого Gateway API-контроллера подготовить результат. В этом примере целевой контроллер — Envoy Gateway. - `--ingress-nginx-ingress-class=nginx` — выбирает только Ingress-ресурсы класса `nginx`. Такой класс создает аддон Nginx Ingress в Timeweb Cloud. - `--namespace=ingress-migration-demo` — ограничивает чтение ресурсов неймспейсом `ingress-migration-demo`, где находится исходный Ingress из примера. Откройте файл `gateway-migration.yaml` и проверьте сгенерированные ресурсы перед применением. Проверьте `gatewayClassName` у ресурса `Gateway`. ingress2gateway может сгенерировать это значение на основе имени исходного `IngressClass`. Например, если исходный Ingress использует класс `nginx`, в сгенерированном Gateway может появиться: ```yaml spec: gatewayClassName: nginx ``` Envoy Gateway не будет обрабатывать такой `Gateway`, если в кластере нет `GatewayClass` с именем `nginx`. Для `GatewayClass` из примера замените значение на `envoy-gateway`: ```yaml spec: gatewayClassName: envoy-gateway ``` ### Применение ресурсов Gateway API После проверки примените файл: ```bash kubectl apply -f gateway-migration.yaml ``` Проверьте, что Gateway создан и получил внешний IP-адрес: ```bash kubectl get gateway -A ``` ### Тестирование перед переключением трафика Пока DNS-записи указывают на старый Nginx Ingress, новый Gateway можно проверить по внешнему IP-адресу с заголовком `Host`: ```bash curl -H "Host: app.example.com" http:/// ``` Где: - `app.example.com` — домен из `HTTPRoute`; - `` — IP-адрес нового Gateway; - `` — путь, который должен обрабатываться маршрутом. Сравните ответы старого Ingress и нового Gateway. Если все работает корректно, можно изменить DNS-записи на IP нового балансировщика. # ExternalDNS Source: https://timeweb.cloud/docs/k8s/addons/externaldns?utm_source=llms_txt&utm_medium=ai ExternalDNS — инструмент для автоматического управления DNS-записями на основе ресурсов Kubernetes. Он обновляет DNS-записи в соответствии с аннотациями, указанными в манифестах сервисов и ingress-ресурсов. ExternalDNS помогает упростить управление доменными именами для сервисов в кластере Kubernetes, устраняя необходимость вручную изменять записи в панели управления DNS. ## Установка Для установки ExternalDNS откройте панель управления кластером, перейдите во вкладку «Дополнения», нажмите на три точки рядом с ExternalDNS и нажмите «Установить». ![Selection 182](https://content.timeweb.com/assets/ec06f496-6887-4d0d-a065-de4908ab92c3.png?width=1028&height=860) После установки дождитесь обновления кластера и убедитесь, что ресурсы ExternalDNS имеют статус «Running»: ```shell kubectl get pods -n external-dns ``` ## Использование ExternalDNS Перед использованием ExternalDNS необходимо вручную создать домены в панели управления, чтобы ExternalDNS мог управлять их записями. #### Использование аннотаций в Ingress ExternalDNS управляет DNS-записями на основе аннотаций в манифестах. Например, для привязки доменного имени к Ingress-ресурсу можно использовать следующий манифест: ```yml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress namespace: ingress-example annotations: external-dns.alpha.kubernetes.io/hostname: "app.example.com" external-dns.alpha.kubernetes.io/ttl: "1200" spec: rules: - host: app.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-app port: number: 80 ``` Описание аннотаций: - `external-dns.alpha.kubernetes.io/hostname` — задает доменное имя, которое будет связано с этим ресурсом. - `external-dns.alpha.kubernetes.io/ttl` — задает TTL DNS-записи в секундах. Этот вариант подойдет, если Ingress-контроллер развернут на всех узлах. Однако у него есть недостатки: - Если Ingress-контроллер работает не на всех узлах, часть трафика может отправляться на недоступные IP-адреса. - Kubernetes может переместить поды на другие узлы, изменив IP-адреса, что приведет к недоступности сервиса. - DNS-балансировка не учитывает доступность узлов, из-за чего могут возникнуть потери трафика. #### Использование LoadBalancer (рекомендуемый вариант) Один из удобных способов работы с ExternalDNS — использовать его с [балансировщиком нагрузки](https://timeweb.cloud/docs/k8s/network/kubernetes-load-balancer). В этом случае сервис получает фиксированный внешний IP-адрес и балансирует трафик между подами. ExternalDNS автоматически создаст DNS-запись с этим IP-адресом. Пример манифеста: ```yml apiVersion: v1 kind: Service metadata: name: ingress-nginx namespace: ingress-nginx annotations: external-dns.alpha.kubernetes.io/hostname: "app.example.com" external-dns.alpha.kubernetes.io/ttl: "1200" spec: selector: app.kubernetes.io/name: ingress-nginx ports: - name: http port: 80 targetPort: 80 - name: https port: 443 targetPort: 443 type: LoadBalancer ``` В этом примере балансировщик направляет трафик в поды с `app.kubernetes.io/name: ingress-nginx`, где работает Ingress-контроллер. Использование ExternalDNS с балансировщиком нагрузки упрощает управление DNS. Вместо того чтобы следить за изменением IP-адресов на разных узлах, достаточно привязать доменное имя к одному фиксированному IP. Это снижает риски недоступности из-за смены узлов, а балансировка нагрузки между подами обеспечивает стабильную работу сервиса. При изменении конфигурации кластера ExternalDNS автоматически обновит DNS-запись, исключая необходимость ручного вмешательства. # Fluent Operator Source: https://timeweb.cloud/docs/k8s/addons/fluent-operator?utm_source=llms_txt&utm_medium=ai В кластерах Kubernetes приложения и системные сервисы генерируют большое количество логов. Для удобного анализа и хранения этих логов их можно собирать в системы вроде Elasticsearch, Loki, Kafka, Prometheus и других. Fluent Bit и Fluentd — инструменты для сбора и обработки логов. Но их настройка в Kubernetes может быть сложной: - Необходимо вручную создавать ресурсы (DaemonSet, StatefulSet); - Настраивать конфигурационные файлы; - Учитывать особенности контейнерных рантаймов; - Управлять секретами для аутентификации; - Следить за обновлениями и совместимостью. Fluent Operator упрощает этот процесс: - Автоматизирует развертывание Fluent Bit и Fluentd, создавая необходимые ресурсы. - Использует Custom Resource Definitions (CRD) для настройки входов, фильтров, выходов и других параметров через YAML-манифест. - Управляет обновлениями и масштабированием Fluent Bit/Fluentd в ответ на изменения в кластере. - Упрощает интеграцию с Elasticsearch, Loki, Kafka, Prometheus и другими. Вместо ручного создания конфигурации для Fluent Bit и Fluentd, вы устанавливаете Fluent Operator и описываете настройки. Оператор приводит кластер в нужное состояние и автоматически обновляет агенты при изменении конфигурации. #### Основные компоненты - **Fluent Bit**: легкий агент для сбора логов. - **Fluentd**: мощный агент, который можно использовать как DaemonSet или StatefulSet для сложной фильтрации и буферизации. - **Fluent Operator**: управляет Fluent Bit и Fluentd через CRD. ## Установка Fluent Operator можно установить через панель управления кластером: 1. Перейдите во вкладку «Дополнения» и найдите дополнение Fluent Operator. ![Selection 170](https://content.timeweb.com/assets/491f370e-0d84-4a29-a9b0-a1deb73145e4.png?width=1001&height=918) 2. Нажмите на него, чтобы открыть мастер настройки. 3. Выберите «Продвинутая установка», отредактируйте конфигурацию под свои задачи и нажмите «Установить». ![Selection 171](https://content.timeweb.com/assets/a7710a08-533d-4850-9ed3-ddc56496b6f2.png?width=996&height=803) ## Параметры установки #### Operator Секция `operator:` - **containerRuntime**: задает используемый контейнерный рантайм. В нашем управляемом Kubernetes используется `containerd`. Это значение менять не нужно. - **logPath**: путь к логам. Для `containerd` используется `/var/log`. - **disableComponentControllers**: список компонентов Fluent Operator, которые нужно отключить. Возможные значения: `fluent-bit` и `fluentd`. По умолчанию устанавливаются оба компонента. #### Fluent Bit Секция `input:` - `tail:` - `enable: true` — включает сбор логов с файлов, находящихся по пути `/var/log/containers/*.log`. - `path: "/var/log/containers/*.log"` — задает путь к лог-файлам контейнеров. - `refreshIntervalSeconds: 10` — частота обновления списка файлов логов (в секундах). - `memBufLimit: 100MB` — ограничение памяти для буфера. - `storageType: memory` — тип хранилища для буфера. Альтернативный вариант — `filesystem`, но перед использованием нужно подготовить том. - `readFromHead: false` — начинать читать логи с конца. - `skipLongLines: true` — пропускать слишком длинные строки. - `systemd:` - `enable: true` — включает сбор логов из journald. - `includeKubelet: true` — добавляет логи `kubelet` из `journald`. - `storageType: memory` — задает тип хранилища для буфера логов `journald`. Секция `output:` Здесь перечислены основные выходы. Для включения каждого достаточно выставить соответствующий ключ `enable: true` и задать параметры: **Elasticsearch** ```yml es: enable: false host: "" port: 9200 logstashPrefix: ks-logstash-log bufferSize: 20MB traceError: true httpUser: "" httpPassword: "" ``` Настройка для отправки логов в Elasticsearch. Укажите URL и порт сервиса, а также учетные данные для аутентификации. **Kafka** ```yml kafka: enable: false brokers: "" topics: ks-log bufferSize: 20MB retryLimit: "10" ``` Настройка для отправки логов в Kafka. Укажите список брокеров через запятую и топик для логов. **Loki** ```yml loki: enable: false retryLimit: "no_limits" host: 127.0.0.1 port: 3100 httpUser: myuser httpPassword: mypass tenantId: "" ``` Позволяет отправлять логи в Loki. Укажите хост, порт, учётные данные и идентификатор тенанта. **stdout** ```yml stdout: enable: true ``` Полезно для тестирования, так как выводит логи в стандартный вывод (`stdout`). Секция `filter:` - `multiline:` - `enable: false` — по умолчанию мультилайн отключён. - Можно настроить парсеры (go, python, java и т.д.) или подключать свои кастомные. - `kubernetes:` - `enable: true` — включает фильтр Kubernetes, чтобы дописывать метаданные подов, такие как `namespace`, `pod`, `labels`, `annotations`. - `labels: false`, `annotations: false` — по умолчанию не добавлять эти поля. - `containerd:` - `enable: true` — включает фильтр для парсинга Containerd-логов. - `systemd:` - `enable: true` — включает фильтр для парсинга `journald`. #### Fluentd - `enable` — если нужно использовать Fluentd (вместо или вместе с Fluent Bit), установите `true`. - `mode`: - `collector` — устанавливает StatefulSet. - `agent` — устанавливает DaemonSet (как Fluent Bit), то есть один агент на ноду. - `forward`: - `port: 24224` — стандартный вход в Fluentd через форвардинг. - `output` — аналогично Fluent Bit, есть секции `es`, `kafka`, `opensearch` и т.д. ## Удаление Удаление дополнения через панель управления не поддерживается, но его можно выполнить вручную. Для этого выполните следующие шаги: 1. Удалите объект `fluent-bit`: ```shell kubectl delete -n fluent-operator fluentbit/fluent-bit ``` 2. Удалите Helm-релиз `fluent-operator`: ```shell helm uninstall -n fluent-operator fluent-operator ``` 3. Удалите все CRD, связанные с `fluent-operator`: ```shell kubectl delete crd $(kubectl get crd | grep fluent | awk '{print $1}') ``` 4. Проверьте, что все связанные ресурсы и пространства имен удалены: ```shell kubectl get namespaces ``` После выполнения этих шагов Fluent Operator будет полностью удален из вашего кластера. # Grafana Loki Source: https://timeweb.cloud/docs/k8s/addons/grafana-loki?utm_source=llms_txt&utm_medium=ai Grafana Loki — это система сбора и просмотра логов, созданная командой Grafana Labs. Она используется совместно с Grafana для удобной визуализации логов. В отличие от ELK-стека, Loki не индексирует содержимое логов, а хранит их вместе с метаданными (например, имя пода или namespace). Это делает систему более быстрой и менее требовательной к ресурсам. Чаще всего Loki используется в связке с Promtail — агентом, который собирает логи с нод и отправляет их в Loki. Затем вы можете просматривать эти логи прямо в Grafana с помощью запросов на языке LogQL. ## Установка Для установки перейдите в раздел «Дополнения» в панели управления кластера.  ![Scr 20250702 Nwug](https://content.timeweb.com/assets/ccd7c712-1040-4d91-b94e-95d32dec837e.png?width=2042&height=1602) После выбора дополнения «Grafana Loki» в панели управления вы увидите YAML-конфигурацию с параметрами по умолчанию.  ![Scr 20250702 Nwyg](https://content.timeweb.com/assets/28cd4ab4-139a-449f-8e49-277608ba827c.png?width=2052&height=1612) Кратко опишем, за что отвечает каждый блок. ```yaml test_pod: enabled: true image: bats/bats:1.8.2 ``` Запускает тестовый под с утилитой `bats`, которая проверяет, что Loki доступен и принимает логи. Используется только для автоматической валидации после установки. ```yaml loki: enabled: true isDefault: true ``` Основной компонент — Loki, который принимает и хранит логи. Здесь можно настроить: - `url` — внутренний адрес сервиса Loki (используется другими компонентами). - `readinessProbe` и `livenessProbe` — проверки состояния сервиса. - `datasource` — настройки подключения к Loki как к источнику данных в Grafana. Если вы используете Grafana, `datasource.uid` может быть задан для явного подключения источника. ```yaml promtail: enabled: true config: clients: - url: http://:3100/loki/api/v1/push ``` Promtail — агент, который собирает логи с узлов кластера (из `/var/log/containers/*.log`) и отправляет их в Loki. Используется по умолчанию. Если вы планируете использовать альтернативные сборщики логов, например, Filebeat или Fluent Bit — можно отключить. ```yaml fluent-bit: enabled: false filebeat: enabled: false filebeatConfig: ... logstash: enabled: false filters: ... outputs: ... ``` Альтернативные агенты для сбора логов. Их можно включить, если Promtail не подходит для вашего случая (например, вы уже используете [Fluent Operator](https://timeweb.cloud/docs/k8s/addons/fluent-operator)). По умолчанию они отключены. ```yaml grafana: enabled: false ``` Отвечает за установку Grafana. Если вы хотите просматривать логи через веб-интерфейс — укажите значение `enabled: true`. Если в кластере уже установлена Grafana, можно оставить выключенным и подключить Loki вручную как источник данных. ```yaml prometheus: enabled: false isDefault: false url: ... ``` Позволяет подключить Prometheus как источник метрик в Grafana. Сам Prometheus при этом не устанавливается — этот блок лишь добавляет его как `datasource`. Можно включить, если у вас уже настроен Prometheus в кластере и вы хотите использовать его в Grafana вместе с Loki. ```yaml proxy: http_proxy: "" https_proxy: "" no_proxy: "" ``` Настройки прокси, которые могут быть нужны при подключении к внешним сервисам.  ## Пример использования В качестве примера рассмотрим работу дополнения в связке с Promtail. В роли источника логов запустим под, который будет писать сообщения в стандартный вывод. Kubelet сохраняет эти сообщения в файл в директории `/var/log/containers/`. Promtail, установленный как DaemonSet, считывает эти файлы и отправляет содержимое в Loki. Loki сохраняет логи, а Grafana позволяет их просматривать через веб-интерфейс. Установите дополнение в панели управления. В окне конфигурации оставьте все параметры по умолчанию, изменив только: ```yaml grafana: enabled: false ``` на: ```yaml grafana: enabled: true ``` Это позволит развернуть Grafana, через которую потом будем смотреть логи. Также установите дополнение [Nginx Ingress](https://timeweb.cloud/docs/k8s/addons/nginx-ingress#ustanovka-nginx-ingress) — оно нужно для доступа к интерфейсу Grafana по доменному имени. Проверьте, что все поды запущены: ```shell kubectl get pods -n loki ``` Вы должны увидеть примерно следующее: ```shell NAME READY STATUS RESTARTS AGE loki-stack-0 1/1 Running 0 3h5m loki-stack-grafana-878d56dc6-s28sq 2/2 Running 0 3h5m loki-stack-promtail-5wtlr 1/1 Running 0 3h5m loki-stack-promtail-hl6pl 1/1 Running 0 3h5m ``` Проверьте, что ingress-контроллер работает: ```shell kubectl get pods -n ingress-nginx ``` Также проверьте сервисы Grafana Loki: ```shell kubectl get svc -n loki ``` Пример вывода: ```shell NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE loki-stack ClusterIP 10.111.63.222 3100/TCP 3h7m loki-stack-grafana ClusterIP 10.104.154.158 80/TCP 3h7m loki-stack-headless ClusterIP None 3100/TCP 3h7m loki-stack-memberlist ClusterIP None 7946/TCP 3h7m ``` После этого настроим nginx ingress для работы с Grafana по домену. Для этого [создадим балансировщик](https://timeweb.cloud/docs/k8s/network/kubernetes-load-balancer). Создайте манифест `loadbalancer.yaml`: ```yaml apiVersion: v1 kind: Service metadata: name: ingress-nginx namespace: ingress-nginx spec: selector: app.kubernetes.io/name: ingress-nginx ports: - name: http port: 80 targetPort: 80 - name: https port: 443 targetPort: 443 type: LoadBalancer ``` Примените манифест: ```shell kubectl apply -f loadbalancer.yaml ``` Создайте правило Ingress в файле `grafana-ingress.yaml`: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: grafana namespace: loki annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: grafana.example.com http: paths: - path: / pathType: Prefix backend: service: name: loki-stack-grafana port: number: 80 ``` Измените `host: grafana.example.com`, указав домен, по которому вы хотите, чтобы открывался веб-интерфейс Grafana. В качестве A-записи для этого домена укажите IP созданного балансировщика. Примените манифест: ```shell kubectl apply -f loadbalancer.yaml ``` Теперь создадим под `logger`, который будет записывать сообщения, эмулируя логи: ```shell kubectl run logger --image=busybox --restart=Never -- sh -c 'while true; do echo "hello from logger"; sleep 5; done' ``` Проверьте, что под запустился: ```shell kubectl get pods ``` У пода `logger` должен быть статус `Running`. Теперь обратимся к веб-интерфейсу графаны. Откройте домен, указанный ранее в Ingress. При переходе вас встретит окно авторизации Grafana. В качестве логина укажите: ```shell admin ``` Пароль для авторизации хранится в секрете. Получите его командой: ```shell kubectl get secret -n loki loki-stack-grafana -o jsonpath="{.data.admin-password}" | base64 --decode ``` В интерфейсе Grafana перейдите в раздел «Explore». ![Scr 20250701 Ojyo](https://content.timeweb.com/assets/fb7fe9a5-d27a-493a-b0d3-143bf0fc39d7.png?width=2884&height=1562) _Основное меню в интерфейсе [Grafana](https://grafana.com/)_ Выберите источник данных «Loki». В поле «Label filters» укажите `pod=logger` и запустите запрос, нажав на кнопку «Run query». ![Scr 20250701 Oksp](https://content.timeweb.com/assets/95f8c71a-1a12-467d-8f0a-acbc4d23f752.png?width=2858&height=1364) _Запуск запроса в интерфейсе [Grafana](https://grafana.com/)_ После этого пролистайте страницу вниз. Вы увидите записи в логе «hello from logger». ![Scr 20250701 Olsq](https://content.timeweb.com/assets/373ffcef-2c0e-453f-9bdf-6dcd46366ed8.png?width=2880&height=1608) _Просмотр логов в интерфейсе [Grafana](https://grafana.com/)_ # Headlamp Source: https://timeweb.cloud/docs/k8s/addons/headlamp?utm_source=llms_txt&utm_medium=ai Headlamp — это веб-интерфейс для управления кластером. Он позволяет просматривать ресурсы кластера, управлять ими и отслеживать состояние приложений без использования [kubectl](https://timeweb.cloud/docs/k8s/cluster-connection/kubectl). ## Установка Перед установкой дополнения убедитесь, что: - В кластере установлен [Nginx Ingress](https://timeweb.cloud/docs/k8s/addons/nginx-ingress). - Есть хотя бы одна нода с публичным IP-адресом. Включить публичный IP можно в [настройках группы воркеров](https://timeweb.cloud/docs/k8s/manage-cluster/worker-node#upravlenie-gruppoj-vorker-nod). Перейдите во вкладку «Дополнения» в панели управления кластером и нажмите на карточку аддона «Headlamp». ![Scr 20260326 Pxid](https://content.timeweb.com/assets/0f49e91a-a529-4d5c-ae6f-6759636fcf5c.png?width=2228&height=1642) В открывшемся меню вы можете включить продвинутую установку или использовать параметры по умолчанию. При редактировании параметров вы можете указать, например: - домен, по которому будет доступен интерфейс; - настройки ingress; - настроить OIDC. Нажмите «Установить», чтобы начать установку. После завершения в карточке дополнения появится статус «Добавлено». Проверить, что дополнение установлено корректно, можно командой: ```bash kubectl get pod -n headlamp ``` В случае успешной установки вы увидите под в статусе «Running». ## Авторизация После установки иконка Headlamp появится в панели управления кластером. ![Scr 20260326 Pwht](https://content.timeweb.com/assets/979c8b66-c17b-4b06-9032-555203b5a26a.png?width=2148&height=1642) Нажмите на нее, чтобы открыть интерфейс. Если вы не авторизованы, потребуется указать токен. Получить токен можно во вкладке «Дашборд» панели управления, нажав на «Скопировать» рядом с «Токен Dashboard». ![Scr 20260326 Pwlc](https://content.timeweb.com/assets/97a002c7-c020-4563-92c4-d01443704a7b.png?width=2102&height=1624) После авторизации откроется интерфейс Headlamp. Основные разделы: - Cluster — информация о кластере и его состоянии; - Map — визуализация ресурсов и их связей; - Workloads — управление рабочими нагрузками (Pods, Deployments, StatefulSet); - Storage — PVC, PV и storage-классы; - Network — сервисы, ingress и сетевые политики; - Gateway — ресурсы Gateway API; - Security — роли, сервисные аккаунты и политики доступа; - Configuration — ConfigMap, Secrets и другие настройки; - Custom Resources — пользовательские ресурсы (CRD); - Create — создание ресурсов через интерфейс. ![Scr 20260326 Pwzc](https://content.timeweb.com/assets/6454a333-1712-4216-ad93-808ab30dced1.png?width=2926&height=1658) _Интерфейс [Headlamp](https://headlamp.dev/)_ ## Настройка авторизации Если интерфейс Headlamp доступен извне, рекомендуется настроить дополнительную базовую авторизацию. Headlamp не поддерживает авторизацию по логину и паролю напрямую. Для этого используется `basic auth` на уровне `ingress`. Создайте файл с логином и паролем: ```bash htpasswd -c auth admin ``` где `admin` — имя пользователя. Во время выполнения команды потребуется дважды ввести желаемый пароль. В результате будет создан файл `auth`. Если утилита `htpasswd` отсутствует, установите пакет `apache2-utils`. Затем создайте секрет в неймспейсе `headlamp` с использованием ранее полученного файла: ```bash kubectl create secret generic headlamp-basic-auth \ --from-file=auth \ -n headlamp ``` Перейдите в раздел «Дополнения» панели управления кластером и откройте установленный Headlamp. Включите продвинутую установку и найдите блок: ```yaml ingress: enabled: true # Желательно настроить авторизацию: https://headlamp.dev/docs/latest/installation/in-cluster/basic-auth/ annotations: {} ``` Удалите `{}` возле `annotations` и добавьте аннотации: ```yaml ingress: enabled: true annotations: nginx.ingress.kubernetes.io/auth-type: basic nginx.ingress.kubernetes.io/auth-secret: headlamp-basic-auth nginx.ingress.kubernetes.io/auth-realm: "Authentication Required" ``` Нажмите «Сохранить» и дождитесь обновления дополнения. После этого при обращении к Headlamp сначала потребуется ввести логин и пароль, а затем токен. Чтобы изменить пароль, создайте новый файл `auth` и обновите секрет в кластере. # MinIO Operator Source: https://timeweb.cloud/docs/k8s/addons/minio-operator?utm_source=llms_txt&utm_medium=ai MinIO Operator — это аддон для Kubernetes, который упрощает развертывание и управление S3-совместимыми хранилищами на базе MinIO. Он позволяет создавать распределенные кластеры хранения через CRD, управлять пользователями, бакетами и конфигурацией через Kubernetes-манифесты. ## Установка в ПУ > [!NOTE] > Для работы аддона необходимо, чтобы в кластере был установлен [аддон CSI-driver](https://timeweb.cloud/docs/k8s/network-drives-connection#ustanovka-drajvera-csi). Для установки MinIO Operator, в панели управления кластером, перейдите во вкладку «Дополнения». Найдите «MinIO Operator» в списке и нажмите на него. ![Scr 20250903 Kpxi](https://content.timeweb.com/assets/b8f3a003-d2f7-4ea8-ab49-06ddd547e2d3.png?width=1976&height=1440) В открывшемся окне можно при необходимости изменить параметры установки. Описание параметров доступно [в официальной документации](https://docs.min.io/community/minio-object-store/reference/operator-chart-values.html#minio-operator-chart-values). Воспользоваться аддоном можно не меняя настроек по умолчанию. Для установки аддона нажмите на кнопку «Установить». ![Scr 20250828 Lape](https://content.timeweb.com/assets/074b972c-34ac-4f4c-b258-6d5ddf34cdc0.png?width=2014&height=1406) Дождитесь завершения установки. Для проверки, что установка завершена корректно, выполните команду: ```shell kubectl get all -n operator ``` У запущенных подов должен быть статус `Running`. ## Пример использования В качестве примера развернем кластер MinIO из одного узла. Данные будут храниться на сетевом диске, а доступ к кластеру будет организован через Nginx Ingress с настроенным HTTPS. > [!NOTE] > В продакшн-среде рекомендуется использовать не менее 4 узлов для обеспечения отказоустойчивость. #### Предварительные требования В кластере должны быть установлены аддоны: - [Nginx Ingress](https://timeweb.cloud/docs/k8s/addons/nginx-ingress) - [CSI-driver](https://timeweb.cloud/docs/k8s/network-drives-connection) - [cert-manager](https://timeweb.cloud/docs/k8s/addons/cert-manager) - MinIO Operator Все аддоны установлены с параметрами по умолчанию. Для доступа к консоли и S3 API мы будем использовать два поддомена: - `minio-console.timeweb-example.cloud` — для доступа к панели управления; - `s3.timeweb-example.cloud` — для доступа к S3 API. Перейдем к созданию кластера. Сначала опишем создание неймспейса в файле `namespace.yaml`: ```yaml apiVersion: v1 kind: Namespace metadata: name: minio-tenant ``` Теперь опишем тенант в файле `tenant.yaml`: ```yaml apiVersion: minio.min.io/v2 kind: Tenant metadata: name: myminio namespace: minio-tenant spec: configuration: name: storage-configuration users: - name: storage-user image: quay.io/minio/minio:RELEASE.2025-04-08T15-41-24Z requestAutoCert: false mountPath: /export podManagementPolicy: Parallel pools: - name: pool-0 servers: 1 volumesPerServer: 1 volumeClaimTemplate: spec: accessModes: - ReadWriteOnce resources: requests: storage: 2Gi storageClassName: nvme.network-drives.csi.timeweb.cloud ``` Здесь: `pools` — определяет пул серверов (узлов) для MinIO: - `servers: 1` — количество серверов в пуле. - `volumesPerServer: 1` — количество томов, подключаемых к каждому серверу; - `volumeClaimTemplate` — шаблон для создания PVC. Указываем: - `accessModes: ReadWriteOnce` — том может быть смонтирован только одним подом на одном узле; - `storage: 2Gi` — размер тома; - `storageClassName: nvme.network-drives.csi.timeweb.cloud` — класс хранилища, соответствующий NVMe-дискам, предоставляемым CSI-драйвером. Обязательный параметр `spec.configuration.name`, в котором мы передаем имя секрета. Параметр используется для создания root-пользователя. В секции `spec.users` указывается список пользователей, для каждого из которых должен быть создан секрет с `access` и `secret key`. Имя секрета передается в поле `name`. Опишем секрет `storage-configuration.yaml`: ```yaml apiVersion: v1 kind: Secret metadata: name: storage-configuration namespace: minio-tenant type: Opaque stringData: config.env: |- export MINIO_ROOT_USER="minio" export MINIO_ROOT_PASSWORD="minio123" export MINIO_BROWSER="on" ``` И `storage-user.yaml`: ```yaml apiVersion: v1 kind: Secret metadata: name: storage-user namespace: minio-tenant type: Opaque data: CONSOLE_ACCESS_KEY: Y29uc29sZQ== # console CONSOLE_SECRET_KEY: Y29uc29sZTEyMw== # console123 ``` Обратите внимание, что `CONSOLE_ACCESS_KEY` и `CONSOLE_SECRET_KEY` передаются закодированные в base64. Например: ```shell echo -n "console" | base64 # Y29uc29sZQ== echo -n "console123" | base64 # Y29uc29sZTEyMw== ``` Применим все манифесты: ```bash kubectl apply -f namespace.yaml kubectl apply -f storage-configuration.yaml kubectl apply -f storage-user.yaml kubectl apply -f tenant.yaml ``` Проверьте, что все манифесты успешно применились и все сервисы корректно запустились: ```bash kubectl get all -n minio-tenant ``` Вы должны будете увидеть примерно такой вывод: ```shell NAME READY STATUS RESTARTS AGE pod/myminio-pool-0-0 2/2 Running 0 113m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/minio ClusterIP 10.97.190.5 80/TCP 113m service/myminio-console ClusterIP 10.96.97.1 9090/TCP 113m service/myminio-hl ClusterIP None 9000/TCP 113m NAME READY AGE statefulset.apps/myminio-pool-0 1/1 113m ``` Теперь перейдем к настройке Nginx Ingress. Создадим файл `ingress.yaml`: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: myminio-ingress namespace: minio-tenant annotations: nginx.ingress.kubernetes.io/backend-protocol: "HTTP" nginx.ingress.kubernetes.io/proxy-body-size: "0" cert-manager.io/cluster-issuer: letsencrypt-prod spec: ingressClassName: nginx rules: - host: minio-console.timeweb-example.cloud http: paths: - path: / pathType: Prefix backend: service: name: myminio-console port: number: 9090 - host: s3.timeweb-example.cloud http: paths: - path: / pathType: Prefix backend: service: name: minio port: number: 80 tls: - hosts: - minio-console.timeweb-example.cloud secretName: minio-console-tls - hosts: - s3.timeweb-example.cloud secretName: s3-tls ``` Не забудьте заменить домены `s3.timeweb-example.cloud` и `minio-console.timeweb-example.cloud`. Для выпуска сертификатов создадим `cluster-issuer.yaml`: ```yaml apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: email: example@timeweb.cloud server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: nginx ``` Поменяйте `example@timeweb.cloud` на вашу почту — она будет использоваться Let's Encrypt. Опишем балансировщик нагрузки в файле `lb.yaml`: ```yaml apiVersion: v1 kind: Service metadata: name: ingress-nginx namespace: ingress-nginx spec: type: LoadBalancer selector: app.kubernetes.io/name: ingress-nginx ports: - name: http port: 80 targetPort: 80 - name: https port: 443 targetPort: 443 ``` Примените все манифесты: ```bash kubectl apply -f ingress.yaml kubectl apply -f cluster-issuer.yaml kubectl apply -f lb.yaml ``` Дождитесь завершения создания балансировщика нагрузки в панели управления и укажите для доменов в качестве A-записи IP-адрес балансировщика. Проверьте, что ingress запущен, а сертификаты выпущены: ```shell kubectl get ingress -n minio-tenant kubectl get certificates -n minio-tenant ``` Теперь можно перейти к панели управления MinIO. Перейдите по домену MinIO-консоли, в нашем примере — это `minio-console.timeweb-example.cloud`. Вы увидите страницу авторизации. ![Scr 20250903 Jwnm](https://content.timeweb.com/assets/da55381a-9f8c-4cd0-b40e-551d0863d574.png?width=2934&height=1638) _Страница авторизации [MinIO](https://www.min.io/)_ Для авторизации используйте данные, указанные в секретах `storage-user.yaml` или `storage-configuration.yaml`, например, логин `console` и пароль `console123`. Перейдите в раздел «Buckets», чтобы создать бакет. ![Scr 20250903 Jylx](https://content.timeweb.com/assets/ae2b7521-9475-44b6-bc88-ace5479d281c.png?width=2910&height=1578) _Раздел «Buckets» в интерфейсе [MinIO](https://www.min.io/)_ Перейдите в раздел «Access Keys», чтобы создать данные для подключения — например, [с помощью S3cmd](https://timeweb.cloud/docs/s3-storage/tools/s3cmd). Простой конфиг для подключения будет выглядеть так: ```bash [default] access_key = [Access Key] secret_key = [Secret Key] host_base = s3.timeweb-example.cloud host_bucket = s3.timeweb-example.cloud use_https = True ``` # NGINX Gateway Fabric Source: https://timeweb.cloud/docs/k8s/addons/nginx-gateway-fabric?utm_source=llms_txt&utm_medium=ai NGINX Gateway Fabric — это контроллер Gateway API для Kubernetes, который использует NGINX для обработки входящего трафика. С его помощью можно публиковать HTTP, HTTPS, gRPC, TCP и UDP-сервисы, настраивать маршрутизацию по доменам и путям, управлять TLS и постепенно переходить от Ingress к Gateway API. Gateway API можно рассматривать как развитие Ingress. Вместо одного ресурса Ingress используются несколько объектов с разными зонами ответственности: - `GatewayClass` — указывает, какой контроллер будет обслуживать шлюзы. - `Gateway` — описывает точку входа: порты, протоколы, домены и TLS-настройки. - `HTTPRoute` — задает правила маршрутизации HTTP-трафика к сервисам. - `GRPCRoute`, `TCPRoute`, `UDPRoute`, `TLSRoute` — используются для других типов трафика. NGINX Gateway Fabric отслеживает ресурсы Gateway API и на их основе создает NGINX data plane: поды NGINX и сервис, через который внешний трафик попадает в кластер и направляется к Kubernetes-сервисам. ## Установка Перед установкой NGINX Gateway Fabric из панели управления нужно вручную установить CRD Gateway API. В команде укажите версию NGINX Gateway Fabric в параметре ref. Например, для версии `v2.6.3`: ```bash kubectl kustomize "https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v2.6.3" | kubectl apply -f - ``` После установки CRD откройте панель управления кластером, перейдите во вкладку «Дополнения» и выберите NGINX Gateway Fabric. В открывшемся мастере установки можно оставить параметры по умолчанию или включить продвинутую установку и изменить `values`. Для начала работы достаточно настроек по умолчанию. Нажмите «Установить» и дождитесь завершения установки. После этого проверьте, что поды NGINX Gateway Fabric запущены: ```bash kubectl get pods -n nginx-gateway ``` Все поды должны находиться в статусе `Running`. Также можно проверить, что в кластере появились ресурсы Gateway API: ```bash kubectl api-resources | grep gateway.networking.k8s.io ``` При стандартной установке NGINX Gateway Fabric создает `GatewayClass` с именем `nginx`. Проверьте его статус: ```bash kubectl get gatewayclass nginx ``` В колонке `ACCEPTED` должно быть значение `True`. ## Использование Рассмотрим пример, в котором NGINX Gateway Fabric будет принимать HTTP-трафик на одном внешнем IP-адресе и направлять запросы в два разных сервиса: - `http://app.example.com/service1` — в сервис `service1`; - `http://app.example.com/service2` — в сервис `service2`. Для примера создадим отдельный неймспейс: ```bash kubectl create namespace nginx-gateway-example ``` ### Создание ConfigMap Создайте файл `configmap.yaml` с HTML-страницами для двух сервисов: ```shell apiVersion: v1 kind: ConfigMap metadata: name: nginx-pages namespace: nginx-gateway-example data: service1.html: | Service 1

Service 1

service2.html: | Service 2

Service 2

``` Примените манифест: ```bash kubectl apply -f configmap.yaml ``` ### Создание Deployment и Service Создайте файл `service1.yaml`: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: service1 namespace: nginx-gateway-example spec: replicas: 2 selector: matchLabels: app: service1 template: metadata: labels: app: service1 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html configMap: name: nginx-pages items: - key: service1.html path: index.html --- apiVersion: v1 kind: Service metadata: name: service1 namespace: nginx-gateway-example spec: selector: app: service1 ports: - name: http port: 80 targetPort: 80 type: ClusterIP ``` Создайте файл `service2.yaml`: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: service2 namespace: nginx-gateway-example spec: replicas: 2 selector: matchLabels: app: service2 template: metadata: labels: app: service2 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html configMap: name: nginx-pages items: - key: service2.html path: index.html --- apiVersion: v1 kind: Service metadata: name: service2 namespace: nginx-gateway-example spec: selector: app: service2 ports: - name: http port: 80 targetPort: 80 type: ClusterIP ``` Примените манифесты: ```bash kubectl apply -f service1.yaml kubectl apply -f service2.yaml ``` Проверьте, что поды запущены: ```bash kubectl get pods -n nginx-gateway-example ``` ### Создание Gateway Gateway описывает внешний вход в приложение. При стандартной установке NGINX Gateway Fabric обслуживает `Gateway` с `gatewayClassName: nginx`. Создайте файл `gateway.yaml`: ```yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: app-gateway namespace: nginx-gateway-example spec: gatewayClassName: nginx listeners: - name: http hostname: app.example.com protocol: HTTP port: 80 allowedRoutes: namespaces: from: Same ``` Примените манифест: ```bash kubectl apply -f gateway.yaml ``` Когда Gateway будет создан, NGINX Gateway Fabric развернет NGINX data plane и балансировщик нагрузки в неймспейсе `nginx-gateway-example`. Проверить статус можно командой: ```bash kubectl get gateway app-gateway -n nginx-gateway-example ``` Дождитесь, когда в колонке `PROGRAMMED` появится значение `True`, а в колонке `ADDRESS` — внешний IP-адрес. Также можно посмотреть созданные ресурсы: ```bash kubectl get deployments -n nginx-gateway-example kubectl get svc -n nginx-gateway-example ``` NGINX Gateway Fabric создает отдельный NGINX data plane для каждого `Gateway`. Поэтому отдельный манифест `Service` типа `LoadBalancer`, как в классическом сценарии с Ingress-контроллером, не требуется. ### Создание HTTPRoute HTTPRoute задает правила маршрутизации. Создайте файл `httproute.yaml`: ```yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: app-route namespace: nginx-gateway-example spec: parentRefs: - name: app-gateway hostnames: - app.example.com rules: - matches: - path: type: PathPrefix value: /service1 filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefixMatch replacePrefixMatch: / backendRefs: - name: service1 port: 80 - matches: - path: type: PathPrefix value: /service2 filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefixMatch replacePrefixMatch: / backendRefs: - name: service2 port: 80 ``` Примените манифест: ```bash kubectl apply -f httproute.yaml ``` Проверьте, что маршрут принят: ```bash kubectl get httproute app-route -n nginx-gateway-example -o yaml ``` В статусе ресурса должны быть условия: ```bash status: "True" type: Accepted status: "True" type: ResolvedRefs ``` В этом манифесте `HTTPRoute` принимает запросы с доменом `app.example.com` и направляет их в разные сервисы по префиксу пути. Фильтр URLRewrite заменяет префиксы `/service1` и `/service2` на `/`, чтобы NGINX внутри каждого сервиса отдавал свою главную страницу. ### Проверка работы Пропишите IP-адрес балансировщика в DNS-настройках домена `app.example.com` в качестве A-записи. После обновления DNS проверьте доступность сервисов: ```bash curl http://app.example.com/service1 curl http://app.example.com/service2 ``` Если DNS еще не обновился, можно выполнить проверку по IP-адресу, передав заголовок `Host`: ```bash curl -H "Host: app.example.com" http:///service1 curl -H "Host: app.example.com" http:///service2 ``` В ответе должны отображаться страницы `Service 1` и `Service 2`. ### Удаление примера Чтобы удалить ресурсы, созданные в примере, выполните: ```bash kubectl delete namespace nginx-gateway-example ``` Дополнение NGINX Gateway Fabric при этом останется установленным в кластере. Удалить его можно во вкладке «Дополнения» в панели управления кластером. ## Миграция с Nginx Ingress на NGINX Gateway Fabric NGINX Gateway Fabric можно развернуть рядом с Nginx Ingress и переносить маршруты постепенно. Такой подход позволяет сначала проверить ресурсы Gateway API на отдельном внешнем IP-адресе, а затем переключить DNS-записи или трафик на новый `Gateway`. Для автоматической конвертации Ingress-ресурсов можно использовать утилиту [ingress2gateway](https://github.com/kubernetes-sigs/ingress2gateway). Она читает существующие Ingress-ресурсы из кластера или из YAML-файлов и выводит эквивалентные ресурсы Gateway API: `Gateway`, `HTTPRoute` и другие объекты. > [!NOTE] > ingress2gateway помогает подготовить миграцию, но не заменяет ручную проверку. Некоторые аннотации Nginx Ingress могут быть не поддержаны или потребовать ручной настройки после конвертации. ### Требования Перед миграцией подготовьте кластер: - установите NGINX Gateway Fabric; - проверьте, что исходные Ingress-ресурсы работают через Nginx Ingress; - проверьте, что в кластере есть `GatewayClass` с именем `nginx`. Если Nginx Ingress установлен из панели управления Timeweb Cloud, для него используется `IngressClass` с именем `nginx`. Это имя понадобится при запуске ingress2gateway. Проверьте классы: ```bash kubectl get ingressclass kubectl get gatewayclass ``` В выводе должны быть: - `IngressClass` с именем `nginx`; - `GatewayClass` с именем `nginx`. ### Установка ingress2gateway Если на локальной машине установлен Go, установите ingress2gateway командой: ```bash go install github.com/kubernetes-sigs/ingress2gateway@v1.1.0 ``` После установки бинарный файл будет доступен в директории `$(go env GOPATH)/bin`. Убедитесь, что эта директория добавлена в `PATH`. Также можно установить ingress2gateway через Homebrew: ```bash brew install ingress2gateway ``` Или скачать готовый бинарный файл со [страницы релизов проекта](https://github.com/kubernetes-sigs/ingress2gateway/releases). ### Исходный пример В примере ниже миграция выполняется для приложения, которое уже опубликовано через Nginx Ingress. В кластере есть неймспейс `ingress-migration-demo`. В нем находятся: - Ingress migration-source; - Service `service1` и `service2`; - два правила маршрутизации для домена `app.example.com`: - `/service1` направляет трафик в `service1`; - `/service2` направляет трафик в `service2`. Проверьте исходный Ingress: ```bash kubectl get ingress -n ingress-migration-demo ``` В колонке `CLASS` должно быть значение `nginx`. ### Конвертация Ingress-ресурсов Чтобы сконвертировать этот Ingress в ресурсы Gateway API, выполните: ```yaml ingress2gateway print \ --providers=ingress-nginx \ --ingress-nginx-ingress-class=nginx \ --namespace=ingress-migration-demo > gateway-migration.yaml ``` В этой команде: - `print` — режим, в котором ingress2gateway выводит сгенерированные ресурсы в стандартный вывод. За счет перенаправления `>` результат сохраняется в файл `gateway-migration.yaml`. - `--providers=ingress-nginx` — указывает тип исходного Ingress-контроллера. В нашем примере исходные маршруты обслуживает Nginx Ingress. - `--ingress-nginx-ingress-class=nginx` — выбирает только Ingress-ресурсы класса nginx. - `--namespace=ingress-migration-demo` — ограничивает чтение ресурсов неймспейсом `ingress-migration-demo`, где находится исходный Ingress из примера. Откройте файл `gateway-migration.yaml` и проверьте сгенерированные ресурсы перед применением. Проверьте `gatewayClassName` у ресурса `Gateway`. Для NGINX Gateway Fabric при стандартной установке значение должно быть `nginx`: ```yaml spec: gatewayClassName: nginx ``` Также проверьте правила `HTTPRoute`. Некоторые Ingress-аннотации могут быть преобразованы в фильтры или типы совпадений, которые нужно скорректировать вручную. Например, для обычной маршрутизации по префиксу пути используйте `PathPrefix`: ```yaml rules: - matches: - path: type: PathPrefix value: /service1 filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefixMatch replacePrefixMatch: / backendRefs: - name: service1 port: 80 ``` Если в сгенерированном файле есть RegularExpression-маршруты или неподдержанные аннотации, проверьте их совместимость с NGINX Gateway Fabric и замените на поддерживаемые правила Gateway API. ### Применение ресурсов Gateway API После проверки примените файл: ```bash kubectl apply -f gateway-migration.yaml ``` Проверьте, что Gateway создан и получил внешний IP-адрес: ```bash kubectl get gateway -A ``` ### Тестирование перед переключением трафика Пока DNS-записи указывают на старый Nginx Ingress, новый Gateway можно проверить по внешнему IP-адресу с заголовком `Host`: ```bash curl -H "Host: app.example.com" http:/// ``` Где: - `app.example.com` — домен из HTTPRoute; - `` — IP-адрес нового `Gateway`; - `` — путь, который должен обрабатываться маршрутом. Сравните ответы старого `Ingress` и нового `Gateway`. Если все работает корректно, можно изменить DNS-записи на IP нового балансировщика. # Nginx Ingress Source: https://timeweb.cloud/docs/k8s/addons/nginx-ingress?utm_source=llms_txt&utm_medium=ai Ingress — это ресурс Kubernetes, позволяющий организовать доступ к сервисам внутри кластера через HTTP и HTTPS. Он предоставляет маршрутизацию на основе URL, доменов и других параметров. В этой статье рассмотрим использование Nginx Ingress на примере трех деплойментов Nginx, имитирующих три разных сервиса. Мы также настроим SSL-сертификат для защиты соединения. ## Установка Nginx Ingress Для начала необходимо установить Nginx Ingress в кластере. В панели управления кластером перейдите во вкладку «Дополнения», нажмите на три точки рядом с Nginx Ingress и выберите «Установить». ![Image2](https://content.timeweb.com/assets/83134417-3b7b-47cd-bbe9-af31473436a1.png?width=1025&height=934) После установки проверьте, что Ingress работает корректно. Выполните команду: ```shell kubectl get pods -n ingress-nginx ``` Убедитесь, что все поды находятся в статусе `Running`. ## Настройка деплойментов и сервисов Рассмотрим пример использования Nginx Ingress. Мы развернем три `Deployment` с образами Nginx, каждый будет имитировать отдельный сервис. К каждому `Deployment` мы создадим `Service` с типом `ClusterIP` — это тип сервиса по умолчанию в Kubernetes, который выдаёт внутренний IP-адрес внутри кластера. Такой сервис не доступен извне напрямую, однако он может быть опубликован во внешнюю сеть с помощью Ingress. Для удобства создадим отдельный неймспейс, в котором будут находиться все манифесты: ```shell kubectl create namespace ingress-example ``` Чтобы отличать сервисы друг от друга, создадим `ConfigMap` с тремя разными HTML-страницами. Создайте файл `configmap.yaml` с таким содержанием: ```shell apiVersion: v1 kind: ConfigMap metadata: name: service-config namespace: ingress-example data: service1.html: | Service 1

Welcome to Service 1!

service2.html: | Service 2

Welcome to Service 2!

service3.html: | Service 3

Welcome to Service 3!

``` Теперь опишем деплойменты: **service1-deployment.yaml**: ```yml apiVersion: apps/v1 kind: Deployment metadata: name: service1 namespace: ingress-example spec: replicas: 2 selector: matchLabels: app: service1 template: metadata: labels: app: service1 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: config-volume mountPath: /usr/share/nginx/html volumes: - name: config-volume configMap: name: service-config items: - key: service1.html path: index.html --- apiVersion: v1 kind: Service metadata: name: service1 namespace: ingress-example spec: selector: app: service1 ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP ``` Пояснения к манифесту: 1. **Deployment** - **replicas**: 2 указывает, что будет запущено две реплики подов с Nginx. - В секции **selector** и **template.metadata.labels** задаётся соответствие между подами и тем, как их будет находить сервис. - **volumeMounts** и **volumes** используются, чтобы подмонтировать файл `service1.html` из `ConfigMap` в директорию, откуда Nginx по умолчанию раздает контент. 3. **Service** - **ClusterIP** означает, что сервис будет доступен только внутри кластера по выделенному IP-адресу. Для внешнего доступа мы будем использовать Ingress. Манифесты для `service2` и `service3` аналогичны, отличается только имя сервиса и используемый HTML-файл. **service2-deployment.yaml**: ```yml apiVersion: apps/v1 kind: Deployment metadata: name: service2 namespace: ingress-example spec: replicas: 2 selector: matchLabels: app: service2 template: metadata: labels: app: service2 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: config-volume mountPath: /usr/share/nginx/html volumes: - name: config-volume configMap: name: service-config items: - key: service2.html path: index.html --- apiVersion: v1 kind: Service metadata: name: service2 namespace: ingress-example spec: selector: app: service2 ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP ``` **service3-deployment.yaml**: ```yml apiVersion: apps/v1 kind: Deployment metadata: name: service3 namespace: ingress-example spec: replicas: 2 selector: matchLabels: app: service3 template: metadata: labels: app: service3 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: config-volume mountPath: /usr/share/nginx/html volumes: - name: config-volume configMap: name: service-config items: - key: service3.html path: index.html --- apiVersion: v1 kind: Service metadata: name: service3 namespace: ingress-example spec: selector: app: service3 ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP ``` Применим все манифесты: ```shell kubectl apply -f configmap.yaml kubectl apply -f service1-deployment.yaml kubectl apply -f service2-deployment.yaml kubectl apply -f service3-deployment.yaml ``` Проверим статус подов: ```shell kubectl get pods -n ingress-example ``` Все поды должны иметь статус `Running`. На этом подготовительные работы можно считать завершенными. ## Создание Ingress  С помощью Ingress мы укажем, какой трафик (по доменам и путям) перенаправлять на соответствующие сервисы. Создадим манифест `ingress.yaml`: ```yml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress namespace: ingress-example annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: ingress1.example.com http: paths: - path: /service1 pathType: Prefix backend: service: name: service1 port: number: 80 - path: /service2 pathType: Prefix backend: service: name: service2 port: number: 80 - host: ingress2.example.com http: paths: - path: / pathType: Prefix backend: service: name: service3 port: number: 80 ``` Пояснения к манифесту: - **rules.host** задает домен, к которому будет привязан Ingress. - **paths** определяет правила маршрутизации: - При обращении к `ingress1.example.com/service1` будет перенаправление на `service1`. - При обращении к `ingress1.example.com/service2` будет перенаправление на `service2`. - При обращении к `ingress2.example.com/` будет перенаправление на `service3`. Применим манифест: ```shell kubectl apply -f ingress.yaml ``` ## Создание LoadBalancer Чтобы обратиться к Nginx Ingress из внешней сети, создадим `Service` типа `LoadBalancer`, который будет отвечать за балансировку нагрузки и предоставит нам внешний IP-адрес. Подготовим для этого манифест `loadbalancer.yaml` следующего содержания: ```yml apiVersion: v1 kind: Service metadata: name: ingress-nginx namespace: ingress-nginx spec: selector: app.kubernetes.io/name: ingress-nginx ports: - name: http port: 80 targetPort: 80 - name: https port: 443 targetPort: 443 type: LoadBalancer ``` Применим манифест: ```shell kubectl apply -f loadbalancer.yaml ``` Дождитесь, пока балансировщик создастся, и убедитесь, что у него появился внешний IP-адрес: ```shell kubectl get services -n ingress-nginx ``` Внешний IP будет отображен в колонке `EXTERNAL-IP`. Полученный IP-адрес необходимо прописать в DNS-настройках домена в виде А-записей для доменов `ingress1.example.com` и `ingress2.example.com`. После обновления DNS ваши домены будут указывать на этот балансировщик, и вы сможете обращаться к сервисам по внешним URL: - `http://ingress1.example.com/service1` — отобразится заголовок «Welcome to Service 1!». - `http://ingress1.example.com/service2` — отобразится заголовок «Welcome to Service 2!». - `http://ingress2.example.com/` — отобразится заголовок «Welcome to Service 3!». ## Настройка SSL-сертификата Для обеспечения защищенного соединения в Nginx Ingress необходимо добавить существующий SSL-сертификат в виде Kubernetes-секрета, а затем указать этот секрет в манифесте Ingress. > [!NOTE] > Если вы хотите автоматизировать выпуск и продление сертификатов (например, через Let’s Encrypt), рекомендуем использовать инструмент [cert-manager](https://timeweb.cloud/docs/k8s/addons/cert-manager). ### Подготовка файлов сертификата и ключа Сохраните файл ключа `tls.key` и сертификат `tls.crt` локально. Если вы заказывали сертификат в Timeweb Cloud, содержимое ключа и сертификата можно скопировать со страницы управления сертификатом в панели Timeweb Cloud. Убедитесь, что сертификат не просрочен и соответствует доменам, которые вы хотите защитить. ![Image1](https://content.timeweb.com/assets/b5cadaa3-8dae-4e85-8009-d10cf4e75af4.png?width=1035&height=541) ### Создание Kubernetes-секрета Чтобы добавить сертификат в кластер, необходимо закодировать файлы в Base64 и создать манифест секрета. Выполните в терминале команды: ```yml base64 -w 0 ./tls.crt base64 -w 0 ./tls.key ``` Затем создайте файл `tls-secret.yaml` следующего содержания: ```yml apiVersion: v1 kind: Secret metadata: name: ingress-example-tls namespace: ingress-example type: kubernetes.io/tls data: tls.crt: |- tls.key: |- ``` Сохраните файл и примените манифест: ```shell kubectl apply -f tls-secret.yaml ``` Проверьте, что значения ключа и сертификата ненулевые. Для этого выполните: ```shell kubectl describe secret ingress-example-tls -n ingress-example ``` ### Обновление манифеста Ingress Обновите ваш манифест `ingress.yaml`, добавив секцию `tls`, и укажите имя созданного секрета: ```yml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress namespace: ingress-example annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: tls: - hosts: - ingress1.example.com - ingress2.example.com secretName: ingress-example-tls rules: - host: ingress1.example.com http: paths: - path: /service1 pathType: Prefix backend: service: name: service1 port: number: 80 - path: /service2 pathType: Prefix backend: service: name: service2 port: number: 80 - host: ingress2.example.com http: paths: - path: / pathType: Prefix backend: service: name: service3 port: number: 80 ``` Примените измененный манифест: ```shell kubectl apply -f ingress.yaml ``` Теперь при обращении к `ingress1.example.com` или `ingress2.example.com` по HTTPS браузер будет использовать сертификат, указанный в секрете `ingress-example-tls`. Таким образом, трафик к вашим сервисам будет защищен. Если у вас несколько сертификатов для разных доменов, создайте `Secret` для каждого из них. Например, для доменов `example.com` и `example.org` создайте два секрета. После этого обновите манифест Ingress, добавив секцию `tls` для каждого домена: ```yml spec: tls: - hosts: - example.com secretName: example-com-tls - hosts: - example.org secretName: example-org-tls ``` После этого каждый домен будет использовать свой сертификат, указанный в соответствующем секрете. # OpenFaaS Kubernetes Source: https://timeweb.cloud/docs/k8s/addons/openfaas?utm_source=llms_txt&utm_medium=ai OpenFaaS — это платформа с открытым исходным кодом для запуска функций (FaaS) поверх Kubernetes. Она упрощает деплой небольших единиц кода, которые выполняются по запросу или событию. В основе OpenFaaS лежит модель Function as a Service (FaaS), при которой вы пишете функцию и оборачиваете ее в Docker-образ. OpenFaaS отвечает за масштабирование, сетевые вызовы и управление жизненным циклом. Для взаимодействия используется удобный веб-интерфейс и CLI-утилита faas-cli. Функции можно писать на популярных языках — Python, Node.js, Go и других — с помощью готовых шаблонов. Полная документация по OpenFaaS Kubernetes доступна [на официальном сайте](https://docs.openfaas.com/) дополнения. ## Установка плагина Для установки OpenFaaS Kubernetes откройте раздел «Дополнения» в панели управления кластером. Найдите «OpenFaaS Kubernetes» в списке и нажмите на него. ![Scr 20250709 Mlfn](https://content.timeweb.com/assets/8ef2cb18-a5b5-4097-a429-0663b7542e61.png?width=1726&height=1576) В открывшемся окне можно изменить параметры установки. Найдите секцию `ingress` и включите ее — установите `enabled: true`, а также укажите свой домен в параметре `host`. Это упростит доступ к дашборду и позволит использовать `faas-cli`. Если вы включаете `ingress`, можно отключить `exposeServices`, который используется по умолчанию. ![Scr 20250709 Mlof](https://content.timeweb.com/assets/8d82de72-256d-482f-b4f9-9d7507db3044.png?width=1540&height=1552) После указания параметров нажмите кнопку «Установить» и дождитесь завершения установки. Чтобы убедиться, что все работает, проверьте состояние подов в неймспейсе `openfaas-fn`: ```shell kubectl get pods -n openfaas-fn ``` Пример вывода: ```shell NAME READY STATUS RESTARTS AGE alertmanager-57767d864c-hdqdn 1/1 Running 0 19h gateway-5f9c4b5754-ksr6x 2/2 Running 1 (19h ago) 19h nats-6ddf479847-dxr2g 1/1 Running 0 19h prometheus-6cbd946f66-wqdf8 1/1 Running 0 19h queue-worker-57c7479989-bw282 1/1 Running 0 19h ``` Если все поды в статусе Running — установка прошла успешно. ## Установка CLI Для работы с OpenFaaS из консоли потребуется утилита `faas-cli`. С ее помощью можно создавать функции, собирать и отправлять образы, деплоить их в кластер, вызывать функции и просматривать их статус. Утилита доступна для Linux, macOS и Windows. Для ее установки выполните следующие команды: Linux ```shell curl -sSL https://cli.openfaas.com | sh ``` MacOS ```shell curl -sSL https://cli.openfaas.com | sh ``` Или через Homebrew: ```shell brew install faas-cli ``` Windows (PowerShell) ```shell $version = (Invoke-WebRequest "https://api.github.com/repos/openfaas/faas-cli/releases/latest" | ConvertFrom-Json)[0].tag_name (New-Object System.Net.WebClient).DownloadFile("https://github.com/openfaas/faas-cli/releases/download/$version/faas-cli.exe", "faas-cli.exe") ``` После установки убедитесь, что все работает корректно: ```shell faas-cli version ``` ## Пример использования Рассмотрим пример использования OpenFaaS. Развернем плагин, привяжем домен для удобного доступа к дашборду и обращения к OpenFaaS через CLI, установим функцию из встроенного стора и создадим собственную функцию с деплоем через Docker Hub. Предварительные требования: - Домен или поддомен, по которому будет доступен OpenFaaS; - установленное дополнение Nginx Ingress; - аккаунт в Docker Hub (для кастомных функций); - установленная утилита faas-cli; - установленный Docker. Перейдите к установке плагина OpenFaaS в панели управления. В разделе «Конфигурация» найдите секцию `ingress` и включите ее, изменив `enabled: false` на `enabled: true`. Также задайте значение `host`, указав домен, по которому будет доступен дашборд. Запустите установку плагина. Теперь необходимо создать балансировщик нагрузки. Создайте манифест `loadbalancer.yaml`: ```yaml apiVersion: v1 kind: Service metadata: name: ingress-nginx-lb namespace: ingress-nginx spec: selector: app.kubernetes.io/name: ingress-nginx type: LoadBalancer ports: - name: http port: 80 targetPort: 80 appProtocol: k8s.timeweb.cloud/proto-http - name: https port: 443 targetPort: 443 appProtocol: k8s.timeweb.cloud/proto-https ``` Примените манифест: ```shell kubectl apply -f loadbalancer.yaml ``` После создания балансировщика, привяжите A-запись к домену. Если домен размещен на наших NS-серверах — просто выберите созданный балансировщик, при настройке А-записи домена. Если используется сторонний DNS, получите IP-адрес балансировщика и добавьте запись вручную: ```shell kubectl get svc --all-namespaces --field-selector spec.type=LoadBalancer ``` IP будет в колонке `EXTERNAL-IP`. Перейдите по домену, указанному при установке. Откроется окно базовой авторизации. - Логин: `admin` - Пароль: можно получить командой: ```shell kubectl -n openfaas-fn get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode ``` После входа откроется главный экран дашборда. ![Scr 20250709 Nvkl](https://content.timeweb.com/assets/e036c968-493b-4791-ab5a-c7966782647e.png?width=2894&height=848) _Главный экран интерфейса [OpenFaaS](https://www.openfaas.com/)_ Перейдем к использованию функций. Установим функцию из встроенного стора OpenFaaS. Сначала авторизуйтесь через CLI. Это позволит выполнять команды, связанные с управлением функциями: ```shell faas-cli login \ --gateway http://<домен> \ --username admin \ --password <пароль> ``` Где: - домен — адрес, указанный при установке OpenFaaS; - admin — имя пользователя по умолчанию; - пароль — пароль можно получить при выполнении команды: ```shell kubectl -n openfaas-fn get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode ``` Теперь установим функцию `figlet`, которая преобразует текст в ASCII-арт: ```shell faas-cli store deploy figlet \ --gateway http://<домен> ``` Убедитесь, что функция установилась: ```shell faas-cli list \ --gateway http://<домен> ``` В списке появится функция `figlet` со статусом `Ready`. Вызовите функцию с передачей строки на вход: ```shell echo "TimewebCloud" | faas-cli invoke figlet \ --gateway http://<домен> ``` В ответ вы получите ASCII-арт с переданным текстом. ![Scr 20250709 Oezl](https://content.timeweb.com/assets/c1c3cd50-e3ef-43fc-856b-9bf97ebe88d3.png?width=1198&height=320) Теперь рассмотрим деплой кастомной функции. Выберите шаблон: ```shell faas-cli template store list ``` Создайте новую функцию на базе нужного шаблона, например `python3-http`: ```shell faas-cli new hello-k8s --lang python3-http ``` Будут созданы: - `hello-k8s/handler.py` — код функции; - `stack.yaml` — манифест функции. Перед сборкой отредактируйте файл `stack.yaml`, указав путь до образа в Docker Hub. Например: ```yaml functions: hello-k8s: lang: python3-http handler: ./hello-k8s image: dockerhubuser/hello-k8s:latest ``` В поле image укажите имя пользователя Docker Hub и название образа. Обратите внимание, что в OpenFaaS Community Edition разрешена работа только с публичными образами. Соберите образ: ```shell faas-cli build -f stack.yaml ``` После сборки образа опубликуйте его в Docker Hub: ```shell faas-cli push -f stack.yaml ``` И наконец, задеплойте функцию в кластер: ```shell faas-cli deploy -f stack.yaml \ --gateway http://<домен> ``` После выполнения команды появится ссылка, по которой доступна функция.  ![Scr 20250709 Ohdk](https://content.timeweb.com/assets/67ed7fe8-9a22-4515-aeb8-0e9f49c8a07e.png?width=1550&height=282) Перейдите по ссылке — вы увидите результат выполнения — сообщение «Hello from OpenFaaS!». # TWC Alert Bot Source: https://timeweb.cloud/docs/k8s/addons/twc-alert-bot?utm_source=llms_txt&utm_medium=ai TWC Alert Bot — аддон для Kubernetes, который отправляет уведомления о событиях в кластере в Telegram, Discord или Slack. Он отслеживает рестарты подов, ошибки `liveness`\- и `readiness`\-проб, недоступность нод и другие потенциально критичные события. Дополнение поможет быстро реагировать на проблемы и поддерживать стабильность инфраструктуры. ## Установка Перейдите во вкладку «Дополнения» в панели управления кластером и нажмите на карточку аддона «TWC Alert Bot». ![Image 20250917162010743](https://content.timeweb.com/assets/85434aaa-4d3a-42d5-b3ce-d28464264a7f.png?width=1998&height=1434) Обязательный параметр для работы уведомлений — `clusterName`. Это произвольное имя кластера, которым будут подписываться уведомления. По умолчанию используется имя кластера. Параметры для подключения Telegram, Slack или Discord описаны в [разделе о настройке уведомлений](https://timeweb.cloud/docs/k8s/addons/twc-alert-bot#nastrojka-uvedomlenij). Можно указать, какие неймспейсы отслеживать, с помощью параметра: ```yaml namespaceToWatch: "" ``` Если нужно получать уведомления только из конкретных неймспейсов — укажите их через запятую: ```yaml namespaceToWatch: "default,production" ``` Также можно исключить из наблюдения определенные поды. Для этого используется параметр `exceptions`. Можно указывать как точные имена подов, так и части имен. Если имя пода совпадает с одной из строк — алерт по нему не придет. ```yaml exceptions: - "test-" - "debug-" - "-temp-" - "my-pod" ``` Сами уведомления настраиваются в секции `alerts:` в манифесте. Доступные варианты: | **Параметр** | **Описание** | | --- | --- | | `podRestarts` | Алерты по рестартам контейнеров в подах | | `podAddDelete` | Алерты при создании и удалении подов | | `workloadAddDelete` | Алерты при создании и удалении деплойментов | | `serviceAddDelete` | Алерты при создании и удалении сервисов | | `podPendingError` | Алерты по зависшим или ошибочным подам (`Pending`, `Unknown`) | | `probesFailures` | Алерты по сбоям `liveness`\- и `readiness`\-проб | | `nodeNotReady` | Алерты при переходе ноды в состояние `NotReady` | | `nodeResources` | Алерты по превышению порогов CPU/Memory на нодах | | `warnEvents` | Алерты по прочим Warning-событиям (например, `FailedScheduling`) | После настройки нажмите «Установить». ![Image 20250917162500189](https://content.timeweb.com/assets/1bc2b83b-e468-41c2-af2c-8dc45abdf167.png?width=2026&height=1404) Проверьте, что установка завершена корректно. Для этого выполните команду ```shell kubectl get all -n twc-alert-bot ``` Вы увидите примерно такой вывод: ```bash NAME READY STATUS RESTARTS AGE pod/twc-alert-bot-7955f9c94b-j57w6 1/1 Running 0 19s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/twc-alert-bot 1/1 1 1 19s NAME DESIRED CURRENT READY AGE replicaset.apps/twc-alert-bot-7955f9c94b 1 1 1 19s ``` ## Настройка уведомлений Чтобы получать уведомления от бота, подключите один или несколько мессенджеров. Telegram Чтобы бот отправлял уведомления в Telegram, укажите в конфигурации: ```shell telegramEnabled: true ``` Обязательные параметры для работы уведомлений: - `telegramBotToken` — токен, полученный с помощью бота [@BotFather](https://t.me/BotFather). - `telegramChatId` — ID чата или канала, в который будут отправляться уведомления. - `clusterName` — произвольное имя кластера, которым будут подписываться уведомления. ### Получение токена Токен необходим для управления ботом. Для создания бота перейдите к [@BotFather](https://t.me/BotFather). Создайте нового бота, отправив команду `/newbot`. Затем укажите имя и юзернейм бота. После этого [@BotFather](https://t.me/BotFather) пришлет токен нового бота. ![Image 20250916183700806](https://content.timeweb.com/assets/d54fe4e4-6f7c-486d-a374-10dd3fef79b9.png?width=1630&height=1228) _Получение токена в интерфейсе [Telegram](https://telegram.org/)_ Этот токен необходимо указать в конфигурации дополнения: ```bash telegramBotToken: "8119738188:AAnjknsd788asd0kl2309s3pipa11239" ``` Добавьте созданного бота в группу или канал с правом на отправку сообщений. ### Получение ID чата Бот может взаимодействовать с пользователями в канале, группе или личном чате. Чтобы получить нужный `chat_id`, выполните одно из следующих действий: - Добавьте бота в группу - Добавьте бота в канал в качестве администратора - Откройте личный чат с ботом После этого отправьте любое сообщение в соответствующий чат (группу, канал или личный). Затем откройте в браузере ссылку: ```shell https://api.telegram.org/bot<ТОКЕН_БОТА>/getUpdates ``` Вы увидите JSON с последними сообщениями, полученными ботом. Найдите блок `chat.id` — он содержит нужный идентификатор: - Для групп и каналов — значение будет отрицательным. - Для личных чатов — положительным. ![Scr 20250918 Kbzc](https://content.timeweb.com/assets/2ae29f93-d3b7-4c39-bea8-efe86487b697.png?width=1868&height=1466) _Просмотр JSON-файла на странице [api.telegram.org](https://api.telegram.org)_ В конфигурации дополнения укажите полученный ID: ```shell telegramChatId: "-1001236503122" ``` По умолчанию также включен параметр: ```shell telegramSendTestMessage: true ``` Благодаря этому параметру бот сразу после установки попытается отправить тестовое сообщение. Если все подключено корректно, вы его увидите. Slack Создайте App. Перейдите на [страницу создания App](https://api.slack.com/apps?new_app=1), нажмите кнопку «Create an App» и выберите пункт «From scratch». Укажите имя App и выберите воркспейс для подключения. Затем нажмите «Create App». ![Image 20250917114319240](https://content.timeweb.com/assets/e99e3cf4-f46b-4946-a603-a177e1261682.png?width=1172&height=1108) _Создание App в [Slack](https://slack.com/)_ Сразу после создания вы будете перенаправлены на страницу настроек App. Перейдите в раздел «Incoming Webhooks», включите вебхуки и создайте новый, нажав кнопку «Add New Webhook». ![Image 20250917114613683](https://content.timeweb.com/assets/d04b378c-600a-483e-a834-edb2b9cacad4.png?width=1874&height=1656) _Страница настроек App в [Slack](https://slack.com/)_ В открывшемся окне выберите канал, в который приложение сможет отправлять сообщения. Затем нажмите «Allow». ![Image 20250917114645794](https://content.timeweb.com/assets/4295db8c-2c0c-433d-b7cc-afaeae1ea7a8.png?width=1164&height=1014) _Выбор канала в [Slack](https://slack.com/)_ После этого вы снова окажетесь на странице настроек, где теперь будет отображаться URL вебхука. Скопируйте его. ![Image 20250917120344567](https://content.timeweb.com/assets/6ae606cc-f017-4802-b642-43460a5ab5e2.png?width=1834&height=1340) _Страница настроек App в [Slack](https://slack.com/)_ Вернитесь к конфигурации дополнения и найдите фрагмент: ```yaml webhooks: [] # - type: slack # url: "https://hooks.slack.com/services/XXX/YYY/ZZZ" # - type: discord # url: https://discord.com/api/webhooks/... ``` Удалите квадратные скобки и раскомментируйте строки, связанные со Slack. В поле url укажите URL вебхука, который вы получили ранее. В итоге конфигурация должна выглядеть так: ```yaml webhooks: - type: slack url: "https://hooks.slack.com/services/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Jz" # - type: discord # url: "https://discord.com/api/webhooks/..." ``` Discord Создайте вебхук. Для этого перейдите в настройки канала, в который будут отправляться уведомления. ![Image 20250917142215743](https://content.timeweb.com/assets/a0d706b4-6daf-4a65-86ee-161e79077b44.png?width=2006&height=722) _Настройки канала в интерфейсе [Discord](https://discord.com/)_ В открывшемся окне настроек перейдите в раздел «Интеграции» и нажмите кнопку «Создать вебхук». ![Image 20250917142629659](https://content.timeweb.com/assets/61c51793-95fa-4dc0-8e21-55e3fc231f59.png?width=2120&height=880) _Раздел «Интеграции» в интерфейсе [Discord](https://discord.com/)_ Затем в появившемся окне снова нажмите «Создать вебхук». После этого разверните его настройки, нажав на созданный вебхук. ![Image 20250917142745076](https://content.timeweb.com/assets/a30f52f9-aa63-4457-af41-7e9b394eac06.png?width=2104&height=1182) _Раздел «Интеграции» → «Вебхуки» в интерфейсе [Discord](https://discord.com/)_ Скопируйте URL вебхука — он понадобится для настройки интеграции. Вернитесь к конфигурации дополнения и найдите фрагмент: ```yaml webhooks: [] # - type: slack # url: "https://hooks.slack.com/services/XXX/YYY/ZZZ" # - type: discord # url: https://discord.com/api/webhooks/... ``` Удалите квадратные скобки и раскомментируйте строки, связанные с Discord. В поле `url` укажите скопированный ранее вебхук. Конфигурация должна выглядеть так: ```yaml webhooks: # - type: slack # url: "https://hooks.slack.com/services/XXX/YYY/ZZZ" - type: discord url: "https://discord.com/api/webhooks/14178357700512334/Z97wSlcrpipanjsS5hsbonushUqD5bSg_WcSptOmckvOj0pBslEZrm8" ``` На этом настройка завершена. # TWC Karpenter Source: https://timeweb.cloud/docs/k8s/addons/karpenter?utm_source=llms_txt&utm_medium=ai Karpenter — это контроллер для Kubernetes, который автоматически создает и удаляет воркер-ноды в зависимости от нагрузки в кластере. Он похож на встроенный [механизм автомасштабирования нод](https://timeweb.cloud/docs/k8s/kubernetes-autoscaling/kubernetes-autoscaler), но работает более гибко: анализирует поды в статусе Pending, подбирает подходящую конфигурацию и создает ноду под текущую нагрузку. При снижении нагрузки неиспользуемые ноды автоматически удаляются. При увеличении нагрузки в кластере Karpenter: - отслеживает поды, которые не удалось разместить; - анализирует их требования и подбирает подходящую конфигурацию ноды; - создает новую ноду через API и размещает на ней поды. При этом Karpenter не использует заранее заданные размеры групп нод, а подбирает конфигурацию под текущую рабочую нагрузку. Это позволяет точнее выбирать тип инстанса и эффективнее использовать ресурсы. При снижении нагрузки он анализирует использование нод и может: - удалять неиспользуемые ноды; - консолидировать нагрузку, перенося поды на меньшее количество узлов; - отключать избыточные или менее эффективные по стоимости ноды. По сравнению с Cluster Autoscaler, Karpenter: - быстрее реагирует на изменение нагрузки; - подбирает конфигурацию ноды под конкретную рабочую нагрузку; - поддерживает консолидацию и оптимизацию ресурсов; - позволяет снизить затраты за счет более точного подбора конфигурации; - тесно интегрируется с облачным провайдером и использует его API для управления нодами. ## Установка > [!NOTE] > Для установки в кластере должна быть хотя бы одна воркер-нода с конфигурацией не менее 2 vCPU и 4 ГБ RAM. Перейдите в раздел «Дополнения» в панели управления кластером, найдите «TWC Karpenter» и откройте карточку аддона. ![Scr 20260408 Oszq](https://content.timeweb.com/assets/e5cba43d-8cad-437a-9a08-2f40e8da2631.png?width=2108&height=1666) Нажмите кнопку «Установить» и дождитесь завершения установки. Проверить состояние можно командой: ```bash kubectl get pods -n karpenter ``` Пример вывода: ```bash NAME READY STATUS RESTARTS AGE karpenter-provider-timeweb-cloud-dc96f8664-dbcb6 1/1 Running 0 3d21h ``` Если под находится в статусе `Running`, установка прошла успешно. ## Использование Перед использованием необходимо создать группы нод, которые сможет использовать Karpenter. Аддон не создает группы нод автоматически. Создайте одну или несколько групп с нужными конфигурациями, после чего Karpenter сможет использовать их для масштабирования. При создании группы отключите автомасштабирование и автохилинг. Karpenter самостоятельно управляет количеством нод и их состоянием, поэтому эти механизмы должны быть отключены. ### NodeClass Для настройки дополнения сначала создайте манифест `nodeclass.yaml`. Ресурс `NodeClass` описывает, какую группу нод использовать и какие параметры применять к создаваемым узлам. Минимальный пример `nodeclass.yaml`: ```yaml apiVersion: karpenter.k8s.timeweb.cloud/v1alpha1 kind: NodeClass metadata: name: default spec: labels: environment: production managed-by: karpenter ``` Для более гибкой настройки можно указать дополнительные параметры. Расширенный пример `nodeclass.yaml`: ```yaml apiVersion: karpenter.k8s.timeweb.cloud/v1alpha1 kind: NodeClass metadata: name: default spec: nodeGroupID: 12345 labels: environment: production managed-by: karpenter maxCapacityPerGroup: 10 ``` В этом манифесте: - `nodeGroupID` задает конкретную группу нод, в которой будут создаваться узлы; - `labels` позволяет назначить дополнительные метки создаваемым нодам; - `maxCapacityPerGroup` ограничивает максимальное количество нод в группе. Узнать `nodeGroupID` можно в панели управления кластером. Перейдите в раздел «Ресурсы», нажмите на три точки рядом с нужной группой и выберите «Редактировать группу». Откроется страница с URL вида: ```shell https://timeweb.cloud/my/kubernetes///edit ``` Значение `` в этом URL и есть идентификатор группы нод. Примените манифест: ```bash kubectl apply -f nodeclass.yaml ``` ### NodePool После создания `NodeClass` необходимо настроить `NodePool`. Этот ресурс определяет требования к нодам, которые будет создавать Karpenter. Здесь задаются параметры, по которым подбирается подходящая конфигурация: тип инстанса, зона, архитектура и другие ограничения. Создайте файл `nodepool.yaml` со следующим содержимым: ```yaml apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: default spec: # Шаблон для новых нод template: spec: nodeClassRef: group: karpenter.k8s.timeweb.cloud kind: NodeClass name: default # Требования к нодам requirements: # Архитектура - key: kubernetes.io/arch operator: In values: ["amd64"] # Операционная система - key: kubernetes.io/os operator: In values: ["linux"] # Instance type — типы которые могут использоваться # Формат: nvme-{cpu}cpu-{ram}ram или highcpu-{cpu}cpu-{ram}ram или dedicatedcpu-{cpu}cpu-{ram}ram или gpu-{cpu}cpu-{ram}ram - key: node.kubernetes.io/instance-type operator: In values: ["nvme-1cpu-2ram", "nvme-2cpu-2ram", "nvme-2cpu-4ram", "nvme-4cpu-8ram", "dedicatedcpu-1cpu-4ram", "dedicatedcpu-2cpu-8ram", "dedicatedcpu-3cpu-12ram", "dedicatedcpu-4cpu-16ram"] - key: karpenter.sh/capacity-type operator: In values: ["on-demand"] # Зона доступности - key: topology.kubernetes.io/zone operator: In values: ["spb-3"] # Ограничения на ресурсы для всех нод в пуле limits: cpu: "1000" # Максимум 1000 CPU по всем узлам memory: 1000Gi # Максимум 1000Gi памяти по всем узлам # Политики disruption (consolidationPolicy: WhenEmpty или WhenEmptyOrUnderutilized) disruption: consolidationPolicy: WhenEmptyOrUnderutilized consolidateAfter: 5m ``` В этом манифесте: - `nodeClassRef` указывает, какой `NodeClass` использовать для создания нод; - `requirements` в блоке задаются ограничения на параметры нод; - `node.kubernetes.io/instance-type` определяет допустимые конфигурации воркеров; - `kubernetes.io/arch` задает архитектуру нод (поддерживается только `amd64`); - `kubernetes.io/os` задает операционную систему (поддерживается только `linux`); - `topology.kubernetes.io/zone` задает зону доступности (поддерживается только `spb-3`); - `limits` ограничивает суммарные ресурсы всех нод; - `disruption` управляет удалением неиспользуемых нод. Обратите внимание, что значения в `requirements` должны соответствовать параметрам доступных групп нод. Например, если у вас создано несколько групп нод, укажите в `instance-type` только те конфигурации, которые используются в этих группах. Примените манифест: ```bash kubectl apply -f nodepool.yaml ``` После применения манифестов убедитесь, что ресурсы созданы: ```bash kubectl get nodeclass kubectl get nodepool ``` Пример вывода: ```shell NAME READY AGE default True 3d22h NAME NODECLASS NODES READY AGE default default 1 True 3d22h ``` ### Пример использования Создадим `deployment` с запросами ресурсов. Создайте файл `inflate.yaml`: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: inflate spec: replicas: 1 selector: matchLabels: app: inflate template: metadata: labels: app: inflate spec: containers: - name: inflate image: public.ecr.aws/eks-distro/kubernetes/pause:3.7 resources: requests: cpu: "250m" memory: "256Mi" ``` Примените манифест: ```bash kubectl apply -f inflate.yaml ``` Увеличьте количество подов: ```bash kubectl scale deployment inflate --replicas=15 ``` Если ресурсов текущих нод недостаточно, часть подов перейдет в статус `Pending`. После этого Karpenter создаст новую ноду, и поды начнут создаваться. Проверить процесс можно командами: ```bash kubectl get pods kubectl get nodes ``` При появлении новых нод в списке при выполнении `kubectl get nodes` можно считать, что Karpenter настроен корректно и работает. # Traefik Source: https://timeweb.cloud/docs/k8s/addons/traefik?utm_source=llms_txt&utm_medium=ai Traefik — это ингресс контроллер и реверс прокси для работы в облачных средах и Kubernetes. Он автоматически обнаруживает сервисы, обеспечивает SSL/TLS-терминацию и расширенные возможности маршрутизации.  Использование Traefik в Kubernetes позволяет гибко управлять маршрутизацией трафика к сервисам внутри кластера. ## Установка 1. Перейдите во вкладку «Дополнения» в панели управления кластером. 2. Найдите Traefik и нажмите на него. ![Image2](https://content.timeweb.com/assets/d841405b-2287-4ae5-8a83-815501fb6bd9.png?width=999&height=861) 3. Откроется мастер установки. Вы можете загрузить собственный `values.yaml` для кастомизации установки или оставить настройки по умолчанию. Запустите установку, нажав на кнопку «Установить». ![Image1](https://content.timeweb.com/assets/add88e43-c082-40d6-af2f-6f9c6e32ade0.png?width=1002&height=789) 4. Дождитесь завершения установки. После этого убедитесь, что все поды в неймспейсе `traefik` запущены и находятся в статусе «Running»: ```shell kubectl get pods -n traefik ``` ## Использование По умолчанию в установленной конфигурации Traefik использует четыре `entryPoints` (входные точки): - :8000/tcp — HTTP (`web`) - :8443/tcp — HTTPS (`websecure`) - :8080/tcp — API Dashboard (`traefik`) - :9100/tcp — Метрики Prometheus (`metrics`) Для работы с Traefik необходимо создать `Service`, который будет маршрутизировать трафик к вашему приложению: ```yml apiVersion: v1 kind: Service metadata: name: example-service namespace: default spec: selector: app: example-app ports: - protocol: TCP port: 80 targetPort: 80 ``` Этот манифест создает сервис `example-service` в пространстве имен `default`, который: - Маршрутизирует HTTP-трафик (порт `80`). - Направляет его на поды, имеющие метку `app: example-app`. - Передает запросы на `targetPort: 80` внутри подов. Теперь можно настроить маршрутизацию через Traefik с помощью `IngressRoute`: ```yml apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: example-service-route namespace: default spec: entryPoints: - web routes: - match: Host(`service.example.com`) kind: Rule services: - name: example-service port: 80 ``` В этом манифесте: - `entryPoints: web` — указывает, что маршрутизация происходит через HTTP (`8000/tcp`). - `match: Host(‘service.example.com’)` — задает правило маршрутизации по доменному имени. - Запросы направляются на сервис `example-service` на порт `80`. ## Пример использования Рассмотрим использование Traefik на примере. Создадим два деплоймента Nginx, которые будут работать на двух разных доменах — service1.example.com и service2.example.com. Также настроим балансировщик нагрузки и маршрутизацию через Traefik. В завершение настроим SSL-сертификаты средствами Traefik. ### Создание ConfigMap Сначала создадим файл `configmap-nginx.yaml`, который определит HTML-страницы для каждого сервиса: ```yml apiVersion: v1 kind: ConfigMap metadata: name: nginx-pages namespace: default data: index1.html: | Service 1

Service 1

index2.html: | Service 2

Service 2

``` ### Создание Deployment для Nginx Манифест `service1-nginx.yaml` описывает деплоймент для первого сервиса: ```yml apiVersion: apps/v1 kind: Deployment metadata: name: service1 namespace: default labels: app: service1 spec: replicas: 2 selector: matchLabels: app: service1 template: metadata: labels: app: service1 spec: containers: - name: nginx image: nginx volumeMounts: - name: html-volume mountPath: /usr/share/nginx/html ports: - containerPort: 80 volumes: - name: html-volume configMap: name: nginx-pages items: - key: index1.html path: index.html ``` Манифест `service2-nginx.yaml` описывает деплоймент для второго сервиса: ```yml apiVersion: apps/v1 kind: Deployment metadata: name: service2 namespace: default labels: app: service2 spec: replicas: 2 selector: matchLabels: app: service2 template: metadata: labels: app: service2 spec: containers: - name: nginx image: nginx volumeMounts: - name: html-volume mountPath: /usr/share/nginx/html ports: - containerPort: 80 volumes: - name: html-volume configMap: name: nginx-pages items: - key: index2.html path: index.html ``` ### Создание Service Определим сервисы, к которым Traefik будет направляться трафик. Манифест `service1-service.yaml`: ```yml apiVersion: v1 kind: Service metadata: name: service1 namespace: default spec: selector: app: service1 ports: - protocol: TCP port: 80 targetPort: 80 ``` Этот манифест создает сервис `service1`, который будет принимать HTTP-запросы на порт `80` и перенаправлять их на поды, имеющие метку `app: service1`. Манифест `service2-service.yaml`: ```yml apiVersion: v1 kind: Service metadata: name: service2 namespace: default spec: selector: app: service2 ports: - protocol: TCP port: 80 targetPort: 80 ``` ### Создание маршрутов в Traefik В манифесте `service1-ingressroute.yaml` описывается маршрут для первого сервиса: ```yml apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: service1-route namespace: default spec: entryPoints: - web routes: - match: Host(`service1.example.com`) kind: Rule services: - name: service1 port: 80 ``` Этот манифест определяет `IngressRoute` для `service1.example.com`. Разберем его компоненты: - `entryPoints: web` — указывает, что маршрут будет доступен через HTTP (порт `80`, указанный в балансировщике Traefik). - `match: Host(‘service1.example.com’)` — определяет, что данный маршрут будет срабатывать при обращении к домену `service1.example.com`. - `name: service1` — маршрут передает трафик в сервис `service1`. - `port: 80` — передача происходит на порт `80` внутри Kubernetes-сервиса `service1`. Файл `service2-ingressroute.yaml` описывает маршрут для второго сервиса: ```yml apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: service2-route namespace: default spec: entryPoints: - web routes: - match: Host(`service2.example.com`) kind: Rule services: - name: service2 port: 80 ``` ### Настройка балансировщика нагрузки Опишем балансировщик для Traefik в `traefik-loadbalancer.yaml`: ```yml apiVersion: v1 kind: Service metadata: name: traefik namespace: traefik spec: type: LoadBalancer selector: app.kubernetes.io/name: traefik ports: - name: web port: 80 targetPort: 8000 - name: websecure port: 443 targetPort: 8443 ``` ### Применение конфигурации Применяем все манифесты: ```shell kubectl apply -f ./ ``` После завершения создания балансировщика указываем его IP-адрес в качестве A-записей для доменов. Теперь можно обращаться к сервисам: - `http://service1.example.com` - `http://service2.example.com` Таким образом, мы настроили два сервиса в Kubernetes с использованием Traefik, обеспечили маршрутизацию и балансировку нагрузки. ## Настройка SSL При использовании Traefik можно получать SSL-сертификаты двумя способами: - встроенными средствами Traefik; - с использованием [cert-manager](https://timeweb.cloud/docs/k8s/addons/cert-manager). Выбор метода зависит от конфигурации кластера. Если используются другие Ingress-контроллеры, рекомендуется cert-manager для централизованного управления сертификатами. Если же в кластере используется только Traefik, можно воспользоваться встроенной функцией получения сертификатов. ### Обновление конфигурации Traefik Для включения поддержки Let's Encrypt необходимо изменить конфигурацию Traefik: 1. Перейдите в панель управления кластером → «Дополнения» → выберите Traefik. 2. Включите режим продвинутой установки. 3. Приведите конфигурацию к виду: ```yml image: registry: dockerhub.timeweb.cloud deployment: kind: Deployment updateStrategy: rollingUpdate: maxUnavailable: 1 maxSurge: 0 additionalArguments: - "--certificatesresolvers.le.acme.email=admin@example.com" - "--certificatesresolvers.le.acme.storage=/data/acme.json" - "--certificatesresolvers.le.acme.tlschallenge=true" ``` **Что изменилось**: - По умолчанию, Traefik устанавливается как `DaemonSet`. В этом режиме сертификаты средствами Traefik получить невозможно. Поэтому тип развёртывания меняется на `Deployment`. - Добавлен сегмент `additionalArguments`. В `--certificatesresolvers.le.acme.email` укажите свою почту для регистрации в Let's Encrypt. ![Image3](https://content.timeweb.com/assets/e008b3c5-d119-44ca-9865-2265b79f7daf.png?width=996&height=873) 4. Сохраните изменения и дождитесь завершения обновления. ### Проверка конфигурации После обновления убедитесь, что конфигурация применена корректно: ```shell kubectl get pod -n traefik ``` Затем проверьте наличие параметров ACME: ```shell kubectl get pod имя_пода -n traefik -o yaml | grep acme ``` Вывод должен содержать строки: ```shell - --certificatesresolvers.le.acme.email=admin@example.com - --certificatesresolvers.le.acme.storage=/data/acme.json - --certificatesresolvers.le.acme.tlschallenge=true ``` ### Автоматический редирект с HTTP на HTTPS Создадим `middleware` для автоматического редиректа с HTTP на HTTPS. Файл `redirect-https.yaml`: ```yml apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: redirect-to-https namespace: default spec: redirectScheme: scheme: https permanent: true ``` Применим манифест: ```shell kubectl apply -f redirect-https.yaml ``` ### Обновление IngressRoute Обновим `IngressRoute`, добавив `middleware` для редиректа с HTTP на HTTPS. Манифест `service1-ingressroute.yaml`: ```yml apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: service1-route namespace: default spec: entryPoints: - web routes: - match: Host(`service1.example.com`) kind: Rule middlewares: - name: redirect-to-https services: - name: service1 port: 80 ``` Манифест `service2-ingressroute.yaml`: ```yml apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: service2-route namespace: default spec: entryPoints: - web routes: - match: Host(`service2.example.com`) kind: Rule middlewares: - name: redirect-to-https services: - name: service2 port: 80 ``` Теперь в манифестах маршрутизации `service1-ingressroute.yaml` и `service2-ingressroute.yaml` добавляется middleware `redirect-to-https`, которая автоматически перенаправляет HTTP-запросы на HTTPS. Обновляем манифесты: ```shell kubectl apply -f service1-ingressroute.yaml kubectl apply -f service2-ingressroute.yaml ``` ### Настройка HTTPS IngressRoute Теперь нам необходимо создать отдельные `IngressRoute` для HTTPS. Это необходимо, потому что стандартные HTTP-маршруты не обрабатывают TLS, и для работы HTTPS необходимо задать `certResolver`, который будет использовать Let's Encrypt для автоматического получения сертификатов. В новых `IngressRoute` указываются `entryPoints: websecure` и параметр `tls`, который активирует поддержку шифрования. Манифест `service1-ingressroute-https.yaml`: ```yml apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: service1-route-https namespace: default spec: entryPoints: - websecure routes: - match: Host(`service1.example.com`) kind: Rule services: - name: service1 port: 80 tls: certResolver: le ``` Манифест `service2-ingressroute-https.yaml`: ```yml apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: service2-route-https namespace: default spec: entryPoints: - websecure routes: - match: Host(`service2.example.com`) kind: Rule services: - name: service2 port: 80 tls: certResolver: le ``` Применяем манифесты для новых роутов: ```shell kubectl apply -f service1-ingressroute-https.yaml kubectl apply -f service2-ingressroute-https.yaml ``` ### Проверка выпуска сертификатов Проверить, что сертификаты успешно выпущены, можно с помощью команды: ```shell kubectl logs -n traefik -l app.kubernetes.io/name=traefik | grep acme ``` Теперь доступ к сервисам осуществляется через HTTPS: - `https://service1.example.com` - `https://service2.example.com` Таким образом, мы настроили автоматическое получение SSL-сертификатов с помощью Let's Encrypt в Traefik и обеспечили безопасное подключение к сервисам. ## Настройка дашборда Traefik предоставляет веб-интерфейс, который позволяет отслеживать состояние маршрутов, сервисов, middleware и других ресурсов, управляемых инстансом Traefik. Дашборд помогает диагностировать проблемы, анализировать маршрутизацию трафика и контролировать конфигурацию. По умолчанию дашборд Traefik доступен без авторизации, что создает угрозу безопасности, так как любому пользователю будет доступна информация о запущенных сервисах. Чтобы защитить доступ, настроим базовую авторизацию с помощью middleware. 1. Получим хэш желаемого пароля: ```shell mkpasswd -m bcrypt "password" ``` 2. Данные для авторизации мы сохраним в секрете Kubernetes, поэтому их нужно закодировать в base64: ```shell echo -n 'логин:полученный_ранее_хэш' | base64 ``` 3. Теперь опишем секрет в манифесте `dashboard-secret.yaml`: ```yml apiVersion: v1 kind: Secret metadata: name: dashboard-auth-secret namespace: traefik type: Opaque data: users: | логин:пароль_закодированный_в_base64 ``` 4. Применим манифест: ```shell kubectl apply -f dashboard-secret.yaml ``` 5. Теперь опишем middleware в файле `dashboard-auth.yaml`: ```yml apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: dashboard-auth namespace: traefik spec: basicAuth: secret: dashboard-auth-secret ``` 6. Применяем манифест: ```shell kubectl apply -f dashboard-auth.yaml ``` 7. Наконец, опишем `IngressRoute` для дашборда в файле `dashboard-ingress.yaml`: ```yml apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: traefik-dashboard namespace: traefik spec: entryPoints: - websecure routes: - match: Host(`dashboard.example.com`) kind: Rule middlewares: - name: dashboard-auth services: - kind: TraefikService name: api@internal tls: certResolver: le ``` Этот манифест задает маршрут для доступа к дашборду Traefik через HTTPS, применяя базовую авторизацию. Описание параметров: - `entryPoints: websecure` — указывает, что маршрут будет доступен только через HTTPS. - `match: Host(dashboard.example.com)` — направляет запросы, полученные для dashboard.example.com, к дашборду. - `middlewares` — применяет созданную ранее middleware `dashboard-auth`, обеспечивающую базовую HTTP-аутентификацию. - `services` — указывает, что запросы должны направляться к встроенному сервису `api@internal`, который отвечает за отображение дашборда. - `tls.certResolver: le` — активирует автоматическое получение SSL-сертификата через Let's Encrypt. 8. Применим манифест: ```shell kubectl apply -f dashboard-ingress.yaml ``` 9. Теперь обратимся к `https://dashboard.example.com`. После авторизации вы увидите дашборд. # Vault Source: https://timeweb.cloud/docs/k8s/addons/vault?utm_source=llms_txt&utm_medium=ai Vault — это система управления секретами от HashiCorp, которая позволяет безопасно хранить и получать доступ к токенам, паролям, сертификатам и другим чувствительным данным. В Kubernetes Vault используется как внешнее хранилище секретов и может обеспечивать централизованное управление доступом к ним. ## Установка Установить Vault в кластер можно через панель управления. Для этого: Перейдите во вкладку «Дополнения» на странице управления кластером. Найдите карточку «Vault» и нажмите «Установить». ![Scr 20251021 Piuk](https://content.timeweb.com/assets/f96762ca-3fae-4978-abd8-0fc40d7ce61b.png?width=1984&height=1656) В появившемся окне вы можете изменить параметры установки: 1. Переключитесь в режим продвинутой установки; 2. Отредактируйте конфигурацию вручную или загрузите свой файл `values.yaml`; 3. Нажмите кнопку «Установить». ![Scr 20251021 Pizg](https://content.timeweb.com/assets/c861f3e3-215e-4d4c-b0b3-0a1e60a485c5.png?width=1984&height=1592) Конфигурация по умолчанию подразумевает что дополнение будет использоваться в dev-режиме. Это упрощенный режим, в котором Vault автоматически инициализируется, не требует настройки хранилища и использует предустановленный `root token`. Такой режим подходит только для тестирования и разработки — он небезопасен для продакшена. ## Проверка установки После завершения установки дополнения убедитесь, что компоненты Vault успешно запустились. Для этого выполните команду: ```shell kubectl get pods -n vault ``` Вы должны увидеть список подов, среди которых: - `vault-0` — основной под Vault; - `vault-agent-injector-xxx` — сервис, отвечающий за автоматическую подстановку секретов в поды; - дополнительные поды (например, `vault-1`, `vault-2`), если установлен в HA-режиме. Если в конфигурации была включена опция `ui = true` (по умолчанию включена), вы можете получить доступ к веб-интерфейсу Vault: Пробросьте порт с помощью следующей команды: ```shell kubectl port-forward -n vault svc/vault 8200:8200 ``` Откройте браузер и перейдите по адресу: ```shell http://localhost:8200 ``` В dev-режиме Vault уже инициализирован, и вы можете авторизоваться с помощью токена, указанного в конфигурации. По умолчанию значение такое: ```shell devRootToken: "root" ``` ![Scr 20251021 Qnui](https://content.timeweb.com/assets/cfcd1d4a-6972-4dd6-a46f-8a12771aee34.png?width=1612&height=875) _Интерфейс [HashiCorp Vault](https://www.hashicorp.com/en/products/vault)_ ## Режим HA Режим **HA** (High Availability) позволяет развернуть несколько экземпляров Vault с распределенным хранением данных. Это обеспечивает: - отказоустойчивость — при выходе из строя одного экземпляра кластер продолжит работать; - централизованное хранилище; - возможность масштабирования. Один из подов становится лидером, остальные работают в режиме `standby`. Запросы на чтение/запись обрабатывает только лидер, но в случае его недоступности управление автоматически перейдет к одному из `standby`\-подов. > [!NOTE] > Для работы в этом режиме рекомендуем установить и использовать дополнения [CSI-S3](https://timeweb.cloud/docs/k8s/addons/csi-s3) или [CSI-driver](https://timeweb.cloud/docs/k8s/network-drives-connection). Чтобы включить режим HA, в конфигурации дополнения укажите параметры: - `server.dev.enabled: false` — отключаем dev-режим; - `server.standalone.enabled: false` — отключаем standalone-режим; - `server.ha.enabled: true` — включаем HA-режим; - `server.ha.replicas: 3` — указываем количество реплик; - `server.ha.raft.enabled: true` — используем встроенное хранилище Raft; - `server.dataStorage.storageClass: csi-s3` — подключаем S3-хранилище через CSI. Пример конфигурации (нажмите, чтобы развернуть) ```yaml global: enabled: true namespace: "" imagePullSecrets: [] tlsDisable: true externalVaultAddr: "" openshift: false psp: enable: false annotations: | seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default,runtime/default apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default seccomp.security.alpha.kubernetes.io/defaultProfileName: runtime/default apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default serverTelemetry: prometheusOperator: false injector: enabled: true replicas: 1 port: 8080 leaderElector: enabled: true metrics: enabled: false externalVaultAddr: "" image: repository: "hashicorp/vault-k8s" tag: "1.7.0" pullPolicy: IfNotPresent agentImage: repository: "hashicorp/vault" tag: "1.20.4" agentDefaults: cpuLimit: "500m" cpuRequest: "250m" memLimit: "128Mi" memRequest: "64Mi" template: "map" templateConfig: exitOnRetryFailure: true staticSecretRenderInterval: "" livenessProbe: failureThreshold: 2 initialDelaySeconds: 5 periodSeconds: 2 successThreshold: 1 timeoutSeconds: 5 readinessProbe: failureThreshold: 2 initialDelaySeconds: 5 periodSeconds: 2 successThreshold: 1 timeoutSeconds: 5 startupProbe: failureThreshold: 12 initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 5 authPath: "auth/kubernetes" logLevel: "info" logFormat: "standard" revokeOnShutdown: false webhook: failurePolicy: Ignore matchPolicy: Exact timeoutSeconds: 30 namespaceSelector: {} objectSelector: | matchExpressions: - key: app.kubernetes.io/name operator: NotIn values: - {{ template "vault.name" . }}-agent-injector annotations: {} failurePolicy: Ignore namespaceSelector: {} objectSelector: {} webhookAnnotations: {} certs: secretName: null caBundle: "" certName: tls.crt keyName: tls.key securityContext: pod: {} container: {} resources: {} extraEnvironmentVars: {} affinity: | podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector app.kubernetes.io/instance: "{{ .Release.Name }}" component: webhook topologyKey: kubernetes.io/hostname topologySpreadConstraints: [] tolerations: [] nodeSelector: {} priorityClassName: "" annotations: {} extraLabels: {} hostNetwork: false service: annotations: {} serviceAccount: annotations: {} podDisruptionBudget: {} strategy: {} server: enabled: true enterpriseLicense: secretName: "" secretKey: "license" image: repository: "hashicorp/vault" tag: "1.20.4" pullPolicy: IfNotPresent updateStrategyType: "OnDelete" logLevel: "info" logFormat: "standard" resources: {} ingress: enabled: false labels: {} annotations: {} ingressClassName: "" pathType: Prefix activeService: true hosts: - host: chart-example.local paths: [] extraPaths: [] tls: [] hostAliases: [] route: enabled: false activeService: true labels: {} annotations: {} host: chart-example.local tls: termination: passthrough authDelegator: enabled: true extraInitContainers: null extraContainers: null shareProcessNamespace: false extraArgs: "" extraPorts: null readinessProbe: enabled: true port: 8200 failureThreshold: 2 initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 3 livenessProbe: enabled: false execCommand: [] path: "/v1/sys/health?standbyok=true" port: 8200 failureThreshold: 2 initialDelaySeconds: 60 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 3 terminationGracePeriodSeconds: 10 preStopSleepSeconds: 5 preStop: [] postStart: [] extraEnvironmentVars: {} extraSecretEnvironmentVars: [] extraVolumes: [] volumes: null volumeMounts: null affinity: | podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app.kubernetes.io/name: {{ template "vault.name" . }} app.kubernetes.io/instance: "{{ .Release.Name }}" component: server topologyKey: kubernetes.io/hostname topologySpreadConstraints: [] tolerations: [] nodeSelector: {} networkPolicy: enabled: false egress: [] ingress: - from: - namespaceSelector: {} ports: - port: 8200 protocol: TCP - port: 8201 protocol: TCP priorityClassName: "" extraLabels: {} annotations: {} includeConfigAnnotation: false service: enabled: true active: enabled: true annotations: {} standby: enabled: true annotations: {} instanceSelector: enabled: true ipFamilyPolicy: "" ipFamilies: [] publishNotReadyAddresses: true externalTrafficPolicy: Cluster port: 8200 targetPort: 8200 annotations: {} dataStorage: enabled: true size: 1Gi mountPath: "/vault/data" storageClass: "csi-s3" accessMode: ReadWriteOnce annotations: {} labels: {} persistentVolumeClaimRetentionPolicy: {} auditStorage: enabled: false size: 1Gi mountPath: "/vault/audit" storageClass: "csi-s3" accessMode: ReadWriteOnce annotations: {} labels: {} dev: enabled: false devRootToken: "root" standalone: enabled: false config: |- ui = true listener "tcp" { tls_disable = 1 address = "[::]:8200" cluster_address = "[::]:8201" } storage "file" { path = "/vault/data" } ha: enabled: true replicas: 3 apiAddr: null clusterAddr: null raft: enabled: true setNodeId: false config: | ui = true listener "tcp" { tls_disable = 1 address = "[::]:8200" cluster_address = "[::]:8201" } storage "raft" { path = "/vault/data" } service_registration "kubernetes" {} disruptionBudget: enabled: true maxUnavailable: null serviceAccount: create: true name: "" createSecret: false annotations: {} extraLabels: {} serviceDiscovery: enabled: true statefulSet: annotations: {} securityContext: pod: {} container: {} hostNetwork: false ui: enabled: true publishNotReadyAddresses: true activeVaultPodOnly: false serviceType: "ClusterIP" serviceNodePort: null externalPort: 8200 targetPort: 8200 serviceIPFamilyPolicy: "" serviceIPFamilies: [] externalTrafficPolicy: Cluster annotations: {} csi: enabled: true image: repository: "hashicorp/vault-csi-provider" tag: "1.5.1" pullPolicy: IfNotPresent volumes: null volumeMounts: null resources: {} hmacSecretName: "" hostNetwork: false daemonSet: updateStrategy: type: RollingUpdate maxUnavailable: "" annotations: {} providersDir: "/var/run/secrets-store-csi-providers" kubeletRootDir: "/var/lib/kubelet" extraLabels: {} securityContext: pod: {} container: {} pod: annotations: {} tolerations: [] nodeSelector: {} affinity: {} extraLabels: {} agent: enabled: true extraArgs: [] image: repository: "hashicorp/vault" tag: "1.20.4" pullPolicy: IfNotPresent logFormat: standard logLevel: info resources: {} securityContext: container: allowPrivilegeEscalation: false capabilities: drop: - ALL readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 100 runAsGroup: 1000 priorityClassName: "" serviceAccount: annotations: {} extraLabels: {} readinessProbe: failureThreshold: 2 initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 3 livenessProbe: failureThreshold: 2 initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 3 logLevel: "info" debug: false extraArgs: [] serverTelemetry: serviceMonitor: enabled: false selectors: {} interval: 30s scrapeTimeout: 10s tlsConfig: {} authorization: {} metricRelabelings: [] prometheusRules: enabled: false selectors: {} rules: [] ``` После установки кластера с включенным HA-режимом Vault не инициализируется автоматически. Это нужно сделать вручную с помощью CLI. Для инициализации Vault подключитесь к основному поду (`vault-0`) : ```shell kubectl exec -it vault-0 -n vault -- /bin/sh ``` И выполните команды: ```shell export VAULT_ADDR=http://127.0.0.1:8200 export VAULT_CLIENT_TIMEOUT=300s vault operator init ``` В результате вы получите несколько `Unseal Keys` и `Initial Root Token`. Сохраните эти данные в надежном месте — без них восстановить доступ к Vault будет невозможно. Пример вывода: ```shell Unseal Key 1: 4ErPXwe87rjULP6yz7h3XZ8Dr/nhTyMrVLiIsQ8s5ksX Unseal Key 2: IVk3hipR5D/yR5ngi1LJaaxRwarEWjR/hjC8DFwXuNYb Unseal Key 3: qBCx+7B+wiehep0yArs7nVT73SyMYXh+AH3jCXTCs80H Unseal Key 4: CQm+0tOTS9wZQWYJJU8Roo2tMCGS+dZt7eXMDLjU5gX+ Unseal Key 5: KTvyD+vhEXPNQgcQJQe69Gu/sjkhhl/ScGZNnmmN64xC Initial Root Token: hvs.uKO8ZtmUgARVtrLhzBlQV4tA ``` По умолчанию создается 5 ключей, из которых требуется минимум 3 для активации хранилища. После инициализации Vault находится в `sealed` состоянии. Чтобы запустить кластер, его нужно активировать. Для этого: 1. Подключитесь к каждому поду по очереди (`vault-0`, `vault-1`, `vault-2`). 2. Выполните команду, указав три любых из полученных ключей: ```shell vault operator unseal vault operator unseal vault operator unseal ``` 3. Проверьте статус: ```shell vault status ``` Если все прошло успешно, `Sealed` будет иметь значение `false`. # Velero Source: https://timeweb.cloud/docs/k8s/addons/velero?utm_source=llms_txt&utm_medium=ai Velero — это инструмент для резервного копирования, восстановления и переноса данных в Kubernetes. Он позволяет создавать бэкапы и восстанавливать состояние кластеров, а также выполнять миграции между кластерами. Для работы с Velero необходимо установить Velero CLI на локальную машину и настроить его в вашем кластере Kubernetes. ## Предварительные требования Перед началом установки убедитесь, что выполнены следующие условия: 1. Настроен доступ к вашему Kubernetes-кластеру через kubectl. Инструкцию по настройке можно найти [здесь](https://timeweb.cloud/docs/k8s/cluster-connection/kubectl). 2. Создан S3-бакет для размещения резервных копий. Создать бакет можно по [инструкции](https://timeweb.cloud/docs/s3-storage/manage-storage/create-bucket). Создадим отдельный неймспейс для Velero: ```shell kubectl create namespace velero ``` ## Создание секрета S3 Для настройки доступа Velero к S3-бакету создадим секрет. Создайте файл манифеста `velero-credentials-secret.yaml` со следующим содержимым: ```yml apiVersion: v1 kind: Secret metadata: name: cloud-credentials namespace: velero type: Opaque stringData: cloud: | [default] aws_access_key_id=S3_Access_Key aws_secret_access_key=S3_Secret_Access_Key ``` Замените `S3_Access_Key` и `S3_Secret_Access_Key` на свои ключи доступа к S3. ![Selection 167](https://content.timeweb.com/assets/da926458-bf59-46af-8ed6-138437f06649.png?width=870&height=873) Примените манифест: ```shell kubectl apply -f velero-credentials-secret.yaml ``` Проверьте создание секрета: ```shell kubectl describe secrets cloud-credentials -n velero ``` Значение `Data.cloud` должно быть ненулевым. ![Screenshot 01 25 25 21:02:04](https://content.timeweb.com/assets/a2bcb618-2f84-468d-9167-677df048cd57.png?width=549&height=214) ## Установка Velero CLI Бинарный файл Скачайте архив с последней версией Velero с официальной [страницы релизов](https://github.com/vmware-tanzu/velero/releases) GitHub: ```shell wget https://github.com/vmware-tanzu/velero/releases/download/v1.15.2/velero-v1.15.2-linux-amd64.tar.gz ``` Распакуйте архив: ```shell tar -xvzf velero-v1.15.2-linux-amd64.tar.gz ``` Переместите бинарный файл Velero в директорию `/usr/local/bin`: ```shell sudo mv ./velero-v1.15.2-linux-amd64/velero /usr/local/bin/ ``` Homebrew Для установки Velero на macOS выполните команду: ```shell brew install velero ``` Chocolatey Для установки Velero на Windows с использованием Chocolatey выполните команду: ```shell choco install velero ``` Проверьте установку: ```shell velero version ``` ![Screenshot 01 25 25 21:04:13](https://content.timeweb.com/assets/bc2ed7e0-d1e8-457c-b8d9-9dd6a2381b67.png?width=625&height=128) ## Установка Velero в кластере Создайте файл `values.yaml` с минимально необходимой конфигурацией: ```yml namespace: name: velero labels: {} credentials: existingSecret: cloud-credentials configuration: backupStorageLocation: - name: default provider: aws bucket: имя_бакета default: true config: region: ru-1 s3ForcePathStyle: true s3Url: https://s3.twcstorage.ru   volumeSnapshotLocation: - name: default provider: aws config: region: ru-1 initContainers: - name: velero-plugin-for-aws image: velero/velero-plugin-for-aws:v1.7.0 volumeMounts: - mountPath: /target name: plugins ``` **Описание параметров:** - `backupStorageLocation`: Настраивает хранилище для бэкапов. - `bucket`: Имя S3-бакета. - `s3Url`: URL для S3-хранилища Timeweb Cloud. - `initContainers`: Добавляет необходимый плагин для работы с S3. - `credentials.existingSecret`: Ссылается на ранее созданный секрет `cloud-credentials`, содержащий ключи доступа к S3. ### Установка через панель управления 1. Перейдите в панель управления кластером и откройте вкладку «Дополнения». Выберите Velero. ![Selection 168](https://content.timeweb.com/assets/de030e07-6fba-433c-9483-c6591cf320dd.png?width=1006&height=919) 2. Включите режим продвинутой установки и загрузите файл `values.yaml`, нажав на «Загрузить конфигурацию из файла». ![Selection 169](https://content.timeweb.com/assets/1df243ec-48b9-45a4-b06f-77f9d2a974ae.png?width=997&height=881) 3. Нажмите «Установить». 4. Дождитесь завершения установки и проверьте стутс подов: ```shell kubectl get pods -n velero ``` ### Установка через Helm Вы можете установить Velero при помощи [Helm](https://timeweb.cloud/docs/k8s/deploy/helm). Для этого: 1. Добавьте репозиторий Velero: ```yml helm repo add velero https://vmware-tanzu.github.io/helm-charts helm repo update ``` 2. Установите Velero с использованием файла конфигурации: ```shell helm install velero velero/velero -f values.yaml --namespace velero ``` 3. Проверьте установку: ```shell kubectl get pods -n velero ``` Статус подов Velero должен быть `Running`. ## Использование Для демонстрации работы Velero создадим тестовый деплоймент с Nginx и покажем процесс создания резервной копии, удаления ресурсов и последующего восстановления данных. #### Создание бэкапа 1. Создайте деплоймент с Nginx в отдельном неймспейсе: ```yml kubectl create namespace nginx-test kubectl create deployment nginx --image=nginx -n nginx-test ``` 2. Создайте бэкап: ```shell velero backup create nginx-backup --include-namespaces nginx-test ``` Мы указали параметр `--include-namespaces`, чтобы выполнить копирование всего неймспейса. Вы также можете указать другие параметры при создании бэкапа: - `--include-resources`: включает конкретные ресурсы (например, `pods`, `services`). - `--exclude-resources`: исключает определённые ресурсы. - `--ttl`: задаёт время жизни бэкапа (например, `10h15m0s`). 3. Проверьте статус бэкапа: ```shell velero backup describe nginx-backup ``` #### Восстановление данных 1. Удалите тестовый неймспейс: ```shell kubectl delete namespace nginx-test ``` 2. Восстановите ресурсы из бэкапа: ```shell velero restore create --from-backup nginx-backup ``` 3. Убедитесь, что неймспейс и деплоймент восстановлены: ```shell kubectl get all -n nginx-test ``` ## Управление расписанием и статусами бэкапов Помимо создания бэкапов вручную, Velero позволяет автоматизировать создание резервных копий по расписанию. Также вы можете управлять существующими бэкапами. ### Настройка автоматического создания бэкапов Вы можете настроить расписание для регулярного создания резервных копий. Например, чтобы создавать бэкап всех неймспейсов каждый день в полночь: ```shell velero schedule create имя_задачи --schedule "0 0 * * *" --include-namespaces '*' ``` - `--schedule "0 0 * * *":` расписание в формате Cron (каждый день в 00:00). - `--include-namespaces '*'`: включить все неймспейсы. Для создания бэкапов одного неймспейса раз в час: ```shell velero schedule create имя_задачи --schedule "0 * * * *" --include-namespaces my-namespace ``` Проверить расписание создания бэкапов можно командой: ```shell velero schedule get ``` Если задача в расписании больше не нужна, ее можно удалить: ```shell velero schedule delete имя_задачи ``` ### Просмотр и управление бэкапами Список всех существующих бэкапов можно вывести командой: ```shell velero backup get ``` Для удаления старого бэкапа воспользуйтесь командой: ```shell velero backup delete имя_бэкапа ``` Чтобы проверить детали бэкапа, включая его статус и ресурсы, выполните: ```shell velero backup describe имя_бэкапа --details ``` Эти функции позволяют гибко управлять процессами резервного копирования и восстановить данные в нужный момент. # VictoriaMetrics Operator Source: https://timeweb.cloud/docs/k8s/addons/victoriametrics-operator?utm_source=llms_txt&utm_medium=ai VictoriaMetrics Operator — оператор для Kubernetes, для автоматизации развертывания и управления компонентами мониторинга на базе VictoriaMetrics. Он позволяет создавать и настраивать отдельные сервисы для сбора, хранения и визуализации метрик. Оператор использует CRD для управления инфраструктурой мониторинга. Основные используемые компоненты: - **VMSingle** — компонент, отвечающий за хранение метрик. Это одиночный инстанс VictoriaMetrics. Она удобна для простых проектов и малонагруженных кластеров. - **VMCluster** — масштабируемый вариант, включающий реплику хранения и прокси. Подходит для продакшена и больших объемов данных. - **VMAgent** — компонент, который собирает метрики с подов, сервисов и других источников. Он отправляет их в VMSingle или VMCluster по remoteWrite. - **VMPodScrape** — объект, описывающий, какие поды и по каким адресам и портам нужно опрашивать для получения метрик. Полная документация по VictoriaMetrics Operator доступна [на официальном сайте](https://docs.victoriametrics.com/operator/) дополнения. ## Установка Для установки VictoriaMetrics Operator перейдите в раздел «Дополнения» в панели управления кластером. Найдите «VictoriaMetrics Operator» в списке и нажмите на него. ![Scr 20250704 Okhr](https://content.timeweb.com/assets/24c6e10f-6731-4eee-b081-ac2ccaf7919d.png?width=2020&height=1608) В открывшемся окне можно при необходимости изменить параметры установки — например, задать собственный неймспейс, изменить версии компонентов или отключить ненужные CRD. После настройки нажмите кнопку «Установить». После установки в кластере появится неймспейс `victoria-metrics-operator` и все необходимые CRD, включая `VMSingle`, `VMAgent`, `VMPodScrape` и другие. Увидеть их вы можете, выполнив: ```shell kubectl get crd | grep 'vm' ``` ## Пример использования В примере мы: - Развернем VMSingle — хранилище метрик - Настроим VMAgent, чтобы собирать метрики из источников - Запустим под с Nginx и `nginx-prometheus-exporter`, чтобы передавать метрики - Создадим VMPodScrape, чтобы VMAgent собирал эти метрики - Настроим Ingress для доступа к веб-интерфейсу VictoriaMetrics Помимо дополнения VictoriaMetrics Operator, для примера потребуется установленное дополнение [Nginx Ingress](https://timeweb.cloud/docs/k8s/addons/nginx-ingress). Создадим компонент VMSingle, который будет принимать и хранить метрики. В примере мы зададим минимальный набор ресурсов и храним данные только в памяти в течение 1 дня. Создайте файл `vmsingle.yaml` со следующим содержимым: ```yaml apiVersion: operator.victoriametrics.com/v1beta1 kind: VMSingle metadata: name: vm-single namespace: victoria-metrics-operator spec: retentionPeriod: "1d" resources: requests: cpu: 100m memory: 256Mi ``` Если вы хотите хранить метрики дольше, стоит рассмотреть использование [сетевых дисков](https://timeweb.cloud/docs/k8s/network-drives-connection). Теперь создадим компонент VMAgent, который будет собирать метрики и передавать их в VMSingle. Создайте файл `vmagent.yaml`: ```yaml apiVersion: operator.victoriametrics.com/v1beta1 kind: VMAgent metadata: name: vmagent namespace: victoria-metrics-operator spec: remoteWrite: - url: http://vmsingle-vm-single.victoria-metrics-operator:8428/api/v1/write scrapeInterval: 30s selectAllByDefault: true port: "8429" ``` Развернем под с Nginx и экспортером метрик. В качестве источника метрик используется `nginx-prometheus-exporter`, который будет читать данные с эндпоинта `/stub_status`. Создайте файл `nginx.yaml`: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx namespace: victoria-metrics-operator spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.25 ports: - containerPort: 80 name: http volumeMounts: - name: nginx-conf mountPath: /etc/nginx/conf.d/default.conf subPath: default.conf - name: exporter image: nginx/nginx-prometheus-exporter:1.1.0 args: - "-nginx.scrape-uri=http://localhost/stub_status" ports: - containerPort: 9113 name: metrics volumes: - name: nginx-conf configMap: name: nginx-conf --- apiVersion: v1 kind: ConfigMap metadata: name: nginx-conf namespace: victoria-metrics-operator data: default.conf: | server { listen 80; location / { return 200 'OK'; } location /stub_status { stub_status; allow 127.0.0.1; deny all; } } --- apiVersion: v1 kind: Service metadata: name: nginx namespace: victoria-metrics-operator spec: selector: app: nginx ports: - name: http port: 80 targetPort: http - name: metrics port: 9113 targetPort: metrics ``` Чтобы указать VMAgent, с каких подов собирать метрики, создадим объект VMPodScrape. Он выберет все поды с меткой `app: nginx` и будет опрашивать порт `metrics` по пути `/metrics`. Создайте файл `vmpodscrape.yaml`: ```yaml apiVersion: operator.victoriametrics.com/v1beta1 kind: VMPodScrape metadata: name: nginx-scrape namespace: victoria-metrics-operator spec: selector: matchLabels: app: nginx podMetricsEndpoints: - port: metrics path: /metrics interval: 30s ``` Прежде чем создавать Ingress, убедитесь, что в кластере есть сервис с типом LoadBalancer, он необходим для доступа к UI извне. Посмотреть текущие балансировщики можно командой: ```shell kubectl get svc -n ingress-nginx ``` Если балансировщик отсутствует, создайте его: ```yaml apiVersion: v1 kind: Service metadata: name: nginx-loadbalancer namespace: ingress-nginx spec: selector: app.kubernetes.io/name: ingress-nginx ports: - port: 80 targetPort: 80 appProtocol: k8s.timeweb.cloud/proto-http type: LoadBalancer ``` После создания получите внешний адрес сервиса: ```shell kubectl get svc -n ingress-nginx nginx-loadbalancer ``` Укажите его как A-запись для домена, по которому будет доступен UI VictoriaMetrics. Наконец, создадим Ingress, чтобы получить доступ к веб-интерфейсу VictoriaMetrics. Укажите в хосте нужное вам доменное имя. Создайте файл `vm-ui-ingress.yaml`: ```yml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: vm-ui namespace: victoria-metrics-operator spec: ingressClassName: nginx rules: - host: vm.example.com http: paths: - path: / pathType: Prefix backend: service: name: vmsingle-vm-single port: number: 8428 ``` Примените все манифесты, созданные ранее: ```shell kubectl apply -f vmsingle.yaml kubectl apply -f vmagent.yaml kubectl apply -f nginx.yaml kubectl apply -f vmpodscrape.yaml kubectl apply -f vm-ui-ingress.yaml ``` После этого перейдите по адресу, указанному в манифесте `vm-ui-ingress.yaml`. В нашем примере это `http://vm.example.com`. В интерфейсе выберите пункт «vmui», чтобы открыть веб-интерфейс VictoriaMetrics. В поле «Query» введите имя метрики, например `up`, и нажмите «Execute Query». Если все настроено правильно, вы увидите значение метрик, которые собираются с пода Nginx. ![Scr 20250703 Lxom](https://content.timeweb.com/assets/0c8b8536-6b4e-4adf-be8a-9296ea98cc4b.png?width=2894&height=1600) _Раздел «Query» в веб-интерфейсе [VictoriaMetrics](https://victoriametrics.com/)_ # WordPress Source: https://timeweb.cloud/docs/k8s/addons/wordpress?utm_source=llms_txt&utm_medium=ai WordPress — это популярная CMS для создания сайтов и блогов. В Kubernetes она разворачивается полностью автоматически: приложение, база данных, хранилище данных и сетевые настройки создаются аддоном. ## Установка Перед установкой WordPress убедитесь, что установлены: - [CSI-driver](https://timeweb.cloud/docs/k8s/network-drives-connection) — обязательный компонент, обеспечивает работу сетевых дисков для WordPress и MariaDB. - [Nginx Ingress](https://timeweb.cloud/docs/k8s/addons/nginx-ingress) — необходим для настройки доступа к сайту по доменному имени. - [CSI S3](https://timeweb.cloud/docs/k8s/addons/csi-s3) — если вы хотите размещать файлы WordPress в S3-бакете. Для установки откройте раздел «Дополнения» в панели управления кластера и выберите «WordPress». ![Scr 20251211 Kurv](https://content.timeweb.com/assets/a06072fc-6901-452f-b671-6305eb12e5f6.png?width=2272&height=1444) После выбора дополнения откроется YAML-конфигурация. Для установки достаточно: - указать `wordpressUsername` и `wordpressPassword`; - включить `ingress.enabled: true`; - указать домен в `ingress.hostname`. В этом случае будут развернуты: - WordPress; - база данных MariaDB; - два сетевых диска для размещения данных; - LoadBalancer; - объект Ingress; - Kubernetes Secrets. ## Настройка параметров ### Основные настройки Ключевые настройки WordPress собраны в одном блоке: ```yaml wordpressUsername: user wordpressPassword: "" existingSecret: "" wordpressEmail: user@example.com wordpressFirstName: FirstName wordpressLastName: LastName wordpressBlogName: User's Blog! wordpressTablePrefix: wp_ wordpressScheme: http wordpressSkipInstall: false wordpressExtraConfigContent: "" wordpressConfiguration: "" existingWordPressConfigurationSecret: "" wordpressConfigureCache: false wordpressPlugins: none apacheConfiguration: "" existingApacheConfigurationConfigMap: "" customPostInitScripts: {} smtpHost: "" smtpPort: "" smtpUser: "" smtpPassword: "" smtpProtocol: "" smtpFromEmail: "" smtpFromName: "" smtpExistingSecret: "" allowEmptyPassword: true allowOverrideNone: false overrideDatabaseSettings: false htaccessPersistenceEnabled: false customHTAccessCM: "" command: [] args: [] extraEnvVars: [] extraEnvVarsCM: "" extraEnvVarsSecret: "" ``` Здесь указываются: - логин и пароль администратора; - адрес электронной почты; - имя сайта; - схема доступа (`http`/`https`). Остальные параметры относятся к расширенной настройке CMS (SMTP, переменные окружения). Их можно оставить без изменений. ### Сетевые настройки **Балансировщик нагрузки** По умолчанию создается [LoadBalancer](https://timeweb.cloud/docs/k8s/network/kubernetes-load-balancer): ```yaml service:   type: LoadBalancer ``` Он получает внешний IP-адрес, через который доступен сайт. **Ingress** Дополнительно можно настроить доступ по доменному имени, указав его в настройках Ingress-контроллера: ```yaml ingress:   enabled: true   hostname: example.com   path: /   tls: false ``` ### Хранилище данных Создаются два тома (PVC): PVC для WordPress: ```yaml persistence:   enabled: true   size: 10Gi ``` PVC для MariaDB: ```yaml mariadb:   enabled: true   primary:     persistence:       enabled: true       storageClass: "nvme.network-drives.csi.timeweb.cloud"       size: 8Gi ``` Оба тома создаются с классом `nvme.network-drives.csi.timeweb.cloud`. Вы можете изменить класс хранения, указав другой в параметре `global.defaultStorageClass` или задав `storageClass` вручную в соответствующих блоках. После установки сетевые диски появятся в панели управления, [в разделе «Сетевые диски»](https://timeweb.cloud/docs/k8s/network-drives-connection). Постоянные хранилища нужны, чтобы данные оставались доступны при пересоздании подов. ## После установки Дождитесь завершения создания балансировщика и создайте A-запись для домена, указав IP-адрес балансировщика. Проверьте состояние подов: ```shell kubectl get pods -n wordpress ``` Вы увидите два пода — в них запущены WordPress и база данных: ```shell NAME READY STATUS RESTARTS AGE wordpress-5f77d8758b-6g2z2 1/1 Running 0 23h wordpress-mariadb-0 1/1 Running 0 23h ``` Проверьте сервисы: ```shell kubectl get svc -n wordpress ``` Пример вывода: ```shell NAME                         TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                      AGE wordpress                    LoadBalancer   10.105.62.193   185.154.193.137   80:31401/TCP,443:32277/TCP   23h wordpress-mariadb            ClusterIP      10.105.69.70                3306/TCP                     23h wordpress-mariadb-headless   ClusterIP      None                        3306/TCP                     23h ``` Поле `EXTERNAL-IP` указывает на IP-адрес балансировщика, через который доступно приложение.