Поделиться через


Использование контейнеров и оркестраторов

Подсказка

Это фрагмент из электронной книги «Архитектура облачных нативных приложений .NET для Azure», доступен на .NET Docs или как бесплатный загружаемый PDF-файл, который можно прочитать в автономном режиме.

Миниатюра обложки электронной книги Azure с Cloud Native .NET приложениями.

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

Проблемы с монолитными развертываниями

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

Монолитная архитектура.

Рис. 3-1. Монолитная архитектура.

Хотя у них есть преимущество простоты, монолитные архитектуры сталкиваются с множеством проблем:

Развертывание

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

Масштабирование

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

Окружающая среда

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

Муфта

Монолитное приложение, скорее всего, имеет высокую связь между функциональными компонентами. Без жестких границ системные изменения часто приводят к непредвиденным и дорогостоящим побочным эффектам. Новые функции и исправления становятся сложными, трудоемкими и дорогостоящими для реализации. Обновления требуют обширного тестирования. Связь также затрудняет рефакторинг компонентов или переключение в альтернативных реализациях. Даже при построении с строгим разделением задач архитектурная эрозия проявляется, так как монолитная база кода ухудшается с бесконечными "особыми случаями".

Блокировка платформы

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

Каковы преимущества контейнеров и оркестраторов?

Мы представили контейнеры в главе 1. Мы подчеркнули, как Cloud Native Computing Foundation (CNCF) считает контейнеризацию первым шагом в их Cloud-Native Дорожной карте — руководство для предприятий, начинающих своё облачное путешествие. В этом разделе мы обсудим преимущества контейнеров.

Docker — это самая популярная платформа управления контейнерами. Он работает с контейнерами как в Linux, так и в Windows. Контейнеры предоставляют отдельные, но воспроизводимые среды приложений, которые выполняются одинаково в любой системе. Этот аспект делает их идеальными для разработки и размещения облачных нативных сервисов. Контейнеры изолированы друг от друга. Два контейнера на одном и том же оборудовании узла могут иметь разные версии программного обеспечения, не вызывая конфликтов.

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

Контейнеры неизменяемы. После определения контейнера можно повторно создать и запустить его точно так же. Эта неизменяемость дает возможность разработки на основе компонентов. Если некоторые части приложения развиваются не так, как другие, зачем повторно развертывать все приложение, когда можно просто развертывать части, которые чаще всего изменяются? Различные функции и перекрестные проблемы приложения могут быть разделены на отдельные единицы. На рисунке 3-2 показано, как монолитное приложение может воспользоваться преимуществами контейнеров и микрослужб, делегируя определенные функции или функциональность. Остальные функции в самом приложении также были контейнеризованы.

Разбиение монолитного приложения для использования микросервисов в бэкенде.

Рис. 3-2. Декомпозиция монолитного приложения для использования микросервисов.

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

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

  • Как будут развертываться экземпляры контейнеров в кластере из множества машин?
  • После развертывания, как контейнеры будут обнаруживать друг друга и вступать в коммуникацию?
  • Как контейнеры могут масштабироваться вверх или вниз по требованию?
  • Как отслеживать работоспособность каждого контейнера?
  • Как защитить контейнер от сбоев оборудования и программного обеспечения?
  • Как обновить контейнеры для динамического приложения с нулевым временем простоя?

Оркестраторы контейнеров устраняют и автоматизируют эти и другие проблемы.

В облачной экосистеме Kubernetes стал де-факто оркестратором контейнеров. Это платформа с открытым кодом, управляемая Cloud Native Computing Foundation (CNCF). Kubernetes автоматизирует развертывание, масштабирование и операционные проблемы контейнерных рабочих нагрузок в кластере компьютеров. Однако установка Kubernetes и управление ими является печально сложной задачей.

Гораздо лучше использовать Kubernetes в качестве управляемой службы от поставщика облака. Облако Azure включает полностью управляемую платформу Kubernetes с именем Azure Kubernetes Service (AKS). AKS абстрагирует сложность и операционные издержки управления Kubernetes. Kubernetes используется как облачная служба; Корпорация Майкрософт несет ответственность за управление и поддержку. AKS также тесно интегрируется с другими службами Azure и средствами разработки.

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

