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. Другие поды (красные) не могут взаимодействовать с фронтенд-подами в рамках данной политики.
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
Ниже представлена визуализация описанных выше манифестов
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.
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
развертывание будет автоматически синхронизироваться между кластерами, обеспечивая масштабируемость и отказоустойчивость приложения в различных окружениях.
Схематичное изображение манифеста
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
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
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
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
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 к вашим услугам).