Kubernetes, ставший де-факто стандартом для оркестрации контейнеров, значительно упрощает развертывание, масштабирование и управление контейнеризированными приложениями. Однако, по мере роста и усложнения инфраструктуры, требования к сетевым возможностям также увеличиваются. В современных распределенных системах, где различные микросервисы взаимодействуют друг с другом, критически важно обеспечить безопасность, производительность и надежность сетевых коммуникаций. Здесь на помощь приходят продвинутые сетевые функции Kubernetes, такие как:
Network Policies
Service Mesh
Ingress Controllers
Функции для масштабирования и оптимизации сети
Функции поддержки высокодоступных и отказоустойчивых архитектур
Механизмы оптимизации и балансировки нагрузки
Функции для диагностики сетевых проблем
Эти функции и механизмы представляют собой набор инструментов, которые выходят за рамки базовой маршрутизации и балансировки нагрузки. Они предоставляют разработчикам и администраторам возможность детально управлять сетевыми взаимодействиями внутри кластера, обеспечивая тем самым высокий уровень безопасности и изоляции. Рассмотрим их подробнее.
Network Policies
C помощью Network Policies можно точно регулировать, какие поды могут общаться друг с другом, что особенно важно в многопользовательских средах или при работе с чувствительными данными.
Как и остальные ресурсы Kubernetes, сетевые политики задаются на языке YAML.
Пример того, как это может быть.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-specific-ingress
namespace: my-namespace
spec:
podSelector:
matchLabels:
role: frontend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: backend
ports:
- protocol: TCP
port: 80
Политика , написанная выше, позволяет только подам с меткой role: backend соединяться с подами с меткой role: frontend на порту 80. Это ограничивает доступ к фронтенд-сервисам, обеспечивая защиту от нежелательного трафика.
Ниже представлена схема, показывающая, как действует политика сети allow-specific-ingress в Kubernetes. Поды с меткой role: backend (зелёные) могут взаимодействовать с подами с меткой role: frontend (голубые) по TCP на порт 80. Другие поды (красные) не могут взаимодействовать с фронтенд-подами в рамках данной политики.
![Политика сети allow-specific-ingress Политика сети allow-specific-ingress](https://habrastorage.org/getpro/habr/upload_files/f82/ed9/140/f82ed9140a096eb0e37299a0b50d1264.png)
2. Service Mesh
Service Mesh, такие как Istio, предоставляют инфраструктуру для управления сетевыми взаимодействиями между микросервисами, обеспечивая такие возможности, как маршрутизация трафика, шифрование данных, аутентификация, авторизация и наблюдаемость.
2.1 Обеспечение безопасности и шифрование трафика с помощью mTLS
В приведенном YAML-манифесте настроена политика PeerAuthentication для использования mTLS (mutual TLS) в namespace my-namespace. Поле mode: STRICT указывает на то, что все связи между подами в этом namespace должны быть шифрованы с использованием mTLS. Это гарантирует, что данные передаются только между аутентифицированными и доверенными сервисами, обеспечивая конфиденциальность и целостность данных.
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: my-namespace
spec:
mtls:
mode: STRICT
2.2 Управление версиями API и маршрутизация трафика
Для управления версиями API и маршрутизации трафика, Istio предоставляет ресурс VirtualService
. С его помощью можно настроить правила маршрутизации для различных версий сервиса в зависимости от условий, таких как пользовательские данные или другие атрибуты.
Предположим, что у нас есть два деплоя сервиса: v1
и v2
. Мы можем использовать VirtualService для того, чтобы направлять трафик от пользователя user1
на версию v2
, а всех остальных пользователей на версию v1
.
Пример конфигурации для данной задачи.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: route-v1-v2
namespace: my-namespace
spec:
hosts:
- my-service
http:
- match:
- headers:
end-user:
exact: "user1"
route:
- destination:
host: my-service
subset: v2
- route:
- destination:
host: my-service
subset: v1
Ниже представлена визуализация описанных выше манифестов
![Визуализация принципов маршрутизации трафика Визуализация принципов маршрутизации трафика](https://habrastorage.org/getpro/habr/upload_files/3f7/f06/98f/3f7f0698f3543fa2319615e0f3473f23.png)
3. Ingress Controllers
Использование Ingress Controllers упрощает управление входящим трафиком, предоставляя единую точку доступа к различным сервисам в кластере и обеспечивая защиту данных с помощью TLS/SSL шифрования. Это решение становится особенно полезным в контексте мульти-кластерных сетей, которые позволяют интегрировать несколько кластеров в единую сетевую инфраструктуру. В таких гибридных или мульти-облачных средах Ingress Controllers помогают эффективно маршрутизировать HTTP(S) запросы к нужным микросервисам на основе URL-пути, упрощая управление и улучшая безопасность.
Пример Ingress-манифеста:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: my-namespace
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: example.com
http:
paths:
- path: /service1
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
- path: /service2
pathType: Prefix
backend:
service:
name: service2
port:
number: 80
Этот манифест маршрутизирует запросы с URL example.com/service1 к сервису service1, а запросы example.com/service2 — к сервису service2. Это упрощает управление входящим трафиком и позволяет легко управлять развертыванием и масштабированием сервисов, направляя запросы к нужным микросервисам без необходимости изменения конфигураций на уровне приложений.
3.1 Ingress Controllers: Варианты и Настройки
Ingress Controllers являются реализациями ресурса Ingress, которые управляют маршрутизацией входящего трафика на основе правил Ingress. Существует несколько популярных Ingress Controllers, включая NGINX, Traefik, и HAProxy, каждый из которых имеет свои особенности и преимущества.
3.1.1 NGINX Ingress Controller
NGINX Ingress Controller — это один из востребованных и широко используемых Ingress Controllers. Он обеспечивает высокую производительность и расширенные возможности настройки, включая маршрутизацию трафика на основе путей и хостов, управление SSL-терминацией и другие функции, необходимые для эффективного управления входящим трафиком в Kubernetes-кластере.
Конфигурация аннотаций для NGINX Ingress Controller:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: my-namespace
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: example.com
http:
paths:
- path: /service1
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
- path: /service2
pathType: Prefix
backend:
service:
name: service2
port:
number: 80
Этот манифест конфигурирует объект Ingress для маршрутизации запросов, приходящих на URL example.com
. Запросы, адресованные example.com/service1
, будут перенаправляться к сервису service1
, а запросы на example.com/service2
— к сервису service2
. В дополнение, аннотации обеспечивают переписывание пути на корневой и принудительное перенаправление HTTP-запросов на HTTPS. Это упрощает управление входящим трафиком и позволяет централизованно управлять маршрутизацией запросов, улучшая масштабируемость и развертывание микросервисов без необходимости изменения конфигураций приложений.
На рисунке представлена визуализация маршрутизации запросов. с помощью NGINX Ingress Controller.
![](https://habrastorage.org/getpro/habr/upload_files/9f8/6f1/4ab/9f86f14ab87e5dafb3f50b83e915f9bb.png)
3.1.2 Traefic Ingress Controller
Traefik — это мощный и современный обратный прокси и Ingress Controller, который выделяется своей способностью к динамическому обнаружению сервисов и автоматической конфигурации. Благодаря встроенной поддержке Let's Encrypt, Traefik упрощает управление SSL сертификатами, автоматически генерируя и обновляя их для обеспечения безопасных соединений. Это делает Traefik идеальным решением для динамичных и быстро меняющихся инфраструктур, где требуется не только эффективное управление трафиком, но и надежная защита данных.
Конфигурация Traefik
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: my-namespace
annotations:
traefik.ingress.kubernetes.io/rewrite-target: /
traefik.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: example.com
http:
paths:
- path: /service1
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
- path: /service2
pathType: Prefix
backend:
service:
name: service2
port:
number: 80
Этот манифест настраивает Ingress для Traefik, чтобы маршрутизировать запросы на example.com. Запросы по путям /service1 и /service2 перенаправляются соответственно к сервисам service1 и service2, с автоматическим переписыванием путей на корневой (/) и принудительным перенаправлением HTTP на HTTPS для повышения безопасности.
3.1.3 HAProxy Ingress Controller
HAProxy Ingress Controller представляет собой инструмент для управления трафиком в Kubernetes, предлагая высокую производительность и расширенные возможности настройки. С его помощью можно эффективно реализовывать балансировку нагрузки, обеспечивать SSL-терминацию и применять сложные правила маршрутизации.
Конфигурации HAProxy Ingress Controller:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: my-namespace
annotations:
haproxy.ingress.kubernetes.io/rewrite-target: /
haproxy.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: example.com
http:
paths:
- path: /service1
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
- path: /service2
pathType: Prefix
backend:
service:
name: service2
port:
number: 80
Этот манифест настраивает Ingress для HAProxy, чтобы маршрутизировать запросы на example.com. Запросы по путям /service1 и /service2 перенаправляются соответственно к сервисам service1 и service2. Он также включает переписывание путей на корневой (/) и автоматическое перенаправление HTTP на HTTPS для улучшения безопасности.
3.2 Мульти-кластерные сети
Мульти-кластерные сети предоставляют возможность интеграции и управления несколькими Kubernetes кластерами как единым целым, что позволяет создавать более масштабируемые и отказоустойчивые инфраструктуры. Это особенно важно для компаний, использующих гибридные облачные решения или работающих в нескольких облачных провайдерах.
3.2.1 Сетевые Политики в Мульти-кластерных Средах
Для обеспечения связи между кластерами можно использовать такие решения, как Istio или Linkerd, которые обеспечивают безопасные и надежные сетевые коммуникации. Эти решения могут управлять межкластерными коммуникациями и обеспечивать безопасность и наблюдаемость на уровне сети.
3.2.2 Использование Federation для Мульти-кластерных развертываний
Kubernetes Federation позволяет управлять несколькими кластерами как единым целым, предоставляя возможность развертывать и синхронизировать ресурсы между кластерами. Это особенно полезно для обеспечения высокодоступных развертываний и управления развертываниями в различных регионах.
Пример настройки Federation:
apiVersion: federation.k8s.io/v1alpha1
kind: FederatedDeployment
metadata:
name: example-deployment
namespace: my-namespace
spec:
template:
metadata:
labels:
app: example
spec:
replicas: 3
selector:
matchLabels:
app: example
template:
metadata:
labels:
app: example
spec:
containers:
- name: example
image: example-image:latest
ports:
- containerPort: 80
Этот манифест создает FederatedDeployment, который управляет развертыванием приложения в нескольких кластерах одновременно. Он развертывает три реплики контейнера с образом example-image:latest
, прослушивающего порт 80. С помощью меток app: example
развертывание будет автоматически синхронизироваться между кластерами, обеспечивая масштабируемость и отказоустойчивость приложения в различных окружениях.
Схематичное изображение манифеста
![](https://habrastorage.org/getpro/habr/upload_files/acc/dfa/b86/accdfab8679c3af13615f66fa1aabeee.png)
4. Продвинутые возможности Kubernetes для масштабирования и оптимизации сети
Продвинутые сетевые функции Kubernetes позволяют не только управлять сетевыми взаимодействиями, но и существенно улучшать масштабируемость, отказоустойчивость и оптимизацию сетевой инфраструктуры. Рассмотрим несколько ключевых аспектов и инструментов, которые могут значительно улучшить работу вашей сети в кластере Kubernetes.
4.1 Поддержка нескольких типов сетевых плагинов
Kubernetes поддерживает множество сетевых плагинов, которые предоставляют различные функции и возможности. Эти плагины реализуют NetworkPolicy и обеспечивают взаимодействие между подами, а также с внешними системами.
4.1.1 Calico
Calico является одним из ведущих сетевых плагинов для Kubernetes, обеспечивая мощные возможности для управления сетями и сетевыми политиками. Calico сочетает в себе сетевое управление и безопасность, предоставляя возможность гибкого контроля доступа между подами и пространствами имен. Calico оптимизирует сетевую производительность и поддерживает детализированное определение правил для изоляции и защиты трафика.
Пример использования Calico для настройки сетевой политики:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: my-namespace
spec:
podSelector:
matchLabels:
role: frontend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: backend
ports:
- protocol: TCP
port: 80
Этот манифест описывает NetworkPolicy, предназначенный для управления сетевым доступом между подами в пространстве имен my-namespace
. Политика разрешает входящие соединения на порт 80 (протокол TCP) только от подов с меткой role: backend
для подов с меткой role: frontend
. Это помогает ограничить доступ, обеспечивая, чтобы только определенные поды могли обмениваться данными по заданному порту.
Схематичное изображение NetworkPolicy
![](https://habrastorage.org/getpro/habr/upload_files/257/54e/42e/25754e42e9f83572460a5c42495dce73.png)
4.1.2 Cilium
Cilium представляет собой современный сетевой плагин для Kubernetes, который использует технологии eBPF (Extended Berkeley Packet Filter) для достижения высокой производительности и масштабируемости сетевых операций. Cilium обеспечивает не только управление сетевыми политиками, но и мониторинг сетевых взаимодействий, интегрируясь глубоко с Kubernetes.
Использования Cilium для настройки сетевой политики:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: cilium-policy
namespace: my-namespace
spec:
podSelector:
matchLabels:
app: myapp
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 80
Схематичное изображение работы Cilium
![Принцип работы Cilium Принцип работы Cilium](https://habrastorage.org/getpro/habr/upload_files/363/8b7/526/3638b7526455dab9ad3cd0dd7c4e142e.png)
5. Поддержка высокодоступных и отказоустойчивых архитектур
Kubernetes предлагает различные механизмы для обеспечения отказоустойчивости и высокой доступности сетевых сервисов. Это включает использование таких инструментов, как StatefulSets, и возможностей для создания резервных копий и восстановления.
5.1 StatefulSets
StatefulSets используются для управления состоянием и идентичностью подов, которые требуют стабильного сетевого идентификатора. Они играют ключевую роль для приложений, которые зависят от сохранения состояния или нуждаются в стабильных сетевых адресах, таких как базы данных или кэш-системы.
Пример конфигурации для StatefulSet:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-statefulset
namespace: my-namespace
spec:
serviceName: "my-service"
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: my-image:latest
ports:
- containerPort: 80
name: http
Манифест создает StatefulSet с именем my-statefulset
в пространстве имен my-namespace
, развертывающий три реплики подов. Подам присваиваются стабильные сетевые идентификаторы через Headless Service с именем my-service
. Каждый под содержит контейнер my-container
, использующий образ my-image:latest
и открывающий порт 80.
Схематичное изображение работы StatefulSet
![Работа StatefulSet Работа StatefulSet](https://habrastorage.org/getpro/habr/upload_files/1f0/70a/e29/1f070ae29c5de504a2cfd08129f0112a.png)
6. Механизмы оптимизации и балансировки нагрузки
Для оптимизации сетевых ресурсов и управления трафиком используются различные механизмы балансировки нагрузки и маршрутизации, включая встроенные возможности Kubernetes и сторонние решения.
6.1 Kubernetes LoadBalancer
Kubernetes включает встроенный ресурс LoadBalancer, который автоматически создает и настраивает балансировщик нагрузки. Этот ресурс позволяет эффективно распределять входящий трафик между несколькими репликами сервиса, обеспечивая высокую доступность и масштабируемость приложений. При создании сервиса с типом LoadBalancer, Kubernetes взаимодействует с облачным провайдером для выделения внешнего IP-адреса и настройки правил маршрутизации, что упрощает управление доступом и равномерное распределение нагрузки на уровне сетевого трафика.
Пример конфигурации LoadBalancer:
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: my-namespace
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
app: my-app
Этот манифест создает Service с типом LoadBalancer в пространстве имен my-namespace, который назначает внешний IP-адрес для доступа к приложению. Сервис прослушивает порт 80 и перенаправляет трафик на порт 80 внутри кластера Kubernetes. Подбор подов осуществляется по метке app: my-app, что позволяет динамически масштабировать и управлять доступом к приложению, сохраняя его доступным и сбалансированным даже при изменениях в количестве реплик.
Схематичное изображение работы LoadBalancer
![Работа LoadBalancer Работа LoadBalancer](https://habrastorage.org/getpro/habr/upload_files/f5a/43f/912/f5a43f9122be8f6889b62b9c92f16cc8.png)
6.2 ExternalDNS для динамического управления DNS
ExternalDNS автоматически управляет DNS-записями для сервисов и Ingress ресурсов в Kubernetes. Он интегрируется с облачными DNS-провайдерами, для автоматического создания и обновления DNS-записей в зависимости от изменений в кластере. Это упрощает назначение доменных имен сервисам и автоматизирует управление записями, позволяя динамически маршрутизировать трафик к вашим приложениям без необходимости вручную обновлять DNS-записи.
Конфигурация для ExternalDNS:
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:latest
args:
- --source=service
- --domain-filter=example.com
- --provider=aws
- --aws-zone-type=public
- --policy=sync
Этот манифест создает Deployment для запуска ExternalDNS в пространстве имен kube-system. ExternalDNS автоматически управляет DNS-записями для сервисов в Kubernetes, интегрируясь с облачными DNS-провайдерами.
7 Наблюдаемость и диагностика сетевых проблем
Кubernetes предоставляет механизмы для наблюдения и диагностики сетевых проблем, что позволяет отслеживать производительность, выявлять узкие места и устранять проблемы.
7.1 Prometheus и Grafana
Prometheus используется для сбора метрик и мониторинга сетевых ресурсов в Kubernetes. Он собирает и хранит данные о различных показателях, таких как использование ресурсов, производительность и состояние приложений. Grafana интегрируется с Prometheus для визуализации собранных метрик, предоставляя мощные дашборды и графики для анализа состояния сети и приложений. Это сочетание позволяет эффективно отслеживать производительность и быстро выявлять проблемы в инфраструктуре, улучшая общую надежность и оперативное управление сетью.
Пример конфигурации Prometheus:
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: prometheus
template:
metadata:
labels:
app: prometheus
spec:
containers:
- name: prometheus
image: prom/prometheus:latest
args:
- "--config.file=/etc/prometheus/prometheus.yml"
Этот манифест создаёт Deployment для запуска Prometheus в пространстве имен monitoring. Prometheus используется для сбора и хранения метрик из различных источников в Kubernetes. В этом Deployment настроен один реплика-под с использованием образа prom/prometheus:latest. Контейнер запускается с конфигурационным файлом prometheus.yml, который определяет источники метрик и правила сбора данных.
В статье мы кратко рассмотрели основные инструменты для управления сетевыми политиками Kubernetes. При этом для реальной настройки требуется глубоко разобраться с требуемым инструментом, и, возможно, мы сделаем отдельный цикл статей, посвященных каждому инструменту.
Автор: Алексей Пономарёв
Если вы не хотите тратить время на настройку сетевых политик в Kubernetes, попробуйте наше облако - Amvera Cloud. Amvera - это альтернатива managed Kubernetes. У нас вы сможете обновлять ваши сервисы через простые коммиты в Git и получите почти все преимущества Kubernetes, не задумываясь об администрировании, настройки CI/CD, мониторинга, алертинга и сопутствующих сервисов. Это выйдет намного дешевле, чем классический managed k8s. Kubernetes у нас внутри, но вы полностью абстрагированы от его администрирования, достаточно просто привязать к сервису ваш Git-репозиторий и обновлять приложения командой “git push amvera master”.
А если у вас сложный проект и вам нужна помощь в построении инфраструктуры на основе Kubernetes, или просто консультация, пишите мне в телеграм (Кирилл Косолапов), либо оставьте контакт для связи на странице нашей DevOps-команды.
Комментарии (3)
n_bogdanov
03.08.2024 14:19+1Я, конечно понимаю, что в статье описывается то, что пробовали/используете в Amvera. Однако заходя в такие статьи ожидаешь более академического описания возможностей. Здесь же вы свалились в описание частностей, причем только в пункте про ingress, обойдя 5, 6 и 7 пункт стороной. А там куча всего интересного есть: metallb, jaeger, descheduler. И это только то, что я могу вспомнить сразу.
Hamletghost
В разделе про ingress еще стоило бы упомянуть istio ingress-gateway - имхо самый гибкий вариант (т.к. вся мощь envoy к вашим услугам).