Это многостраничный печатный вид этого раздела. Нажмите что бы печатать.

Вернуться к обычному просмотру страницы.

Администрирование кластера

Lower-level detail relevant to creating or administering a Kubernetes cluster.

Обзор администрирования кластера предназначен для всех, кто создает или администрирует кластер Kubernetes. Это предполагает некоторое знакомство с основными концепциями Kubernetes.

Планирование кластера

См. Руководства в разделе настройка для получения примеров того, как планировать, устанавливать и настраивать кластеры Kubernetes. Решения, перечисленные в этой статье, называются distros.

Прежде чем выбрать руководство, вот некоторые соображения:

  • Вы хотите опробовать Kubernetes на вашем компьютере или собрать много узловой кластер высокой доступности? Выбирайте дистрибутивы, наиболее подходящие для ваших нужд.
  • Будете ли вы использовать размещенный кластер Kubernetes, такой, как Google Kubernetes Engine или разместите собственный кластер?
  • Будет ли ваш кластер в помещении или в облаке (IaaS)? Kubernetes не поддерживает напрямую гибридные кластеры. Вместо этого вы можете настроить несколько кластеров.
  • Если вы будете настраивать Kubernetes в помещении (локально), подумайте, какая сетевая модель подходит лучше всего.
  • Будете ли вы запускать Kubernetes на оборудований "bare metal" или на виртуальных машинах (VMs)?
  • Вы хотите запустить кластер или планируете активно разворачивать код проекта Kubernetes? В последнем случае выберите активно разрабатываемый дистрибутив. Некоторые дистрибутивы используют только двоичные выпуски, но предлагают более широкий выбор.
  • Ознакомьтесь с компонентами необходимые для запуска кластера.

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

Обеспечение безопасности кластера

Обеспечение безопасности kubelet

Дополнительные кластерные услуги

1 - Сертификаты

Чтобы узнать, как генерировать сертификаты для кластера, см. раздел Сертификаты.

2 - Управление ресурсами

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

Организация конфигураций ресурсов

Многие приложения требуют создания нескольких ресурсов типа Deployment и Service. Управление ими можно упростить, сгруппировав в один YAML-файл (со строкой "---" в качестве разделителя). Например:

apiVersion: v1
kind: Service
metadata:
  name: my-nginx-svc
  labels:
    app: nginx
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

Можно создавать сразу несколько ресурсов:

kubectl apply -f https://k8s.io/examples/application/nginx-app.yaml
service/my-nginx-svc created
deployment.apps/my-nginx created

Ресурсы будут создаваться в порядке, в котором они описаны в файле. Таким образом, первым лучше всего описать сервис — это позволит планировщику распределять Pod'ы этого сервиса по мере их создания контроллером (контроллерами), например, Deployment'ом.

kubectl apply также может принимать сразу несколько аргументов -f:

kubectl apply -f https://k8s.io/examples/application/nginx/nginx-svc.yaml -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml

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

kubectl apply -f https://k8s.io/examples/application/nginx/

kubectl прочитает все файлы с расширениями .yaml, .yml или .json.

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

Также в качестве источника конфигурации можно указать URL — это удобно при создании/настройке с использованием конфигурационных файлов, размещенных на GitHub:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx created

Пакетные операции в kubectl

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

kubectl delete -f https://k8s.io/examples/application/nginx-app.yaml
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted

В случае двух ресурсов их можно перечислить в командной строке, используя синтаксис вида resource/name:

kubectl delete deployments/my-nginx services/my-nginx-svc

При большем количестве ресурсов удобнее указать селектор (запрос по лейблу) с помощью -l или --selector, который отфильтрует ресурсы по их лейблам:

kubectl delete deployment,services -l app=nginx
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted

Поскольку kubectl выводит имена ресурсов в том же синтаксисе, что и получает, можно выстраивать цепочки операций с помощью $() или xargs:

kubectl get $(kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service)
kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service | xargs -i kubectl get {}
NAME           TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)      AGE
my-nginx-svc   LoadBalancer   10.0.0.208   <pending>     80/TCP       0s

Приведенные выше команды сначала создают ресурсы в разделе examples/application/nginx/, выводят о них информацию в формате -o name (то есть в виде пары resource/name). Затем в результатах производится поиск по "service" (grep), и информация о найденных ресурсах выводится с помощью kubectl get.

Если ресурсы хранятся в нескольких поддиректориях в пределах одной директории, можно рекурсивно выполнять операции и в этих поддиректориях, указав --recursive или -R наряду с флагом --filename, -f.

Предположим, что существует директория project/k8s/development, в которой хранятся все манифесты, необходимые для dev-окружения, организованные по типу ресурсов:

project/k8s/development
├── configmap
│   └── my-configmap.yaml
├── deployment
│   └── my-deployment.yaml
└── pvc
    └── my-pvc.yaml

По умолчанию при выполнении массовых операций над project/k8s/development команда остановится на первом уровне, не обрабатывая поддиректории. К примеру, попытка создать ресурсы, описанные в этой директории, приведет к ошибке:

kubectl apply -f project/k8s/development
error: you must provide one or more resources by argument or filename (.json|.yaml|.yml|stdin)

Вместо этого следует указать флаг --recursive или -R с флагом --filename, -f:

kubectl apply -f project/k8s/development --recursive
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created

Флаг --recursive работает с любыми операциями, принимающими флаг --filename, -f, например: kubectl {create, get, delete, describe, rollout} и т.д.

Флаг --recursive также работает для нескольких аргументов -f:

kubectl apply -f project/k8s/namespaces -f project/k8s/development --recursive
namespace/development created
namespace/staging created
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created

В разделе Инструмент командной строки kubectl доступна дополнительная информация о kubectl.

Эффективное использование лейблов

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

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

     labels:
        app: guestbook
        tier: frontend

в то время как у master'а и slave'а Redis будут лейблы tier и, возможно, даже дополнительный лейбл role:

     labels:
        app: guestbook
        tier: backend
        role: master

и

     labels:
        app: guestbook
        tier: backend
        role: slave

Лейблы позволяют группировать ресурсы по любому параметру с соответствующим лейблом:

kubectl apply -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml
kubectl get pods -Lapp -Ltier -Lrole
NAME                           READY     STATUS    RESTARTS   AGE       APP         TIER       ROLE
guestbook-fe-4nlpb             1/1       Running   0          1m        guestbook   frontend   <none>
guestbook-fe-ght6d             1/1       Running   0          1m        guestbook   frontend   <none>
guestbook-fe-jpy62             1/1       Running   0          1m        guestbook   frontend   <none>
guestbook-redis-master-5pg3b   1/1       Running   0          1m        guestbook   backend    master
guestbook-redis-slave-2q2yf    1/1       Running   0          1m        guestbook   backend    slave
guestbook-redis-slave-qgazl    1/1       Running   0          1m        guestbook   backend    slave
my-nginx-divi2                 1/1       Running   0          29m       nginx       <none>     <none>
my-nginx-o0ef1                 1/1       Running   0          29m       nginx       <none>     <none>
kubectl get pods -lapp=guestbook,role=slave
NAME                          READY     STATUS    RESTARTS   AGE
guestbook-redis-slave-2q2yf   1/1       Running   0          3m
guestbook-redis-slave-qgazl   1/1       Running   0          3m

Канареечные развертывания

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

В примере ниже лейбл track помогает различить релизы.

У основного, стабильного релиза он будет иметь значение stable:

     name: frontend
     replicas: 3
     ...
     labels:
        app: guestbook
        tier: frontend
        track: stable
     ...
     image: gb-frontend:v3

У нового релиза фронтенда гостевой книги значение этого лейбла будет другим (canary), чтобы два набора Pod'ов не пересекались:

     name: frontend-canary
     replicas: 1
     ...
     labels:
        app: guestbook
        tier: frontend
        track: canary
     ...
     image: gb-frontend:v4

Чтобы охватить оба набора реплик, сервис фронтенда следует настроить на выбор общего подмножества их лейблов (т.е. опустить лейбл track). В результате трафик будет поступать на обе версии приложения:

  selector:
     app: guestbook
     tier: frontend

При этом число стабильных и канареечных реплик можно менять, регулируя долю production-трафика, которую будет получать каждая версия приложения (три к одному в нашем случае). Убедившись в стабильности новой версии, можно поменять значение ее лейбла track с canary на stable.

Более подробный пример доступен в руководстве по развертыванию Ghost.

Обновление лейблов

