- PVSM.RU - https://www.pvsm.ru -
Когда я впервые столкнулся с задачей масштабирования сложного приложения в Kubernetes, то был полон оптимизма. Однако вскоре стало ясно, что управление сетевым трафиком и безопасностью в такой динамичной среде — это непросто. Наше приложение начало страдать от потерь пакетов данных и сетевых задержек, что сказывалось на общей производительности и пользовательском опыте. Из-за этого возникла потребность в глубоком понимании сетевых возможностей Kubernetes, таких, как сервисы, Ingress и Network Policies, чтобы эффективно управлять трафиком, обеспечивать безопасность и максимизировать производительность. Этот опыт стал для меня настоящим откровением и подтолкнул к написанию данной статьи.
Меня зовут Дмитрий, и я старший DevOps-инженер в ГК Иннотех. В моей работе я часто сталкиваюсь с задачами, которые требуют глубокого понимания сетевых аспектов в Kubernetes.
Например, для обеспечения стабильного взаимодействия между микросервисами я использую сервисы в Kubernetes, которые позволяют мне абстрагироваться от конкретных подов и обеспечивают надёжный механизм балансировки нагрузки.
Когда дело доходит до экспозиции наших приложений наружу, я применяю Ingress для управления входящим трафиком. Это не только упрощает настройку SSL/TLS, но и предоставляет гибкие возможности для маршрутизации. И, конечно же, безопасность стоит не на последнем месте. С помощью Network Policies можно тонко настроить сетевые правила, определяя, какие поды могут взаимодействовать друг с другом, что значительно повышает уровень безопасности нашей инфраструктуры.
Данная статья будет особенно полезна для DevOps-инженеров, системных администраторов и архитекторов, которые хотят глубже понять механизмы сетевого взаимодействия в Kubernetes.
Сосредоточимся на критически важных элементах, таких, как сервисы, Ingress и Network Policies. Освоение этих базовых принципов не только упростит вашу работу с Kubernetes, но и даст вам уверенность в управлении сложными системами. Надеюсь, это будет полезно!
Давайте начнём по порядку.
Сервис в Kubernetes — это высокоуровневая абстракция, предназначенная для обеспечения доступа к одному или нескольким подам, работающим в кластере. Сервисы упрощают процесс взаимодействия между различными компонентами приложения и предоставляют удобный интерфейс для доступа к ресурсам. Проще говоря, сервис в Kubernetes выступает в роли стабильной сетевой точки входа для приложений, которые работают в кластере.
Важно упомянуть, что сервисы используют селекторы для идентификации подов, которые должны быть частью данного сервиса. Селекторы позволяют группировать поды по определённым критериям, таким, как метки или имена.
Каждый сервис имеет уникальное имя и может быть сконфигурирован для работы в разных режимах доступа. Например, service может быть настроен на внутренний доступ только внутри кластера или он может быть настроен на внешний доступ через внешний балансировщик нагрузки. В связи с такой вариативностью сервисы разделили на несколько типов:

Анализ типов сервисов в Kubernetes: ClusterIP, NodePort и LoadBalancer
Давайте более детально разберёмся с перечисленными типами сервисов. Для удобства по каждому из типов я выделил основные характеристики, постарался рассказать, как работает тот или иной тип, и рассказал о его применении.
Пожалуй, начнём с ClusterIP.
ClusterIP — это наиболее распространённый тип сервиса в Kubernetes и, возможно, самый простой для понимания. Он предназначен для внутренних нужд кластера, обеспечивая доступ к подам внутри кластера.

Внутренний IP-адрес
ClusterIP получает внутренний IP-адрес, который доступен только внутри кластера. Этот IP-адрес не может быть доступен извне кластера.
Балансировка нагрузки
ClusterIP автоматически распределяет входящий трафик между подами, соответствующими селектору сервиса. Это обеспечивает балансировку нагрузки и повышает отказоустойчивость.
Сессионная аффинность
ClusterIP может быть настроен для поддержки сессионной аффинности на основе клиентского IP-адреса. Это позволяет всем запросам от одного и того же клиента направляться на один и тот же под.
Работа ClusterIP:
Применение:
ClusterIP — это мощный инструмент для организации внутреннего взаимодействия в Kubernetes-кластере. Он предоставляет балансировку нагрузки, сессионную аффинность и множество других функций, которые делают его идеальным выбором для многих сценариев использования.
NodePort — это один из типов сервисов в Kubernetes, который позволяет обращаться к приложениям внутри кластера снаружи. Этот тип сервиса открывает статический порт на каждом узле кластера и перенаправляет входящий трафик с этого порта на поды, соответствующие селектору сервиса.

