Руководство по системному администрированию#
Термины и определения#
Термин/Аббревиатура |
Определение |
|---|---|
Node |
Node — единица Kubernetes, предоставляющая изолированную среду для работы контейнеров |
Лимит |
Максимальный объем ресурсов, который выдается на работу сервиса |
Реквест |
Объем ресурсов, который необходим для запуска приложения |
Платформа |
Платформа оркестрации приложений со средствами автоматизации и управления на основе политик, например, Kubernetes |
Istio SE |
Настраиваемая сервисная сетка с открытым исходным кодом, служащая для взаимодействия, мониторинга и обеспечения безопасности контейнеров в кластере Kubernetes |
Проект / namespace |
Изолированная область (пространство имен) в кластере Kubernetes, предназначенная для разграничения доступа к ресурсам кластера (deployment, service, и т.д.) |
Контрольная панель |
Namespace, где запущены управляющие приложения |
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 |
Переход в нужный namespace |
Выберите нужный namespace в выпадающем списке в шапке веб-интерфейса Kubernetes |
Запуск pod |
1. В меню выберите пункт Workload/Deployments. |
Выход из веб-консоли Kubernetes |
1. Щелкните по имени пользователя, чтобы раскрыть меню учетной записи. |
С использованием консоли Kubernetes#
Шаг |
Действие |
|---|---|
Вход в клиент Kubernetes |
Запросите у администратора кластера kubeconfig для kubectl |
Запуск компонента |
В консоли выполните команду: |
Остановка#
С использованием веб-интерфейса Kubernetes#
Шаг |
Действие |
|---|---|
Логин в веб-консоль Kubernetes |
Перейдите по ссылке (URL) веб-консоли нужного кластера Kubernetes, в окне ввода учетных данных введите токен пользователя или kubeconfig |
Переход в нужный namespace |
Выберите нужный namespace в выпадающем списке в шапке веб-интерфейса Kubernetes |
Остановка компонента |
Выполните следующие действия: |
Выход из веб-консоли Kubernetes |
Выполните следующие действия: |
С использованием консоли Kubernetes#
Шаг |
Действие |
|---|---|
Запросить kubeconfig для kubectl |
Запросите у администратора кластера kubeconfig для kubectl |
Остановка компонента |
В консоли выполните команду: |
Настройка выделения ресурсов#
С использованием веб-интерфейса Kubernetes#
Шаг |
Действие |
|---|---|
Логин в веб-консоль Kubernetes |
Перейдите по ссылке (URL) веб-консоли нужного кластера Kubernetes, в окне ввода учетных данных введите токен пользователя или kubeconfig |
Переход в namespace |
Выберите нужный namespace в выпадающем списке в шапке веб-интерфейса Kubernetes |
Вход в Deployment |
Выполните следующие действия: |
Корректировка параметров |
Выполните следующие действия: |
Сохранение |
Нажмите кнопку Update |
Проверка конфигурации |
Снова зайдите на вкладку Edit в YAML или JSON |
Выход из веб-консоли Kubernetes |
Выполните следующие действия: |
Также можно менять ресурсы в конфигурации Istio Operator (если есть доступ к этому ресурсу).
Шаг |
Действие |
|---|---|
Логин в веб-консоль Kubernetes |
Перейдите по ссылке (URL) веб-консоли нужного кластера Kubernetes, в окне ввода учетных данных введите токен пользователя или kubeconfig |
Переход в namespace |
Выберите нужный namespace в выпадающем списке в шапке веб-интерфейса Kubernetes |
Открытие Istio Operator |
Выполните следующие действия: |
Корректировка параметров |
В окне редактирования по пути |
Сохранение |
Нажмите кнопку Update |
Проверка конфигурации |
Зайдите в нужный namespace и проверьте deployments затрагиваемых компонентов |
Выход из веб-консоли Kubernetes |
Выполните следующие действия: |
Настройка выделения ресурсов сервисных прокси на уровне кластера#
В настройках контрольной панели можно задать ресурсы, проставляемые сервисным proxy при inject их в прикладные pods.
Через конфигурацию Istio Operator (если к нему есть доступ)#
Шаг |
Действие |
|---|---|
Логин в веб-консоль Kubernetes |
Перейдите по ссылке (URL) веб-консоли нужного кластера Kubernetes, в окне ввода учетных данных введите токен пользователя или kubeconfig |
Переход в namespace |
Выберите нужный namespace в выпадающем списке в шапке веб-интерфейса Kubernetes |
Открытие Istio Operator |
Выполните следующие действия: |
Корректировка параметров |
В окне редактирования по пути |
Сохранение |
Кликните по кнопке Update |
Проверка конфигурации |
Зайдите в нужный namespace и проверьте pods затрагиваемых компонентов |
Выход из веб-консоли Kubernetes |
Выполните следующие действия: |
Через ConfigMap (istio-sidecar-injector)#
Шаг |
Действие |
|---|---|
Логин в веб-консоль Kubernetes |
Перейдите по ссылке (URL) веб-консоли нужного кластера Kubernetes, в окне ввода учетных данных введите токен пользователя или kubeconfig |
Переход в namespace |
Выберите нужный namespace в выпадающем списке в шапке веб-интерфейса Kubernetes |
Открытие ConfigMap |
Выполните следующие действия: |
Корректировка параметров |
В окне редактирования по пути |
Сохранение |
Кликните по кнопке Update |
Проверка конфигурации |
Зайдите в нужный namespace и проверьте pods затрагиваемых компонентов |
Выход из веб-консоли Kubernetes |
Выполните следующие действия: |
Подключение для пользовательского namespace возможности автоматического добавления (inject) сервисного прокси#
Контрольную панель (Управление политиками) можно установить как с spec.revision, так и без данной настройки. От этого зависит также то, какие labels необходимо добавлять пользовательским namespaces.
Обеспечение сетевого доступа к namespace Контрольной панели (Управления политиками)#
Так как Граничные прокси и Сервисные прокси напрямую по имени сервиса подключаются к сервису Управление политиками, то необходимо, чтобы между прикладными namespaces пользователей и namespace контрольной панели была сетевая доступность.
Сделать ее можно, в том числе, с помощью такой конфигурации:
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#
В прикладных namespaces при использовании Istio CNI Plugin необходимо создать конфигурацию NetworkAttachmentDefinition, для того чтобы Multus использовал Istio CNI Plugin для настройки сети pod.
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: istio-cni
С использованием настройки ревизии#
При использовании spec.revision пользовательскому namespace необходимо добавить label istio.io/rev=<значение_поля_revision_из_конфигурации_IstioOperator>.
Если у пользовательского namespace есть label istio-injection, то его необходимо удалить.
Для удаления у namespace возможности автоматического inject сервисного proxy достаточно удалить label istio.io/rev.
Без использования настройки ревизии#
По умолчанию, без использования spec.revision, все namespaces подключаются к контрольной панели (Управление политиками). Но для подключения к пользовательскому namespace возможности автоматического добавление (inject) istio-proxy sidecar (компонент Сервисный прокси) необходимо добавить в этот namespace label istio-injection=enabled. Сделать это может администратор namespace с помощью команды:
kubectl --kubeconfig=<путь_к_конфигурационному_файлу_kubeconfig> label namespace <имя_namespace> istio-injection=enabled
Также можно сделать это через пользовательский интерфейс. Необходимо выполнить следующие действия:
Зайдите в namespace контрольной панели.
В меню выберите пункт Cluster/Namespaces.
На странице найдите нужный namespace.
У этого namespace нажмите на ⋮ и выберите Edit.
Добавьте label по пути metadata.labels и нажмите Update.
Для удаления у namespace возможности автоматического inject сервисного proxy достаточно удалить созданный ранее label или проставить вместо значения enabled значение disabled.
В случае с пользовательским интерфейсом удаление ничем не отличается от добавления, а в случае консоли необходимо выполнить следующую команду:
для изменения текущего значение label:
kubectl –kubeconfig=<путь_к_конфигурационному_файлу_kubeconfig> label namespace <имя_namespace> istio-injection=disabled –overwrite!
для удаления существующего label:
kubectl –kubeconfig=<путь_к_конфигурационному_файлу_kubeconfig> label namespace <имя_namespace> istio-injection-
Подключение namespace при использовании discoverySelectors#
При использовании spec.meshConfig.discoverySelectors необходимо добавлять labels, соответствующие настройке spec.meshConfig.discoverySelectors, в пользовательские namespaces.
Если была также использована настройка spec.revision, то пользовательскому namespace необходимо добавить label istio.io/rev=<значение_поля_revision_из_конфигурации_IstioOperator>. Поэтому удобнее будет задавать в Istio Operator spec.meshConfig.discoverySelectors как istio.io/rev=<значение_поля_revision_из_конфигурации_IstioOperator>. Тогда будет необходимо добавить только один label на пользовательский namespace.
Для удаления пользовательского namespace из Контрольной панели необходимо удалить у данного namespace labels, соответствующие настройке spec.meshConfig.discoverySelectors.
Работа с cooperator#
Cooperator обрабатывает три основных ресурса:
ServiceMeshMemberRoll — ресурс, создаваемый в namespace POLM. В ServiceMeshMemberRoll перечисляются:
labels, которые нужно добавить/удалить к подключаемым Data Plane namespaces
список namespaces, c которыми работает контрольная панель, а также их статус
ServiceMeshMember — ресурс, создаваемый в namespaces Data Plane, в нем указывается имя namespace POLM.
Namespace — ресурс, в котором Cooperator поддерживает список необходимых labels.
Допускается три варианта подключения Data Plane к POLM:
через конфигурацию ServiceMeshMemberRoll силами Администраторов POLM
через конфигурацию ServiceMeshMember силами Администраторов Data Plane namespaces.
через список labels ресурса Namespace силами Администраторов POLM. При этом для подключения Data Plane namespace не обязательно одновременно указывать его в ServiceMeshMemberRoll, создавать ServiceMeshMember и добавлять labels в ресурс Namespace, достаточно выполнить одно их этих действий.
Важно отметить, что на один namespace POLM предполагается не более одного ресурса ServiceMeshMemberRoll и, аналогично, на один namespace Data plane предполагается не более одного ресурса ServiceMeshMember. При создании более чем одного ресурса — в обоих случаях поведение сервиса неопределенно.
Подключение администратором Data Plane через ServiceMeshMember#
Пример конфигурации
apiVersion: networking.synapse.sber/v1alpha1
kind: ServiceMeshMember
metadata:
name: member
spec:
controlPlaneRef:
namespace: istio-system
При создании ресурса ServiceMeshMember в namespace Data Plane, в нем указывается ссылка на namespace POLM, к которому требуется подключить данный Data Plane (поле Control PlaneRef).
Если в namespace POLM нет ресурса ServiceMeshMemberRoll, то namespace Data Plane не будет подключен, в блоке status будет сообщение о том, почему не удалось подключить namespace.
Пример конфигурации
apiVersion: networking.synapse.sber/v1alpha1 kind: ServiceMeshMember metadata: name: member spec: controlPlaneRef: namespace: istio-system status: included: false message: Control plane not foundЕсли в namespace POLM есть ресурс ServiceMeshMemberRoll, то возможны следующие сценарии:
Напротив Namespace Data Plane в списке data-planes стоит значение
falseилиtrueресурса ServiceMeshMemberRoll, тогда никакие действия над namespace производиться не будут, так как обработка namespaces из этих списков будет выполняться в рамках работы контроллера ServiceMeshMemberRoll. Запись об этом появится в блоках status ресурсов.Пример конфигурации со значением
falseapiVersion: networking.synapse.sber/v1alpha1 kind: ServiceMeshMember metadata: name: member namespace: cooperator-a spec: controlPlaneRef: namespace: istio-system status: included: false message: Excluded --- apiVersion: networking.synapse.sber/v1alpha1 kind: ServiceMeshMemberRoll metadata: name: roll namespace: istio-system spec: data-planes: cooperator-a: false labelSelector: matchLabels: istio.io/rev: istio-systemПример конфигурации со значением
trueapiVersion: networking.synapse.sber/v1alpha1 kind: ServiceMeshMember metadata: name: member namespace: cooperator-a spec: controlPlaneRef: namespace: istio-system status: included: true message: Connected --- apiVersion: networking.synapse.sber/v1alpha1 kind: ServiceMeshMemberRoll metadata: name: roll namespace: istio-system spec: labelSelector: matchLabels: istio.io/rev: istio-system data-planes: cooperator-a: trueNamespace Data Plane не находится в списке spec.data-planes ресурса ServiceMeshMemberRoll, тогда namespace Data Plane будет подключен к POLM. Запись об этом появится в блоках status ресурсов.
Пример конфигурации
apiVersion: networking.synapse.sber/v1alpha1 kind: ServiceMeshMember metadata: name: member namespace: cooperator-a spec: controlPlaneRef: namespace: istio-system status: included: true message: Connected --- apiVersion: networking.synapse.sber/v1alpha1 kind: ServiceMeshMemberRoll metadata: name: roll namespace: istio-system spec: data-planes: cooperator-a: true labelSelector: matchLabels: istio.io/rev: istio-system
При удалении ресурса ServiceMeshMember namespace отключается от POLM.
Подключение Data Plane администратором Control Plane через ServiceMeshMember#
Пример конфигурации
apiVersion: networking.synapse.sber/v1alpha1
kind: ServiceMeshMemberRoll
metadata:
namespace: istio-system
name: roll
spec:
data-planes:
cooperator-a: true
cooperator-b: false
labelSelector:
matchLabels:
istio.io/rev: istio-system
В ресурсе ServiceMeshMemberRoll, создаваемом в namespace POLM, есть два основных блока:
data-planes — список namespaces Data Plane, которые подключены или отключены (в зависимости от значения) от Control Plane;
labelSelector — значение labelSelector из настройки discoverySelector POLM (см. Руководство по установке).
При обработке ресурса Cooperator выполняет следующие действия:
Проверяет, удаляется ли ресурс, который в данный момент поступил на обработку Cooperator:
Если ресурс не удаляется и у него нет finalizers, то они добавляются к данному ресурсу.
Из кластера выгружаются все ресурсы ServiceMeshMember с полем
spec.controlPlaneRef.namespaceравным Namespace Control Plane, а также все ресурсы Namespace, соответствующие labelSelector:
Если ресурс удаляется, то все namespaces Data Plane из списка spec.data-planes отключаются от POLM;
Если ресурс не удаляется, то вычисляется разница между текущим состоянием кластера и тем, что описано в ServiceMeshMemberRoll. Эта разница нивелируется в списке spec.data-planes:
все namespaces, которые имеют значение
false, будут отключены;все namespaces, которые имеют значение
trueили имеют ресурс ServiceMeshMember, ссылающийся на нашу Control Plane или соответствуютspec.labelSelector, будут подключены;все остальные namespaces будут проигнорированны.
Если во время обработки ресурса какого-либо namespace уже нет на кластере, то ошибка об этом будет записана в прикладной журнал Cooperator, при этом данная ошибка не остановит и не сломает работу Cooperator.
При удалении ресурса ServiceMeshMemberRoll, все подключенные namespaces к POLM будут отключены.
Метрики Cooperator#
При подключении Data Plane Namespace «data-plane» к Control Plane Namespace «control-panel», изменяются две основные метрики Cooperator-а:
data_planes_named - Показывает статус подключения Data Plane к Control Plane. Значение всегда равно нулю.
# HELP data_planes_named Data plane name, associated with Control plane
# TYPE data_planes_named gauge
data_planes_named{cp="control-panel",dp="data-plane",status="included"} 0
data_planes_total - Показывает количество Data Plane-ов, которые были обработаны определенной Control Plane с определенным статусом.
# HELP data_planes_total Number of Data planes, associated with Control plane
# TYPE data_planes_total gauge
data_planes_total{cp="control-panel",status="error"} 0
data_planes_total{cp="control-panel",status="excluded"} 0
data_planes_total{cp="control-panel",status="included"} 1
Поле status в метриках data_planes_named и data_planes_total имеет всего 3 возможных значения:
included - Data Plane успешно подключен к Control Plane
excluded - Data Plane успешно отключен от Control Plane
error - ошибка при подключении/отключении Data Plane от Control Plane
Так как Cooperator может завершить обработку с ошибкой еще до проверки Data Plane-ов, существует метрика controller_runtime_reconcile_errors_total, отображающая количество непредвиденных ошибок в Cooperator. Она всегда содержит label controller="servicemeshmemberroll".
# HELP controller_runtime_reconcile_errors_total Total number of reconciliation errors per controller
# TYPE controller_runtime_reconcile_errors_total counter
controller_runtime_reconcile_errors_total{controller="servicemeshmemberroll"} 0
Дополнительные примеры кастомизации 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 для Управления политиками#
При большом количестве подключенных namespace отводимого для старта контейнера времени initialDelaySeconds readinessProbe контейнера discovery может быть недостаточно для успешного старта (значение по умолчанию - 10 секунд). Задать новое значение можно через k8s.overlays. Сделать это можно двумя способами:
Через имя контейнера:
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
Через индекс контейнера (индекс контейнера 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 задается значение в секундах, в течение которого контейнер 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
для указания namespace, в котором будет происходить валидация (значение по умолчанию — текущий namespace kubectl config);
-i, –istioNamespace
namespace с контрольной панелью (значение по умолчанию - istio-system);
–context
имя контекста kubectl config ;
-v, –vklog
номер уровня детализации логов. Например: –vklog=9
Типы валидируемых конфигураций#
Команда istioctl validate поддерживает следующие типы конфигураций:
Deployment
Sidecar
Service
Gateway
VirtualService
DestinationRule
EnvoyFilter
ServiceEntry
Правила валидации#
1. Deployment:
Ingress и Egress должны иметь уникальное название в selector.matchLabels в значении app (например: ingress-название namespace), чтобы перехватываемый ими трафик не смешивался с другими Ingress и Egress в кластере;
значение Selector.MatchLabels не должно полностью содержаться в другом deployment этого namespace, и другие deployments namespace не должны содержать все Selector.MatchLabels текущего;
нельзя использовать аннотации и labels maistra.io/<любое значение> для ресурсов, созданных вручную, т.к. они означают, что ресурсы созданы и управляются Istio Operator. Во время ближайшего обновления ресурсы с этими аннотациями и labels будут перезаписаны или удалены оператором.
2. Sidecar:
нельзя создавать Sidecar в namespace istio-system, т.к. в этом случае обновления из контрольной панели перестают приходить в pods подключенных к ней namespaces.
3. Service:
по требованиям безопасности нельзя использовать type: NodePort, type: LoadBalancer, так как использование этих настроек откроет прямой доступ к сервису извне кластера OpenShift;
должны присутствовать labels в поле spec.selector;
имя порта должно соответствовать маске <protocol>-* (например: http, http-8080, tcp, tcp-7575), т.к. правила распределения запросов применяются Istio к портам Service в соответствии с протоколом в имени порта;
нельзя использовать targetPort ниже 1024, т.к. он может быть занят служебными портами компонентов service mesh.
4. Gateway:
значение labels spec.selector не должно полностью содержаться в другом gateway этого namespace, и другие gateways namespace не должны содержать все spec.selector текущего;
нельзя использовать port.number ниже 1024, т.к. он может быть занят служебными портами компонентов service mesh;
имя порта должно соответствовать маске <protocol>-* (например: http, http-8080, tcp, tcp-7575), т.к. правила распределения запросов применяются Istio к портам Gateway в соответствии с протоколом в имени порта;
конфигурация обязательно должна содержать поле spec.selector.
5. VirtualService:
проверяется уникальность 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).
6. DestinationRule:
конфигурационный файл должен содержать уникальный spec.host + spec.workloadSelector.matchLabels в рамках namespace, т.к. применится только первый загруженный конфигурационный файл;
допустимы конфигурационные файлы только со значением exportTo: «.» (применить конфигурационный файл к текущему namespace);
не допускается использование «*» в поле hosts. Можно писать DNS-имя, IP или DNS-имя с wildcard (например: *.ХХ.ХХ.ru).
7. EnvoyFilter:
конфигурационный файл должен содержать поле 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, чтобы задать количество ресурсов для вычисления регулярного выражения.
8. ServiceEntry:
в одном конфигурационном файле должен быть описан только 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
2. 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: Х.Х.Х.Х
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
3. 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
4. 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
5. 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 для Egress и Ingress
6. 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
7. 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
8. 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 у контрольной панели задано, то контрольная панель будет валидировать конфигурации только из namespaces, имеющих label istio.io/rev = <значение_revision_контрольной_панели>. Если же revision у контрольной панели отсутствует, то будут валидироваться конфигурации из namespaces, имеющих label istio.io/rev = default.
Обработка обратнонесовместимого блока status в конфигурациях Istio#
У конфигураций Istio есть блок status. Этот блок возможно проставить либо средствами контрольной панели, либо используя специальные программные клиенты, написанные именно с целью изменения блока status. Обычные манипуляции пользователя через UI или kubectl никак не повлияют на блок status.
В opensource Istio, начиная с версии 1.8, поменялся API блока status, он стал обратно несовместим с предыдущими версиями. Если на кластере имеются инсталляции Istio версий ниже 1.8, то это может привести к блокировке работы POLM (istiod).
У этой проблемы два решения:
Удалить блок status.
Использовать 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 могут быть видны между всеми пользовательскими namespaces, подключенными к одной Контрольной панели (Управления политиками). Чтобы включить изоляцию данных конфигураций, то есть ограничить видимость только теми namespaces, в которых они были созданы, достаточно добавить данный блок в конфигурацию 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: istioControl Plane
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 доступны только в пределах namespaces, подключенных к той же Контрольной панели.
Для того чтобы создать Istio Soft Multitenancy, необходимо использовать spec.revision (позволяет ставить независимо несколько Контрольных панелей) и spec.meshConfig.discoverySelectors (позволяет включить изоляцию). Также важно задать в конфигурационном файле spec.meshConfig.rootNamespace <имя_namespace_контрольной_панели>. В 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>: <значение_label>
...
revision: istio-system
...
Пример:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: istioControl Plane
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: <имя_namespace_контрольной_панели>. При использовании spec.revision для подключения автоматического добавления (inject) Сервисного прокси в прикладной pod пользовательского namespace необходимо будет добавить этому namespace label istio.io/rev: <имя_namespace_контрольной_панели>.
Cooperator#
Для подключения и отключения Data plane от Control Plane, можно использовать Cooperator.
Запуск Cooperator#
При установке Cooperator в кластер важно задать значение для переменной softStart. Если в кластере уже имеется POLM, то переменной нужно задать значение true. Это гарантирует, что уже подключенные Data plane не отключатся при удалении ресурсов Cooperator. Подробнее описанно в документации по установке.
Управление подключениями namespace#
Для управления подключением namespace используются два типа ресурсов: ServiceMeshMember и ServiceMeshMemberRoll.
Управление из Control Plane#
В Control plane namespace’а POLM необходимо вручную добавить ServiceMeshMemberRoll, предварительно описав необходимые labels для подключения к текущей Control plane в spec.labelsSelector.matchLabels. ServiceMeshMemberRoll имеет возможность определения списка spec.data-planes. После установки сконфигурированного ServiceMeshMemberRoll, Cooperator актуализирует список spec.data-planes.
Когда ServiceMeshMemberRoll создан, ресурс предоставляет возможность добавить название Data plane в список spec.data-planes со значением true для подключения к текущей контрольной панели, или со значением false для отключения от текущей контрольной панели.
Для безопасного отключения всех namespace от Control plane, нужно удалить ServiceMeshMemberRoll из Control Plane. В таком случае, все неймспейсы, не содержащие лейбл sbertech.ru/cooperator: ok будут отключены от текущей Control plane.
Управление из Data Plane#
Для подключения Data Plane, необходимо добавить в него ресурс ServiceMeshMember, предварительно указав название Control plane, к которому собираемся присоединиться в spec.controlPlaneRef.namespace. После установки сконфигурированного ServiceMeshMember, Cooperator опишет текущее состояние Data plane в status ресурса.
Если Data plane содержит все labels из spec.labelsSelector.matchLabels хотя бы одного ServiceMeshMemberRoll в кластере, то ServiceMeshMember автоматически создастся Cooperaotr-ом, при этом с параметром spec.controlPlaneRef.namespace=<Control plane Namespace>.
Когда ServiceMeshMember создан, можно переподключиться к другой контрольной панели, изменив название Control plane в spec.controlPlaneRef.namespace. Также можно отключиться от контрольной панели, удалив ресурс ServiceMeshMember из Data plane.
При отлючении от Control plane с помощью ServiceMeshMember, название Data plane в списке spec.data-planes не будет иметь значение false ресурса ServiceMeshMemberRoll, а лишь удалится из этого списка.
События системного журнала#
Для просмотра системного журнала через веб-интерфейс Kubernetes необходимо выполнить следующие действия:
Зайдите в namespace контрольной панели.
В меню выберите пункт Workload/Pods.
На странице найдите нужный pod.
Перейдите по ссылке в этот pod.
Перейдите на вкладку ≡ (Logs). В консоли не должно быть ошибок.
Шаг |
Действие |
|---|---|
Вход в веб-консоль Kubernetes |
Перейдите по ссылке (URL) веб-консоли нужного кластера Kubernetes, в окне ввода учетных данных введите токен пользователя или kubeconfig |
Переход в namespace |
Выберите нужный namespace в выпадающем списке в шапке веб-интерфейса Kubernetes |
Переход в Workload/Pods |
Выполните следующие действия: |
Просмотр событий системного журнала |
В появившемся окне можно увидеть системный журнал приложения (логи) |
Выход из веб-консоли Kubernetes |
Выполните следующие действия: |
В разделе Событий можно увидеть как успешные запуски 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 можно настроить уровень логирования несколькими способами:
Настройка конфигурации установки IstioOperator
Пример:
apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: ... spec: ... values: global: logging: level: <значение_логирования> ...
Настройка values в Helm chart
Пример для консольного аргумента:
helm ... --set global.logging.level=<значение_логирования>Пример для файла values:
global: logging: level: <значение_логирования>
Ручная настройка 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 |
В namespace контрольной панели могут быть созданы конфигурации препятствующие взаимодействия kubeapi-server и POLM |
Необходимо обратиться к сопровождению инфраструктуры для обеспечения доступа между kubeapi-server и POLM |
Не происходит inject SVPX в прикладной pod |
У прикладного namespace или его pod отсутствуют необходимые labels/аннотации |
Необходимо убедиться, что у namespace проставлен label |
POLM не может аутентифицировать SVPX |
Невалидный токен или отсутствие токена в файловой системе контейнера SVPX |
Если при подключении SVPX возникает ошибка аутентификации со стороны POLM, то необходимо проверить, что в контейнере SVPX по пути |
Не стартует pod приложения istiod (POLM) |
Недостаточно ресурсов |
Увеличить лимиты/requests для приложения |
Не стартует pod приложения istiod (POLM) |
Ресурсы pod не соответствуют ограничениям, заданным в LimitRanges |
Изменить ресурсы для приложения таким образом, чтобы они соответствовали LimitRanges, либо удалить LimitRanges |
Не стартует pod приложения istiod (POLM) |
Нет доступной Node для запуска |
Зарегистрировать обращение в поддержку инфраструктуры |
Не стартует pod приложения istiod (POLM) |
Ошибка в конфигурации |
Выгрузить лог, провести анализ, скорректировать конфигурацию |
Частый рестарт контейнера приложения istiod (POLM) |
Медленная загрузка приложения |
Увеличить задержку и/или интервал опроса Liveness/Readiness-пробы: увеличить в Deployment POLM параметр |
Частый рестарт контейнера приложения istiod (POLM) |
Недостаточно ресурсов |
Увеличить лимиты/requests для приложения |
Cooperator не обрабатывает ресурсы ServiceMeshMemberRoll и ServiceMeshMember |
Cooperator не запущен |
Создать Deployment Cooperato-а в кластере |
Cooperator не обрабатывает ресурс ServiceMeshMember |
Control plane, на которую ссылается ServiceMeshMember не содержит ресурс ServiceMeshMemberRoll |
Создать ресурс ServiceMeshMemberRoll в Namespace Control Plane |