Иногда возникает необходимость поменять лейблы у существующих Pod'ов и других ресурсов перед созданием новых. Сделать это можно с помощью команды kubectl label. Например, чтобы промаркировать все Pod'ы NGINX как имеющие отношение к фронтенду, выполните следующую команду:

kubectl label pods -l app=nginx tier=fe
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
pod/my-nginx-2035384211-u3t6x labeled

Сначала она выберет все Pod'ы с лейблом app=nginx, а затем пометит их лейблом tier=fe. Чтобы просмотреть список этих Pod'ов, выполните:

kubectl get pods -l app=nginx -L tier
NAME                        READY     STATUS    RESTARTS   AGE       TIER
my-nginx-2035384211-j5fhi   1/1       Running   0          23m       fe
my-nginx-2035384211-u2c7e   1/1       Running   0          23m       fe
my-nginx-2035384211-u3t6x   1/1       Running   0          23m       fe

Будут выведены все Pod'ы app=nginx с дополнительным столбцом tier (задается с помощью -L или --label-columns).

Дополнительную информацию можно найти в разделах Лейблы и kubectl label.

Обновление аннотаций

Иногда возникает потребность навесить на ресурсы аннотации. Аннотации — это произвольные неидентифицирующие метаданные для извлечения клиентами API (инструментами, библиотеками и т.п.). Добавить аннотацию можно с помощью команды kubectl annotate. Например:

kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx'
kubectl get pods my-nginx-v4-9gw19 -o yaml
apiVersion: v1
kind: pod
metadata:
  annotations:
    description: my frontend running nginx
...

Для получения дополнительной информации обратитесь к разделу Аннотации и описанию команды kubectl annotate.

Масштабирование приложения

Для масштабирования приложения можно воспользоваться инструментом kubectl. Например, следующая команда уменьшит число реплик с 3 до 1:

kubectl scale deployment/my-nginx --replicas=1
deployment.apps/my-nginx scaled

После ее применения количество Pod'ов под управлением соответствующего объекта Deployment сократится до одного:

kubectl get pods -l app=nginx
NAME                        READY     STATUS    RESTARTS   AGE
my-nginx-2035384211-j5fhi   1/1       Running   0          30m

Чтобы система автоматически выбирала необходимое количество реплик NGINX в диапазоне от 1 до 3, выполните следующую команду:

kubectl autoscale deployment/my-nginx --min=1 --max=3
horizontalpodautoscaler.autoscaling/my-nginx autoscaled

Теперь количество реплик NGINX будет автоматически увеличиваться и уменьшаться по мере необходимости.

Для получения дополнительной информации см. разделы kubectl scale, kubectl autoscale и horizontal pod autoscaler.

Обновление ресурсов "на месте"

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

kubectl apply

Хранить конфигурационные файлы рекомендуемтся в системе контроля версий (см. конфигурация как код). В этом случае их можно будет поддерживать и версионировать вместе с кодом ресурсов, которые те конфигурируют. Далее с помощью команды kubectl apply изменения, внесенные в конфигурацию, можно применить к кластеру.

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

kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx configured

Обратите внимание, что kubectl apply добавляет к ресурсу аннотацию, помогающую отслеживать изменения в конфигурации с момента предыдущего вызова. При вызове kubectl apply проводит трехстороннее сравнение (three-way diff) предыдущей конфигурации, ее текущей и новой версий, которое определяет, какие правки следует внести в ресурс.

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

При всех последующих вызовах kubectl apply и других команд, меняющих конфигурацию, таких как kubectl replace и kubectl edit, аннотация будет обновляться. В результате kubectl apply сможет проводить трехстороннее сравнение (three-way diff), определяя, какие свойства требуют удаления, и удалять их.

kubectl edit

Ресурсы также можно обновлять с помощью команды kubectl edit:

kubectl edit deployment/my-nginx

По сути, kubectl edit объединяет в себе логику нескольких команд, упрощая жизнь пользователям: сначала она получает (get) ресурс, вызывает текстовый редактор, а затем применяет (apply) обновленную конфигурацию:

kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml
vi /tmp/nginx.yaml
# внесите правки и сохраните файл

kubectl apply -f /tmp/nginx.yaml
deployment.apps/my-nginx configured

rm /tmp/nginx.yaml

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

За дополнительной информацией обратитесь к разделу kubectl edit.

kubectl patch

Команда kubectl patch обновляет объекты API "на месте". Она поддерживает форматы JSON patch, JSON merge patch и strategic merge patch. См. разделы Обновление объектов API "на месте" с помощью kubectl patch и kubectl patch.

Обновления, требующие перерыва в работе

Иногда может понадобиться обновить поля ресурса, которые нельзя изменить после инициализации, или возникнет необходимость немедленно внести рекурсивные изменения, например, "починить" сбойные Pod'ы, созданные Deployment'ом. Для этого можно воспользоваться командой replace --force, которая удалит и пересоздаст ресурс. Вот как можно внести правки в исходный файл конфигурации в нашем примере:

kubectl replace -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml --force
deployment.apps/my-nginx deleted
deployment.apps/my-nginx replaced

Обновление приложения без перерыва в работе

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

Ниже будет рассказано, как создавать и обновлять приложения с помощью объектов Deployment.

Предположим, что в кластере используется версия NGINX 1.14.2:

kubectl create deployment my-nginx --image=nginx:1.14.2
deployment.apps/my-nginx created

с тремя репликами (чтобы старые и новые ревизии могли сосуществовать):

kubectl scale deployment my-nginx --current-replicas=1 --replicas=3
deployment.apps/my-nginx scaled

Чтобы перейти на версию 1.16.1, измените значение параметра .spec.template.spec.containers[0].image с nginx:1.14.2 на nginx:1.16.1:

kubectl edit deployment/my-nginx

Вот и все! Deployment декларативно обновит развернутое приложение NGINX "за кулисами". При этом Kubernetes проследит, чтобы число недоступных реплик в каждый момент времени не превышало определенного значения, а также за тем, чтобы количество новых реплик не превышало определенного предела, установленного для желаемого числа Pod'ов. Более подробную информацию об этом можно получить в разделе Deployment.

Что дальше

3 - Сеть в кластере

Сеть — важная часть Kubernetes, но понять, как именно она работает, бывает непросто. Существует 4 уникальных сетевых проблемы, которые требуют внимнаия:

  1. Высокосвязанные коммуникации между контейнерами: решается организацией коммуникации между Pod'ами и localhost.
  2. Связь Pod'ов друг с другом (Pod-to-Pod): именно ей уделяется основное внимание в этом документе.
  3. Связь Pod'ов с сервисами (Pod-to-Service): подробнее об этом можно почитать в разделе Сервисы.
  4. Связь внешних систем с сервисами (External-to-Service): информация о данных коммуникациях также приведена в разделе Сервисы.

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

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

Больше узнать о сетевой модели Kubernetes можно в соответствующем разделе.

Реализация сетевой модели Kubernetes

Сетевая модель реализуется средой исполнения для контейнеров на узлах. Наиболее распространенные среды исполнения используют плагины Container Network Interface (CNI) для управления сетью и обеспечения безопаснояти коммуникаций. Существует множество различных плагинов CNI от разных разработчиков. Некоторые из них предлагают только базовые функции, такие как добавление и удаление сетевых интерфейсов. Другие позволяют проводить интеграцию с различныеми системами оркестрации контейнеров, поддерживают запуск нескольких CNI-плагинов/расширенные функции IPAM и т.д.

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

Что дальше

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

4 - Архитектура для сбора логов

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

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

Например, может возникнуть необходимость просмотреть логи приложения при аварийном завершении работы Pod'а, его вытеснении (eviction) или "падении" узла.

В кластере у логов должно быть отдельное хранилище и жизненный цикл, не зависящий от узлов, Pod'ов или контейнеров. Эта концепция называется сбор логов на уровне кластера.

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

Основы сбора логов в Kubernetes

В примере ниже используется спецификация Pod с контейнером для отправки текста в стандартный поток вывода раз в секунду.

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox:1.28
    args: [/bin/sh, -c,
            'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']

Запустить его можно с помощью следующей команды:

kubectl apply -f https://k8s.io/examples/debug/counter-pod.yaml

Результат будет таким:

pod/counter created

Получить логи можно с помощью команды kubectl logs, как показано ниже:

kubectl logs counter

Результат будет таким:

0: Mon Jan  1 00:00:00 UTC 2001
1: Mon Jan  1 00:00:01 UTC 2001
2: Mon Jan  1 00:00:02 UTC 2001
...

