среда, 27 февраля 2019 г.

Cumulus Linux | Getting started и первая демка



Всем привет!

Ничем не примечательная в целом картинка для сетевого блога. Горстка лифов, пара спайнов, выход в "Интернеты" и OOB устройства. Нравится мне в этой лабе то, что это Linux лаба. )

История

Сейчас такое смутное время, когда "все есть Linux".  F5, IOS-XR, Juniper... Примеров можно найти сколько угодно. Поэтому для современного сетевика действительно важно понимать, что такое Unix-like. Но во всех обозначенных выше системах есть одна закавыка. Они сделаны так, чтобы администратор не очень то и взаимодействовал с самой системой. Да, баланс начинает смещаться, но в том же F5 большинство операций выполняется в tmsh, а не в bash. 

Но есть так называемые white-box коммутаторы. По сути, это как раз реализации тех самых идей SDNа. Это то, где сейчас находится серверная индустрия. У вас есть железка и загрузчик на этой железке. А вот что поставить на эту железку решаете вы. Это может быть как платный дистрибутив, так и совсем бесплатный. 

Однажды я слушал подкаст с Иваном Пепельняком про интерфейсы в Linux. После подкаста я окончательно запутался в интерфейсах, но, что более важно, на нем пара разработчиков Cumulux рассказывали об их прогрессе в этой области. Ребята рассказывали про действительно классные вещи, которые они контрибьютят в ядро Linux.  

Тут мы подходим к Cumulus Linux - по-настоящему Linux сетевому дистрибутиву. Короче, я решил его попробовать и скачал тестовый дистрибутив. Поставил и начал играться. Через некоторое время на меня вышли ребята из Cumulus с предложением рассказать мне про систему и дать дополнительные материалы. Собственно, что и произошло. Пообщались мы прекрасно. Действительно видно, как ребятам нравится то, что они делают. Я, признаться, заразился их энтузиазмом и решил сделать пару тройку постов на эту тему. Нет, посты не проплачены, а жаль...

Почему Cumulus это интересно:
  1. Это квинтэссенция реализация сетевой ОС на Linux
  2. Ребята активно развивают систему и ядро Linux
  3. Сети и Linux, прям все что я люблю. )
  4. Возможность пользоваться всеми наработками автоматизации для серверов
  5. Хочешь файлопомойку на свиче? Не проблема... Ставить можно что угодно
  6. Легко виртуализируется (хотя что сейчас трудно виртуализирвать... )
Важный момент здесь - производительность. Как же так, можете воскликнуть вы, ведь коммутатор использует ASICи для оффлоада данных для которых нужен быстрый доступ. Короче, как выяснилось, вопрос стоит уже не так остро. Во-первых, производительность CPU уже довольно высока для некоторых сетевых применений. Во-вторых, Cumulus Linux и Linux вообще уже давно умеет офллоадить что-либо на ASIC, который выглядит для сервера как обычное PCI устройство. Да, там не все так просто, это понятно. Но технологию уже давно не "эксклюзивная".

Как начать?

Начать лабить в наш век Github'a и Vagrant'a проще чем два байта переслать...

В этом посте я пробегусь по пожалуй самому простому пути. В посте нет особо ничего очень уж оригинального, это скорее обзор наиболее простого способа начать что-то делать.
По сути, все что нам требуется это репозиторий cldemo-vagrant. Что это? Это коллекция vagrant файлов, конфигов и Ansible плейбуков. Воу-воу, полегче, скажут некоторые из вас. Уберите ваши девопсы. Но тут нет ничего сложного.

Данный репозиторий позволяет:
  1. Абсолютно автоматически разворачивать тестовую топологию в одну команду
  2. Автоматически разворачивать демо конфигурации, чтобы с ними поиграть. 
Итак, что нужно сделать.

1. Выполнить пререквезиты

Если очень кратко, то надо установить Virtualbox и Vagrant. Есть инструкции под Mac, Linux или Windows.

2. Копируем репозиторий 

Самый простой способ это выполнить git clone https://github.com/CumulusNetworks/cldemo-vagrant.git на вашей машине, но можно хоть выкачать архивом с GitHub (кнопка Clone and Download).

3. Разворачиваем машины

