Динамическая маршрутизация BGP в Kubernetes с Calico: интеграция с MikroTik, Cisco, Ubiquiti | AdminWiki
Timeweb Cloud — сервера, Kubernetes, S3, Terraform. Лучшие цены IaaS.
Попробовать

Динамическая маршрутизация BGP в Kubernetes с Calico: интеграция с MikroTik, Cisco, Ubiquiti

03 апреля 2026 13 мин. чтения

Что вы получите после настройки

Настроив динамический BGP между вашим кластером Kubernetes и корпоративной сетью, вы автоматизируете ключевые операционные процессы:

  • Автоматическое масштабирование: Новые узлы и сети подов автоматически объявляются через BGP без ручного вмешательства.
  • Отказоустойчивость: При выходе узла из строя его маршруты автоматически удаляются из таблицы маршрутизации, предотвращая blackhole трафика.
  • Интеграция сервисов LoadBalancer: Бесшовное включение Kubernetes-сервисов типа LoadBalancer (например, через MetalLB) в существующую сетевую инфраструктуру.
  • Снижение операционных рисков: Минимизация человеческих ошибок за счет декларативной конфигурации через YAML-манифесты.

Почему динамический BGP вместо статических маршрутов?

Ручное прописывание статических маршрутов между кластером Kubernetes и корпоративной сетью — это анахронизм, который тормозит развитие и создает операционные риски. Динамический BGP (Border Gateway Protocol) решает эту проблему, автоматизируя обмен маршрутами между сетевым оборудованием и узлами кластера. Вместо того чтобы вручную добавлять каждый новый сетевой префикс подов или сервисов в таблицы маршрутизации, вы настраиваете BGP-сессию один раз, и дальше Calico самостоятельно объявляет все изменения.

Рассмотрим на практике, чем отличается статический подход от динамического:

Критерий Статические маршруты Динамический BGP с Calico
Масштабирование При добавлении нового узла или изменении IP-пула необходимо вручную обновлять конфигурацию на всех маршрутизаторах. Новые узлы и сети подов автоматически объявляются через BGP. Маршрутизатор получает обновления без вмешательства администратора.
Отказоустойчивость При выходе узла из строя его статические маршруты продолжают «висеть» в таблице, что может приводить к blackhole трафика. BGP-сессия с нерабочим узлом разрывается, и его маршруты автоматически удаляются из таблицы маршрутизации.
Риск человеческой ошибки Высокий. Ошибка в префиксе или next-hop при ручном вводе может заблокировать доступ к целому сегменту сети. Минимальный. Конфигурация выполняется декларативно через YAML-манифесты в Kubernetes, что снижает вероятность опечаток.
Поддержка гибридных сред Крайне сложна. Интеграция с облачными VPN или несколькими ЦОД требует создания сложных скриптов синхронизации. BGP является стандартом де-факто для межсетевого взаимодействия. Настройка пиринга с облачными маршрутизаторами (AWS Direct Connect, GCP Cloud Router) происходит по той же схеме.
Время на внедрение и поддержку Высокое. Каждое изменение требует ручной синхронизации, что замедляет развертывание и увеличивает нагрузку на команду. Низкое. Первоначальная настройка выполняется один раз, дальнейшие изменения в сети кластера автоматически распространяются через BGP.

Calico, как один из самых популярных CNI (Container Network Interface) для Kubernetes, имеет встроенную поддержку BGP. Каждый узел кластера, на котором работает демон calico-node, выступает в роли BGP-спикера. Это означает, что вам не нужно разворачивать отдельные BGP-демоны (вроде Bird или FRR) — вся необходимая функциональность уже есть «из коробки».

BGP становится не просто удобным, а необходимым решением в сценариях, когда:

  • Кластер динамически масштабируется (узлы добавляются и удаляются).
  • Используются несколько пулов IP-адресов для подов (например, разделение на frontend и backend сети).
  • Требуется бесшовная интеграция Kubernetes-сервисов типа LoadBalancer (например, через MetalLB) в существующую сетевую инфраструктуру.
  • Строится гибридная инфраструктура, где часть сервисов работает в Kubernetes, а часть — на физических серверах или в другом кластере.

Подготовка инфраструктуры и проверка совместимости

Перед началом настройки критически важно убедиться в совместимости всех компонентов. Несоответствие версий или неправильно спланированные IP-пулы приведут к тому, что BGP-сессия либо не установится, либо будет работать некорректно.

