Создание распределенных систем на AWS

В этой статье мы рассмотрим, как можно создать архитектуру распределенных сервисов. Использование контейнеров Docker, NodeJS, приложения Python/Flask и нескольких ресурсов AWS

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

Давайте разделим наш блог на 4 основные части:

  1. Архитектурный обзор
  2. Ресурсы AWS
  3. Разработка
  4. Развертывание

1. Архитектурный обзор

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

Наш поток приложений

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

Ключевые моменты контейнерной архитектуры

  • Последовательная и изолированная среда
  • Мобильность — возможность запуска в любом месте
  • Повторяемость и автоматизация
  • Тестирование, откат и развертывание
  • Гибкость
  • Совместная работа, модульность и масштабирование

Наши 4 контейнера

  • container-main: открыт для публичного доступа, будет обрабатывать вызовы API
  • container-process: частный контейнер может взаимодействовать с нашим основным контейнером и не является общедоступным
  • container-consume: контейнер-потребитель очередей, который будет потреблять очереди, создаваемые в SQS главным контейнером
  • container-xray: будет прослушивать наш трафик и перехватывать http-соединения, чтобы потом можно было провести аудит из консоли.

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

2. Ресурсы AWS

SQS
Amazon Simple Queue Service (SQS) — это полностью управляемый сервис очередей сообщений, который позволяет разделить и масштабировать микросервисы, распределенные системы и бессерверные приложения.

В нашей архитектуре один из контейнеров будет производить сообщения, а другой — потреблять их.

  • Производитель: Конечные точки, которые записывают сообщения в очередь
  • Потребитель: Срабатывает, когда сообщение передается в очередь.

X-Ray
AWS X-Ray — это служба, которая помогает разработчикам анализировать и отлаживать распределенные приложения. Вы можете использовать X-Ray для мониторинга трассировки приложения, включая производительность вызовов других компонентов или сервисов.

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

Демон X-Ray
Демон AWS X-Ray — это программное приложение, которое прослушивает трафик на порту UDP 2000, собирает необработанные данные сегментов и передает их в AWS X-Ray API. Демон работает совместно с AWS X-Ray SDK и должен быть запущен, чтобы данные, отправленные SDK, могли достичь службы X-Ray.

Вместо того чтобы отправлять данные трассировки непосредственно в X-Ray, SDK отправляет документы сегментов JSON процессу демона, прослушивающему UDP-трафик.

Демон X-Ray буферизирует сегменты в очереди и загружает их в X-Ray партиями.

CloudWatch
Amazon CloudWatch — это служба мониторинга и управления, которая предоставляет данные и практические выводы для AWS.

3. Разработка

IAM
Для того чтобы иметь возможность использовать AWS cli, необходимо создать пользователя IAM и предоставить ему соответствующие права. (Например, наша команда docker compose up развернет/создаст множество ресурсов AWS, ECS, Security Group и т.д., поэтому наш пользователь IAM должен иметь необходимые разрешения, чтобы иметь возможность сделать это).

Образ NodeJS (container-main, container-consume)

FROM node:alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD ["node", "index.js"]
Вход в полноэкранный режим Выход из полноэкранного режима

Образ Python (container-process) (стек Python необязателен, наша основная цель его использования — показать, как мы можем использовать несколько различных языков в распределенной архитектуре)

FROM python:3
WORKDIR /usr/src/app
COPY . .
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 8082
CMD ["python", "app.py"]
Вход в полноэкранный режим Выход из полноэкранного режима

Образ демона рентгеновского излучения (container-xray)
Ссылка: https://docs.aws.amazon.com/xray/latest/devguide/xray-daemon-ecs.html

FROM amazonlinux
RUN yum install -y unzip
RUN curl -o daemon.zip https://s3.us-east-2.amazonaws.com/aws-xray-assets.us-east-2/xray-daemon/aws-xray-daemon-linux-3.x.zip
RUN unzip daemon.zip && cp xray /usr/bin/xray
ENTRYPOINT ["/usr/bin/xray", "-t", "0.0.0.0:2000", "-b", "0.0.0.0:2000"]
EXPOSE 2000/udp
EXPOSE 2000/tcp
Вход в полноэкранный режим Выход из полноэкранного режима

