Руководство по системному администрированию#

Термины и определения#

Термин/Аббревиатура

Определение

Node

Нода — единица Kubernetes, предоставляющая среду для работы контейнеров

Лимит

Максимальный объем ресурсов, который выдается на работу сервиса

Реквест

Объем ресурсов, который необходим для запуска приложения

Платформа

Платформа оркестрации приложений со средствами автоматизации и управления на основе политик, например, Kubernetes

Istio SE

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

Контрольная панель

Проект, где запущены управляющие приложения

Deployment/Деплоймент

Набор инструкций для запуска приложения в Kubernetes

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

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

Граничный прокси / IGEG

Компонент Граничный прокси

Сервисный прокси / SVPX

Компонент Сервисный прокси

Pod

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

Istio SE

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

Liveness-проба

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

Readiness-проба

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

Secret

Объект, предназначенный для хранения конфиденциальной информации

Назначение документа#

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

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

Ниже приведены возможные сценарии администрирования, как с использованием веб-интерфейcа Kubernetes, так и с использованием консоли клиента Kubernetes (kubectl). Название deployment/pod: istiod.

Сценарии администрирования#

Требования к набору привилегий администратора Kubernetes в части выполнения сценариев, перечисленных ниже: для установки и настройки POLM необходимы как минимум права, описанные в роли role, или же права роли cluster-admin, стандартная роль платформы Kubernetes.

Запуск#

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

С использованием веб-интерфейса Kubernetes#

Шаг

Действие

Вход в веб-консоль Kubernetes

Перейдите по ссылке (URL) веб-консоли нужного кластера Kubernetes, в окне ввода учетных данных введите токен пользователя или kubeconfig

Переход в нужный проект

Выберите нужный проект можно в выпадающем списке в шапке веб-интерфейса Kubernetes

Запуск pod

1. В меню выберите пункт Workload/Deployments.
2. На странице найдите нужный Deployment (можно использовать поиск по имени).
3. Нажмите ⋮ и выберите Scale ;
4. Задайте нужное количество pods и нажмите Scale

Выход из веб-консоли Kubernetes

1. Щелкните по имени пользователя, чтобы раскрыть меню учетной записи.
2. Выберите пункт Log out.
3. Закройте окно браузера

С использованием консоли Kubernetes#

Шаг

Действие

Вход в клиент Kubernetes

Запросите у администратора кластера kubeconfig для kubectl

Запуск компонента

В консоли выполните команду: kubectl --kubeconfig=<путь_к_файлу_kubeconfig> scale --replicas=<N> deployment/<имя deployment>,
где: N>0 — требуемое количество запущенных pods

Остановка#

С использованием веб-интерфейса Kubernetes#

Шаг

Действие

Логин в веб-консоль Kubernetes

Перейдите по ссылке (URL) веб-консоли нужного кластера Kubernetes, в окне ввода учетных данных введите токен пользователя или kubeconfig

Переход в нужный проект

Выберите нужный проект в выпадающем списке в шапке веб-интерфейса Kubernetes

Остановка компонента

Выполните следующие действия:
1. В меню выберите пункт Workload/Deployments .
2. На странице найдите нужный Deployment (при необходимости воспользоваться поиском по имени).
3. Нажмите ⋮ и выберите Scale .
4. Уменьшите количество pods до 0 и нажмите Scale

Выход из веб-консоли Kubernetes

Выполните следующие действия:
1. Кликом по иконке пользователя раскройте меню.
2. Выберите пункт Sign out .
3. Закройте окно браузера

С использованием консоли Kubernetes#

Шаг

Действие

Запросить kubeconfig для kubectl

Запросите у администратора кластера kubeconfig для kubectl

Остановка компонента

В консоли выполните команду: kubectl --kubeconfig=<путь_к_файлу_kubeconfig> scale --replicas=0 deployment/<имя deployment>

Настройка выделения ресурсов#

С использованием веб-интерфейса Kubernetes#

Шаг

Действие

Логин в веб-консоль Kubernetes

Перейдите по ссылке (URL) веб-консоли нужного кластера Kubernetes, в окне ввода учетных данных введите токен пользователя или kubeconfig

Переход в проект

Выберите нужный проект в выпадающем списке в шапке веб-интерфейса Kubernetes

Вход в Deployment

Выполните следующие действия:
1. В меню выберите пункт Workload/Deployments.
2. На странице найдите нужный Deployment (при необходимости воспользоваться поиском по имени).
3. Перейдите по ссылке в наименовании ⋮ , выберите Edit, перейдите на вкладку YAML или JSON

Корректировка параметров

Выполните следующие действия:
1. В окне редактирования найдите параметры:
spec.template.spec.containers[0].resources.limits.cpu
spec.template.spec.containers[0].resources.limits.memory
spec.template.spec.containers[0].resources.requests.cpu
spec.template.spec.containers[0].resources.requests.memory
2. Установите нужные значения

Сохранение

Нажмите кнопку Update

Проверка конфигурации

Снова зайдите на вкладку Edit в YAML или JSON

Выход из веб-консоли Kubernetes

Выполните следующие действия:
1. Кликом по иконке пользователя раскройте меню.
2. Выберите пункт Sign out.
3. Закройте окно браузера

Также можно менять ресурсы в конфигурации Istio Operator (если есть доступ к этому ресурсу).

Шаг

Действие

Логин в веб-консоль Kubernetes

Перейдите по ссылке (URL) веб-консоли нужного кластера Kubernetes, в окне ввода учетных данных введите токен пользователя или kubeconfig

Переход в проект

Выберите нужный проект в выпадающем списке в шапке веб-интерфейса Kubernetes

Открытие Istio Operator

Выполните следующие действия:
1. В меню выберите пункт Custom Resource Definitions.
2. На странице найдите Istio Operator (при необходимости воспользуйтесь поиском по имени).
3. Перейдите по ссылке и на странице найдите в блоке Objects ресурс, создавший контрольную панель.
4. Перейдите по ссылке этого ресурса и нажмите символ пера для редактирования

Корректировка параметров

В окне редактирования по пути spec.values.pilot.resources.limits.cpu, spec.values.pilot.resources.limits.memory, spec.values.pilot.resources.requests.cpu и spec.values.pilot.resources.requests.memory задайте значения лимитов и requests для CPU и Memory, соответственно.
Для ingress- и egressgateway ресурсы задаются по путям spec.values.gateways.istio-ingressgateway.sds.resources.limits.cpu, spec.values.gateways.istio-ingressgateway.sds.resources.limits.memory, spec.values.gateways.istio-ingressgateway.sds.resources.requests.cpu и spec.values.gateways.istio-ingressgateway.sds.resources.requests.memory для ingress и spec.values.gateways.istio-egressgateway.sds.resources.limits.cpu, spec.values.gateways.istio-egressgateway.sds.resources.limits.memory, spec.values.gateways.istio-egressgateway.sds.resources.requests.cpu и spec.values.gateways.istio-egressgateway.sds.resources.requests.memory для egress

Сохранение

Нажмите кнопку Update

Проверка конфигурации

Зайдите в нужный проект и проверьте deployments затрагиваемых компонентов

Выход из веб-консоли Kubernetes

Выполните следующие действия:
1. Кликом по иконке пользователя раскройте меню.
2. Выберите пункт Sign out.
3. Закройте окно браузера

Настройка выделения ресурсов сервисных прокси на уровне кластера#

В настройках контрольной панели можно задать ресурсы, проставляемые сервисным proxy при inject их в прикладные pods.