Используя Vagrant, вам даже не надо тратить время на загрузку дистрибутива... Например, одной командой vargant up oob-mgmt-server мы скачаем дистрибутив, развернем машину и настроим все, что нужно на ней настроить. 
vagrant halt oob-mgmt-server - выключит виртуалку
vagrant destroy oob-mgmt-server - удалит виртуалку
vagrant up - поднимет все виртуалки из конфигруации (всю топологию)
vagrant status - покажет статус по всем машинам

Все три пункта уместились у меня на один скриншот.



Как видно, если открыть virtualbox (опционально) виртуалка и правда появилась.


4. Заходим на машину

Если делать это через vagrant, то вам даже не нужно беспокоится о паролях. Ключики уже лежат на своих местах. vagrant ssh oob-mgmt-server и мы на машине. Классный баннер, не находите... 



Вот как бы и все базовые шаги. Понятно, что с одной машиной в сетях далеко не уйдешь, поэтому попробуем поднять еще несколько машинок. Очевидно, нам понадобится oob коммутатор. Кроме того, давайте поднимем один лиф, один спайн и сервер. К слову, удобно копировать имена машин из вывода vagrant status. К сожалению, server дистрибутивы копируются c Amazon S3 очень долго, придется потерпеть. Хорошая новость, скачать его придется только один раз.


Все манипуляции с лабораторкой нужно делать через "прыжковый" OOB сервер. Сначала заходим на него по ssh с помощью vagrant ssh oob-mgmt-server, далее с него уже прыгаем на нужный хост через обычный ssh по имени хоста. Например, ssh spine01


Этот свич как раз таки соединен с каждый устройством через отдельный линк.


Демо

В репозитории так же есть довольно большое количество демо конфигураций на поиграться. Как с ними работать? 
  1. Выбираем одну из представленных конфигураций
  2. Поднимаем нужные VMки
  3. Запускаем конфигурация с oob-mgmt-server. Обычно это Ansible, который стоит прям на Cumulus Linux, но есть примеры и с Shef'ом и c Puppet
  4. Бегаем по железкам и смотрим как все настроилось.
Итак, я выберу конфигурацию с MLAG, потому что мне интересно как это будет работать в виртуальной среде. Напомню, MLAG это LAG от хоста до двух коммутаторов сразу. Для хоста конфигурация абсолютно прозрачна, он ничего и не подозревает, а вот на уровне коммутаторов нужно договорится о многих вещах. Для связности всех leaf коммутатором используется bgp, так что удастся еще взглянуть на настройку FRR. Это форк quagga, который делает из Linux машины довольно функциональный маршрутизатор. 

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



vagrant up oob-mgmt-server oob-mgmt-switch spine01 leaf01 leaf02 leaf03 leaf04 server01 server03

После успешного деплоя, переходим на сервер управления.

vagrant ssh oob-mgmt-server

Копируем репозиторий с демкой и переходим в каталог. Репозиторий - это не что иное как просто коллекция конфигов и Ansible playbook, который их разливает по устройствам. Взглянем на него чуть позже.

git clone https://github.com/cumulusnetworks/cldemo-config-mlag && cd cldemo-config-mlag

Запускаем playbook. (Теперь мы девопс...)
ansible-playbook deploy.yml

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


Теперь быстро проверяем и приступаем к разбору. В нашем случае, самой очевидной проверкой будет пинг от server01 до server03 и обратно.

Как видно, результат очень так себе, чему я даже рад. ) server03 не доступен с server01. Судя по трассировке, даже первый хоп недоступен... Приступаем к следующей секции!


Что вообще произошло?

Перед тем как разбираться в проблеме, надо понять, что вообще произошло.

Вся магия происходит на уровне Ansible плейбука, которым мы разливали конфигурацию. Давайте глянем, что вообще он делает.

---
- hosts: network
  become: yes
  tasks:
    - name: copy interfaces
      copy: src=mlag/{{ansible_hostname}}/interfaces dest=/etc/network/
    - name: copy FRR daemons
      copy: src=mlag/{{ansible_hostname}}/daemons dest=/etc/frr/
    - name: copy FRR conf
      copy: src=mlag/{{ansible_hostname}}/frr.conf dest=/etc/frr/
    - name: reload networking
      command: ifreload -a
    - name: reload FRR
      service: name=frr state=restarted

