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

Зачем индивидуализировать облако и в чем преимущества такого подхода?

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

Преимущества такого подхода заключаются в следующем:

  1. Гибкость и масштабируемость. Инфраструктура будет масштабироваться в соответствии с ростом бизнеса. Вы можете добавлять или уменьшать ресурсы по мере необходимости.

  2. Безопасность. Адаптация среды к потребностям приложения позволяет реализовать эффективные политики безопасности, уменьшая риски и повышая уровень защиты данных.

  3. Оптимизация ресурсов. Вы избавите себя от избыточных расходов на ресурсы и сэкономите финансы компании.

  4. Быстрая реакция к изменяющимся условиям рынка и требованиям приложений.

  5. Улучшенная производительность и надежность.

Сложности, с которыми вы можете столкнуться

Несмотря на все преимущества, ваша команда должна учитывать следующие потенциальные риски:

  1. Сложность в управлении и поддержке. Более сложные кластеры требуют глубокого понимания Kubernetes и специализированных навыков управления. Это может повысить требования к команде DevOps и администраторам.

  2. Возможные проблемы совместимости. Некоторые кастомные настройки могут привести к проблемам совместимости с другими приложениями или компонентами в экосистеме Kubernetes. Не всегда легко найти оптимальный баланс между конфигурацией настроек и совместимостью.

  3. Увеличенное время развертывания и обновления. Кастомизация может увеличить время развертывания и обновления кластера из-за необходимости тщательного тестирования и верификации изменений.

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

Важно оценить возможности команды и принять решение, основанное на конкретных потребностях и характеристиках вашего приложения. 

Почему именно Kubernetes?

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

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

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

  3. Различные компоненты Kubernetes позволяют изменить инфраструктуру с понятной абстракцией и контролем. Например, с помощью служб вы можете определить, как приложения взаимодействуют или какие сетевые соединения могут быть установлены. С помощью контроллеров вы можете управлять жизненным циклом приложений, от развертывания до обновления и масштабирования. Учет ролей и политик безопасности Kubernetes позволяет контролировать доступ к ресурсам и заданиям в зависимости от пользователей или групп. Это создает слой безопасности, исключающий несанкционированный доступ и действия, что также уменьшает вероятность ошибок.

  4. Благодаря стандартизации Kubernetes вы сможете упрощенно мигрировать с одного облачного провайдера к другому. Также это доступно и на self-hosted решениях.

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

Ресурсы

Первое, с чего следует начать — это настройка ресурсов. Вы можете указать, сколько ресурсов необходимо контейнеру, что позволит планировщику (kube-scheduler) определить, на какой узел разместить под. Если узел, на котором работает под, имеет достаточное количество ресурса, контейнер может использовать больше ресурсов, чем указано в его запросе (параметр — request). Однако контейнеру не разрешено использовать больше ресурса, чем указано в его пределах (параметр — limit). За это, кстати, отвечает агент kubelet. Например, если вы зададите лимит памяти в 4 ГБ для контейнера и этот контейнер попытается использовать больше, системное ядро завершит процесс с ошибкой переполнения памяти. Для настройки ресурсов каждого контейнера вы можете использовать следующие параметры:

  • spec.containers[].resources.limits.cpu

  • spec.containers[].resources.limits.memory

  • spec.containers[].resources.requests.cpu

  • spec.containers[].resources.requests.memory

Настройка этих параметров позволяет вам контролировать использование ресурсов и гарантировать стабильность и производительность вашей инфраструктуры Kubernetes.

Пример использования ресурсов контейнера:

---
apiVersion: v1
kind: Pod
metadata:
 name: frontend
spec:
 containers:
 - name: app
   image: images.my-company.example/app:v4
   resources:
     requests:
       memory: "64Mi"
       cpu: "250m"
     limits:
       memory: "128Mi"
       cpu: "500m"
 - name: log-aggregator
   image: images.my-company.example/log-aggregator:v6
   resources:
     requests:
       memory: "64Mi"
       cpu: "250m"
     limits:
       memory: "128Mi"
       cpu: "500m"

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

Политики маршрутизации

