Книга: Паттерны Kubernetes: Шаблоны разработки собственных облачных приложений
Назад: Глава 12. Обнаружение служб
Дальше: Часть III. Структурные паттерны

Глава 13. Самоанализ

Некоторые приложения должны иметь возможность получать информацию о себе. Паттерн Self Awareness (Самоанализ) описывает Kubernetes Downward API — простой механизм для самоанализа и внедрения метаданных в приложения.

Задача

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

Например, в зависимости от ресурсов, доступных контейнеру, приложение может настраивать размер пула потоков выполнения, изменять алгоритм сбора мусора или распределение памяти. Имя пода и имя хоста могут пригодиться для журналирования или отправки метрик на центральный сервер. Также вам может понадобиться отыскать другие поды в том же пространстве имен с определенной меткой и объединить их в кластерное приложение. Для этих и других случаев Kubernetes предоставляет Downward API.

Решение

Описанные требования и решение, представленное ниже, относятся не только к контейнерам, но и к любому динамическому окружению, где метаданные ресурсов могут изменяться. Например, AWS предлагает службы Instance Metadata и User Data, которые можно запросить у любого экземпляра EC2. Аналогично, AWS ECS предоставляет API, с помощью которого контейнеры могут запрашивать и получать информацию о кластере.

В Kubernetes используется еще более элегантный и простой подход. Downward API позволяет передавать метаданные о поде в контейнеры и в кластер через переменные окружения и файлы. Это те же механизмы, которые мы использовали для передачи данных, связанных с приложением, из ConfigMap и Secret. Но в этом случае данные создаются не нами. Мы просто указываем ключи, которые нас интересуют, а Kubernetes присваивает им значения динамически. На рис. 13.1 представлена общая схема, как Downward API внедряет в поды информацию о ресурсах и о среде времени выполнения.

594009.png 

Рис. 13.1. Механизмы интроспекции приложений

Суть в том, что Downward API внедряет метаданные в под и они становятся доступными локально. Приложению не нужно использовать клиента и взаимодействовать с Kubernetes API, и оно может оставаться независимым от Kubernetes. Давайте рассмотрим листинг 13.1, демонстрирующий, насколько просто запрашивать метаданные через переменные окружения.

Листинг 13.1. Передача информации из Downward API через переменные окружения

apiVersion: v1

kind: Pod

metadata:

  name: random-generator

spec:

  containers:

  - image: k8spatterns/random-generator:1.0

    name: random-generator

    env:

    - name: POD_IP

      valueFrom:

        fieldRef:                      

          fieldPath: status.podIP

    - name: MEMORY_LIMIT

      valueFrom:

        resourceFieldRef:

          container: random-generator  

  resource: limits.memory

Переменная окружения POD_IP получает значение из свойств пода и инициализируется во время запуска пода.

Переменная окружения MEMORY_LIMIT получает значение, равное лимиту памяти, выделенной для этого контейнера; фактическое объявление лимита здесь не показано.

Для доступа к метаданным уровня пода в этом примере используется свойство fieldRef. Ключи, перечисленные в табл. 13.1, доступны в fieldRef.fieldPath и в виде переменных окружения, и в виде томов downwardAPI.

По аналогии с fieldRef, для доступа к метаданным, относящимся к конкретному контейнеру в поде, можно использовать resourceFieldRef. Эти метаданные относятся к контейнеру, который можно задать с помощью resourceFieldRef.container. При использовании переменной окружения по умолчанию сообщаются метаданные для текущего контейнера. Возможные ключи для resourceFieldRef.resource перечислены в табл. 13.2.

Таблица 13.1. Информация из Downward API, доступная в fieldRef.fieldPath

Имя

Описание

spec.nodeName

Имя узла, где размещается под

status.hostIP

IP-адрес узла, где размещается под

metadata.name

Имя пода

metadata.namespace

Пространство имен, в котором действует под

status.podIP

IP-адрес пода

spec.serviceAccountName

Учетная запись ServiceAccount, используемая подом

metadata.uid

Уникальный идентификатор пода

metadata.labels[‘key']

Значение метки key пода

metadata.annotations[‘key']

Значение аннотации key пода

Таблица 13.2. Информация из Downward API, доступная в resourceFieldRef.resource

Имя

Описание

requests.cpu

Число процессоров, запрошенное контейнером

limits.cpu

Лимит процессоров для контейнера

requests.memory

Объем памяти, запрошенный контейнером

limits.memory

Лимит памяти, доступной контейнеру

Некоторые метаданные, такие как метки и аннотации, могут меняться пользователем во время работы пода. Переменные окружения будут отражать такие изменения только после перезапуска пода. Но тома downwardAPI способны динамически отражать изменения в метках и аннотациях. В дополнение к отдельным полям, перечисленным выше, тома downwardAPI могут хранить все метки и аннотации подов в файлах с именами metadata.labels и metadata.annotations. Листинг 13.2 показывает, как можно использовать такие тома.

Листинг 13.2. Передача информации из Downward API через тома

apiVersion: v1

kind: Pod

metadata:

  name: random-generator

spec:

  containers:

  - image: k8spatterns/random-generator:1.0

    name: random-generator

    volumeMounts:

    - name: pod-info

      mountPath: /pod-info

  volumes:

  - name: pod-info                     

    downwardAPI:

      items:

      - path: labels                   

        fieldRef:

          fieldPath: metadata.labels

      - path: annotations              

        fieldRef:

          fieldPath: metadata.annotations

Значения из Downward API можно монтировать как файлы в поде.

Файл labels содержит все метки, по одной в каждой строке, в формате имя=значение. Этот файл обновляется синхронно с изменением меток.

Файл annotations содержит все аннотации в том же формате, что и метки.

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

Пояснение

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

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

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

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

• Пример самоанализа (http://bit.ly/2TYBXpc).

• Получение информации контейнером о поде через файлы (http://bit.ly/2CoZyFy).

• Получение информации контейнером о поде через переменные окружения (http://bit.ly/2JpuHPe).

• Агент интроспекции в Amazon ECS (https://amzn.to/2JnVXgX).

• Службы Instance Metadata и User Data (http://amzn.to/1Cu0fTl).

Назад: Глава 12. Обнаружение служб
Дальше: Часть III. Структурные паттерны