Docker compose

version: '3'
x-environment:
  &default-environment
  AWS_REGION: ${AWS_REGION}
  AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
  AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
  AWS_XRAY_DAEMON_ADDRESS: xray:2000
  MAIN_SQS_QUEUE_URL: ${MAIN_SQS_QUEUE_URL}
services:
  xray:
    image: ${XRAY_IMAGE}
    container_name: XRAY
    build:
      context: ./container-xray
      dockerfile: ./Dockerfile
    environment: *default-environment
    command: --local-mode
    ports:
      - "2000:2000/udp"
    networks:
      mynet:
        ipv4_address: 172.19.20.1

  main:
    image: ${MAIN_IMAGE}
    container_name: MAIN
    build:
      context: ./container-main
      dockerfile: ./Dockerfile
    depends_on:
      - xray
    ports:
      - "8080:8080"
    environment: *default-environment
    networks:
      mynet:
        ipv4_address: 172.19.10.1

  consume:
    image: ${CONSUME_IMAGE}
    container_name: CONSUME
    build:
      context: ./container-consume
      dockerfile: ./Dockerfile
    environment: *default-environment
    networks:
      mynet:
        ipv4_address: 172.19.10.2

  process:
    image: ${PROCESS_IMAGE}
    container_name: PROCESS
    build:
      context: ./container-process
      dockerfile: ./Dockerfile
    environment: *default-environment
    networks:
      mynet:
        ipv4_address: 172.19.10.3

networks:
  mynet:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.19.0.0/16
Вход в полноэкранный режим Выход из полноэкранного режима

Основные возможности Docker compose

  • Запуск нескольких изолированных сред
  • Модель параллельного выполнения
  • Обнаружение изменений в файлах Compose
  • Открытый исходный код

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

  • Вы всегда можете использовать docker-compose --help, чтобы увидеть все доступные опции.

Что касается нашего .env файла, вы можете проверить .env.sample, чтобы заполнить все необходимые переменные, и создать новый .env файл с теми же значениями

AWS_ACCESS_KEY_ID=<account_access_key>
AWS_SECRET_ACCESS_KEY=<account_secret>
AWS_REGION=<region>
MAIN_SQS_QUEUE_URL=<sqs_fifo_url>

MAIN_IMAGE=<ecr_image_for_container_main>
PROCESS_IMAGE=<ecr_image_for_container_process>
CONSUME_IMAGE=<ecr_image_for_container_consume>
XRAY_IMAGE=<ecr_image_for_container_xray>
Войдите в полноэкранный режим Выход из полноэкранного режима

Создание новой SQS FIFO
Очереди FIFO (First-In-First-Out) предназначены для улучшения обмена сообщениями между приложениями, когда порядок операций и событий является критическим, или когда нельзя допускать дублирования. После создания очереди убедитесь, что вы скопировали Url и вставили его в файл переменных окружения (.env).

Коммуникационная логика

  • Наш контейнер-main может взаимодействовать с частным контейнером, который называется ‘process’, поэтому, по сути, мы можем сделать обычный вызов API на http://process:8082/api/process (с помощью AWS Cloud Map и его сервиса discovery мы можем это сделать).
  • Мы можем отправить SQS сообщение, используя aws-sdk.
  • Наш контейнер-консум слушает нашу очередь SQS каждый раз, когда у нас есть сообщение, он потребляет его.

[примечание] проект с открытым исходным кодом и вы можете получить доступ к ссылке в конце этого блога

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

Первым делом нам нужно разместить наши образы в Amazon Elastic Container Registry (Amazon ECR), который является управляемым AWS сервисом реестра образов контейнеров.

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