Требования к версиям:

  • Kubernetes: 1.24+. Рекомендуется 1.26+ для полной поддержки последних возможностей Calico.
  • Calico: v3.26+. Для данной статьи используется режим BGP Full-Mesh (по умолчанию) или BGP с указанием пиров (Node-specific). Убедитесь, что Calico установлен с включенной опцией BGP. При установке через манифест это обычно параметр calico_backend: bird.
  • Сетевое оборудование:
    • MikroTik RouterOS: v6.45+ (рекомендуется v7.x).
    • Cisco IOS/XE: 16.9+ (для поддержки современных BGP-атрибутов).
    • Ubiquiti EdgeRouter: firmware v2.0+.

Планирование IP-адресации:

Конфликт IP-адресов — самая частая причина неработоспособности. Выделите для Calico IPAM пулы, которые не пересекаются с адресным пространством вашей корпоративной сети. Например, если ваша LAN — это 10.0.0.0/16, для подов можно использовать 192.168.0.0/16 или уникальный диапазон из RFC 1918.

Проверьте текущую конфигурацию Calico:

# Проверка узлов и их IP-адресов
calicoctl get nodes -o wide

# Проверка настроенных IP-пулов
calicoctl get ippool -o yaml

Убедитесь, что между узлами Kubernetes и физическим маршрутизатором есть IP-связность. Запустите ping с узла на IP-адрес интерфейса маршрутизатора, который будет использоваться для BGP-пиринга.

Ключевые параметры BGP и их согласование с маршрутизатором

Для успешного установления BGP-сессии параметры на обеих сторонах должны быть согласованы.

  • AS Number (Autonomous System Number):
    • Для кластера Kubernetes используйте приватный AS номер из диапазона 64512–65534 (стандарт RFC 6996). Например, 64512.
    • Для физического маршрутизатора используйте его реальный AS номер, если он участвует в глобальной маршрутизации (публичный AS), или также приватный, если это внутренняя сеть.
  • Таймеры Keepalive и Hold Time:
    • Keepalive — интервал отправки keepalive-сообщений для проверки активности пира. Стандартное значение — 30 секунд.
    • Hold Time — время, после которого пир считается недоступным, если не получено ни keepalive, ни update-сообщение. Стандартное значение — 90 секунд.
    • Важно: Hold Time на обеих сторонах должен быть одинаковым или Hold Time маршрутизатора должен быть больше, чем Hold Time Calico. Рекомендуется оставлять значения по умолчанию (keepaliveTime: 30s, holdTime: 90s в Calico).

Особенности по вендорам:

  • MikroTik RouterOS часто использует упрощенную конфигурацию BGP. Убедитесь, что в настройках пира включена опция multihop, если узел Kubernetes находится за несколькими прыжками.
  • Cisco IOS/XE требует точного указания remote-as. Для приватного AS кластера может потребоваться команда neighbor <IP> local-as <AS> no-prepend replace-as.
  • Ubiquiti EdgeRouter (на основе Vyatta) имеет синтаксис, близкий к Cisco, но с особенностями в GUI. Для стабильной работы рекомендуется настройка через CLI.

Практическая реализация: настройка BGP-сессий с маршрутизатором

Базовая архитектура: каждый узел Kubernetes с Calico устанавливает отдельную BGP-сессию с физическим маршрутизатором (модель «каждый с каждым»). Это обеспечивает отказоустойчивость — при падении одного узла сессии с остальными остаются активными. Альтернативная модель — использование Route Reflector или выделенного BGP-роутера (например, через MetalLB), но она сложнее в начальной настройке.

Мы настроим пиринг со всеми узлами кластера. Для этого нужно выполнить два ключевых действия: создать конфигурацию BGP в Kubernetes и настроить пира на физическом маршрутизаторе.

Конфигурация Calico: создание BGPConfiguration и BGPPeer

В Calico настройка BGP осуществляется через два основных кастомных ресурса: BGPConfiguration (глобальные параметры) и BGPPeer (определение удаленных пиров).

1. BGPConfiguration — задаем глобальные параметры, такие как AS номер кластера и логгирование.

# bgp-configuration.yaml
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
  name: default
spec:
  logSeverityScreen: Info # Уровень логирования
  nodeToNodeMeshEnabled: false # Отключаем full-mesh между узлами, так как будем использовать внешний пиринг
  asNumber: 64512 # Приватный AS номер для всего кластера

Примените конфигурацию:

calicoctl apply -f bgp-configuration.yaml