- hosts: servers
  become: yes
  tasks:
    - name: install ifenslave package
      apt: name={{ item }} update_cache=yes
      with_items:
        - ifenslave-2.6
    - name: Setup bonding module in Kernel
      command: modprobe bonding
    - name: copy interfaces
      copy: src=mlag/{{ansible_hostname}}/interfaces dest=/etc/network/      
    - name: restarts servers with their new configuration
      shell: sleep 1 && shutdown -r 0
      async: 1
      poll: 0
      ignore_errors: true
    - name: Wait for everything to come back up
      local_action: wait_for port=22 host="{{ inventory_hostname }}" search_regex=OpenSSH delay=10

Плейбук делится на две части. Вторая часть посвящена серверам и не очень нас интересует сейчас. Там ставится пакетик, добавляется модуль в ядро и подсовывается файлик с конфигами интерйесов, который мы посмотрим чуть позже. В первой части, которая для сетевых девайсов, все еще проще. Копируем настройки сетевых интерфейсов, демоны frr и сам конфиг для frr.

Конфиги лежат в соответсвующих директориях, например для leaf01 тут. Если разбирать конфиги по кускам, то:

leaf interfaces 

1. Создается loopback
auto lo
iface lo inet loopback
    address 10.0.0.11/32

2. Создается интерфейс для управления
auto eth0
iface eth0 inet dhcp

3. Прописываем два интерфейса в сторону spine коммутатора
auto swp51
iface swp51

auto swp52
iface swp52

4. Формируем линки к соседнему leaf коммутатору, он же MLAG пир
auto swp49
iface swp49
    post-up ip link set $IFACE promisc on     # Only required on VX

auto swp50
iface swp50
    post-up ip link set $IFACE promisc on     # Only required on VX

5. Формируем транк из линков к соседу
auto peerlink
iface peerlink
    bond-slaves swp49 swp50

6. Навешиваем на него адрес и саму конфигурацию MLAG
auto peerlink.4094
iface peerlink.4094
    address 169.254.255.1
    netmask 255.255.255.0
    clagd-priority 4096
    clagd-peer-ip 169.254.255.2
    clagd-backup-ip 10.0.0.12
    clagd-sys-mac 44:38:39:ff:00:01

7. Тут бутерброд. Инициализируем свитч порт (swp) до сервера.
auto swp1
iface swp1

8. Создаем bond (LAG) server1 с одним интерфейсом swp1.
auto server1
iface server1
    bond-slaves swp1
    clag-id 1

9. Порт для второго сервера
auto swp2
iface swp2

10. И его бонд
auto server2
iface server2
    bond-slaves swp2
    clag-id 2

11. Объединяем в бридж три бонда (LAGa) - в сторону серверов и в сторону соседа. Здесь же вешаем адрес.
auto br0
iface br0
    bridge-ports server1 server2 peerlink
    address 172.16.1.1/24
    bridge-stp on

spine interfaces (вообще просто)

1. Loopback для BGP
auto lo
iface lo inet loopback
    address 10.0.0.21/32

2. MGMT порт
auto eth0
iface eth0 inet dhcp

3. Порты в сторону leaf свичей
auto swp1
iface swp1

auto swp2
iface swp2

auto swp3
iface swp3

auto swp4
iface swp4

leaf frr.conf (ах как знакомо...)

1. Включаем bgp со своей AS.
router bgp 65011
 bgp router-id 10.0.0.11
 bgp bestpath as-path multipath-relax
 neighbor fabric peer-group
 neighbor fabric remote-as external
 neighbor fabric description Internal Fabric Network
 neighbor fabric capability extended-nexthop
 neighbor swp51 interface peer-group fabric
 neighbor swp52 interface peer-group fabric

2. Анонсируем свой loopback и свою сетку
 address-family ipv4 unicast
  network 10.0.0.11/32
  network 172.16.1.0/24
  neighbor fabric prefix-list dc-leaf-in in
  neighbor fabric prefix-list dc-leaf-out out
 exit-address-family

3. Самая интересная секция. ) Здесь активируются соседи из группы fabric, к которой привязаны интерфейсы swp51 и swp52.
 address-family ipv6 unicast
  neighbor fabric activate
 exit-address-family
 exit