Каковы преимущества масштабирования?

Службы, созданные на основе контейнеров, могут использовать преимущества масштабирования, предоставляемые средствами оркестрации, такими как Kubernetes. Контейнеры по своей конструкции знают только о себе. После того как у вас есть несколько контейнеров, которые должны работать вместе, следует упорядочить их на более высоком уровне. Оркестрирование помогает организовать большое количество контейнеров и их общие зависимости, такие как конфигурация сети, спасая ситуацию! Kubernetes создает слой абстракции над группами контейнеров, а упорядочивает их в pods. Модули Pod выполняются на рабочих компьютерах, называемых узлами. Эта упорядоченная структура называется кластером. На рисунке 3-3 показаны различные компоненты кластера Kubernetes.

Компоненты кластера Kubernetes. Рис. 3-3. Компоненты кластера Kubernetes.

Масштабирование контейнерных рабочих нагрузок является ключевой функцией оркестраторов контейнеров. AKS поддерживает автоматическое масштабирование в двух измерениях: экземпляры контейнеров и вычислительные узлы. Вместе они дают AKS возможность быстро и эффективно реагировать на пики спроса и добавлять дополнительные ресурсы. Далее в этой главе мы обсудим масштабирование в AKS.

Декларативное и императивное

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

Императивные команды отлично подходят для обучения и интерактивного экспериментирования. Однако вы захотите декларативно создать файлы манифеста Kubernetes, чтобы использовать инфраструктуру в качестве подхода к коду, обеспечивая надежные и повторяемые развертывания. Файл манифеста становится артефактом проекта и используется в конвейере CI/CD для автоматизации развертываний Kubernetes.

Если вы уже настроили кластер с помощью императивных команд, можно экспортировать декларативный манифест с помощью kubectl get svc SERVICENAME -o yaml > service.yaml. Эта команда создает манифест, аналогичный приведенному ниже:

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2019-09-13T13:58:47Z"
  labels:
    component: apiserver
    provider: kubernetes
  name: kubernetes
  namespace: default
  resourceVersion: "153"
  selfLink: /api/v1/namespaces/default/services/kubernetes
  uid: 9b1fac62-d62e-11e9-8968-00155d38010d
spec:
  clusterIP: 10.96.0.1
  ports:
  - name: https
    port: 443
    protocol: TCP
    targetPort: 6443
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

При использовании декларативной конфигурации можно предварительно просмотреть изменения, которые будут внесены, используя kubectl diff -f FOLDERNAME в папке, где находятся ваши файлы конфигурации, перед фиксацией их. Убедившись, что вы хотите применить изменения, выполните команду kubectl apply -f FOLDERNAME. Добавьте -R для рекурсивной обработки иерархии папок.

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

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

Какие сценарии идеально подходят для контейнеров и оркестраторов?

Следующие сценарии идеально подходят для использования контейнеров и оркестраторов.

Приложения, требующие высокой доступности и масштабируемости

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

Большое количество приложений

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

Когда следует избегать использования контейнеров и оркестраторов?

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

Ресурсы разработки

В этом разделе представлен краткий список ресурсов разработки, которые помогут вам приступить к работе с контейнерами и оркестраторами для следующего приложения. Если вы ищете рекомендации по проектированию приложения архитектуры микрослужб на основе облака, ознакомьтесь с книгой-компаньоном .NET Microservices: Архитектура для контейнерных приложений .NET.

Локальная разработка Kubernetes

Развертывания Kubernetes обеспечивают большую ценность в производственных средах, но также могут выполняться локально на вашем компьютере для разработки. Хотя вы можете работать независимо от отдельных микрослужб, может возникнуть время, когда вам потребуется запустить всю систему локально, так же, как и при развертывании в рабочей среде. Существует несколько инструментов, которые могут помочь: Minikube и Docker Desktop. Visual Studio также предоставляет инструменты для разработки Docker.

Minikube