Команда kubectl logs --previous позволяет извлечь логи из предыдущего воплощения контейнера. Если в Pod'е несколько контейнеров, выбрать нужный для извлечения логов можно с помощью флага -c:

kubectl logs counter -c count

Для получения дополнительной информации см. документацию по kubectl logs.

Сбор логов на уровне узла

Сбор логов на уровне узла

Среда исполнения для контейнера обрабатывает и перенаправляет любой вывод в потоки stdout и stderr приложения. Docker Engine, например, перенаправляет эти потоки драйверу журналирования, который в Kubernetes настроен на запись в файл в формате JSON.

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

Важным моментом при сборе логов на уровне узла является их ротация, чтобы логи не занимали все доступное место на узле. Kubernetes не отвечает за ротацию логов, но способен развернуть инструмент для решения этой проблемы. Например, в кластерах Kubernetes, развертываемых с помощью скрипта kube-up.sh, имеется инструмент logrotate, настроенный на ежечасный запуск. Также можно настроить среду исполнения контейнера на автоматическую ротацию логов приложения.

Подробную информацию о том, как kube-up.sh настраивает логирование для образа COS на GCP, можно найти в соответствующем скрипте configure-helper.

При использовании среды исполнения контейнера CRI kubelet отвечает за ротацию логов и управление структурой их директории. kubelet передает данные среде исполнения контейнера CRI, а та сохраняет логи контейнера в указанное место. С помощью параметров containerLogMaxSize и containerLogMaxFiles в конфигурационном файле kubelet'а можно настроить максимальный размер каждого лог-файла и максимальное число таких файлов для каждого контейнера соответственно.

При выполнении команды kubectl logs (как в примере из раздела про основы сбора логов) kubelet на узле обрабатывает запрос и считывает данные непосредственно из файла журнала. Затем он возвращает его содержимое.

Логи системных компонентов

Существует два типа системных компонентов: те, которые работают в контейнере, и те, которые работают за пределами контейнера. Например:

  • планировщик Kubernetes и kube-proxy выполняются в контейнере;
  • kubelet и среда исполнения контейнера работают за пределами контейнера.

На машинах с systemd среда исполнения и kubelet пишут в journald. Если systemd отсутствует, среда исполнения и kubelet пишут в файлы .log в директории /var/log. Системные компоненты внутри контейнеров всегда пишут в директорию /var/log, обходя механизм ведения логов по умолчанию. Они используют библиотеку для сбора логов klog. Правила сбора логов и рекомендации можно найти в соответствующей документации.

Как и логи контейнеров, логи системных компонентов в директории /var/log необходимо ротировать. В кластерах Kubernetes, созданных с помощью скрипта kube-up.sh, эти файлы настроены на ежедневную ротацию с помощью инструмента logrotate или при достижении 100 МБ.

Архитектуры для сбора логов на уровне кластера

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

  • использовать агент на уровне узлов (запускается на каждом узле);
  • внедрить в Pod с приложением специальный sidecar-контейнер для сбора логов;
  • отправлять логи из приложения непосредственно в бэкенд.

Использование агента на уровне узлов

Использование агента на уровне узлов

Сбор логов на уровне кластера можно реализовать, запустив node-level-агент на каждом узле. Лог-агент — это специальный инструмент, который предоставляет доступ к логам или передает их бэкенду. Как правило, лог-агент представляет собой контейнер с доступом к директории с файлами логов всех контейнеров приложений на этом узле.

Поскольку лог-агент должен работать на каждом узле, рекомендуется запускать его как DaemonSet.

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

Контейнеры пишут в stdout и stderr, но без согласованного формата. Агент на уровне узла собирает эти логи и направляет их на агрегацию.

Сбор логов с помощью sidecar-контейнера с лог-агентом

Sidecar-контейнер можно использовать одним из следующих способов:

  • sidecar-контейнер транслирует логи приложений на свой собственный stdout;
  • в sidecar-контейнере работает агент, настроенный на сбор логов из контейнера приложения.

Транслирующий sidecar-контейнер

Sidecar-контейнер с транслирующим контейнером

Настроив sidecar-контейнеры на вывод в их собственные потоки stdout и stderr, можно воспользоваться преимуществами kubelet и лог-агента, которые уже работают на каждом узле. Sidecar-контейнеры считывают логи из файла, сокета или journald. Затем каждый из них пишет логи в собственный поток stdout или stderr.

Такой подход позволяет разграничить потоки логов от разных частей приложения, некоторые из которых могут не поддерживать запись в stdout или stderr. Логика, управляющая перенаправлением логов, проста и не требует значительных ресурсов. Кроме того, поскольку stdout и stderr обрабатываются kubelet'ом, можно использовать встроенные инструменты вроде kubectl logs.

Предположим, к примеру, что в Pod'е работает один контейнер, который пишет логи в два разных файла в двух разных форматах. Вот пример конфигурации такого Pod'а:

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox:1.28
    args:
    - /bin/sh
    - -c
    - >
      i=0;
      while true;
      do
        echo "$i: $(date)" >> /var/log/1.log;
        echo "$(date) INFO $i" >> /var/log/2.log;
        i=$((i+1));
        sleep 1;
      done      
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  volumes:
  - name: varlog
    emptyDir: {}

Не рекомендуется писать логи разных форматов в один и тот же поток, даже если удалось перенаправить оба компонента в stdout контейнера. Вместо этого можно создать два sidecar-контейнера. Каждый из них будет забирать определенный лог-файл с общего тома и перенаправлять логи в свой stdout.

Вот пример конфигурации Pod'а с двумя sidecar-контейнерами:

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox:1.28
    args:
    - /bin/sh
    - -c
    - >
      i=0;
      while true;
      do
        echo "$i: $(date)" >> /var/log/1.log;
        echo "$(date) INFO $i" >> /var/log/2.log;
        i=$((i+1));
        sleep 1;
      done      
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  - name: count-log-1
    image: busybox:1.28
    args: [/bin/sh, -c, 'tail -n+1 -F /var/log/1.log']
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  - name: count-log-2
    image: busybox:1.28
    args: [/bin/sh, -c, 'tail -n+1 -F /var/log/2.log']
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  volumes:
  - name: varlog
    emptyDir: {}

Доступ к каждому потоку логов такого Pod'а можно получить отдельно, выполнив следующие команды:

kubectl logs counter count-log-1

Результат будет таким:

0: Mon Jan  1 00:00:00 UTC 2001
1: Mon Jan  1 00:00:01 UTC 2001
2: Mon Jan  1 00:00:02 UTC 2001
...
kubectl logs counter count-log-2

Результат будет таким:

Mon Jan  1 00:00:00 UTC 2001 INFO 0
Mon Jan  1 00:00:01 UTC 2001 INFO 1
Mon Jan  1 00:00:02 UTC 2001 INFO 2
...

Агент на уровне узла, установленный в кластере, подхватывает эти потоки логов автоматически без дополнительной настройки. При желании можно настроить агент на парсинг логов в зависимости от контейнера-источника.

Обратите внимание: несмотря на низкое использование процессора и памяти (порядка нескольких milliCPU для процессора и пары мегабайт памяти), запись логов в файл и их последующая потоковая передача в stdout может вдвое увеличить нагрузку на диск. Если приложение пишет в один файл, рекомендуется установить /dev/stdout в качестве адресата, нежели использовать подход с транслирующим контейнером.

Sidecar-контейнеры также можно использовать для ротации файлов логов, которые не могут быть ротированы самим приложением. В качестве примера можно привести небольшой контейнер, периодически запускающий logrotate. Однако рекомендуется использовать stdout и stderr напрямую, а управление политиками ротации и хранения оставить kubelet'у.

Sidecar-контейнер с лог-агентом

Sidecar-контейнер с лог-агентом

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

Ниже приведены два файла конфигурации sidecar-контейнера с лог-агентом. Первый содержит ConfigMap для настройки fluentd.

apiVersion: v1
kind: ConfigMap
metadata:
  name: fluentd-config
data:
  fluentd.conf: |
    <source>
      type tail
      format none
      path /var/log/1.log
      pos_file /var/log/1.log.pos
      tag count.format1
    </source>

    <source>
      type tail
      format none
      path /var/log/2.log
      pos_file /var/log/2.log.pos
      tag count.format2
    </source>

    <match **>
      type google_cloud
    </match>    