Используя AWS CLI, вам нужно запустить 4 командные строки, сначала вы войдете в ECR cli и docker, затем создадите свой образ docker, пометите его и запустите его, эти командные строки можно найти, нажав на «View push commands» внутри репозитория ECR, который вы создали.

Для развертывания нашего приложения мы будем использовать команду docker compose up, по умолчанию Docker Compose CLI создает кластер ECS для вашего приложения Compose, группу безопасности для сети в вашем файле Compose на стандартном VPC вашего аккаунта AWS, LoadBalancer для маршрутизации трафика к вашим сервисам, а также прикрепляет IAM роль Task execution с двумя IAM ролями для вашего ECS Task Definition (AmazonEC2ContainerRegistryReadOnly & AmazonECSTaskExecutionRolePolicy).

[примечание] обязательно проверьте, можете ли вы запускать 2 задачи одновременно, если нет, вам нужно открыть запрос в AWS Support Center, чтобы добавить ваш лимит.

Для того чтобы развернуть нашу архитектуру, нам необходимо выполнить следующие командные строки

docker context create ecs <your_ecs_context_name>
docker context use <your_ecs_context_name>
docker compose up
Войти в полноэкранный режим Выйти из полноэкранного режима

Команда docker context позволяет легко экспортировать и импортировать контексты на разных машинах с установленным клиентом Docker

[примечание] docker-compose up создает контейнеры docker compose file на вашей локальной машине, однако docker compose up развертывает ваш docker compose file в AWS.

После развертывания он создаст следующие ресурсы (вы можете просмотреть все ресурсы, созданные в cloudformation stack)

  • Кластер ECS
  • Карта облака AWS
  • AWS Network Load Balancer (NLB)
  • Группа безопасности
  • Целевая группа

Amazon Elastic Container Service (Amazon ECS) — это высокомасштабируемая и быстрая служба управления контейнерами. Вы можете использовать его для запуска, остановки и управления контейнерами на кластере. Вы можете запускать либо Fargate, либо экземпляры EC2. При использовании типа запуска EC2 вы получите больше контроля, но пользователю необходимо управлять, предоставлять, масштабировать и исправлять виртуальные машины. В то время как Fargate является бессерверным, то есть вам больше не нужно предоставлять, настраивать и масштабировать кластеры виртуальных машин для запуска контейнеров. После определения требований приложения (вычислительные ресурсы и ресурсы памяти) Fargate будет управлять масштабированием для запуска контейнеров в высокодоступной среде. Он может одновременно запускать тысячи контейнеров и масштабироваться для запуска критически важных приложений.

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

Давайте посмотрим на изображение ниже.

Как мы видим, наш кластер содержит наш контейнерный экземпляр ECS, который в нашем случае является Fargate, и для каждого контейнера у нас есть аналогичные 4 коробки (зеленые), четыре из которых находятся внутри одного кластера. Задача находится внутри сервиса, и она может запускать несколько контейнеров docker

ECS Task Definition ваши контейнеры определены в определении задачи, которое вы используете для запуска отдельной задачи или задач внутри сервиса. Одно определение задачи может создать несколько идентичных задач.

AWS Cloud Map — это служба обнаружения облачных ресурсов. С помощью Cloud Map вы можете определять пользовательские имена для ресурсов ваших приложений, и она поддерживает обновленное местоположение этих динамически изменяющихся ресурсов.

Наша Cloud Map:

Балансировщик нагрузки сети распределяет трафик конечного пользователя между несколькими облачными ресурсами, чтобы обеспечить низкую задержку и высокую пропускную способность. В нашем примере, поскольку мы открыли один из наших контейнеров на порт 8080:8080, создается NLB, но если бы мы открыли его на 80:80, то был бы создан ALB (https://docs.docker.com/cloud/ecs-compose-examples/).

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

Входящие правила:

Целевая группа указывает балансировщику нагрузки, куда направить трафик.


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

В дальнейшем я буду добавлять множество функций к текущей архитектуре и углубляться в конкретные темы.
Исходный код: https://github.com/awedis/containers-architecture

Оцените статью
Procodings.ru
Добавить комментарий