Настройка политик маршрутизации пода в Kubernetes при помощи Node Affinity и Taints/Tolerations дает возможность более точно и гибко контролировать где будут выполняться ваши приложения.

Node Affinity позволяет вашим подам указать, на каких узлах они предпочитают запускаться на основе меток узлов. Есть два типа Node Affinity:

  • requiredDuringSchedulingIgnoredDuringExecution: поды будут назначены на узел, только если условия совпадают.

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

Для использования Node Affinity, вы должны добавить nodeAffinity в поле affinity спецификации пода.

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

kubectl taint nodes node-name special=GPU:NoSchedule

Теперь вы можете добавить toleration в спецификацию пода:

tolerations:
- key: "special"
  operator: "Equal"
  value: "GPU"
  effect: "NoSchedule"

Обратите внимание, что вы также можете использовать Node Affinity вместе с Taints и Tolerations, чтобы создать определенные наборы узлов, которые запускают только нужные поды. Управляя размещением и выполнением подов на узлах, удовлетворяющих требованиям вашего приложения вы также кастомизируете вашу инфраструктуру.

Автомасштабирование

В Kubernetes, Horizontal Pod Autoscaler (HPA) и Cluster Autoscaler позволяют распределить нагрузку между контейнерами и снизить риск сбоя. HPA проверяет нагрузку на приложение, исходя из которой либо создает, либо удаляет поды. Второй инструмент анализирует запросы подов и автоматически изменяет количество узлов кластера Kubernetes.

Например, для автоматического масштабирования Deployment под названием "my-app" вы можете использовать следующую команду:

kubectl autoscale deployment my-app --min=2 --max=10 --cpu-percent=80

В этом примере:

  • min=2 указывает минимальное количество подов, которое HPA должен поддерживать;

  • max=10 указывает максимальное количество подов, которое HPA может развернуть при высокой нагрузке;

  • cpu-percent=80 означает, что HPA будет добавлять поды, когда среднее использование CPU превысит 80%.

Добавление инструментов автомасштабирования в вашу инфраструктуру позволяет осуществлять анализ нагрузки вашего приложения, оптимизировать использование ресурсов и реагировать на изменения нагрузки в реальном времени. 

Создание собственных версий объектов API

В Kubernetes есть возможность создания собственных версий объектов API, которые могут быть обработаны как стандартные объекты, такие как под, сервис и др. Для этих целей существует Custom Resource Definitions (CRD). CRD позволяет создавать специфические типы ресурсов, что делает Kubernetes еще более гибким и адаптируемым к требованиям вашего проекта.

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

  1. Создайте файл YAML (resourcedefinition.yaml) для определения CRD.

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: crontabs.stable.example.com
spec:
  group: stable.example.com
  versions:
  - name: v1
    served: true
    storage: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              cronSpec:
                type: string
              image:
                type: string
              replicas:
                type: integer
  scope: Namespaced
  names:
    plural: crontabs
    singular: crontab
    kind: CronTab
    shortNames:
    - ct

В этом манифесте мы создали CRD с именем CronTab в группе stable.example.com. Данный объект имеет три свойства: cronSpec, image, replicas.

  1. Далее применяем CRD с помощью kubectl:

kubectl apply -f resourcedefinition.yaml

Так мы создадим RESTful API эндпоинт /apis/stable.example.com/v1/namespaces//crontabs/, который сможем использовать для создания и управления кастомными объектами.

  1. После создания CRD мы сможем создавать кастомные объекты с помощью этого манифеста:

apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
  name: my-new-cron-object
spec:
  cronSpec: "* * * * */5"
  image: my-awesome-cron-image

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

Операторы Kubernetes

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

  1. Правильно использовать вотчеры (watches). Операторы в Kubernetes работают, наблюдая за определенными событиями. Это достигается с помощью механизма под названием Watches. Каждый вотчер следит за событиями определенного типа ресурса.

  2. Реализовывать контроллеры с учетом уровневого подхода. При возникновении события контроллеру следует рассматривать всё состояние экземпляра, а не только то, что изменилось.

  3. Пользоваться лучшими практиками при создании CDR. Если ваш оператор вводит новый CRD, убедитесь, что он соответствует лучшим практикам Kubernetes для расширения API. Operator SDK поможет вам в этом, позволяя генерировать шаблоны для CRD.

  4. Настроить веб-хуки. Если оператор создает новый CRD, вы также можете настроить веб-хуки для выполнения мутаций и валидаций с применением изменений к вашему объекту. Это улучшит точность и безопасность операций, которые можно выполнять с вашим CRD.

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

