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

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

Принцип работы Cilium
Принцип работы 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

Работа StatefulSet
Работа 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

Работа LoadBalancer
Работа 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)


  1. Hamletghost
    03.08.2024 14:19
    +4

    В разделе про ingress еще стоило бы упомянуть istio ingress-gateway - имхо самый гибкий вариант (т.к. вся мощь envoy к вашим услугам).


  1. GunterVas
    03.08.2024 14:19

    Торт.


  1. n_bogdanov
    03.08.2024 14:19
    +1

    Я, конечно понимаю, что в статье описывается то, что пробовали/используете в Amvera. Однако заходя в такие статьи ожидаешь более академического описания возможностей. Здесь же вы свалились в описание частностей, причем только в пункте про ingress, обойдя 5, 6 и 7 пункт стороной. А там куча всего интересного есть: metallb, jaeger, descheduler. И это только то, что я могу вспомнить сразу.