Через конфигурацию Istio Operator (если к нему есть доступ)#

Шаг

Действие

Логин в веб-консоль Kubernetes

Перейдите по ссылке (URL) веб-консоли нужного кластера Kubernetes, в окне ввода учетных данных введите токен пользователя или kubeconfig

Переход в проект

Выберите нужный проект в выпадающем списке в шапке веб-интерфейса Kubernetes

Открытие Istio Operator

Выполните следующие действия:
1. В меню выберите пункт Custom Resource Definitions
2. На странице найдите Istio Operator (при необходимости воспользуйтесь поиском по имени).
3. Перейдите по ссылке и на странице найдите в блоке Objects ресурс, создавший контрольную панель.
4. Перейдите по ссылке этого ресурса и нажмите символ пера для редактирования

Корректировка параметров

В окне редактирования по пути spec.global.proxy.resources.limits.cpu, spec.global.proxy.resources.limits.memory, spec.global.proxy.resources.requests.cpu и spec.global.proxy.resources.requests.memory задайте значения для лимитов и requests по CPU и Memory, соответственно

Сохранение

Кликните по кнопке Update

Проверка конфигурации

Зайдите в нужный проект и проверьте pods затрагиваемых компонентов

Выход из веб-консоли Kubernetes

Выполните следующие действия:
1. Кликом по иконке пользователя раскройте меню.
2. Выберите пункт Sign out.
3. Закройте окно браузера

Через ConfigMap (istio-sidecar-injector)#

Шаг

Действие

Логин в веб-консоль Kubernetes

Перейдите по ссылке (URL) веб-консоли нужного кластера Kubernetes, в окне ввода учетных данных введите токен пользователя или kubeconfig

Переход в проект

Выберите нужный проект в выпадающем списке в шапке веб-интерфейса Kubernetes

Открытие ConfigMap

Выполните следующие действия:
1. В меню выберите пункт Config and Storage/ConfigMaps.
2. На странице найдите нужный ConfigMap

Корректировка параметров

В окне редактирования по пути spec.global.proxy.resources.limits.cpu, spec.global.proxy.resources.limits.memory, spec.global.proxy.resources.requests.cpu и spec.global.proxy.resources.requests.memory задайте значения для лимитов и реквестов по CPU и Memory, соответственно

Сохранение

Кликните по кнопке Update

Проверка конфигурации

Зайдите в нужный проект и проверьте pods затрагиваемых компонентов

Выход из веб-консоли Kubernetes

Выполните следующие действия:
1. Кликом по иконке пользователя раскройте меню.
2. Выберите пункт Sign out.
3. Закройте окно браузера

Подключение для пользовательского проекта возможности автоматического добавления (inject) сервисного прокси#

Контрольную панель (Управление политиками) можно установить как с spec.revision, так и без данной настройки. От этого зависит также то, какие labels необходимо добавлять пользовательским проектам.

Обеспечение сетевого доступа к проекту Контрольной панели (Управления политиками)#

Так как Граничные прокси и Сервисные прокси напрямую по имени сервиса подключаются к сервису Управление политиками, то необходимо, чтобы между прикладными проектами пользователей и проектом контрольной панели была сетевая доступность.

Сделать ее можно, в том числе, с помощью такой конфигурации:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: istio-mesh
spec:
  podSelector: {}
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              istio.io/rev: <label_из_значения_revision>
  policyTypes:
    - Ingress

Создание конфигурации NetworkAttachmentDefinition при использовании CNI Multus#

В прикладных проектах при использовании Istio CNI Plugin необходимо создать конфигурацию NetworkAttachmentDefinition, для того чтобы Multus использовал Istio CNI Plugin для настройки сети pod.

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: istio-cni

С использованием настройки ревизии#

При использовании spec.revision пользовательскому проекту необходимо добавить label istio.io/rev=<значение_поля_revision_из_конфигурации_IstioOperator>.

Если у пользовательского проекта есть label istio-injection, то его необходимо удалить.

Для удаления у проекта возможности автоматического inject сервисного proxy достаточно удалить label istio.io/rev.

Без использования настройки ревизии#

По умолчанию, без использования spec.revision, все проекты подключаются к контрольной панели (Управление политиками). Но для подключения к пользовательскому проекту возможности автоматического добавление (inject) istio-proxy sidecar (компонент Сервисный прокси) необходимо добавить в этот проект label istio-injection=enabled. Сделать это может администратор проекта с помощью команды:

kubectl --kubeconfig=<путь_к_конфигурационному_файлу_kubeconfig> label namespace <имя_проекта> istio-injection=enabled

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

  1. Зайдите в проект контрольной панели.

  2. В меню выберите пункт Cluster/Namespaces.

  3. На странице найдите нужный проект.

  4. У этого проекта нажмите на и выберите Edit.

  5. Добавьте label по пути metadata.labels и нажмите Update.

Для удаления у проекта возможности автоматического inject сервисного proxy достаточно удалить созданный ранее label или проставить вместо значения enabled значение disabled.

В случае с пользовательским интерфейсом удаление ничем не отличается от добавления, а в случае консоли необходимо выполнить следующую команду:

  • для изменения текущего значение label:

    kubectl --kubeconfig=<путь_к_конфигурационному_файлу_kubeconfig> label namespace <имя_проекта> istio-injection=disabled --overwrite!

  • для удаления существующего label:

    kubectl --kubeconfig=<путь_к_конфигурационному_файлу_kubeconfig> label namespace <имя_проекта> istio-injection-

Подключение проекта при использовании discoverySelectors#

При использовании spec.meshConfig.discoverySelectors необходимо добавлять в пользовательские проекты labels, соответствующие настройке spec.meshConfig.discoverySelectors.

Если была также использована настройка spec.revision, то пользовательскому проекту необходимо добавить label istio.io/rev=<значение_поля_revision_из_конфигурации_IstioOperator>. Поэтому удобнее будет задавать в Istio Operator spec.meshConfig.discoverySelectors как istio.io/rev=<значение_поля_revision_из_конфигурации_IstioOperator>. Тогда будет необходимо добавить только один label на пользовательский проект.

Для удаления пользовательского проекта из Контрольной панели необходимо удалить у данного проекта labels, соответствующие настройке spec.meshConfig.discoverySelectors.

Дополнительные примеры кастомизации Istio Operator#

Общий пример для кастомизации компонентов#

Можно кастомизировать некоторые ресурсы из блока spec.components.<название_компонента>.

К примеру, можно менять ресурсы env и affinity: spec.components.<название_компонента>.k8s.resources, spec.components.<название_компонента>.k8s.env или spec.components.<название_компонента>.k8s.affinity, соответственно.

Как использовать k8s.overlays#

В конфигурации IstioOperator для блока spec.components.<название_компонента> можно использовать spec.components.<название_компонента>.k8s.overlays - это структура, позволяющая применять JSON Patch операции к устанавливаемым Istio Operator конфигурациям. Удобно использовать в том случае, если других параметров кастомизации не хватает.

Поле

Тип

Описание

Обязательность

apiVersion

строка

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

Нет

kind

строка

Поле kind изменяемой конфигурации

Нет

name

строка

Имя (поле [metadata.name][2])изменяемой конфигурации

Нет

patches

PathValue[]

Лист Json Patch для применения

Нет