Что такое Minikube? Проект Minikube говорит: "Minikube реализует локальный кластер Kubernetes в macOS, Linux и Windows". Ее основными целями являются "лучший инструмент для разработки локальных приложений Kubernetes и поддержка всех функций Kubernetes, которые подходят". Установка Minikube отличается от Docker, но Minikube поддерживает разные гипервизоры, отличные от поддержки Docker Desktop. Следующие функции Kubernetes в настоящее время поддерживаются Minikube:

  • DNS (Система доменных имён)
  • NodePorts
  • ConfigMaps и секреты
  • Дашборды
  • Среды выполнения контейнеров: Docker, rkt, CRI-O и containerd
  • Включение сетевого интерфейса контейнера (CNI)
  • Вход

После установки Minikube вы можете сразу же начать его использование, выполните команду minikube start, которая скачает образ и запустит локальный кластер Kubernetes. После запуска кластера вы взаимодействуете с ним с помощью стандартных команд Kubernetes kubectl .

Docker Desktop

Вы также можете работать с Kubernetes непосредственно из Docker Desktop в Windows. Это единственный вариант, если вы используете контейнеры Windows, и это отличный выбор для контейнеров, отличных от Windows. На рисунке 3-4 показано, как включить поддержку локальных Kubernetes при запуске Docker Desktop.

Настройка Kubernetes в Docker Desktop

Рис. 3-4. Настройка Kubernetes в Docker Desktop.

Docker Desktop — это наиболее популярное средство для настройки и запуска контейнерных приложений локально. При работе с Docker Desktop вы можете разрабатывать локально, используя тот же набор образов контейнеров Docker, который будет развёрнут на продакшн-сервере. Docker Desktop предназначен для локального создания, тестирования и отправки контейнерных приложений. Он поддерживает контейнеры Linux и Windows. После отправки образов в реестр образов, таких как Реестр контейнеров Azure или Docker Hub, AKS может извлекать и развертывать их в рабочей среде.

Средства для работы с Docker в Visual Studio

Visual Studio поддерживает разработку Docker для веб-приложений. При создании нового приложения ASP.NET Core вы можете настроить его с поддержкой Docker, как показано на рис. 3-5.

Включение поддержки Docker в Visual Studio

Рис. 3-5. Включение поддержки Docker в Visual Studio

При выборе этого параметра проект создается в Dockerfile корневом каталоге, который можно использовать для сборки и размещения приложения в контейнере Docker. Пример Dockerfile показан на рис. 3-6.

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["eShopWeb/eShopWeb.csproj", "eShopWeb/"]
RUN dotnet restore "eShopWeb/eShopWeb.csproj"
COPY . .
WORKDIR "/src/eShopWeb"
RUN dotnet build "eShopWeb.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "eShopWeb.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "eShopWeb.dll"]

Рис. 3-6. Dockerfile, созданный Visual Studio

После добавления поддержки приложение можно запустить в контейнере Docker в Visual Studio. На рисунке 3-7 показаны различные варианты выполнения, доступные из нового проекта ASP.NET Core, созданного с помощью поддержки Docker.

Параметры запуска Visual Studio Docker

Рис. 3-7. Параметры запуска Visual Studio Docker

Кроме того, в любое время можно добавить поддержку Docker в существующее приложение ASP.NET Core. В обозревателе решений Visual Studio щелкните проект правой кнопкой мыши и выберите "Добавить>поддержку Docker", как показано на рисунке 3-8.

Добавление поддержки Docker в Visual Studio

Рис. 3-8. Добавление поддержки Docker в Visual Studio

Инструменты Docker для Visual Studio Code

Существует множество расширений для Visual Studio Code, поддерживающих разработку Docker.

Корпорация Майкрософт предоставляет расширение Docker для Visual Studio Code. Это расширение упрощает процесс добавления поддержки контейнеров в приложения. Он создает необходимые файлы, создает образы Docker и позволяет выполнять отладку приложения внутри контейнера. Расширение содержит визуальный обозреватель, который упрощает выполнение действий в контейнерах и изображениях, таких как запуск, остановка, проверка, удаление и многое другое. Расширение также поддерживает Docker Compose, позволяющее управлять несколькими запущенными контейнерами в виде одной единицы.