Книга: Паттерны Kubernetes: Шаблоны разработки собственных облачных приложений
Назад: Глава 15. Паттерн Sidecar
Дальше: Глава 17. Посредник

Глава 16. Адаптер

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

Задача

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

Решение

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

Однако службы, написанные на разных языках, могут иметь разные возможности и поставлять метрики в разных форматах, отличных от ожидаемого инструментом мониторинга. Такое разнообразие создает проблему для мониторинга разнородных приложений с использованием единого решения, которое ожидает поддержки единого формата всей системой. Паттерн Adapter (Адаптер) позволяет организовать унифицированный интерфейс мониторинга, экспортируя метрики из различных контейнеров приложений в один стандартный формат и протокол. На рис. 16.1 изображен контейнер-адаптер, который преобразует информацию с метриками, хранящуюся локально, во внешний формат, который понимает сервер мониторинга.

586647.png 

Рис. 16.1. Паттерн Adapter (Адаптер)

При таком подходе каждая служба, представленная отдельным подом, кроме основного контейнера приложения будет включать еще один контейнер, который знает, как прочитать метрики приложения и преобразовать их в формат, понятный инструменту мониторинга. Например, мы можем иметь один контейнер-адаптер, который знает, как экспортировать Java-метрики через HTTP, и другой контейнер-адаптер, в другом поде, который знает, как экспортировать Python-метрики через HTTP. Инструменту мониторинга все метрики будут доступны через HTTP в общем нормализованном формате.

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

Паттерн Adapter (Адаптер) идеально подходит для этого случая: вспомогательный контейнер запускает небольшой HTTP-сервер и при каждом запросе читает файл журнала и преобразует его в формат, понятный для Prometheus. В листинге 16.1 представлено определение развертывания Deployment с таким контейнером-адаптером. Эта конфигурация избавляет основное приложение от необходимости знать что-либо о Prometheus. Полный пример в нашем репозитории GitHub демонстрирует эту конфигурацию вместе с установкой Prometheus.

Листинг 16.1. Адаптер, преобразующий информацию в формат, понятный Prometheus

apiVersion: apps/v1

kind: Deployment

metadata:

  name: random-generator

spec:

  replicas: 1

  selector:

    matchLabels:

      app: random-generator

  template:

    metadata:

      labels:

        app: random-generator

    spec:

      containers:

      - image: k8spatterns/random-generator:1.0      

        name: random-generator

        env:

        - name: LOG_FILE                             

          value: /logs/random.log

        ports:

        - containerPort: 8080

          protocol: TCP

        volumeMounts:                                

        - mountPath: /logs

          name: log-volume

      # --------------------------------------------

      - image: k8spatterns/random-generator-exporter

        name: prometheus-adapter

        env:

        - name: LOG_FILE                             

          value: /logs/random.log

        ports:

        - containerPort: 9889

          protocol: TCP

        volumeMounts:                                

        - mountPath: /logs

          name: log-volume

      volumes:

      - name: log-volume                             

        emptyDir: {}

Главный контейнер приложения со службой, генерирующей случайные числа, доступной через порт 8080.

Путь к файлу журнала с информацией о времени создания случайных чисел.

Каталог, используемый совместно с контейнером-адаптером.

Образ контейнера, экспортирующего информацию в Prometheus через порт 9889.

Путь к файлу журнала, куда основное приложение записывает интересующую нас информацию.

Общий том монтируется также в контейнер-адаптер.

Общие файлы находятся в томе emptyDir, в файловой системе узла.

Этот паттерн может также использоваться для журналирования. Разные контейнеры могут записывать информацию в разных форматах и с разной степенью детализации. Контейнер-адаптер может нормализовать эту информацию, очистить ее, обогатить контекстной информацией с помощью паттерна Self Awareness (Самоанализ), описанного в главе 13, а затем сделать результат доступным для централизованного агрегатора журналов.

Пояснение

Паттерн Adapter (Адаптер) — это специализированный вариант паттерна Sidecar (Прицеп), описанного в главе 15. Он действует как обратный прокси для гетерогенной системы, скрывая ее сложность за унифицированным интерфейсом. Использование отдельного названия, отличного от названия более общего паттерна Sidecar (Прицеп), позволяет более точно обозначить назначение этого паттерна.

В следующей главе вы познакомитесь с еще одним специализированным вариантом паттерна Sidecar (Прицеп): паттерн Ambassador (Посредник), который действует как прокси, для доступа к службам во внешнем мире.

Дополнительная информация

• Пример реализации паттерна Адаптер (http://bit.ly/2HvFF3Y).

• Инструменты распределенных систем: паттерны контейнеров для создания модульных распределенных систем (https://bit.ly/2U2iWD9).

Назад: Глава 15. Паттерн Sidecar
Дальше: Глава 17. Посредник