2. BGPPeer — создаем ресурс, который описывает наш физический маршрутизатор как BGP-пира. Предположим, IP-адрес маршрутизатора — 10.0.100.1, а его AS номер — 65001.

# bgp-peer-router.yaml
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
  name: physical-router
spec:
  peerIP: 10.0.100.1 # IP-адрес физического маршрутизатора
  asNumber: 65001     # AS номер маршрутизатора
  nodeSelector: "all()" # Применяем это правило ко всем узлам кластера
calicoctl apply -f bgp-peer-router.yaml

После применения манифестов Calico на каждом узле попытается установить BGP-сессию с указанным IP-адресом. Проверить статус можно командой:

calicoctl node status

Теперь необходимо настроить ответную часть на маршрутизаторе.

Настройка BGP на MikroTik RouterOS

Подключаемся к MikroTik через WinBox или SSH и выполняем команды в терминале.

# Включаем BGP и создаем экземпляр
/routing bgp instance
add name=kubernetes as=65001 router-id=10.0.100.1

# Добавляем пира (первый узел Kubernetes с IP 10.0.100.10)
/routing bgp peer
add name=calico-node-1 instance=kubernetes remote-address=10.0.100.10 remote-as=64512 \
    ttl=default multihop=yes update-source=10.0.100.1

# Повторяем команду для каждого узла в кластере, меняя remote-address.
# Для автоматизации можно использовать скрипт или список адресов.

Пояснения:

  • multihop=yes — позволяет устанавливать сессию, даже если узел не находится в непосредственно подключенной сети.
  • update-source — указывает, с какого интерфейса/IP устанавливать соединение.

Проверить состояние сессий:

/routing bgp peer print

Настройка маршрутизатора Cisco (IOS/XE)

Конфигурация выполняется в режиме глобальной конфигурации.

router bgp 65001
 bgp router-id 10.0.100.1
 bgp log-neighbor-changes
 !
 ! Сосед - первый узел Kubernetes
 neighbor 10.0.100.10 remote-as 64512
 neighbor 10.0.100.10 description calico-node-1
 neighbor 10.0.100.10 ebgp-multihop 255
 neighbor 10.0.100.10 update-source Vlan100 ! Или конкретный интерфейс
 !
 ! Аналогично добавляем соседей для остальных узлов.
 !
 address-family ipv4
  neighbor 10.0.100.10 activate
  neighbor 10.0.100.10 soft-reconfiguration inbound
  neighbor 10.0.100.10 route-map ACCEPT-CALICO in
  neighbor 10.0.100.10 route-map SET-LOCAL-PREF out
 exit-address-family
!
! Маршрутная карта для базового фильтра (см. раздел безопасности)
ip prefix-list CALICO-POOLS seq 5 permit 192.168.0.0/16 le 24
!
route-map ACCEPT-CALICO permit 10
 match ip address prefix-list CALICO-POOLS

Настройка маршрутизатора Ubiquiti (EdgeRouter)

Настройку можно выполнить через веб-интерфейс (Dashboard) или CLI. Через CLI (режим конфигурации):

configure
set protocols bgp 65001 parameters router-id 10.0.100.1
set protocols bgp 65001 neighbor 10.0.100.10 remote-as 64512
set protocols bgp 65001 neighbor 10.0.100.10 description calico-node-1
set protocols bgp 65001 neighbor 10.0.100.10 ebgp-multihop 255
set protocols bgp 65001 neighbor 10.0.100.10 update-source 10.0.100.1
# Повторить для других узлов
commit
save

В веб-интерфейсе настройка находится в разделе Routing > BGP. Нужно создать новый экземпляр BGP и добавить соседей, указав их IP и AS.

Безопасность BGP-пиринга: защита от утечки маршрутов

Открытая BGP-сессия без защиты — это риск. Злоумышленник, получивший доступ к сети, может внедрить ложные маршруты или перехватить трафика. Для защиты используются три основных метода: аутентификация сессии, фильтрация префиксов и ограничение списка пиров.

1. Фильтрация префиксов на маршрутизаторе. Это самый важный шаг. Маршрутизатор должен принимать только те префиксы, которые принадлежат пулам Calico IPAM. Пример для Cisco (продолжение конфигурации выше):

! Создаем prefix-list, разрешающий только наши пулы Calico
ip prefix-list ALLOW-CALICO seq 10 permit 192.168.0.0/16 ge 24 le 28
! Применяем его как inbound фильтр для всех BGP-соседей из Kubernetes
route-map FILTER-CALICO-IN permit 10
 match ip address prefix-list ALLOW-CALICO