PathValue состоит из двух значений:

  • Path - это путь к полю в конфигурации, который задается в форме a.[key1:value1].b.[:value2], где [key1:value1]— это селектор для ключ-значение, позволяющий идентифицировать элемент в массиве;

  • Value - значение в поле конфигурации, которое необходимо удалить, добавить или обновить. Если поля, найденного через переменную path нет, то оно будет создано со значением из value. Найденное поле есть — значение будет изменено. Для удаления существующего поля необходимо не задавать значение value. Все значения третируются как строки.

Пример:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
  components:
    ...
    <имя_компонента>:
      enabled: true
      k8s:
        overlays:
          - kind: Deployment
            name: <имя_deployment_istiod>
            patches:
                # Удлаяем env с именем (name) CLUSTER_ID из контейнера с именем (name) discovery
              - path: spec.template.spec.containers[name:discovery].env[name:CLUSTER_ID]
                # Добавляем или перезаписываем env с именем (name) PILOT_ENABLE_ANALYSIS из контейнера с именем (name) discovery
              - path: spec.template.spec.containers[name:discovery].env[name:PILOT_ENABLE_ANALYSIS].value
                value: 'true'
    ...

Изменение значения initialDelaySeconds для Управления политиками#

Иногда значения initialDelaySeconds readinessProbe контейнера discovery недостаточно (значение по умолчанию - 10). Задать новое значение можно через k8s.overlays. Сделать это можно двумя способами:

  1. Через имя контейнера:

    apiVersion: install.istio.io/v1alpha1 kind: IstioOperator … spec: components: … pilot: enabled: true k8s: overlays: - kind: Deployment name: <имя_deployment_istiod> patches: - path: spec.template.spec.containers[name:discovery].readinessProbe.initialDelaySeconds value: 120

  1. Через индекс контейнера (индекс контейнера discovery = 0):

    apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: components: … pilot: enabled: true k8s: overlays: - kind: Deployment name: <имя_deployment_istiod> patches: - path: spec.template.spec.containers[0].readinessProbe.initialDelaySeconds value: 120

Стоит учесть, что при установке istiod Istio Operator проверяет готовность pod istiod, проверяя статус readiness. Проверка идет в рамках env Istio Operator - WAIT_FOR_RESOURCES_TIMEOUT (значение по умолчанию — 300 секунд). Если значение initialDelaySeconds istiod будет превышать значение env WAIT_FOR_RESOURCES_TIMEOUT Istio Operator, то статус установки компонента pilot будет считаться неуспешным, что будет отображено в конфигурации IstioOperator, но при этом сам компонент будет установлен успешно.

Как задавать env для Управления политиками#

Для того чтобы задать новый env для istiod — сервиса Управления политиками, необходимо добавить его в spec.values.pilot.env.

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
  ...
  values:
    ...
    pilot:
      env:
        <имя_env>: <значение_env>
    ...

Для того чтобы удалить значение одного из env для istiod, который проставляется по умолчанию, необходимо добавить его в spec.components.pilot.k8s.overlays, прописав путь (path) к переменной и оставить пустым значение value.

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
  components:
    ...
    pilot:
      enabled: true
      k8s:
        overlays:
          - kind: Deployment
            name: <имя_деплоймента_istiod>
            patches:
              - path: spec.template.spec.containers[name:discovery].env[name:<имя_env>]

Для того чтобы поменять значение одного из env для istiod, который проставляется по умолчанию, необходимо добавить его в spec.components.pilot.k8s.overlays, прописав путь (path) к переменной и задать новое значение в value.

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
  components:
    ...
    pilot:
      enabled: true
      k8s:
        overlays:
          - kind: Deployment
            name: <имя_деплоймента_istiod>
            patches:
              - path: spec.template.spec.containers[name:discovery].env[name:<имя_env>].value
                value: <значение_env>

Как задать образы через sha256#

В конфигурации Istio Operator для сервиса Управления политиками, Сервисного и граничного прокси можно задавать ссылки на образы через хеш-сумму (sha256).

В случае сервиса Управления политиками (istiod) ссылка задается в spec.values.pilot.image. Для Граничного и Сервисного прокси (istio-proxy) - spec.values.global.proxy.image.

Пример такого конфигурационного файла:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
  values:
    ...
    pilot:
      image: <ссылка_на_докер_образ_istiod>
    ...
    global:
      proxy:
        image: <ссылка_на_докер_образ_istio-proxy>
    ...


Пример:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
  values:
    ...
    pilot:
      image: my.cloud.com/pilot@sha256:1234
    ...
    global:
      proxy:
        image: my.cloud.com/proxyv2@sha256:56789
    ...

Как задавать значение rewriteAppHTTPProbe#

Параметр rewriteAppHTTPProbe имеет булево значение. В значении true все liveness, readiness и startup пробы контейнера будут проходить через istio-proxy (Сервисный прокси). Это необходимо в том случае, когда на порт, по которому проходят пробы, настроено шифрование. В зависимости от того, какой профиль был выбран, значение rewriteAppHTTPProbe может быть уже проставлено как true, к примеру, в профиле default.

В конфигурации значение rewriteAppHTTPProbe задается в spec.values.sidecarInjectorWebhook.rewriteAppHTTPProbe. Пример:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
  ...
  values:
    ...
    sidecarInjectorWebhook:
      rewriteAppHTTPProbe: true

Значение rewriteAppHTTPProbers также может быть задано на уровне пользователя, путем добавления аннотации [sidecar.istio.io/rewriteAppHTTPProbers][3] в pod прикладного сервиса.

Слияние пользовательских метрик с метриками istio-proxy#

По умолчанию метрики istio-proxy сливаются с прикладными метриками пользовательских приложений. Доступ к объединенным метрика доступен по endpoint :15020/stats/prometheus.

Отключить такое поведение можно на уровне SVPX, проставив в аннотациях pod следующее значение:

prometheus.istio.io/merge-metrics: 'false'

Или же сделать это глобально (для всех data plane), выставив следующую настройку в конфигурации IstioOperator, с помощью которой устанавливалась контрольная панель:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
  ...
  meshConfig:
    ...
    enablePrometheusMerge: false

Пример использования lifecycle.prestop#

В конфигурации IstioOperator можно также задавать параметры для Сервисного прокси в блоке spec.values.global.lifecycle.prestop. В данном блоке можно задать логику, которая будет обрабатываться при удалении pod.

При добавлении в pod аннотации [sidecar.istio.io/prestop_sleep_envoy_duration][4] задается значение в секундах, в течение которого контейнер istio-proxy не будет завершать свою работу, получив сигнал о завершении работы (будет вызвана команда sleep). Если же аннотации нет, то значение будет проставлено как 0.

Пример:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
  ...
  values:
    global:
      ...
      proxy:
        lifecycle:
          preStop:
            exec:
              command:
                - /bin/sh
                - '-c'
                - >- PRESTOP_SLEEP=$(cat /etc/istio/pod/annotations | grep -oP 'sidecar.istio.io/prestop_sleep_envoy_duration=\K.*' | sed -e 's/^"//' -e 's/"$//') ; if [ ! -z "$PRESTOP_SLEEP" ] ; then sleep $PRESTOP_SLEEP ; fi
    ...

Пример использования Horizontal Pod Autoscalling (HPA) и проставления количества реплик для сервиса Управления политиками#

В некоторых профилях по умолчанию задано использование HPA для istiod (сервиса Управления политиками). Включить или выключить его можно по пути spec.values.pilot.autoscaleEnabled, по путям spec.values.pilot.autoscaleMin и spec.values.pilot.autoscaleMax задаются значения максимального и минимального количества реплик. Для включения HPA необходимо задать сразу все эти параметры.