Статический порт
NodePort открывает статический порт в диапазоне 30 000–32 767 на каждом узле кластера. Этот порт доступен снаружи и может быть использован для доступа к сервису.
Перенаправление трафика
Весь входящий трафик на NodePort перенаправляется на соответствующий ClusterIP, который затем направляет его на поды.
Балансировка нагрузки
Трафик, поступающий на NodePort, распределяется между подами с использованием балансировки нагрузки, предоставляемой ClusterIP.
Работа NodePort:
Применение:
NodePort — это удобный способ предоставления внешнего доступа к приложениям, работающим в Kubernetes. Он легко настраивается и не требует дополнительных ресурсов, что делает его идеальным выбором для многих сценариев.
LoadBalancer — это тип сервиса в Kubernetes, который автоматически предоставляет внешний балансировщик нагрузки для приложений в кластере. Этот тип сервиса используется, когда необходимо обеспечить доступ к приложениям извне кластера.

Внешний балансировщик нагрузки
LoadBalancer автоматически создаёт и настраивает внешний балансировщик нагрузки, который перенаправляет входящий трафик на NodePort или ClusterIP.
Автоматическое проксирование
LoadBalancer автоматически настраивает правила проксирования для перенаправления трафика на подходящие поды.
Интеграция с облачными провайдерами
LoadBalancer часто интегрируется с облачными провайдерами для автоматического создания и управления ресурсами балансировщика нагрузки.
Работа LoadBalancer:
Применение:
LoadBalancer — это мощный инструмент для обеспечения внешнего доступа к приложениям в Kubernetes. Он предлагает автоматическую балансировку нагрузки, интеграцию с облачными провайдерами и множество других функций, которые делают его идеальным выбором для различных сценариев.
Конечно же, некоторые, читая статью, могут сказать: «Вообще-то не все типы сервисов в Kubernetes перечислены». Ничего я не забыл, просто решил выделить их в отдельную группу :)
В Kubernetes также существует несколько типов сервисов, каждый из которых решает определённые задачи. В этом контексте Headless Services, Dual-Stack Services и Topology-Aware Routing являются специализированными типами сервисов, предназначенными для решения конкретных проблем в различных сценариях.
Пройдёмся по каждому типу по тому же принципу, как делали выше.
Headless Services: представляют собой особый тип сервисов, который не имеет ClusterIP. Это позволяет подам общаться напрямую друг с другом без промежуточного слоя в виде kube-proxy.
Этот механизм часто используется в распределённых системах, где требуются низкая латентность и высокая производительность.
Основные характеристики:
Пример YAML-конфигурации:
apiVersion: v1
kind: Service
metadata:
name: my-heandless-service
spec:
clusterIP: None
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targerPort: 8080
В этом примере ключевым моментом является строка `clusterIP: None`, которая указывает, что это Headless Service.
При использовании Headless Service DNS возвращает A-записи для подов, которые соответствуют селектору сервиса. Например, если у вас есть два пода с IP-адресами `192.168.1.1` и `192.168.1.2`, то DNS вернёт оба этих адреса в ответ на запрос к `my-headless-service`.
StatefulSets
Headless Services часто используются с StatefulSets для обеспечения стабильной сетевой идентификации подов.
Распределённые базы данных
В распределённых системах, таких, как Cassandra или MongoDB, Headless Services позволяют подам обнаруживать друг друга и общаться напрямую.
Peer-to-Peer сети
В P2P-сетях, где каждый узел является равноправным, Headless Services предоставляют возможность для прямого обмена данными между подами.
Headless Services в Kubernetes предоставляют гибкий и эффективный механизм для управления сетевыми соединениями в сложных распределённых системах. Они убирают некоторые слои абстракции, что может быть критично для систем, требующих высокой производительности и низкой латентности.
Dual-Stack Services в Kubernetes предоставляют возможность использовать как IPv4, так и IPv6 адреса для одного и того же сервиса. Это особенно полезно для организаций, которые переходят на IPv6, но всё ещё нуждаются в поддержке IPv4.
Основные характеристики:
Пример YAML-конфигурации:
apiVersion: v1
kind: Service
metadata:
name: my-dual-stack-service
spec:
ipFamilyPolicy: PreferDualStack
ipFamilies:
- IPv4
- IPv6
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targerPort: 8080
В этом примере ключевыми параметрами являются `ipFamilyPolicy: PreferDualStack` и `ipFamilies: [IPv4, IPv6]`, которые указывают на использование обоих стеков IP.
Когда вы создаёте Dual-Stack Service, Kubernetes автоматически назначает два IP-адреса: один — из диапазона IPv4, и один — из диапазона IPv6. Эти адреса будут использоваться для маршрутизации трафика в зависимости от версии IP исходного запроса.
Гибридные облака
В гибридных облачных средах, где часть ресурсов использует IPv4, а часть — IPv6, Dual-Stack Services обеспечивают единый интерфейс для обоих типов ресурсов.
Миграция и обратная совместимость
Для организаций, которые переходят на IPv6, Dual-Stack Services предоставляют возможность поддерживать существующие IPv4-системы, минимизируя риски и сложности миграции.
Сетевая оптимизация
Использование Dual-Stack позволяет оптимизировать сетевую производительность, выбирая наилучший маршрут для каждой версии IP.
Dual-Stack Services в Kubernetes предоставляют мощный инструмент для управления сетевым трафиком в современных разнообразных сетевых средах. Они обеспечивают гибкость, обратную совместимость и оптимизацию производительности, делая их неотъемлемой частью современных кластеров Kubernetes.
Topology-Aware Routing — это функциональность в Kubernetes начиная с версии 1.17, которая позволяет сервисам маршрутизировать трафик с учётом топологии кластера. Это может быть полезно для снижения сетевой задержки, улучшения производительности и повышения надёжности системы.
Основные характеристики:
Пример YAML-конфигурации:
apiVersion: v1
kind: Service
metadata:
name: my-topology-aware-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targerPort: 8080
topologyKeys:
- "kubernetes.io/hostname"
- "topology.kubernetes.io/zone"
- "topology.kubernetes.io/region"
В этом примере ключевым параметром является `topologyKeys`, который определяет приоритеты для маршрутизации трафика.
При использовании `topologyKeys` Kubernetes будет пытаться маршрутизировать трафик на поды, которые соответствуют указанным ключам топологии в порядке их приоритета.
Например, сначала будет попытка направить трафик на поды на том же узле (`kubernetes.io/hostname`), затем — в той же зоне (`topology.kubernetes.io/zone`), и так далее.
Микросервисы
В микросервисных архитектурах, где задержка может критически влиять на производительность, Topology-Aware Routing может быть очень полезным.
Большие кластеры и много зон
В больших и географически распределённых кластерах эта функциональность может существенно снизить затраты на передачу данных и улучшить общую производительность.
Высоконагруженные системы
В системах с высокой нагрузкой и требованиями к надёжности умная маршрутизация трафика может снизить вероятность точек отказа.
Topology-Aware Routing в Kubernetes представляет собой мощный инструмент для оптимизации сетевого взаимодействия в кластере. Он предлагает гибкие настройки и может адаптироваться к различным требованиям и сценариям использования, делая вашу систему более производительной и надёжной.
Итак, по типам сервисов в Kubernetes мы прошлись. Давайте двигаться дальше.
Ранее я уже писал, что сервисы в Kubernetes выступают в роли стабильной сетевой точки входа для приложений, которые работают в кластере. Так вот, есть механизм, который предоставляет внешнюю точку входа для различных сервисов, запущенных внутри кластера, — Ingress.
Ingress в Kubernetes — это API-объект, который управляет внешним доступом к сервисам в кластере. Он предоставляет HTTP- и HTTPS-маршруты к сервисам на основе условий, таких, как URL-путь или имя хоста. Ingress работает в тандеме с Ingress Controller, который реализует правила, определённые в Ingress. Wildcard Hosts и IngressClass являются специализированными атрибутами или объектами, которые расширяют функциональность Ingress.