!
router bgp 65001
 address-family ipv4
  neighbor 10.0.100.10 route-map FILTER-CALICO-IN in

2. Ограничение списка BGP-пиров. На маршрутизаторе нужно явно указать IP-адреса только тех узлов, которые входят в кластер. Не используйте широковещательные адреса или диапазоны.

3. Ограничение исходящих анонсов с маршрутизатора в кластер. Кластеру Kubernetes обычно не нужно знать маршруты всей корпоративной сети. Настройте outbound-фильтр на маршрутизаторе, чтобы он не отправлял (или отправлял минимально необходимый набор) маршрутов в Calico.

Настройка аутентификации MD5 в Calico и на маршрутизаторах

BGP MD5-аутентификация добавляет криптографическую проверку источника каждого TCP-сегмента в сессии. Пароль должен быть одинаковым на обеих сторонах.

В Calico аутентификация настраивается в ресурсе BGPPeer:

# bgp-peer-router-secure.yaml
apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
  name: physical-router-secure
spec:
  peerIP: 10.0.100.1
  asNumber: 65001
  nodeSelector: "all()"
  password:
    secretKeyRef:
      name: bgp-secret  # Имя Kubernetes Secret
      key: password     # Ключ в Secret

Предварительно нужно создать Secret с паролем:

kubectl create secret generic bgp-secret --from-literal=password='YourStrong!BGPp@ssw0rd'

На маршрутизаторе MikroTik:

/routing bgp peer
set [find name="calico-node-1"] password="YourStrong!BGPp@ssw0rd"

На маршрутизаторе Cisco:

router bgp 65001
 neighbor 10.0.100.10 password YourStrong!BGPp@ssw0rd

На маршрутизаторе Ubiquiti (CLI):

set protocols bgp 65001 neighbor 10.0.100.10 password YourStrong!BGPp@ssw0rd

После настройки аутентификации сессия BGP не установится, если пароли не совпадают.

Обеспечение отказоустойчивости и балансировки нагрузки

Базовая настройка уже обеспечивает отказоустойчивость на уровне узлов: если один узел падает, его BGP-сессия разрывается, и трафик не направляется на недоступный адрес. Однако для production-сред этого недостаточно.

1. Резервирование BGP-сессий с несколькими маршрутизаторами (Multi-hop). Вы можете настроить пиринг не напрямую с edge-маршрутизатором, а с парой внутренних BGP-роутеров, которые, в свою очередь, анонсируют маршруты дальше. В Calico это делается созданием нескольких ресурсов BGPPeer с разными peerIP. Узлы будут пытаться установить сессии с обоими, обеспечивая резервирование на уровне сетевого пути.

2. Балансировка нагрузки через ECMP (Equal-Cost Multi-Path). Если несколько узлов Kubernetes анонсируют один и тот же префикс (например, IP-адрес сервиса типа LoadBalancer), и эти маршруты имеют одинаковую метрику (вес), маршрутизатор будет распределять входящий трафик между всеми этими узлами. Это встроенная функция BGP.

В Calico ECMP включается в глобальной конфигурации:

# bgp-configuration-ecmp.yaml
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
  name: default
spec:
  asNumber: 64512
  serviceClusterIPs:
  - cidr: 10.96.0.0/12 # Укажите ваш CIDR сервисов Kubernetes
  serviceExternalIPs:
  - cidr: 192.168.100.0/24 # Укажите пул для ExternalIP/LoadBalancer
  nodeToNodeMeshEnabled: false
  listenPort: 179
  logSeverityScreen: Info
  ecmpEnabled: true # Включаем ECMP

3. Graceful Restart. Эта функция позволяет BGP-пиру (маршрутизатору) временно сохранять маршруты, полученные от узла, пока тот перезапускается (например, при обновлении calico-node). Это предотвращает кратковременные потери трафика. Поддержка Graceful Restart зависит от версии Calico и маршрутизатора. В Calico v3.26+ она включается автоматически при поддержке со стороны пира.

4. Распределение IP-пулов между узлами. Не назначайте весь большой IP-пул одному узлу. Используйте аннотации или политики Calico IPAM, чтобы распределять блоки адресов. Это предотвратит ситуацию, когда падение одного узла делает недоступными все поды с его IP.

Мониторинг и диагностика работоспособности BGP-сессий