Второй файл описывает Pod с sidecar-контейнером, в котором работает fluentd. Pod монтирует том с конфигурацией fluentd.

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox:1.28
    args:
    - /bin/sh
    - -c
    - >
      i=0;
      while true;
      do
        echo "$i: $(date)" >> /var/log/1.log;
        echo "$(date) INFO $i" >> /var/log/2.log;
        i=$((i+1));
        sleep 1;
      done      
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  - name: count-agent
    image: registry.k8s.io/fluentd-gcp:1.30
    env:
    - name: FLUENTD_ARGS
      value: -c /etc/fluentd-config/fluentd.conf
    volumeMounts:
    - name: varlog
      mountPath: /var/log
    - name: config-volume
      mountPath: /etc/fluentd-config
  volumes:
  - name: varlog
    emptyDir: {}
  - name: config-volume
    configMap:
      name: fluentd-config

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

Прямой доступ к логам из приложения

Прямой доступ к логам из приложения

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

5 - Логи системных компонентов

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

Klog

klog — библиотека Kubernetes для сбора логов. Отвечает за генерацию соответствующих сообщений для системных компонентов оркестратора.

Дополнительные сведения о настройке klog можно получить в Справке по CLI.

В настоящее время ведется работа по упрощению процесса сбора логов в компонентах Kubernetes. Приведенные ниже флаги командной строки klog устарели, начиная с версии Kubernetes 1.23, и будут удалены в одном из будущих релизов:

  • --add-dir-header
  • --alsologtostderr
  • --log-backtrace-at
  • --log-dir
  • --log-file
  • --log-file-max-size
  • --logtostderr
  • --one-output
  • --skip-headers
  • --skip-log-headers
  • --stderrthreshold

Вывод всегда будет записываться в stderr независимо от его формата. Перенаправление вывода должно осуществляться компонентом, который вызывает компонент Kubernetes, например, POSIX-совместимой командной оболочкой или инструментом вроде systemd.

Иногда эти опции недоступны — например, в случае контейнера без дистрибутива (distroless) или системной службы Windows. Тогда kube-log-runner можно использовать в качестве обертки вокруг компонента Kubernetes для перенаправления вывода. Его предварительно собранный исполняемый файл включен в некоторые базовые образы Kubernetes под старым именем /go-runner, а в актуальных бинарных релизах архивов с kubernetes-server и kubernetes-node он называется kube-log-runner.

В таблице ниже показаны соответствия между вызовами kube-log-runner и логикой перенаправления командной оболочки:

ИспользованиеОболочка POSIX (например, Bash)kube-log-runner <options> <cmd>
Объединить stderr и stdout, вывести в stdout2>&1kube-log-runner (default behavior)
Перенаправить оба потока в файл лога1>>/tmp/log 2>&1kube-log-runner -log-file=/tmp/log
Скопировать в файл лога и в stdout2>&1 | tee -a /tmp/logkube-log-runner -log-file=/tmp/log -also-stdout
Перенаправить только stdout в файл лога>/tmp/logkube-log-runner -log-file=/tmp/log -redirect-stderr=false

Вывод klog

Пример оригинального "родного" формата klog:

I1025 00:15:15.525108       1 httplog.go:79] GET /api/v1/namespaces/kube-system/pods/metrics-server-v0.3.1-57c75779f-9p8wg: (1.512ms) 200 [pod_nanny/v0.0.0 (linux/amd64) kubernetes/$Format 10.56.1.19:51756]

Сообщение может содержать переносы строк:

I1025 00:15:15.525108       1 example.go:79] This is a message
which has a line break.

Структурированное логирование

СТАТУС ФИЧИ: Kubernetes v1.23 [beta]

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

По умолчанию структурированные сообщения форматируются как текст, при этом его формат обратно совместим с традиционным форматом klog:

<klog header> "<message>" <key1>="<value1>" <key2>="<value2>" ...

Пример:

I1025 00:15:15.525108       1 controller_utils.go:116] "Pod status updated" pod="kube-system/kubedns" status="ready"

Строки заключаются в кавычки. Другие значения форматируются с помощью %+v. В результате сообщение может продолжиться на следующей строке в зависимости от типа данных.

I1025 00:15:15.525108       1 example.go:116] "Example" data="This is text with a line break\nand \"quotation marks\"." someInt=1 someFloat=0.1 someStruct={StringField: First line,
second line.}

Контекстное логирование

СТАТУС ФИЧИ: Kubernetes v1.24 [alpha]

Контекстное логирование базируется на структурированном логировании. Речь идет в первую очередь о том, как разработчики используют лог-вызовы: код, основанный на этой концепции, более гибок и поддерживает дополнительные сценарии использования (см. Contextual Logging KEP).

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

В настоящее время за включение контекстного логирования отвечает переключатель функционала StructuredLogging. По умолчанию оно отключено. Соответствующая инфраструктура появилась в версии 1.24 и она не потребовала изменений в компонентах. Команда component-base/logs/example показывает, как использовать новые лог-вызовы и как ведет себя компонент, поддерживающий контекстное логирование.

$ cd $GOPATH/src/k8s.io/kubernetes/staging/src/k8s.io/component-base/logs/example/cmd/
$ go run . --help
...
      --feature-gates mapStringBool  A set of key=value pairs that describe feature gates for alpha/experimental features. Options are:
                                     AllAlpha=true|false (ALPHA - default=false)
                                     AllBeta=true|false (BETA - default=false)
                                     ContextualLogging=true|false (ALPHA - default=false)
$ go run . --feature-gates ContextualLogging=true
...
I0404 18:00:02.916429  451895 logger.go:94] "example/myname: runtime" foo="bar" duration="1m0s"
I0404 18:00:02.916447  451895 logger.go:95] "example: another runtime" foo="bar" duration="1m0s"

Префикс example и foo="bar" были добавлены вызовом функции, которая пишет в лог сообщение runtime и значение duration="1m0s", при этом вносить изменения в эту функцию не потребовалось.

При отключенном контекстном логировании WithValues и WithName ничего не делают, а вызовы журнала проходят через глобальный логгер klog. Соответственно, эта дополнительная информация более не отображается в логе:

$ go run . --feature-gates ContextualLogging=false
...
I0404 18:03:31.171945  452150 logger.go:94] "runtime" duration="1m0s"
I0404 18:03:31.171962  452150 logger.go:95] "another runtime" duration="1m0s"

Логи в формате JSON

СТАТУС ФИЧИ: Kubernetes v1.19 [alpha]

Флаг --logging-format=json переключает формат логов с родного формата klog на JSON. Пример лога в формате JSON (стилистически отформатированном):

{
   "ts": 1580306777.04728,
   "v": 4,
   "msg": "Pod status updated",
   "pod":{
      "name": "nginx-1",
      "namespace": "default"
   },
   "status": "ready"
}

Специальные ключи:

  • ts — временная метка в формате времени Unix (обязательный параметр, float);
  • v — детализация (для общей информации — не для сообщений об ошибках, int);
  • err — ошибка (опциональный параметр, string);
  • msg — сообщение (обязательный параметр, string).

Список компонентов, поддерживающих формат JSON:

Уровень детализации лога

Флаг -v задает степень детализации лога. Увеличение значения увеличивает количество регистрируемых событий. Уменьшение значения уменьшает количество регистрируемых событий. Увеличение детализации приводит к тому, что регистрируются все менее значимые события. При уровне детализации, равном 0, регистрируются только критические события.

Местоположение лога

Существует два типа системных компонентов: те, которые работают в контейнере, и те, которые работают за пределами контейнера. Например:

На машинах с systemd среда исполнения и kubelet пишут в journald. В противном случае ведется запись в файлы .log в директории /var/log. Системные компоненты внутри контейнеров всегда пишут в файлы .log в директории /var/log, обходя механизм логирования по умолчанию. Как и логи контейнеров, логи системных компонентов в /var/log нуждаются в ротации. В кластерах Kubernetes, созданных с использованием скрипта kube-up.sh, ротация логов настраивается с помощью инструмента logrotate. logrotate ротирует логи ежедневно или при достижении ими размера в 100 МБ.

Что дальше

6 - Типы прокси-серверов в Kubernetes

На этой странице рассказывается о различных типах прокси-серверов, которые используются в Kubernetes.

Прокси-серверы