4. Пару префикс листов на вход и на выход.
На вход:
Можно маршрут по умолчанию
Можно все, что начинается с 10.0.0. и с префиксом /32
Можно 172.16.2.0/24 от соседа
Остальное нельзя
На выход:
Можно свою сеть
Остальное нет
ip prefix-list dc-leaf-in seq 10 permit 0.0.0.0/0
ip prefix-list dc-leaf-in seq 20 permit 10.0.0.0/24 le 32
ip prefix-list dc-leaf-in seq 30 permit 172.16.2.0/24
ip prefix-list dc-leaf-in seq 500 deny any
ip prefix-list dc-leaf-out seq 10 permit 172.16.1.0/24
ip prefix-list dc-leaf-out seq 500 deny any

spine frr.conf (отличается только префикс листами)

router bgp 65020
 bgp router-id 10.0.0.21
 bgp bestpath as-path multipath-relax
 neighbor fabric peer-group
 neighbor fabric remote-as external
 neighbor fabric description Internal Fabric Network
 neighbor fabric capability extended-nexthop
 neighbor swp1 interface peer-group fabric
 neighbor swp2 interface peer-group fabric
 neighbor swp3 interface peer-group fabric
 neighbor swp4 interface peer-group fabric
 !
 address-family ipv4 unicast
  network 10.0.0.21/32
  neighbor fabric prefix-list dc-spine in
  neighbor fabric prefix-list dc-spine out
 exit-address-family
 !
!
 address-family ipv6 unicast
  neighbor fabric activate
 exit-address-family
 exit
!
ip prefix-list dc-spine seq 10 permit 0.0.0.0/0
ip prefix-list dc-spine seq 20 permit 10.0.0.0/24 le 32
ip prefix-list dc-spine seq 30 permit 172.16.1.0/24
ip prefix-list dc-spine seq 40 permit 172.16.2.0/24
ip prefix-list dc-spine seq 500 deny any

Плейбук просто кладет эти файлики на устройства и дергает сервисы.

Troubleshooting 

Начинаем от сервера. Смотрим маршрут до server03, получаем первый хоп и исходящий интерфейс. Как видно, интерфейс uplink получил адрес и находится в up состоянии. Однако пинг первого хопа не проходит. В файле интерфейсов видно, что uplink это бонд собранный из двух интерфейсов eth1 и eth2. Собственно, в выводе ip a это тоже видно в секции master. Особых отклонений тут не видно, все интерфейсы в UP состоянии, настройки выглядят корректно. Похоже на L2 проблему. К тому же, если посмотреть ARP таблицу, мы увидим HWaddress в incomplete статусе (на рисунке нет). Значит, что ответа так и не пришло. 


Идем на коммутатор leaf01. В целом, здесь можно применять все тот же инструментарий - посмотреть interfaces, глянуть вывод ip a. Помним, что это обычный линукс. Но, посмотрим что там у Cumulus. Сейчас нас интересуют интерфейсы.

cumulus@leaf01:~$ net show interface
State  Name           Spd   MTU    Mode           LLDP                    Summary
-----  -------------  ----  -----  -------------  ----------------------  -------------------------
UP     lo             N/A   65536  Loopback                               IP: 127.0.0.1/8
       lo                                                                 IP: 10.0.0.11/32
       lo                                                                 IP: ::1/128
UP     eth0           1G    1500   Mgmt           oob-mgmt-switch (swp6)  IP: 192.168.0.11/24(DHCP)
UP     swp1           100M  1500   BondMember     server01 (eth1)         Master: server1(DN)
UP     swp2           1G    1500   BondMember                             Master: server2(DN)
UP     swp49          1G    1500   BondMember     leaf02 (swp49)          Master: peerlink(UP)
UP     swp50          1G    1500   BondMember     leaf02 (swp50)          Master: peerlink(UP)
UP     swp51          1G    1500   NotConfigured
UP     swp52          1G    1500   NotConfigured
UP     br0            N/A   1500   Bridge/L3                              IP: 172.16.1.1/24
UP     peerlink       2G    1500   802.3ad                                Master: br0(UP)
       peerlink                                                           Bond Members: swp49(UP)
       peerlink                                                           Bond Members: swp50(UP)
UP     peerlink.4094  2G    1500   SubInt/L3                              IP: 169.254.255.1/24
DN     server1        N/A   1500   802.3ad                                Master: br0(UP)
       server1                                                            Bond Members: swp1(UP)