Схема примера Ingress
IngressClass — это концепция в Kubernetes, введённая в версии 1.18, которая позволяет более гибко управлять различными Ingress-контроллерами в кластере. Это особенно полезно в сложных или многоуровневых архитектурах, где может быть несколько разных Ingress-контроллеров, каждый из которых выполняет специфические задачи.
Основные характеристики:
Пример YAML-конфигурации:
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadaata:
name: custom-ingress-class
spec:
controller: example.com/custom-controller
parameters:
apiGroup: example.com/v1
kind: CustomParameters
name: custom-params
В этом примере создаётся IngressClass с именем `custom-ingress-class`, который использует пользовательский контроллер `example.com/custom-controller` и параметры `CustomParameters`.
После создания IngressClass вы можете ссылаться на него в спецификации Ingress-ресурса:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
ingressClassName: custom-ingress-class
Теперь этот Ingress будет обрабатываться контроллером, указанным в `custom-ingress-class`.
Многотенантные кластеры
В многотенантных кластерах, где разные команды или приложения могут требовать различных настроек Ingress, IngressClass позволяет изолировать трафик и параметры настройки.
Файн-тюнинг и оптимизация
IngressClass позволяет оптимизировать производительность и безопасность, применяя различные Ingress-контроллеры для разных типов трафика или приложений.
Гибкая пасширяемость
С помощью IngressClass вы можете легко добавлять новые Ingress-контроллеры или обновлять существующие, не затрагивая других частей системы.
IngressClass в Kubernetes предоставляет высокую степень гибкости и контроля при работе с Ingress-ресурсами. Это упрощает управление сложными кластерами и позволяет адаптировать систему под различные требования и сценарии использования.
Wildcard Hosts в контексте Kubernetes Ingress позволяют управлять маршрутизацией трафика для нескольких поддоменов с помощью одного и того же Ingress-ресурса. Эта функциональность особенно полезна для динамически масштабируемых приложений и микросервисов.
Основные характеристики:
Пример YAML-конфигурации:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: default
spec:
rules:
- host: "*.example.foo.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
В этом примере Ingress-ресурс настроен для обработки всех запросов, направленных на поддомены домена `example.com`.
Когда запрос приходит на любой поддомен вида `*.example.com`, Kubernetes Ingress с использованием Wildcard Hosts перенаправляет этот запрос на соответствующий сервис (`my-service` в данном примере).
Многотенантные приложения
В многотенантных приложениях, где каждому клиенту может быть выделен свой поддомен, Wildcard Hosts позволяют упростить управление и маршрутизацию трафика.
Динамические среды
В динамических средах, где поддомены могут часто добавляться или удаляться, использование Wildcard Hosts упрощает процесс изменения конфигурации.
Сокращение ресурсов
Использование Wildcard Hosts может сократить количество необходимых Ingress-ресурсов, что положительно сказывается на производительности и управляемости кластера.
Wildcard Hosts в Kubernetes Ingress предоставляют гибкий и эффективный способ управления маршрутизацией трафика для множества поддоменов. Это упрощает архитектуру и уменьшает нагрузку на систему, делая ваш кластер более удобным в управлении и масштабировании.
Ещё следует уделить внимание объектам, которые контролируют, как поды могут общаться между собой и с другими сетевыми ресурсами. Они называются Network Policies.
Эти политики позволяют устанавливать сложные правила для управления сетевым трафиком, что повышает безопасность и изоляцию компонентов приложения. Namespace Selectors и Egress Policies являются ключевыми элементами, которые предоставляют дополнительные возможности для управления сетевым трафиком и доступом.
Поды-источники и поды-назначения:

Схема примера Network Policy
Namespace Selectors в Kubernetes позволяют управлять доступом к ресурсам на уровне пространств имён (namespaces). Это особенно полезно для улучшения безопасности, изоляции рабочих нагрузок и управления политиками сетевого доступа.
Основные характеристики:
Пример YAML-конфигурации для NetworkPolicy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-namespace-selector
spec:
policyTypes:
- Ingress
podSelector: {}
ingress:
- from:
- namespaceSelector:
matchLabels:
project: my-project
В этом примере NetworkPolicy разрешает входящий трафик от всех подов в пространствах имён, помеченных меткой `project: my-project`.
Namespace Selectors работают путём сопоставления меток пространств имён с метками, указанными в селекторе. В случае совпадения политика или правило применяется к этому пространству имён.
Многотенантные кластеры
В многотенантных кластерах, где несколько команд или проектов разделяют один и тот же кластер, Namespace Selectors обеспечивают необходимую изоляцию и безопасность.
Файн-тюнинг политик
Namespace Selectors позволяют создавать более сложные и гибкие политики доступа, которые могут варьироваться в зависимости от конкретных требований проекта или команды.
Сегментация сети
С помощью Namespace Selectors можно эффективно сегментировать сетевой трафик, создавая барьеры между различными частями приложения или микросервисами.
Namespace Selectors в Kubernetes предоставляют мощный инструмент для управления доступом и безопасностью на уровне пространств имён. Они предлагают гибкость и гранулярный контроль, что делает их незаменимым инструментом в сложных и многотенантных кластерах.
Egress Policies в Kubernetes позволяют контролировать исходящий трафик от подов к ресурсам внутри или вне кластера. Это ключевой элемент для улучшения безопасности и соблюдения политик сетевого доступа в вашем кластере.
Основные характеристики:
Пример YAML-конфигурации для NetworkPolicy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: restrict-egress
spec:
policyTypes:
- Egress
podSelector:
matchLabels:
app: my-app
egress:
- to:
- ipBlock:
cidr: 192.168.0.0/16
ports:
- protocol: TCP
port: 80
В этом примере NetworkPolicy ограничивает исходящий трафик от подов с меткой `app: my-app` только до IP-адресов в диапазоне `192.168.0.0/16` на порту 80.
Egress Policies работают, применяя набор правил к исходящему трафику от выбранных подов.
Эти правила могут включать в себя различные параметры, такие, как IP-адреса, порты и даже другие пространства имён.
Контроль доступа к внешним ресурсам
С помощью Egress Policies можно ограничить доступ подов к внешним API, базам данных или другим ресурсам, улучшая тем самым безопасность.
Соблюдение нормативов
Для организаций, которые должны соблюдать строгие нормативы по безопасности, такие, как GDPR или HIPAA, Egress Policies предоставляют необходимые средства для контроля и мониторинга данных.
Изоляция рабочих нагрузок
В многотенантных или микросервисных архитектурах Egress Policies помогают изолировать рабочие нагрузки и ограничивать взаимодействие между ними для повышения безопасности и производительности.
Egress Policies в Kubernetes являются мощным инструментом для управления исходящим трафиком и улучшения безопасности кластера. Они предлагают гибкость и гранулярный контроль, что делает их незаменимым элементом в любом сложном или многотенантном кластере.
Понимание сетевых аспектов Kubernetes является ключевым для эффективного управления и масштабирования приложений. Это играет важную роль в обеспечении сетевой безопасности и доступности. Все вместе эти компоненты обеспечивают гибкое управление сетевым трафиком и доступностью приложений в Kubernetes. Сервисы предоставляют стабильные точки входа для приложений, Ingress обеспечивает управление внешним трафиком и правила маршрутизации, а Network Policies позволяют настраивать безопасность и доступность сетевых соединений внутри кластера. Надеюсь, что эта статья помогла вам лучше понять сетевые аспекты Kubernetes.
Автор: Дмитрий Колесников
Источник [1]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/servisy/387621
Ссылки в тексте:
[1] Источник: https://habr.com/ru/companies/T1Holding/articles/767056/?utm_source=habrahabr&utm_medium=rss&utm_campaign=767056
Нажмите здесь для печати.