При работе с Kubernetes можно столкнуться со следующими типами прокси-серверов:

  1. kubectl:

    • работает на локальной машине или в Pod'е;
    • поднимает канал связи от локальной машины к интерфейсу API-сервера Kubernetes;
    • данные от клиента к прокси-серверу передаются по HTTP;
    • данные от прокси к серверу API передаются по HTTPS;
    • отвечает за обнаружение сервера API;
    • добавляет заголовки аутентификации.
  2. Прокси-сервер API:

    • бастион, встроенный в API-сервер;
    • подключает пользователя за пределами кластера к IP-адресам кластера, которые в ином случае могут оказаться недоступными;
    • входит в процессы сервера API;
    • данные от клиента к прокси-серверу передаются по HTTPS (или по HTTP, если сервер API настроен соответствующим образом);
    • данные от прокси-сервера к цели передаются по HTTP или HTTPS в зависимости от настроек прокси;
    • используется для доступа к узлам, Pod'ам или сервисам;
    • при подключении к сервису выступает балансировщиком нагрузки.
  3. kube proxy:

    • работает на каждом узле;
    • обрабатывает трафик UDP, TCP и SCTP;
    • "не понимает" HTTP;
    • выполняет функции балансировщика нагрузки;
    • используется только для доступа к сервисам.
  4. Прокси-сервер/балансировщик нагрузки перед API-сервером(-ами):

    • наличие и тип (например, nginx) определяется конфигурацией кластера;
    • располагается между клиентами и одним или несколькими серверами API;
    • балансирует запросы при наличии нескольких серверов API.
  5. Облачные балансировщики нагрузки на внешних сервисах:

    • предоставляются некоторыми облачными провайдерами (например, AWS ELB, Google Cloud Load Balancer);
    • создаются автоматически для сервисов Kubernetes с типом LoadBalancer;
    • как правило, поддерживают только UDP/TCP;
    • наличие поддержки SCTP зависит от реализации балансировщика нагрузки облачного провайдера;
    • реализация варьируется в зависимости от поставщика облачных услуг.

Пользователи Kubernetes, как правило, в своей работе сталкиваются только с прокси-серверами первых двух типов. За настройку остальных типов обычно отвечает администратор кластера.

Запросы на перенаправления

На смену функциям перенаправления (редиректам) пришли прокси-серверы. Перенаправления устарели.

7 - Равноправный доступ к API

СТАТУС ФИЧИ: Kubernetes v1.20 [beta]

Контроль за поведением API-сервера Kubernetes в условиях высокой нагрузки — ключевая задача для администраторов кластера. В kube-apiserver имеются некоторые механизмы управления (например, флаги командной строки --max-requests-inflight и --max-mutating-requests-inflight) для ограничения нагрузки на сервер. Они предотвращают наплыв входящих запросов и потенциальный отказ сервера API, но не позволяют гарантировать прохождение наиболее важных запросов в периоды высокой нагрузки.

Функция регулирования приоритета и обеспечения равноправного доступа к API (API Priority and Fairness), или РДА, — отличная альтернатива флагам. Она оптимизирует вышеупомянутые ограничения на максимальное количество запросов. РДА тщательнее классифицирует запросы и изолирует их. Также она поддерживает механизм очередей, который помогает обрабатывать запросы при краткосрочных всплесках нагрузки. Отправка запросов из очередей осуществляется на основе метода организации равноправных очередей, поэтому плохо работающий контроллер не будет мешать работе других (даже с аналогичным уровнем приоритета).

Эта функция предназначена для корректной работы со стандартными контроллерами, которые используют информеры и реагируют на неудачные API-запросы, экспоненциально увеличивая выдержку (back-off) между ними, а также клиентами, устроенными аналогичным образом.

Включение/отключение равноправного доступа к API

Управление РДА осуществляется с помощью переключателя функционала (feature gate); по умолчанию функция включена. В разделе Переключатели функционала приведено их общее описание и способы включения/отключения. В случае РДА соответствующий переключатель называется "APIPriorityAndFairness". Данная функция также включает группу API, при этом: (a) версия v1alpha1 по умолчанию отключена, (b) версии v1beta1 и v1beta2 по умолчанию включены. Чтобы отключить РДА и бета-версии групп API, добавьте следующие флаги командной строки в вызов kube-apiserver:

kube-apiserver \
--feature-gates=APIPriorityAndFairness=false \
--runtime-config=flowcontrol.apiserver.k8s.io/v1beta1=false,flowcontrol.apiserver.k8s.io/v1beta2=false \
 # …и остальные флаги, как обычно

Кроме того, версию v1alpha1 группы API можно включить с помощью --runtime-config=flowcontrol.apiserver.k8s.io/v1alpha1=true.

Флаг командной строки --enable-priority-and-fairness=false отключит функцию равноправного доступа к API, даже если другие флаги ее активировали.

Основные понятия

Функция равноправного доступа к API в своей работе использует несколько базовых понятий/механизмов. Входящие запросы классифицируются по атрибутам с помощью т.н. FlowSchemas, после чего им присваиваются уровни приоритета. Уровни приоритета обеспечивают некоторую степень изоляции, обеспечивая различные пределы параллелизма, предотвращая влияние запросов с разными уровнями приоритета друг на друга. В пределах одного приоритета алгоритм равнодоступного формирования очереди предотвращает взаимное влияние запросов из разных потоков и формирует очередь запросов, снижая число неудачных запросов во время всплесков трафика при приемлемо низкой средней нагрузке.

Уровни приоритета

Без включенного равноправного доступа к API управление общим параллелизмом в API-сервере осуществляется флагами --max-requests-inflight и --max-mutating-requests-inflight для kube-apiserver. При включенном равноправном доступе к API пределы параллелизма, заданные этими флагами, суммируются, а затем сумма распределяется по настраиваемому набору уровней приоритета. Каждому входящему запросу присваивается определенный уровень приоритета, причем каждый уровень приоритета может отправлять только такое количество параллельных запросов, которое прописано в его конфигурации.

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

Очереди

Каждый уровень приоритета может включать большое количество различных источников трафика. Во время перегрузки важно предотвратить негативное влияние одного потока запросов на остальные (например, в идеале один сбойный клиент, переполняющий kube-apiserver своими запросами, не должен оказывать заметного влияния на других клиентов). Для этого при обработке запросов с одинаковым уровнем приоритета используется алгоритм равнодоступной очереди. Каждый запрос приписывается к потоку, который идентифицируется по имени соответствующей FlowSchema и дифференциатору потока: пользователю-источнику запроса, пространству имен целевого ресурса или пустым значением. Система старается придать примерно равный вес запросам в разных потоках с одинаковым уровнем приоритета. Для раздельной обработки различных инстансов контроллеры с большим их числом должны аутентифицироваться под разными именами пользователей.

Распределив запрос в некоторый поток, РДА приписывает его к очереди. Этот процесс базируется на методе, известном как shuffle sharding (тасование между шардами), который относительно эффективно изолирует потоки низкой интенсивности от потоков высокой интенсивности с помощью очередей.

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

Запросы-исключения

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

Ресурсы

API управления потоками включает в себя два вида ресурсов. PriorityLevelConfigurations определяет доступные классы изоляции, долю доступного бюджета параллелизма, которая выделяется для каждого класса, и позволяет выполнять тонкую настройку работы с очередями. FlowSchema используется для классификации отдельных входящих запросов, сопоставляя каждый из них с одной из конфигураций PriorityLevelConfiguration. Кроме того, существует версия v1alpha1 данной группы API, с аналогичными Kinds с теми же синтаксисом и семантикой.

PriorityLevelConfiguration

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

Пределы параллелизма для PriorityLevelConfigurations указываются не в виде абсолютного количества запросов, а в виде "долей параллелизма" (concurrency shares). Совокупный объем ресурсов API-сервера, доступных для параллелизма, распределяется между существующими PriorityLevelConfigurations пропорционально этим долям. Администратор кластера может увеличить или уменьшить совокупный объем трафика на сервер, просто перезапустив kube-apiserver с другим значением --max-requests-inflight (или --max-mutating-requests-inflight). В результате пропускная способность каждой PriorityLevelConfigurations возрастет (или снизится) соразмерно ее доле.

Поле type спецификации PriorityLevelConfiguration определяет судьбу избыточных запросов, когда их объем, отнесенный к одной PriorityLevelConfiguration, превышает ее допустимый уровень параллелизма. Тип Reject означает, что избыточный трафик будет немедленно отклонен с ошибкой HTTP 429 (Too Many Requests). Тип Queue означает, что запросы, превышающие пороговое значение, будут поставлены в очередь, при этом для балансировки прогресса между потоками запросов будут использоваться методы тасования между шардами и равноправных очередей.

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

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

  • Увеличение длины очереди (queueLengthLimit) позволяет выдерживать большие всплески трафика без потери запросов за счет увеличения задержек и повышенного потребления памяти.

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

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