Пакетный менеджер Helm

Пакетный менеджер Helm для Kubernetes упрощает установку и управление компонентами приложения. С помощью Helm вы можете создавать чарты (Charts), которые содержат описание всех ресурсов и зависимостей вашего приложения.

Вот несколько основных практик для кастомизации инфраструктуры с помощью Helm:

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

  • Контролируйте версии чартов и приложений. В Helm есть две отдельные версии для каждого чарта: версия чарта и версия приложения.  Вы можете изменять версии чарта и приложения вместе (синхронизировать) или отдельно (инкрементировать независимо) в зависимости от того, как меняется ваш код и конфигурация развертывания.

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

  • Больше, чем шаблонизация. Helm больше, чем просто движок шаблонов. Он представляет собой менеджер пакетов и предоставляет возможности для управления группами манифестов, управления релизами и поддержания реестра работающих приложений.

  • Независимые сабчарты. Каждый сабчарт в Helm должен быть автономным чартом. Это означает, что он должен иметь свою собственную конфигурацию и быть способным функционировать независимо.

Инструмент кастомизации

Kustomize — это отдельный инструмент для настройки объектов Kubernetes через файл kustomization.yaml. Он позволяет пользователям создавать новые вариации ресурсов Kubernetes, например, ConfigMap или Secret, без необходимости внесения изменений напрямую в исходный код.

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

  1. Генерировать ресурсы. Kustomize может генерировать ConfigMaps и Secrets из файлов или литералов, что позволяет хранить конфигурацию или чувствительные данные, используемые другими объектами Kubernetes, в надежных и централизованных местах.

  2. Задавать перекрывающиеся поля. Вы можете задать общие значения для набора полей, которые перекрываются между различными ресурсами. Например, вы можете включить метки или аннотации для всех ресурсов в вашем проекте.

  3. Создавать и настраивать коллекции ресурсов. Kustomize позволяет компоновать и настраивать наборы ресурсов. Вы можете создавать коллекции ресурсов, которые сгруппированы вместе для определенных целей, и затем настраивать их как единую сущность.

Чтобы использовать Kustomize, вам нужно создать файл kustomization.yaml, который описывает, как вы хотите настроить свои ресурсы. Затем вы можете применить эти изменения с помощью команды kubectl apply -k <kustomization_directory>.

Заключение

Кастомизация инфраструктуры в облачных вычислениях с помощью Kubernetes является ключевым фактором для обеспечения оптимальной производительности, эффективности и безопасности работы приложений. Выбор подходящего облачного провайдера, правильная конфигурация кластера и индивидуализация его компонентов позволяют адаптировать среду под конкретные потребности бизнеса. Настройка ресурсов, использование Custom Resource Definitions (CRD) и операторов, а также управление через пакетный менеджер Helm — это мощные инструменты для достижения оптимальной производительности и эффективности приложений. Грамотная модернизация инфраструктуры сокращает издержки, повышает надежность и обеспечивает гибкость в реагировании на изменения в бизнес-среде. Таким образом, инвестирование времени в кастомизацию инфраструктуры оправдывается высокой эффективностью работы приложений и конкурентоспособностью вашей команды.

Спасибо за внимание! Пишите ваши предложения и замечания в комментариях. В следующий раз поговорим о персонализации инфраструктуры с помощью Kubernetes. Мы подробно рассмотрим операторы Kubernetes и создание собственных версий объектов API. 

Автор статьи @exzvor


НЛО прилетело и оставило здесь промокод для читателей нашего блога:
— 15% на заказ любого VDS (кроме тарифа Прогрев) — HABRFIRSTVDS.

Комментарии (0)