Пример выключения HPA:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
  ...
  values:
    pilot:
      autoscaleEnabled: false

Пример включения HPA:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
  ...
  values:
    pilot:
      autoscaleEnabled: true
      autoscaleMin: <минимальное_количество_реплик>
      autoscaleMax: <максимальное_количество_реплик>

Задать конкретное количество реплик для istiod (сервиса Управления политиками) можно путем проставления значения в блоке spec.values.pilot.replicaCount.

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
  ...
  values:
    pilot:
      replicaCount: <количество_реплик>

Предварительная валидация пользовательских конфигураций#

В состав компонента POLM входит консольная утилита валидации конфигураций:

istioctl validate

где istioctl — исполняемый файл, клиент istioctl, поставляемый в дистрибутиве по пути ./istioctl

Флаги#

Для команды validate доступны следующие флаги:

  • -a, --additional

    включает дополнительную валидацию (проверки, добавленные в рамках доработки валидатора);

  • -f, --filename string

    после флага -f необходимо указать имя или путь к файлу, который мы хотим провалидировать, или "-" , если валидируем уже установленную в кластере конфигурацию и используем pipe. Пример:

    kubectl get services -o yaml | istioctl validate -a -f -
    

    Если нужно провалидировать несколько файлов, можно использовать несколько флагов -f:

    istioctl validate -a -f deployment.yml -f ../../ingress.yml -f virtualservice.yml
    
  • -k, --kuber

    включает проверки, которые требуют запроса в кластер (например, проверка отсутствия дублирования пары host\port в destinationRule). По умолчанию валидация происходит в текущем namespace контекста kubectl ;

  • -h, --help

    выводит подсказки по команде validate ;

  • -x, --referential

    включает структурную проверку для политики и телеметрии (включен по умолчанию);

  • -w, --write

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

Также есть глобальные флаги:

  • -n, --namespace

    для указания проекта, в котором будет происходить валидация (значение по умолчанию — текущий проект kubectl config);

  • -i, --istioNamespace

    проект с контрольной панелью (значение по умолчанию - istio-system);

  • –context

    имя контекста kubectl config ;

  • -v, --vklog

    номер уровня детализации логов. Например: --vklog=9

Типы валидируемых конфигураций#

Команда istioctl validate поддерживает следующие типы конфигураций:

  • Deployment

  • Sidecar

  • Service

  • Gateway

  • Virtual Service

  • Destination Rule

  • Envoy Filter

  • Service Entry

Правила валидации#

  1. Deployment:

  • Ingress и Egress должны иметь уникальное название в selector.matchLabels в значении app (например: ingress-название namespace), чтобы перехватываемый ими трафик не смешивался с другими Ingress и Egress в кластере;

  • значение Selector.MatchLabels не должно полностью содержаться в другом deployment этого проекта, и другие deployments проекта не должны содержать все Selector.MatchLabels текущего;

  • нельзя использовать аннотации и labels maistra.io/<любое значение> для ресурсов, созданных вручную, т.к. они означают, что ресурсы созданы и управляются Istio Operator. Во время ближайшего обновления ресурсы с этими аннотациями и labels будут перезаписаны или удалены оператором.

  1. Sidecar:

  • нельзя создавать Sidecar в namespace istio-system, т.к. в этом случае обновления из контрольной панели перестают приходить в pods подключенных к ней проектов.

  1. Service:

  • по требованиям безопасности нельзя использовать type: NodePort, type: LoadBalancer, так как использование этих настроек откроет прямой доступ к сервису извне кластера OpenShift;

  • должны присутствовать labels в поле spec.selector;

  • имя порта должно соответствовать маске <protocol>-* (например: http, http-8080, tcp, tcp-7575), т.к. правила распределения запросов применяются Istio к портам Service в соответствии с протоколом в имени порта;

  • нельзя использовать targetPort ниже 1024, т.к. он может быть занят служебными портами компонентов service mesh.

  1. Gateway:

  • значение labels spec.selector не должно полностью содержаться в другом gateway этого проекта, и другие gateways проекта не должны содержать все spec.selector текущего;

  • нельзя использовать port.number ниже 1024, т.к. он может быть занят служебными портами компонентов service mesh;

  • имя порта должно соответствовать маске <protocol>-* (например: http, http-8080, tcp, tcp-7575), т.к. правила распределения запросов применяются Istio к портам Gateway в соответствии с протоколом в имени порта;

  • конфигурация обязательно должна содержать поле spec.selector.

  1. Virtual Service:

  • проверяется уникальность spec.hosts + spec.[tcp/http/tls].match.gateways + spec.[tcp/http/tls].match.port, чтобы исключить перехватывание трафика на один host+port несколькими gateway;

  • допустимы конфигурационные файлы только со значением exportTo: "." (применить конфигурационный файл к текущему namespace);

  • не допускается использование "*" в поле hosts. Можно писать DNS-имя, IP или DNS-имя с wildcard (например: *.ХХ.ХХ.ru).

  1. Destination Rule:

  • конфигурационный файл должен содержать уникальный spec.host + spec.workloadSelector.matchLabels в рамках namespace, т.к. применится только первый загруженный конфигурационный файл;

  • допустимы конфигурационные файлы только со значением exportTo: "." (применить конфигурационный файл к текущему namespace);

  • не допускается использование "*" в поле hosts. Можно писать DNS-имя, IP или DNS-имя с wildcard (например: *.ХХ.ХХ.ru).

  1. Envoy Filter:

  • конфигурационный файл должен содержать поле workloadSelector;

  • конфигурационный файл должен содержать поле configPatches;

  • для фильтра envoy.filters.http.rbac должно присутствовать поле spec.ConfigPatches.patch.value.config.rules;

  • для фильтра envoy.filters.http.rbac нужно использовать safe_regex вместо regex;

  • для фильтра envoy.filters.http.rbac в блоке safe_regex должно присутствовать поле google_re2.max_program_size, чтобы задать количество ресурсов для вычисления регулярного выражения.

  1. Service Entry:

  • в одном конфигурационном файле должен быть описан только 1 хост;

  • допустимы конфигурационные файлы только со значением exportTo: "." (применить конфигурационный файл к текущему namespace);

  • значение spec.hosts + spec.workloadSelector.matchLabels должно быть уникальным в рамках namespace;

  • проверяется уникальность spec.hosts + spec.ports + spec.resolution, и если в рамках namespace уже есть совпадение, то выдается информация о нем;

  • должно присутствовать поле spec.resolution, и его значение не должно быть NONE.

Примеры валидации#

  1. Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: service-deployment
  labels:
    app: egress
    version: v1
    maistra.io/v1: werwer
spec:
  replicas: 1
  selector:
    matchLabels:
      app: egress
  template:
    metadata:
      labels:
        app: egress
        version: v1
    spec:
      containers:
        - name: service-container
          image: service
          imagePullPolicy: Never
          ports:
            - containerPort: 8081
          securityContext:
            runAsUser: 1000
          resources:
            limits:
              memory: 32Mi
              cpu: 100m

Команда:

istioctl validate -a -k -n test-pg-multi -f deployment.yml

Результат:

Error: 4 errors occurred:
        * Deployment//service-deployment: для label app указано невалидное значение egress. labels (spec.selector.matchlabels) должны иметь префикс типа "igw-*", "egw-*", "ingressgateway-*", "egressgateway-*" (например, igw-<namespace>)
        * Deployment//service-deployment: для metadata.labels нельзя использовать аннотацию metadata.labels.maistra.io/<любое значение>
        * Deployment//service-deployment: значение Selector.MatchLabels.app: egress уже используется в Deployment: egress в namespace: test-pg-multi
        * Deployment//service-deployment: значения Selector.MatchLabels пересекаются с Deployment: egress в namespace: test-pg-multi
  1. DestinationRule

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: bookinfo-ratings
spec:
  host: postgres-db-svc.test-pg-multi.svc.cluster.local
  # host: '*'
  # host: 123.03.21.00
  exportTo:
    - .
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
  subsets:
    - name: testversion
      labels:
        version: v3
      trafficPolicy:
        loadBalancer:
          simple: ROUND_ROBIN
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: egress2-gw-svc-dr
spec:
  exportTo:
    - .
  host: egress-gw-svc
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN
    portLevelSettings:
      - port:
          number: 54320
        tls:
          mode: ISTIO_MUTUAL
      - port:
          number: 54321
        tls:
          mode: ISTIO_MUTUAL
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: bad-postgres-dr
spec:
  exportTo:
    - .
  host: postgres-db-svc.test-pg-multi.svc.cluster.local
  workloadSelector:
    matchLabels:
      app: egress
      version: v1
  subsets:
    - labels:
        version: postgres-back
      name: postgres-back
      trafficPolicy:
        portLevelSettings:
          - port:
              number: 5432
            tls:
              mode: MUTUAL
              clientCertificate: /var/lib/istio/data/pgcerts/tls.crt
              privateKey: /var/lib/istio/data/pgcerts/tls.key
              caCertificates: /var/lib/istio/data/pgcerts/ca.crt
              # credentialName: pg-client-certs-postgres
    - labels:
        version: testuser-back
      name: testuser-back
      trafficPolicy:
        portLevelSettings:
          - port:
              number: 5432
            tls:
              mode: MUTUAL
              clientCertificate: /var/lib/istio/data/tucerts/tls.crt
              privateKey: /var/lib/istio/data/tucerts/tls.key
              caCertificates: /var/lib/istio/data/tucerts/ca.crt
              # credentialName: pg-client-certs-testuser
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN

Команда:

istioctl validate -a -k -n test-pg-multi -f destinationrule.yml

Результат:

Error: 2 errors occurred:
        * DestinationRule//bookinfo-ratings: значение host: postgres-db-svc.test-pg-multi.svc.cluster.local уже используется в destinationRule: postgres-dr в namespace: test-pg-multi
        * DestinationRule//egress2-gw-svc-dr: значение host: egress-gw-svc уже используется в destinationRule: egress-gw-svc-dr в namespace: test-pg-multi
  1. EnvoyFilter

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: ingress-certificate-filter
spec:
  # configPatches:
  #   - applyTo: HTTP_FILTER
  #     match:
  #       context: GATEWAY
  #       listener:
  #         filterChain:
  #           filter:
  #             name: envoy.http_connection_manager
  #         portNumber: 5443
  #     patch:
  #       operation: INSERT_BEFORE
  #       value:
  #         name: envoy.filters.http.rbac
  #         config:
  #           rules:
  #             action: ALLOW
  #             policies:
  #               istio_pilot_2:
  #                 permissions:
  #                 - {any: true}
  #                 principals:
  #                 - authenticated:
  #                     principal_name:
  #                       safe_regex:
  #                         google_re2:
  #                           max_program_size: 100
  #                         regex: '${FILTER_CN_REGEX}'
  workloadSelector:
    labels:
      app: ingress
---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: postgres-starttls-filter
spec:
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
      context: GATEWAY
      listener:
        portNumber: 54320
    patch:
      operation: INSERT_BEFORE
      value:
        name: envoy.filters.network.postgres_proxy
        typed_config:
          '@type': type.googleapis.com/envoy.extensions.filters.network.postgres_proxy.v3alpha.PostgresProxy
          enable_sql_parsing: true
          stat_prefix: postgres
          terminate_ssl: true
  - applyTo: NETWORK_FILTER
    match:
      context: GATEWAY
      listener:
        portNumber: 54321
    patch:
      operation: INSERT_BEFORE
      value:
        name: envoy.filters.network.postgres_proxy
        typed_config:
          '@type': type.googleapis.com/envoy.extensions.filters.network.postgres_proxy.v3alpha.PostgresProxy
          enable_sql_parsing: true
          stat_prefix: postgres
          terminate_ssl: true
  # workloadSelector:
  #   labels:
  #     app: egress

Команда:

istioctl validate -a -f envoyfilters.yml 

Результат:

Error: 2 errors occurred:
        * EnvoyFilter//ingress-certificate-filter: отсутствует обязательное поле spec.ConfigPatches
        * EnvoyFilter//postgres-starttls-filter: отсутствует обязательное поле spec.WorkloadSelector
  1. Gateway

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: fluent-bit-gw-1
spec:
  selector:
    app: egress
  servers:
    - hosts: [XX.XX.XX.ru']
      port:
        name: wer-fluent-bit-1
        number: 10001
        protocol: TCP
---
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: egress2-gw
spec:
  selector:
    app: egress
  servers:
    - hosts:
        - '*'
      port:
        name: tls-postgres-gw
        number: 54320
        protocol: TLS
      tls:
        mode: ISTIO_MUTUAL
    - hosts:
        - '*'
      port:
        name: tls-testuser-gw
        number: 54321
        protocol: TLS
      tls:
        mode: ISTIO_MUTUAL

Команда:

istioctl validate -a -k -n test-pg-multi -f gateway.yml

Результат:

Error: 3 errors occurred:
        * Gateway//fluent-bit-gw-1: для порта указано некорректное имя wer-fluent-bit-1. Имя порта должно соответствовать маске <protocol>-* (пример: http, http-8080, tcp, tcp-7575)
        * Gateway//fluent-bit-gw-1: значение Selector.MatchLabels пересекается с Gateway: egress-gw в namespace: test-pg-multi
        * Gateway//egress2-gw: значение Selector.MatchLabels пересекается с Gateway: egress-gw в namespace: test-pg-multi
  1. Service

apiVersion: v1
kind: Service
metadata:
  name: service-a-srv
  labels:
    app: egress
    service: service-a-app-srv
spec:
  type: NodePort
  ports:
    - port: 80
      name: werwer-http-80
      targetPort: 1021
  selector:
    app: egress

Команда:

istioctl validate -a -f service.yml

Результат:

Error: 4 errors occurred:
        * Service//service-a-srv: service "service-a-srv//:" port "werwer-http-80" does not follow the Istio naming convention. See https://istio.io/v1.17/docs/ops/deployment/requirements/
        * Service//service-a-srv: нельзя использовать type: NodePort, type: LoadBalancer. Они запрещены безопасностью
        * Service//service-a-srv: для порта указано некорректное имя werwer-http-80. Имя порта должно соответствовать маске <protocol>-* (пример: http, http-8080, tcp, tcp-7575)
        * Service//service-a-srv: в поле spec.ports.targetPorts нельзя использовать порты до 1024 для егрессов и ингрессов
  1. ServiceEntrу

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: tzuku2
spec:
  exportTo:
    - '*'
  addresses:
    - 10.ХХХ.ХХХ.Х/ХХ
    - 10.ХХХ.ХХХ.Х/ХХ
  endpoints:
    - address: 10.ХХХ.ХХХ.Х
    - address: 10.ХХХ.ХХХ.Х
  hosts:
    - XX.XX.XX.ru
    - XX.XX.ХХ.ru
  location: MESH_EXTERNAL
  ports:
    - name: tcp
      number: 9093
      protocol: http
  resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: tzuku3
spec:
  exportTo:
    - '*'
  addresses:
    - 10.ХХХ.ХХХ.Х/ХХ
  endpoints:
    - address: 10.ХХХ.ХХХ.Х
  hosts:
    - XX.XX.XX.ru
  location: MESH_EXTERNAL
  ports:
    - name: tcp
      number: 9093
      protocol: http
  resolution: NONE
---
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: postgres2-back-se
spec:
  exportTo:
    - .
  hosts:
    - postgres-db-svc.test-pg-multi.svc.cluster.local
  location: MESH_EXTERNAL
  ports:
    - name: postgres-5432
      number: 5432
      protocol: postgres
  resolution: DNS
  workloadSelector:
    labels:
      version: postgres-back
---
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: testuser2-back-se
spec:
  exportTo:
    - .
  hosts:
    - postgres-db-svc.test-pg-multi.svc.cluster.local
  location: MESH_EXTERNAL
  ports:
    - name: postgres-5432
      number: 5432
      protocol: postgres
  resolution: DNS
  workloadSelector:
    labels:
      version: testuser-back

Команда:

istioctl validate -a -k -n test-pg-multi -f serviceentry.yml

Результат:

Error: 8 errors occurred:
        * ServiceEntry//tzuku2: CIDR addresses are allowed only for NONE/STATIC resolution types
        * ServiceEntry//tzuku3: no endpoints should be provided for resolution type none
        * ServiceEntry//tzuku2: рекомендуется создавать по одному serviceEntry на каждый host
        * ServiceEntry//tzuku3: значение поля spec.resolution не должно быть NONE (Для версии RHSM ниже 2.*)
        * ServiceEntry//postgres2-back-se: для spec.hosts: postgres-db-svc.test-pg-multi.svc.cluster.local labels workloadSelector пересекаются с serviceEntry: postgres-back-se в namespace: test-pg-multi
        * ServiceEntry//postgres2-back-se: для spec.hosts: postgres-db-svc.test-pg-multi.svc.cluster.local определены порты: 5432 в serviceEntry: postgres-back-se в namespace: test-pg-multi
        * ServiceEntry//testuser2-back-se: для spec.hosts: postgres-db-svc.test-pg-multi.svc.cluster.local labels workloadSelector пересекаются с serviceEntry: testuser-back-se в namespace: test-pg-multi
        * ServiceEntry//testuser2-back-se: для spec.hosts: postgres-db-svc.test-pg-multi.svc.cluster.local определены порты: 5432 в serviceEntry: testuser-back-se в namespace: test-pg-multi
  1. Sidecar

apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: default
  namespace: istio-system
spec:
  egress:
    - hosts:
        - "./*"

Команда:

istioctl validate -a -f sidecar.yml

Результат:

Error: 1 error occurred:
        * Sidecar//default: namespace не должно быть равно istio-system
  1. VirtualService

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: vs-egress-1
spec:
  exportTo:
    - "*"
  gateways:
    - mesh
    - gw-egress
  hosts:
    - "1.1.1.1"
  tcp:
    - match:
        - gateways:
            - mesh
          port: 9300
      route:
        - destination:
            host: svc-egress
            port:
              number: 9200
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: vs-egress-2
spec:
  exportTo:
    - .
  gateways:
    - mesh
    - gw-egress
  hosts:
    - "*"
  tcp:
    - match:
        - gateways:
            - mesh
          port: 9300
      route:
        - destination:
            host: svc-egress
            port:
              number: 9200
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: postgres2-vs
spec:
  exportTo:
    - .
  gateways:
    - egress-gw
    - mesh
  hosts:
    - postgres-db-svc.test-pg-multi.svc.cluster.local
  tcp:
    - match:
        - gateways:
            - mesh
          sourceLabels:
            app: pg-client-postgres
      route:
        - destination:
            host: egress-svc.test-pg-multi.svc.cluster.local
            port:
              number: 54320
          weight: 100
    - match:
        - gateways:
            - mesh
          sourceLabels:
            app: pg-client-testuser
      route:
        - destination:
            host: egress-svc.test-pg-multi.svc.cluster.local
            port:
              number: 54321
          weight: 100
    - match:
        - gateways:
            - mesh
          sourceLabels:
            app: java-pg-client
      route:
        - destination:
            host: egress-svc.test-pg-multi.svc.cluster.local
            port:
              number: 54321
          weight: 100
    - match:
        - gateways:
            - egress-gw
          port: 54320
      route:
        - destination:
            host: postgres-db-svc.test-pg-multi.svc.cluster.local
            port:
              number: 5432
            subset: postgres-back
          weight: 100
    - match:
        - gateways:
            - egress-gw
          port: 54321
      route:
        - destination:
            host: postgres-db-svc.test-pg-multi.svc.cluster.local
            port:
              number: 5432
            subset: testuser-back
          weight: 100

Команда:

istioctl validate -a -k -n test-pg-multi -f virtualservices.yml

Результат:

Error: 5 errors occurred:
        * VirtualService//vs-egress-2: wildcard host * is not allowed for virtual services bound to the mesh gateway
        * VirtualService//vs-egress-1: допустимы конфигурационные файлы только со значением exportTo: "."
        * VirtualService//vs-egress-2: нельзя использовать * в поле hosts. Допустимы DNS-имя, IP или DNS-имя с wildcard (например: .ХХ.ХХ.ru, но не просто "")
        * VirtualService//postgres2-vs: для host: postgres-db-svc.test-pg-multi.svc.cluster.local, tcp.match.gateway: egress-gw, port: 54320 уже есть проверка в VirtualService: postgres-vs в namespace: test-pg-multi
        * VirtualService//postgres2-vs: для host: postgres-db-svc.test-pg-multi.svc.cluster.local, tcp.match.gateway: egress-gw, port: 54321 уже есть проверка в VirtualService: postgres-vs в namespace: test-pg-multi

Валидация пользовательских конфигураций Istio, загруженных в кластер#

Для валидации пользовательских конфигураций Istio используется Validating Admission Webhook - специальный контроллер POLM. По умолчанию он обрабатывает те конфигурации, у которых есть label istio.io/rev = <значение_revision_контрольной_панели>. Если значения revision у контрольной панели нет, тогда будут обрабатываться конфигурации, имеющие label istio.io/rev = default.

Пример:

Значение revision у контрольной панели = my-test-plane

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: test-se
  labels:
    istio.io/rev: my-test-plane
spec:
  ...

Значение revision у контрольной панели отсутствует

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: test-se
  labels:
    istio.io/rev: default
spec:
  ...

Для того чтобы настроить валидацию пользовательских конфигураций независимо от labels, можно задать настройки namespaceWideValidation = true (значение по умолчанию false, аналогичное значение, если настройка namespaceWideValidation не указана совсем). В случае, если контрольная панель устанавливалась с использованием istio-operator, то настройка проставляется по пути spec.values.pilot.

Пример:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
  ...
  values:
    pilot:
      namespaceWideValidation: true

Если контрольная панель была установлена с помощью helm, то достаточно в values прописать namespaceWideValidation: true.

Стоит учесть, что при использовании namespaceWideValidation = true значение revision контрольной панели все также играет роль. Если значение revision у контрольной панели задано, то контрольная панель будет валидировать конфигурации только из проектов, имеющих label istio.io/rev = <значение_revision_контрольной_панели>. Если же revision у контрольной панели отсутствует, то будут валидироваться конфигурации из проектов, имеющих label istio.io/rev = default.

Обработка обратно несовместимого блока status в конфигурациях Istio#

У конфигураций Istio есть блок status. Этот блок возможно проставить либо средствами контрольной панели, либо используя специальные программные клиенты, написанные именно с целью изменения блока status. Обычные манипуляции пользователя через UI или kubectl никак не повлияют на блок status.

В opensource Istio, начиная с версии 1.8, поменялся API блока status, он стал обратно несовместим с предыдущими версиями. То есть если на кластере имеются конфигурации с обратно несовместимым блоком status, то есть конфигурации разных версий Istio — это может привести к блокировке работы POLM (istiod).

У этой проблемы два решения:

  1. Удалить блок status.

  2. Использовать env ESCAPE_STATUS = true в Deployment POLM.

Удалить блок status#

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

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

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

Использовать env ESCAPE_STATUS = true в Deployment POLM#

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

2023-04-25T08:24:36.666527Z	info	env ESCAPE_STATUS was set to true. Client with status escape is enabled

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

2023-04-25T08:26:53.729775Z	error	Error occurred during decode phase: v1alpha3.ServiceEntry.Status: unmarshalerDecoder: unknown value "Error" for enum istio.analysis.v1alpha1.AnalysisMessageBase_Level, error found in #10 byte of ...|"Test"}}]}}|..., bigger context ...|rror","type":{"code":"test-code","name":"Test"}}]}}|... status block will be ignored

Ограничение видимости конфигураций#

По умолчанию конфигурации DestinationRule, VirtualService, ServiceEntry и Service могут быть видны между всеми пользовательскими проектами, подключенными к одной Контрольной панели (Управления политиками). Чтобы включить изоляцию данных конфигураций, то есть ограничить видимость только теми проектами, в которых они были созданы, достаточно добавить данный блок в конфигурацию IstioOperator.

spec:
  meshConfig:
    defaultDestinationRuleExportTo:
      - .
    defaultServiceExportTo:
      - .
    defaultVirtualServiceExportTo:
      - .

Стоит отметить, что данная конфигурация проставляет значение видимости по умолчанию, то есть пользователь может в своих конфигурациях DestinationRule, VirtualService, ServiceEntry и Service переопределить данное значение.

Настройка исходящего трафика во внешнюю сеть#

По умолчанию Istio позволяет Граничным и Сервисным прокси выводить трафик на внешние по отношению к кластерам hosts. Чтобы запретить это делать, необходимо сделать настройку:

spec:
  meshConfig:
    outboundTrafficPolicy:
      mode: REGISTRY_ONLY

Пример:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: istiocontrolplane
spec:
  profile: default
  hub: my.corp.cloud.ru/sber
  tag: custom-1.11.2-alt
  meshConfig:
    rootNamespace: istio-system
    outboundTrafficPolicy:
      mode: REGISTRY_ONLY
  components:
    egressGateways:
      - name: istio-egressgateway
        enabled: true
    ingressGateways:
      - name: istio-ingressgateway
        enabled: true
    cni:
      enabled: false
    pilot:
      enabled: true
  values:
    global:
      imagePullSecrets:
        - default-secret
      istioNamespace: istio-system
      imagePullPolicy: Always
    pilot:
      resources:
        limits:
          cpu: 1000m
          memory: 2Gi
        requests:
          cpu: 1000m
          memory: 2Gi

Настройка Soft Multitenancy#

Soft Multitenancy - это изоляция Контрольных панелей Istio и конфигурации Istio в рамках одного кластера, то есть когда несколько Контрольных панелей Istio могут работать одновременно и независимо на одном кластере, а конфигурации Istio доступны только в пределах проектов, подключенных к той же Контрольной панели.

Для того чтобы создать Istio Soft Multitenancy, необходимо использовать spec.revision (позволяет ставить независимо несколько Контрольных панелей) и spec.meshConfig.discoverySelectors (позволяет включить изоляцию). Также важно задать в конфигурационном файле spec.meshConfig.rootNamespace <имя_проекта_контрольной_панели>. В spec.meshConfig.discoverySelectors задаются K8S Selectors.

Также стоить отметить, что при использовании spec.revision важно включать каждый компонент, если они используются, в том числе pilot. То есть в spec.components для каждого компонента при pilot, ingressGateway, egressGateway и cni необходимо выставлять enabled: true.

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
...
  meshConfig:
    discoverySelectors:
      - matchLabels:
          <лейбл>: <значение_label>
  ...
  revision: istio-system
...

Пример:

 apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: istiocontrolplane
spec:
  profile: default
  hub: my.corp.cloud.ru/sber
  tag: custom-1.11.2-alt
  revision: istio-system
  meshConfig:
    rootNamespace: istio-system
    discoverySelectors:
      - matchLabels:
          istio.io/rev: istio-system
  components:
    egressGateways:
      - name: istio-egressgateway
        enabled: true
    ingressGateways:
      - name: istio-ingressgateway
        enabled: true
    cni:
      enabled: false
    pilot:
      enabled: true
  values:
    global:
      imagePullSecrets:
        - default-secret
      istioNamespace: istio-system
      imagePullPolicy: Always
    pilot:
      resources:
        limits:
          cpu: 1000m
          memory: 2Gi
        requests:
          cpu: 1000m
          memory: 2Gi

Задавать значение spec.meshConfig.discoverySelectors можно любым, но рекомендуется проставлять istio.io/rev: <имя_проекта_контрольной_панели>. При использовании spec.revision для подключения автоматического добавления (inject) Сервисного прокси в прикладной pod пользовательского проекта необходимо будет добавить этому проекту label istio.io/rev: <имя_проекта_контрольной_панели>.

События системного журнала#

Для просмотра системного журнала через веб-интерфейс Kubernetes необходимо выполнить следующие действия:

  1. Зайдите в проект контрольной панели.

  2. В меню выберите пункт Workload/Pods.

  3. На странице найдите нужный pod.

  4. Перейдите по ссылке в этот pod.

  5. Перейдите на вкладку (Logs). В консоли не должно быть ошибок.

Шаг

Действие

Вход в веб-консоль Kubernetes

Перейдите по ссылке (URL) веб-консоли нужного кластера Kubernetes, в окне ввода учетных данных введите токен пользователя или kubeconfig

Переход в проект

Выберите нужный проект в выпадающем списке в шапке веб-интерфейса Kubernetes

Переход в Workload/Pods

Выполните следующие действия:
• В меню выберите пункт Cluster/Namespaces ;
• На странице найдите нужный pod (при необходимости воспользуйтесь поиском по имени);
• Перейдите по ссылке в наименовании pod и нажмите на вкладку ≡ (Logs);

Просмотр событий системного журнала

В появившемся окне можно увидеть системный журнал приложения (логи)

Выход из веб-консоли Kubernetes

Выполните следующие действия:
• Кликом по имени пользователя раскройте меню пользователя;
• Выберите пункт Log out ;
• Закройте окно браузера

В разделе Событий можно увидеть как успешные запуски pod, так и различные ошибки.

Пример события: _MountVolume.SetUp failed for volume "istiod-ca-cert" : configmap "istio-ca-root-cert" not found. Также в событиях будет видно, с каким pod проблема и в какое время случилось событие.

Запуск контейнера SVPX первым с postStart hook#

(!) Важным стоит отметить, что данный механизм holdApplicationUntilProxyStarts опирается в своей работе на недокументированную особенность K8S, которая со временем может перестать поддерживаться. Данная особенность гарантирована В DropApp/DropApp+ c K8S 1.25.

По умолчанию контейнер istio-proxy (SVPX) в прикладном pod запускается не первым, что может привести к нештатным ситуациям, в виду того, что весь cетевой трафик проходит через SVPX. К примеру, сетевое взаимодействие прикладного контейнера может произойти до того, как SVPX перейдет в статус Ready, что в свою очередь вызовет ошибки сетевого взаимодействия.

Если такое поведение является нежелательным, то можно установить флаг holdApplicationUntilProxyStarts в значение true.

Сделать это можно как на уровне POLM, так и на уровне SVPX.

Пример на уровне POLM:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  ...
spec:
...
  values:
    global:
      proxy:
        holdApplicationUntilProxyStarts: true
    ...

Пример на уровне SVPX:

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: 'true'
        proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
    ...

Настройка holdApplicationUntilProxyStarts на уровне SVPX имеет больший приоритет, чем настройка на уровне POLM.

Как работает настройка holdApplicationUntilProxyStarts#

Контейнеры в pod запускаются не всегда параллельно. Если у какого-либо контейнера есть настройка lifecycle.postStart, то пока инструкция/команда, описанная в блоке lifecycle.postStart не завершит свое исполнение, контейнер, следующий после этого контейнера, не будет запущен.

Данная настройка меняет порядок контейнеров в pod таким образом, чтобы SVPX был первым контейнером, и добавляет lifecycle.postStart.

lifecycle:
  postStart:
    exec:
      command:
      - pilot-agent
      - wait

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

Команда pilot-agent wait, запускаемая в lifecycle.postStart, раз в 500 миллисекунд проверяет статус Envoy через readinessProbe. При успешной проверке команда pilot-agent wait завершается успехом. Максимальное значение времени, в течение которого идут данные проверки - 60 секунд. По истечении этого периода времени команда pilot-agent wait завершается ошибкой.

Настройки уровня логирования#

Для компонента POLM можно настроить уровень логирования несколькими способами:

  1. Настройка конфигурации установки IstioOperator

    • Пример:

      apiVersion: install.istio.io/v1alpha1
      kind: IstioOperator
      metadata:
        ...
      spec:
      ...
        values:
          global:
            logging:
              level: <значение_логирования>
          ...
      
  2. Настройка values в Helm chart

  • Пример для консольного аргумента:

    helm ... --set global.logging.level=<значение_логирования>
    
  • Пример для файла values:

    global:
      logging:
        level: <значение_логирования>
    
  1. Ручная настройка Deployment

    Для настройки уровня логирования можно задать аргумент --log_output_level контейнеру discovery в Deployment POLM

    Пример:

    kind: Deployment
    apiVersion: apps/v1
    metadata:
      ...
    spec:
      ...
      template:
        ...
        spec:
          ...
          containers:
            - name: discovery
              args:
                - discovery
                - '--monitoringAddr=:15014'
                - '--log_output_level=default:info'
                ...
    

Допустимые уровни логирования:

  • default:debug

  • default:info

  • default:warn

  • default:error

  • default:fatal

  • default:none

Задавать эту настройку может только Администратор.

Включение уровня логирования debug не рекомендуется в промышленных инсталляциях.

В целом логирование выглядит в виде время-уровень логирования-текст.

Пример уровня логирования info:

2023-02-16T17:55:51.701328Z info ads LDS: PUSH request for node:istio-egressgateway-b54bfffbb-qn9hc.istio-test resources:0 size:0B

Пример уровня логирования debug:

2023-02-17T08:10:52.495547Z debug Build 6 listeners for node pg-client-postgres-b6665b5c8-k2v7n.pgbouncer-load-test including 4 outbound, 0 http proxy, 1 virtual outbound and 1 virtual inbound listeners

Пример уровня логирования warn:

2023-02-17T08:10:40.320893Z warn kube Skipping CRD gateway.networking.k8s.io/v1alpha2/GatewayClass as it is not present

Пример уроня логирования error:

2023-02-17T08:13:17.057172Z error kube failed to list CRDs: customresourcedefinitions.apiextensions.k8s.io is forbidden: User "system:serviceaccount:istio-system:istiod-istio-system" cannot list resource "customresourcedefinitions" in API group "apiextensions.k8s.io" at the cluster scope

События мониторинга#

Компонент POLM не интегрирован с компонентом «Объединенный мониторинг Unimon» продукта Plaform V Monitor (MONA).

Со стороны POLM никаких требований к мониторингу платформы Kubernetes не предъявляется.

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

Часто встречающиеся проблемы и пути их устранения#

Проблема

Причина

Решения

Pod istiod (POLM) перезапускается с ошибкой OOM Killed

Недостаточно ресурсов

Необходимо в конфигурации установки задать limits/requests для pilot и/или же увеличить количество реплик (подробнее в документе Руководство по установке

Ошибка вызова AdmissionWebhook: kubeapi-server не может отправить запрос в POLM

В проекте контрольной панели могут быть созданы конфигурации препятствующие взаимодействия kubeapi-server и POLM

Необходимо обратиться к сопровождению инфраструктуры для обеспечения доступа между kubeapi-server и POLM

Не происходит inject SVPX в прикладной pod

У прикладного проекта или его pod отсутствуют необходимые labels/аннотации

Необходимо убедиться, что у проекта проставлен label istio-injection=enabled или, при использовании настройки revision, проставлен label, соответствующий тому, что прописан в конфигурации установки контрольной панели (подробнее в документе Руководство по установке). Проект должен иметь исключительно один из этих label. У pod должна быть проставлена аннотация sidecar.istio.io/inject=true

POLM не может аутентифицировать SVPX

Невалидный токен или его отсутствие в файловой система контейнера SVPX

Если при подключении SVPX возникает ошибка аутентификации со стороны POLM, то необходимо проверить, что в контейнере SVPX по пути /var/run/secrets/kubernetes.io/serviceaccount/token примонтирован токен service account, под которым запускается pod. Если токен примонтирован, то необходимо обратиться к сопровождению инфраструктуры, так как токен, выпущенный контролером Kubernetes, является невалидным

Не стартует pod приложения istiod (POLM)

Недостаточно ресурсов

Увеличить лимиты/requests для приложения

Не стартует pod приложения istiod (POLM)

Ресурсы pod не соответствуют ограничениям, заданным в LimitRanges

Изменить ресурсы для приложения таким образом, чтобы они соответствовали LimitRanges, либо удалить LimitRanges

Не стартует pod приложения istiod (POLM)

Нет доступной node для запуска

Зарегистрировать обращение в поддержку инфраструктуры

Не стартует pod приложения istiod (POLM)

Ошибка в конфигурации

Выгрузить лог, провести анализ, скорректировать конфигурацию

Частый рестарт контейнера приложения istiod (POLM)

Медленная загрузка приложения

Увеличить задержку и/или интервал опроса Liveness/Readiness-пробы: увеличить в Deployment POLM параметр initialDelaySeconds у liveness и readiness проб

Частый рестарт контейнера приложения istiod (POLM)

Недостаточно ресурсов

Увеличить лимиты/requests для приложения