Конфигурации shuffle sharding
handSizeЧисло очередей1 слон4 слона16 слонов
12324.428838398950118e-090.114313488300991440.9935089607656024
10321.550093439632541e-080.06264798402235450.9753101519027554
10646.601827268370426e-120.000455713209903707760.49999929150089345
9643.6310049976037345e-110.000455012123041122730.4282314876454858
8642.25929199850899e-100.00048866970530404460.35935114681123076
81286.994461389026097e-133.4055790161620863e-060.02746173137155063
71281.0579122850901972e-116.960839379258192e-060.02406157386340147
72567.597695465552631e-146.728547142019406e-080.0006709661542533682
62562.7134626662687968e-122.9516464018476436e-070.0008895654642000348
65124.116062922897309e-144.982983350480894e-092.26025764343413e-05
610246.337324016514285e-168.09060164312957e-114.517408062903668e-07

FlowSchema

FlowSchema сопоставляется со входящими запросами; по результатам данного действия тем приписывается определенный уровень приоритета. Каждый входящий запрос по очереди проверяется на соответствие каждой FlowSchema, начиная с тех, у которых наименьшее численное значение matchingPrecedence (т.е., логически наивысший приоритет). Проверка ведется до первого совпадения.

Схема FlowSchema подходит определенному запросу, если хотя бы одно из ее правил (rules) подходит ему. В свою очередь, правило соответствует запросу, если ему соответствует хотя бы один из его субъектов (subjects) и хотя бы одно из его правил resourceRules или nonResourceRules (в зависимости от того, является ли входящий запрос ресурсным или нересурсным URL).

Для поля name в субъектах (subjects) и полей verbs, apiGroups, resources, namespaces и nonResourceURLs в ресурсных и нересурсных правилах может быть указан универсальный символ *, который будет соответствовать всем значениям для данного поля, фактически исключая его из рассмотрения.

Параметр distinguisherMethod.type схемы FlowSchema определяет, как запросы, соответствующие этой схеме, будут разделяться на потоки. Он может быть либо ByUser (в этом случае один запрашивающий пользователь не сможет лишить других пользователей ресурсов), либо ByNamespace (в этом случае запросы на ресурсы в одном пространстве имен не смогут помешать запросам на ресурсы в других пространствах имен), либо он может быть пустым (или distinguisherMethod может быть опущен) (в этом случае все запросы, соответствующие данной FlowSchema, будут считаться частью одного потока). Правильный выбор для определенной FlowSchema зависит от ресурса и конкретной среды.

Значения по умолчанию

kube-apiserver поддерживает два вида объектов конфигурации РДА: обязательные и рекомендуемые.

Обязательные объекты конфигурации

Четыре обязательных объекта конфигурации отражают защитное поведение, встроенное в серверы. Оно реализуется независимо от этих объектов; параметры последних просто его отражают.

  • Обязательный уровень приоритета exempt используется для запросов, которые вообще не подчиняются контролю потока: они всегда будут доставляться немедленно. Обязательная FlowSchema exempt относит к этому уровню приоритета все запросы из группы system:masters. При необходимости можно задать другие FlowSchemas, которые будут наделять другие запросы данным уровнем приоритета.

  • Обязательный уровень приоритета catch-all используется в сочетании с обязательной FlowSchema catch-all, гарантируя, что каждый запрос получит какую-либо классификацию. Как правило, полагаться на эту универсальную конфигурацию не следует. Рекомендуется создать свои собственные универсальные FlowSchema и PriorityLevelConfiguration (или использовать опциональный уровень приоритета global-default, доступный по умолчанию). Поскольку предполагается, что обязательный уровень приоритета catch-all будет использоваться редко, его доля параллелизма невысока, кроме того, он не ставит запросы в очередь.

Опциональные объекты конфигурации

Опциональные объекты FlowSchemas и PriorityLevelConfigurations образуют оптимальную конфигурацию по умолчанию. При желании их можно изменить и/или создать дополнительные объекты конфигурации. Если велика вероятность высокой нагрузки на кластер, следует решить, какая конфигурация будет работать лучше всего.

Опциональная конфигурация группирует запросы по шести уровням приоритета:

  • Уровень приоритета node-high предназначен для проверки здоровья узлов.

  • Уровень приоритета system предназначен для запросов от группы system:nodes, не связанных с состоянием узлов, а именно: от kubelet'ов, которые должны иметь возможность связываться с сервером API для планирования рабочих нагрузок.

  • Уровень приоритета leader-election предназначен для запросов на выборы лидера от встроенных контроллеров (в частности, запросы на объекты типа Endpoint, ConfigMap или Lease, поступающие от пользователей system:kube-controller-manager или system:kube-scheduler и служебных учетных записей в пространстве имен kube-system). Их важно изолировать от другого трафика, поскольку сбои при выборе лидеров приводят к перезагрузкам контроллеров. Соответственно, новые контроллеры потребляют трафик, синхронизируя свои информеры.

  • Уровень приоритета workload-high предназначен для прочих запросов от встроенных контроллеров.

  • Уровень приоритета workload-low предназначен для запросов от остальных учетных записей служб, которые обычно включают все запросы от контроллеров, работающих в Pod'ах.

  • Уровень приоритета global-default обрабатывает весь остальной трафик, например, интерактивные команды kubectl, выполняемые непривилегированными пользователями.

Опциональные FlowSchemas служат для направления запросов на вышеуказанные уровни приоритета и здесь не перечисляются.

Обслуживание обязательных и опциональных объектов конфигурации

Каждый kube-apiserver самостоятельно обслуживает обязательные и опциональные объекты конфигурации, используя стратегию начальных/периодических проходов. Таким образом, в ситуации с серверами разных версий может возникнуть пробуксовка (thrashing) из-за разного представления серверов о правильном содержании этих объектов.

Каждый kube-apiserver выполняет начальный проход по обязательным и опциональным объектам конфигурации, а затем периодически (раз в минуту) обходит их.

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

Обслуживание опциональных объектов конфигурации предусматривает возможность переопределения их спецификации (spec). Кроме того, удаление носит непостоянный характер: объект будет восстановлен в процессе обслуживания. Если опциональный объект конфигурации не нужен, его не нужно удалять, но достаточно настроить spec'и так, чтобы последствия были минимальными. Обслуживание опциональных объектов также рассчитано на поддержку автоматической миграции при выходе новой версии kube-apiserver, при этом вероятны конфликты (thrashing), пока группировка серверов остается смешанной.

Обслуживание опционального объекта конфигурации предусматривает его создание — с рекомендуемой спецификацией сервера — если тот не существует. В то же время, если объект уже существует, поведение при обслуживании зависит от того, кто им управляет — kube-apiserver'ы или пользователи. В первом случае сервер гарантирует, что спецификация объекта соответствует рекомендуемой; во втором случае спецификация не анализируется.

Чтобы узнать, кто управляет объектом, необходимо найти аннотацию с ключом apf.kubernetes.io/autoupdate-spec. Если такая аннотация существует и ее значение равно true, то объект контролируется kube-apiserver'ами. Если аннотация существует и ее значение равно false, объект контролируется пользователями. Если ни одно из этих условий не выполняется, выполняется обращение к metadata.generation объекта. Если этот параметр равен 1, объект контролируется kube-apiserver'ами. В противном случае объект контролируют пользователи. Эти правила были введены в версии 1.22, и использование metadata.generation обусловлено переходом от более простого предыдущего поведения. Пользователи, желающие контролировать опциональный объект конфигурации, должны убедиться, что его аннотация apf.kubernetes.io/autoupdate-spec имеет значение false.

Обслуживание обязательного или опционального объекта конфигурации также предусматривает проверку наличия у него аннотации apf.kubernetes.io/autoupdate-spec, которая позволяет понять, контролируют ли его kube-apiserver'ы.

Обслуживание также предусматривает удаление объектов, которые не являются ни обязательными, ни опциональными, но имеют аннотацию apf.kubernetes.io/autoupdate-spec=true.

Освобождение проверок работоспособности от параллелизма

Опциональная конфигурация не предусматривает особого отношения к health check-запросам на kube-apiserver'ы от их локальных kubelet'ов. В данном случае обычно используется защищенный порт, но учетные данные не передаются. В опциональной конфигурации такие запросы относятся к FlowSchema global-default и соответствующему уровню приоритета global-default, где другой трафик может мешать их прохождению.

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

apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: FlowSchema
metadata:
  name: health-for-strangers
spec:
  matchingPrecedence: 1000
  priorityLevelConfiguration:
    name: exempt
  rules:
  - nonResourceRules:
    - nonResourceURLs:
      - "/healthz"
      - "/livez"
      - "/readyz"
      verbs:
      - "*"
    subjects:
    - kind: Group
      group:
        name: system:unauthenticated

Диагностика

Каждый HTTP-ответ от сервера API с включенной функцией РДА содержит два дополнительных заголовка: X-Kubernetes-PF-FlowSchema-UID и X-Kubernetes-PF-PriorityLevel-UID. В них указываются схема потока и уровень приоритета соответственно. Имена объектов API не включаются в эти заголовки на случай, если запрашивающий пользователь не обладает правами на их просмотр, поэтому при отладке можно использовать команду типа:

kubectl get flowschemas -o custom-columns="uid:{metadata.uid},name:{metadata.name}"
kubectl get prioritylevelconfigurations -o custom-columns="uid:{metadata.uid},name:{metadata.name}"

чтобы привязать UID к именам для FlowSchemas и PriorityLevelConfigurations.

Наблюдаемость

Метрики

При включении функции равноправного доступа к API kube-apiserver начинает экспортировать дополнительные метрики. Их мониторинг помогает выявить негативное влияние (throttling) текущей конфигурации на важный трафик или найти неэффективные рабочие нагрузки, которые вредят здоровью системы.

  • apiserver_flowcontrol_rejected_requests_total — вектор-счетчик (кумулятивный с момента запуска сервера) запросов, которые были отклонены, с разбивкой по лейблам flow_schema (указывает на FlowSchema у запросов, попавших под соответствие), priority_level (уровень приоритета, который был присвоен этим запросам) и reason. Лейбл reason будет иметь одно из следующих значений:

    • queue-full — в очереди уже слишком много запросов;
    • concurrency-limit — PriorityLevelConfiguration настроена на отклонение, а не на постановку в очередь избыточных запросов;
    • time-out — запрос все еще находился в очереди, когда истек его лимит ожидания.
  • apiserver_flowcontrol_dispatched_requests_total — вектор-счетчик (кумулятивный с момента запуска сервера) запросов, которые начали выполняться, сгруппированный по лейблам flow_schema (указывает на FlowSchema у запросов, попавших под соответствие) и priority_level (уровень приоритета, который был присвоен этим запросам).

  • apiserver_current_inqueue_requests — вектор предыдущего максимума числа запросов в очереди, сгруппированных по лейблу request_kind, значение которого mutating или readOnly. Эти максимумы описывают наибольшее число, наблюдавшееся в последнем завершенном односекундном окне. Они дополняют более старый вектор apiserver_current_inflight_requests, который показывает максимум активно обслуживаемых запросов в последнем окне.

  • apiserver_flowcontrol_read_vs_write_request_count_samples — вектор-гистограмма наблюдений за тогда-текущим количеством запросов с разбивкой по лейблам phase (принимает значения waiting и executing) и request_kind (принимает значения mutating и readOnly). Наблюдения проводятся периодически с высокой частотой. Каждое наблюдаемое значение представляет собой число в диапазоне от 0 до 1, равное отношению числа запросов к соответствующему ограничению на их количество (ограничение длины очереди в случае ожидания и лимит параллелизма в случае выполнения).

  • apiserver_flowcontrol_read_vs_write_request_count_watermarks — вектор-гистограмма максимумов или минимумов количества запросов (число запросов, деленное на соответствующее ограничение) с разбивкой по лейблам phase (принимает значения waiting и executing) и request_kind (принимает значения mutating и readOnly); лейбл mark принимает значения high и low. Минимумы и максимумы собираются в окнах, ограниченных временем, когда наблюдение было добавлено в apiserver_flowcontrol_read_vs_write_request_count_samples. Эти экстремумы помогают определить разброс диапазона значений, наблюдавшийся в разных сэмплах.

  • apiserver_flowcontrol_current_inqueue_requests — gauge-вектор, содержащий количество стоящих в очереди (не выполняющихся) запросов в каждый момент с разбивкой по лейблам priority_level и flow_schema.

  • apiserver_flowcontrol_current_executing_requests — gauge-вектор, содержащий количество исполняемых (не ожидающих в очереди) запросов в каждый момент с разбивкой по лейблам priority_level и flow_schema.

  • apiserver_flowcontrol_request_concurrency_in_use — gauge-вектор, содержащий количество занятых мест в каждый момент с разбивкой по лейблам priority_level и flow_schema.

  • apiserver_flowcontrol_priority_level_request_count_samples — вектор-гистограмма наблюдений за текущим-на-тот-момент количеством запросов с разбивкой по лейблам phase (принимает значения waiting и executing) и priority_level. Каждая гистограмма получает наблюдения, сделанные периодически, вплоть до последней активности соответствующего рода. Наблюдения проводятся с высокой частотой. Каждое наблюдаемое значение представляет собой число в диапазоне от 0 до 1, равное отношению числа запросов к соответствующему ограничению на их количество (ограничение длины очереди в случае ожидания и лимит параллелизма в случае выполнения).

  • apiserver_flowcontrol_priority_level_request_count_watermarks — вектор-гистограмма максимумов или минимумов количества запросов с разбивкой по лейблам phase (принимает значения waiting и executing) и priority_level; лейбл mark принимает значения high и low. Минимумы и максимумы собираются в окнах, ограниченных временем, когда наблюдение было добавлено в apiserver_flowcontrol_priority_level_request_count_samples. Эти экстремумы показывают диапазон значений, наблюдавшийся в разных сэмплах.

  • apiserver_flowcontrol_priority_level_seat_count_samples — вектор-гистограмма наблюдений за использованием лимита параллелизма для уровня приоритета с разбивкой по priority_level. Использование — отношение (количество занятых мест) / (предел параллелизма). Метрика учитывает все стадии выполнения (как обычную, так и дополнительную задержку в конце записи для покрытия соответствующей работы по уведомлению) всех запросов, кроме WATCHes; для этих запросов учитывается только начальная стадия по доставке уведомлений о ранее существующих объектах. Каждая гистограмма в векторе также помечена лейблом phase: executing (количество мест для фазы ожидания не ограничено). Каждая гистограмма получает наблюдения, сделанные периодически, вплоть до последней активности соответствующего рода. Наблюдения производятся с высокой частотой.

  • apiserver_flowcontrol_priority_level_seat_count_watermarks — вектор-гистограмма минимумов и максимумов использования предела параллелизма для уровня приоритета с разбивкой по priority_leve и mark (принимает значения high и low). Каждая гистограмма в векторе также помечена лейблом phase: executing (для фазы ожидания предел на места отсутствует). Максимумы и минимумы собираются в окнах, ограниченных временем, когда наблюдение было добавлено в apiserver_flowcontrol_priority_level_seat_count_samples. Эти экстремумы помогают определить разброс диапазона значений, наблюдавшийся в разных сэмплах.

  • apiserver_flowcontrol_request_queue_length_after_enqueue — вектор-гистограмма длины очереди для очередей с разбивкой по лейблам priority_level и flow_schema как выборки по поставленным в очередь запросам. Каждый запрос при постановке в очередь вносит один сэмпл в гистограмму, сообщая о длине очереди сразу после добавления запроса. Обратите внимание, что это дает иную статистику, чем при объективном исследовании.

  • apiserver_flowcontrol_request_concurrency_limit — gauge-вектор, содержащий вычисленный лимит параллелизма (основанный на общем лимите параллелизма сервера API и долях параллелизма PriorityLevelConfigurations), с разбивкой по лейблу priority_level.

  • apiserver_flowcontrol_request_wait_duration_seconds — вектор-гистограмма времени ожидания запросов в очереди с разбивкой по лейблам flow_schema (указывает, какая схема соответствует запросу), priority_level (указывает, к какому уровню был отнесен запрос) и execute (указывает, начал ли запрос выполняться).

  • apiserver_flowcontrol_request_execution_seconds — вектор-гистограмма времени, затраченного на выполнение запросов, с разбивкой по по лейблам flow_schema (указывает, какая схема соответствует запросу) и priority_level (указывает, к какому уровню был отнесен запрос).

  • apiserver_flowcontrol_watch_count_samples — вектор-гистограмма количества активных запросов WATCH, относящихся к данной записи, с разбивкой по flow_schema и priority_level.

  • apiserver_flowcontrol_work_estimated_seats — вектор-гистограмма количества предполагаемых мест (максимум начального и конечного этапа выполнения), связанных с запросами, с разбивкой по flow_schema и priority_level.

  • apiserver_flowcontrol_request_dispatch_no_accommodation_total — вектор-счетчик количества событий, которые в принципе могли бы привести к отправке запроса, но не привели из-за отсутствия доступного параллелизма, с разбивкой по flow_schema и priority_level. Соответствующими событиями являются поступление запроса и завершение запроса.