После настройки необходимо убедиться, что сессии установлены и маршруты передаются корректно.

1. Проверка со стороны Calico:

# Статус BGP на конкретном узле
calicoctl node status --node=<node-name>

# Список всех BGP-пиров
calicoctl get bgppeers

# Детальная информация о пире
calicoctl get bgppeer physical-router -o yaml

2. Проверка со стороны маршрутизатора:

  • MikroTik: /routing bgp peer print detail. Обращайте внимание на статус established.
  • Cisco: show bgp ipv4 unicast summary и show bgp ipv4 unicast neighbors <IP> advertised-routes.
  • Ubiquiti: show ip bgp summary (в режиме оператора).

3. Проверка таблица маршрутизации: На маршрутизаторе убедитесь, что префиксы из кластера появились в таблице маршрутизации. Например, на Cisco: show ip route bgp.

Типовые проблемы и решения:

  • Сессия в состоянии Active/Connect, но не Established.
    • Причина: Несовпадение AS номеров, блокировка TCP-порта 179 межсетевым экраном, отсутствие IP-связности.
    • Решение: Проверьте конфигурацию AS, откройте порт 179 в обе стороны, проверьте ping.
  • Сессия установлена, но маршруты не видны.
    • Причина: Неправильные фильтры на маршрутизаторе, отсутствие активных сетей для анонса на узлах Calico (нет подов).
    • Решение: Проверьте calicoctl get ippool -o wide, убедитесь, что пулы имеют флаг disabled: false. Проверьте логи Calico на узле: journalctl -u calico-node.

Интеграция с Prometheus/Grafana: Calico экспортирует метрики BGP, включая состояние сессий и количество полученных/переданных префиксов. Для сбора этих метрик настройте ServiceMonitor или прямой scrape эндпоинта :9091/metrics на каждом calico-node. В Grafana можно создать дашборд для визуализации состояния всех BGP-сессий в кластере.

Для глубокой диагностики сложных проблем с кастомными ресурсами в Kubernetes, включая анализ их состояния и логики контроллеров, обратитесь к нашему полному руководству: Полная диагностика Custom Resources в Kubernetes: от простых ошибок до глубокой отладки.

Оптимизация: управление предпочтением маршрутов с BGP-атрибутами

Когда инфраструктура растет и появляется несколько путей до одного и того же сервиса, возникает необходимость управлять выбором маршрута. BGP предоставляет для этого мощные атрибуты.

  • Local Preference (LOCAL_PREF): Атрибут, влияющий на исходящую маршрутизацию в пределах вашего AS. Более высокое значение LOCAL_PREF означает более предпочтительный маршрут. Вы можете настроить на маршрутизаторе, чтобы маршруты от определенных узлов Kubernetes (например, расположенных в основном ЦОД) имели больший LOCAL_PREF, чем маршруты от узлов в резервном ЦОД.
  • AS Path Prepending: Искусственное увеличение длины AS_PATH для того, чтобы сделать маршрут менее предпочтительным. Например, если вы хотите, чтобы трафик к сервису в основном шел через ЦОД A, а через ЦОД B только для резерва, вы можете настроить Calico на узлах в ЦОД B добавлять ваш AS номер несколько раз в анонсируемый маршрут.
  • BGP Communities: Это метки, которые можно прикреплять к маршрутам. Они не влияют на выбор пути напрямую, но позволяют маршрутизаторам фильтровать или модифицировать маршруты на основе этих меток. Например, вы можете пометить все маршруты из Kubernetes определенным community (64512:100), а затем на корпоративных маршрутизаторах настроить политику, которая на основе этой метки задает определенный LOCAL_PREF или фильтрует маршруты при передаче внешним провайдерам.

Пример настройки Community в Calico: Атрибуты можно задать для IP-пула через аннотации.

# ippool-with-community.yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: external-pool
  annotations:
    projectcalico.org/BGPCommunity: "64512:100" # Указываем community
spec:
  cidr: 192.168.100.0/24
  blockSize: 26
  nodeSelector: "all()"
  vxlanMode: Never
  ipipMode: Never
  natOutgoing: true

На стороне маршрутизатора (пример для Cisco) нужно настроить route-map, которая будет «читать» это community и применять нужные действия:

route-map SET-PREF-FROM-COMMUNITY permit 10
 match community KUBE-COMMUNITY
 set local-preference 200
!
ip community-list standard KUBE-COMMUNITY permit 64512:100
Поделиться:
Сохранить гайд? В закладки браузера