DN     server2        N/A   1500   802.3ad                                Master: br0(UP)
       server2                                                            Bond Members: swp2(UP)

Как видно, swp1 и swp2 порты в UP, прям здесь же видно мастер интерфейсы server1 и server2. Вот тут и видно проблему - интерфейсы в DOWN состоянии. Т.е. физические интерфейсы подняты, а вот бонды на них нет... Заметьте, как информативно выглядит вывод! Тут тебе и сами порты, и бонды, адреса интерфейсов, соседи, тип интерфейса. Оч круто!

Ниже вывод интерфейса.

cumulus@leaf01:~$ net show interface server1
    Name     MAC                Speed  MTU   Mode
--  -------  -----------------  -----  ----  -------
DN  server1  44:38:39:00:00:03  N/A    1500  802.3ad

Bond Details
------------------  --------
Bond Mode:          802.3ad
Load Balancing:     layer3+4
Minimum Links:      1
LACP Sys Priority:
LACP Rate:          1
LACP Bypass:        Inactive

All VLANs on L2 Port
--------------------
1

Untagged
--------
1

cl-netstat counters
-------------------
RX_OK  RX_ERR  RX_DRP  RX_OVR  TX_OK  TX_ERR  TX_DRP  TX_OVR
-----  ------  ------  ------  -----  ------  ------  ------
   58       0       0       0    100       0       0       0

LLDP Details
------------
LocalPort  RemotePort(RemoteHost)
---------  ----------------------
swp1       eth1(server01)

Routing
-------
  Interface server1 is up, line protocol is down
  Link ups:       0    last: (never)
  Link downs:     0    last: (never)
  PTM status: disabled
  vrf: default
  index 16 metric 0 mtu 1500 speed 4294967295
  flags: <UP,BROADCAST,MULTICAST>
  Type: Ethernet
  HWaddr: 44:38:39:00:00:03
  Interface Type Other
  Master (bridge) ifindex 18

Проверим статус MLAG пира, который alive

cumulus@leaf01:~$ net show clag
The peer is alive
     Our Priority, ID, and Role: 4096 44:38:39:00:00:10 primary
    Peer Priority, ID, and Role: 8192 44:38:39:00:00:11 secondary
          Peer Interface and IP: peerlink.4094 169.254.255.2
                      Backup IP: 10.0.0.12 (inactive)
                     System MAC: 44:38:39:ff:00:01

CLAG Interfaces
Our Interface      Peer Interface     CLAG Id   Conflicts              Proto-Down Reason
----------------   ----------------   -------   --------------------   -----------------
         server1   -                  1         -                      -
         server2   -                  2         -                      -

Короче, как выяснилось в итоге, это связано с типом драйвера в virtualbox. Пришлось поменять драйвер на Intel PRO1000. Правда для корректного запуска нужно сделать правки в vagrant файле, который используется для провиженинга. Issue создал, посмотрим, что нам скажут ребята из Cumulus.

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


На трейсе видно, как трафик проходит через leaf01 (172.16.1.1), spine01 (10.0.0.21) и leaf02 (10.0.0.13).

Все, можно играться!

Я, пожалуй, проверю BGP и на этом getting started пост можно заканчивать. Cumulus CLI немного непривычен, но в целом очень удобен. Ниже видно, что мы получаем пару маршрутов по BGP (B>). Заметили интересную вещь?


А так?


Да, BGP поднят по IPv6, но передает IPv4 префиксы. Немного писал о таком подходе здесь. Возможно, когда вы просматривали конфигурацию, которую Ansible отправляет на устройства, вас тоже напряг тот факт, что там нет конфигурации для интерфейсов между leaf и spine. Интерфейсы просто поднимаются и на них включается BGP. Это меня дико смутило, но потом я понял в чем дело, используются link-local адреса. Довольно интересная конфигурация на мой взгляд. То есть соседи не задаются руками в нашем случае!

Пост получился довольно большим для getting started. В любом случае, я показал как быстро можно начать работать с Cumulus Linux. Более того, немного посмотрели на выводы команд, увидели как работает Ansible и даже чуть-чуть потраблшутили. Наверное, возникло больше вопросов, чет ответов. Разберемся с этим в других постах.

Комментариев нет:

Отправить комментарий