Динамическая маршрутизация 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 (Border Gateway Protocol) решает эту проблему, автоматизируя обмен маршрутами между сетевым оборудованием и узлами кластера. Вместо того чтобы вручную добавлять каждый новый сетевой префикс подов или сервисов в таблицы маршрутизации, вы настраиваете BGP-сессию один раз, и дальше Calico самостоятельно объявляет все изменения.

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

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

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

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

Настройка маршрутизатора 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

Правильное использование атрибутов BGP позволяет построить интеллектуальную, саморегулирующуюся сетевую инфраструктуру, где трафик автоматически направляется по оптимальным путям с учетом бизнес-логики.

Для принятия обоснованных решений о том, как хранить подобные расширенные конфигурации в кластере — в виде гибких ConfigMap или строго типизированных Custom Resource Definitions (CRD) — рекомендуем ознакомиться с нашим подробным сравнением: CRD vs ConfigMap: практическое руководство по выбору инструмента для конфигурации в Kubernetes.

Поделиться:
Сохранить гайд? В закладки браузера