Отладочные endpoint'ы

При включении функции равноправного доступа к API kube-apiserver предоставляет следующие дополнительные пути на своих HTTP[S]-портах.

  • /debug/api_priority_and_fairness/dump_priority_levels — список всех уровней приоритета и текущее состояние каждого из них. Получить его можно следующим образом:

    kubectl get --raw /debug/api_priority_and_fairness/dump_priority_levels
    

    Вывод выглядит примерно так:

    PriorityLevelName, ActiveQueues, IsIdle, IsQuiescing, WaitingRequests, ExecutingRequests,
    workload-low,      0,            true,   false,       0,               0,
    global-default,    0,            true,   false,       0,               0,
    exempt,            <none>,       <none>, <none>,      <none>,          <none>,
    catch-all,         0,            true,   false,       0,               0,
    system,            0,            true,   false,       0,               0,
    leader-election,   0,            true,   false,       0,               0,
    workload-high,     0,            true,   false,       0,               0,
    
  • /debug/api_priority_and_fairness/dump_queues — список всех очередей и их текущее состояние. Получить его можно следующим образом:

    kubectl get --raw /debug/api_priority_and_fairness/dump_queues
    

    Вывод выглядит примерно так:

    PriorityLevelName, Index,  PendingRequests, ExecutingRequests, VirtualStart,
    workload-high,     0,      0,               0,                 0.0000,
    workload-high,     1,      0,               0,                 0.0000,
    workload-high,     2,      0,               0,                 0.0000,
    ...
    leader-election,   14,     0,               0,                 0.0000,
    leader-election,   15,     0,               0,                 0.0000,
    
  • /debug/api_priority_and_fairness/dump_requests — список всех запросов, которые в настоящее время ожидают в очереди. Получить его можно следующим образом:

    kubectl get --raw /debug/api_priority_and_fairness/dump_requests
    

    Вывод выглядит примерно так:

    PriorityLevelName, FlowSchemaName, QueueIndex, RequestIndexInQueue, FlowDistingsher,       ArriveTime,
    exempt,            <none>,         <none>,     <none>,              <none>,                <none>,
    system,            system-nodes,   12,         0,                   system:node:127.0.0.1, 2020-07-23T15:26:57.179170694Z,
    

    В дополнение к запросам, стоящим в очереди, вывод включает одну фантомную строку для каждого уровня приоритета, на которую не распространяется ограничение.

    Более подробный список можно получить с помощью следующей команды:

    kubectl get --raw '/debug/api_priority_and_fairness/dump_requests?includeRequestDetails=1'
    

    Вывод выглядит примерно так:

    PriorityLevelName, FlowSchemaName, QueueIndex, RequestIndexInQueue, FlowDistingsher,       ArriveTime,                     UserName,              Verb,   APIPath,                                                     Namespace, Name,   APIVersion, Resource, SubResource,
    system,            system-nodes,   12,         0,                   system:node:127.0.0.1, 2020-07-23T15:31:03.583823404Z, system:node:127.0.0.1, create, /api/v1/namespaces/scaletest/configmaps,
    system,            system-nodes,   12,         1,                   system:node:127.0.0.1, 2020-07-23T15:31:03.594555947Z, system:node:127.0.0.1, create, /api/v1/namespaces/scaletest/configmaps,
    

Что дальше

Для получения подробной информации о функции равноправного доступа к API см. предложение по улучшению (KEP). Предложения и запросы функционала принимаются через SIG API Machinery или в специализированном канале Slack.

8 - Установка дополнений

Надстройки расширяют функциональность Kubernetes.

На этой странице перечислены некоторые из доступных надстроек и ссылки на соответствующие инструкции по установке.

Сеть и сетевая политика

  • ACI обеспечивает интегрированную сеть контейнеров и сетевую безопасность с помощью Cisco ACI.
  • Antrea работает на уровне 3, обеспечивая сетевые службы и службы безопасности для Kubernetes, используя Open vSwitch в качестве уровня сетевых данных.
  • Calico Calico поддерживает гибкий набор сетевых опций, поэтому вы можете выбрать наиболее эффективный вариант для вашей ситуации, включая сети без оверлея и оверлейные сети, с или без BGP. Calico использует тот же механизм для обеспечения соблюдения сетевой политики для хостов, модулей и (при использовании Istio и Envoy) приложений на уровне сервисной сети (mesh layer).
  • Canal объединяет Flannel и Calico, обеспечивая сеть и сетевую политику.
  • Cilium - это плагин сети L3 и сетевой политики, который может прозрачно применять политики HTTP/API/L7. Поддерживаются как режим маршрутизации, так и режим наложения/инкапсуляции, и он может работать поверх других подключаемых модулей CNI.
  • CNI-Genie позволяет Kubernetes легко подключаться к выбору плагинов CNI, таких как Calico, Canal, Flannel, Romana или Weave.
  • Contrail, основан на Tungsten Fabric, представляет собой платформу для виртуализации мультиоблачных сетей с открытым исходным кодом и управления политиками. Contrail и Tungsten Fabric интегрированы с системами оркестрации, такими как Kubernetes, OpenShift, OpenStack и Mesos, и обеспечивают режимы изоляции для виртуальных машин, контейнеров/подов и рабочих нагрузок без операционной системы.
  • Flannel - это поставщик оверлейной сети, который можно использовать с Kubernetes.
  • Knitter - это плагин для поддержки нескольких сетевых интерфейсов Kubernetes подов.
  • Multus - это плагин Multi для работы с несколькими сетями в Kubernetes, который поддерживает большинство самых популярных CNI (например: Calico, Cilium, Contiv, Flannel), в дополнение к рабочим нагрузкам основанных на SRIOV, DPDK, OVS-DPDK и VPP в Kubernetes.
  • OVN-Kubernetes - это сетевой провайдер для Kubernetes основанный на OVN (Open Virtual Network), реализация виртуальной сети, появившийся в результате проекта Open vSwitch (OVS). OVN-Kubernetes обеспечивает сетевую реализацию на основе наложения для Kubernetes, включая реализацию балансировки нагрузки и сетевой политики на основе OVS.
  • OVN4NFV-K8S-Plugin - это подключаемый модуль контроллера CNI на основе OVN для обеспечения облачной цепочки сервисных функций (SFC), несколько наложенных сетей OVN, динамического создания подсети, динамического создания виртуальных сетей, сети поставщика VLAN, сети прямого поставщика и подключаемого к другим Multi Сетевые плагины, идеально подходящие для облачных рабочих нагрузок на периферии в сети с несколькими кластерами.
  • NSX-T плагин для контейнера (NCP) обеспечивающий интеграцию между VMware NSX-T и контейнерами оркестраторов, таких как Kubernetes, а так же интеграцию между NSX-T и контейнеров на основе платформы CaaS/PaaS, таких как Pivotal Container Service (PKS) и OpenShift.
  • Nuage - эта платформа SDN, которая обеспечивает сетевое взаимодействие на основе политик между Kubernetes подами и не Kubernetes окружением, с отображением и мониторингом безопасности.
  • Romana - это сетевое решение уровня 3 для сетей подов, которое также поддерживает NetworkPolicy API. Подробности установки Kubeadm доступны здесь.
  • Weave Net предоставляет сеть и обеспечивает сетевую политику, будет работать на обеих сторонах сетевого раздела и не требует внешней базы данных.

Обнаружение служб

  • CoreDNS - это гибкий, расширяемый DNS-сервер, который может быть установлен в качестве внутрикластерного DNS для подов.

Визуализация и контроль

  • Dashboard - это веб-интерфейс панели инструментов для Kubernetes.

Инфраструктура

  • KubeVirt - это дополнение для запуска виртуальных машин в Kubernetes. Обычно работает на bare-metal кластерах.

Legacy Add-ons

В устаревшем каталоге cluster/addons задокументировано несколько других дополнений.

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