Глава 13. NFV и координация - большие экосистемы

В данной главе мы охватим следующие рецепты:

  • Построение VNF с помощью OPNFV

  • Обработка пакетов посредством DPDK

  • Разбор сообщений BMP при помощи SNAS.io

  • Управление дронами через некую беспроводную сеть

  • Создание кластеров PNDA

Введение

Сетевая программная поддержка привносит в сетевую среду аспекты разработки программного обеспечения. Мы уже обсуждали как SDN делают возможной логическую централизацию управления в разрезе данных в предыдущих главах. В данной главе мы взглянем на экосистемы большего размера со стороны Виртуализации сетевых функций (NFV, Network Function Virtualization) и координации (orchestration, оркестрации).

Сообщество Linux ведёт множество проектов с открытым исходным кодом сетевой среды и оркестрации, такие как OPNFV, ONAP, PNDA, DPDK, SNAS, ODPi и FD.io. Мы рассмотрим как применять Python для расширения этих проектов и усиливать их для построения и координации сетевых решений корпоративного уровня. Хотя многие из них построены с поддержкой множества языков, Python играет некую важную роль в большинстве этих проектов в качестве инструмента построения и проверки, если уж не основного языка кодирования. Мы рассмотрим как Python применяется для настройки и установки этих проектов для решения распространённых проблем, с которыми сталкиваются при конфигурировании таких проектов корпоративного уровня.

В сообществе Linux имеется большая совместная работа по соединению в одно целое различных компаний и организаций для набора проектов с открытым исходным кодом. Мы рассмотрели ряд значимых для NFV и оркестрации проектов в своих рецептах предыдущей главы. На самом деле имеется намного больше проектов в сообществе Linux, на которые стоит обратить внимание и их перечень сохраняет рост. Мы можем найти некий список активных проектов сообщества Linux на его вебсайте: https://www.linuxfoundation.org/projects.

Построение VNFs с помощью OPNFV

Открытая платформа для NFV (OPNFV, Open Platform for NFV - http://docs.opnfv.org/en/stable-danube/index.html) является некоторой открытой платформой сообщества Linux для снабжения NFV (Network Functions Virtualization, Виртуализацией сетевых функций) различных проектов. Различные сетевые функции делаются виртуальными и разрабатываются как FNV, (Virtual Network Functions, виртуальные сетевые функции) с поддержкой платформ NFV таких как OPNFV. OPNFV состоит из многих проектов и функций для инфраструктуры виртуализации сетевых функций (NFVI Network Function Virtualization Infrastructure).

OPNFV может устанавливаться при помощи различных инструментов установки: Compass, Fuel, TripleO из Apex и Juju. Подробности имеющихся альтернатив установки можно найти по адресу https://www.opnfv.org/software/downloads/release-archives/danube-2-0. В данном рецепте мы подробно рассмотрим установку OPNFV при помощи Compass. Будучи неким крупномасштабным многоуровневым проектом с большим числом компонентов, OPNFV разрабатывается на множестве языков. Python применяется в OPNFV для многих сценариев, включая действия на конфигурированию и настройке. Как мы изучим в данном рецепте, установка и обнаружение неисправностей OPNFV требует неокторой среды разработки Python и существенного опыта в Python.

Приготовление

Данный рецепт развивает установку определённой платформы OPNFV на голом железе для построения VHF. Мы слегка изменили производимый OPNFV quickstart для его работы в некотором отдельном сценарии. Данный рецепт требует выгрузки нескольких ГБ файлов образов. Если вы не имеете возможности выгрузки 20-30 ГБ в своём текущем плане данных, прекратите исполнение данного рецепта. Если ваше дисковое пространство ограничено, он может исчерпать остающееся свободным пространство при настройке OPNFV.

Данный рецепт требует около 1ТБ свободного дискового пространства и 64 ГБ ОЗУ. Диски меньшего размера могут вызвать проблемы, такие как ошибки выхода за имеющиеся размеры пространства когда данный сценарий устанавливает пять хостов для данного NFV. Аналогично, если у вас нет достаточной оперативной памяти, вы получите отказ при запуске данного домена. Этот рецепт требует от вас наличия самой последней версии Python (проверено на Python 2.7). Проект OPNFV ещё пока не совместим с Python 3, так как несколько библиотек не совместимы для работы с Python 3.

Процесс установки займёт приблизительно час. Поэтому будьте готовы к ожиданию .Убедитесь что у вас имеется по крайней мере 30ГБ дискового пространства для использования в данном упражнении и устойчивое интернет соединение для выгрузки необходимого сценария и настройки всех репозиториев. Дополнительные подробности по OPNFV можно найти по ссылке http://docs.opnfv.org/en/stable-danube/submodules/compass4nfv/docs/release/installation/vmdeploy.html. Приводимые здесь детали являются дополнением к руководству по установке OPNFV. Полная автономная установка также возможна, как это описывается в http://docs.opnfv.org/en/stable-danube/submodules/compass4nfv/docs/release/installation/offline-deploy.html.

Как это сделать

Установите OPNFV на своём компьютере применив следующий сценарий:


$ sh 13_1_quickstart.sh
		

Листинг 13.1 является неким сценарием, который запускает прочие команды для построения и установки OPNFV следующим образом:

 

#!/bin/bash
##################################################
# Книга рецептов сетевого программирования Python, второе издание -- Глава - 13
##################################################

sudo apt-get update
sudo apt-get install -y git
# Для предложения возможностей системным администраторам ограничения способностей программ
# с помощью профилей для каждой программы.
sudo apt-get install -y apparmor

# Pyyaml я вляется необходимым пакетом для данных сценариев настройки.
sudo pip2 install pyyaml

# Cheetah является необходимым пакетом для шаблонов и генерации кода.
sudo pip2 install cheetah

git clone https://gerrit.opnfv.org/gerrit/compass4nfv

cd compass4nfv

CURRENT_DIR=$PWD
SCENARIO=${SCENARIO:-os-nosdn-nofeature-ha.yml}

# Данный сценарий построения строит необходимый файл iso.
# Вы также можете выгрузить данный файл iso: например с,
# $ wget http://artifacts.opnfv.org/compass4nfv/danube/opnfv-2017-07-19_08-55-09.iso
./build.sh

export TAR_URL=file://$CURRENT_DIR/work/building/compass.tar.gz

# Экспорт приводимых ниже расположений. 
export DHA=$CURRENT_DIR/deploy/conf/vm_environment/$SCENARIO
export NETWORK=$CURRENT_DIR/deploy/conf/vm_environment/network.yml
# В противном случае ваша установка получит отказ с неким сообщением об ошибке, аналогичном приводимому ниже:
# + check_input_para
# + python /home/pradeeban/programs/opnfv/util/check_valid.py '' ''
# DHA file doesn't exist
# + '[' 1 -ne 0 ']'
# + exit 1

# Если вы следуете автономной установкой, вам также потребуется выгрузить некий пакет среды jumpshot.
# Он состоит из необходимых зависимостей.
# $ wget http://artifacts.opnfv.org/compass4nfv/package/master/
jh_env_package.tar.gz
# Теперь экспортируйте требующиеся абсолютные пути для этих каталогов (следуйте приводимому ниже примеру):
# export ISO_URL=file:///home/compass/compass4nfv.iso
# export JHPKG_URL=file:///home/compass/jh_env_package.tar.gz

# Именно эта команда является общей для установок через интернет и в автономном режиме.
./deploy.sh
		

Данный сценарий выгружает проект установки OPNFV Compass для настройки OPNFV. Он строит OPNFV посредством имеющегося установщика и развёртывает его. Вы можете наблюдать за процессом установки по его журналу регистрации.

 

Рисунок 1


Установка OPNFV

Как это работает

Если компьютер, на котором вы исполняете данный рецепт не имеет достаточного объёма памяти, он предоставит следующую запись в журнале регистрации в процессе самых последних этапов:


+ sudo virsh start host4
error: Failed to start domain host4
error: internal error: early end of file from monitor,
possible problem: 2017-07-18T16:29:50.376832Z
qemu-system-x86_64: cannot set up guest memory
'pc.ram': Cannot allocate memory
		

В этом можно убедиться проверив compass4nfv/work/deploy/vm/hostN/libvirt.xml, где N = [1, 6. В этих файлах вы можете обнаружить следующие строки:


<memory unit='MiB'>16384</memory>
<currentMemory unit='MiB'>16384</currentMemory>
		

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

Убедитесь что и командаpython, и команда pip, указывают на некую установку Python 2. Если установлены и Python 2, и Python 3, скорее всего, вы имеете pip, предпочитающий Python 3, в то время как python ссылается на Python 2. Например, обратите внимание на такой сценарий:


$ pip --version
pip 9.0.1 from /home/pradeeban/.local/lib/python3.5/site-packages (python 3.5)
$ python --version
Python 2.7.12
$ python3 --version
Python 3.5.2
$ pip2 --version
pip 8.1.1 from /usr/lib/python2.7/dist-packages (python 2.7)
		

Здесь очевидно, что команды pip и python указывают на две различные версии - Python 2 и Python 3. Чтобы исправить это:


$ sudo python3 -m pip install -U --force-reinstall pip
$ sudo python -m pip install -U --force-reinstall pip
		

Предыдущие команды гарантируют, что pip указывает на pip2, вашу версию Python 2. Вы можете убедиться в этом, выполнив предыдущие команды:


$ pip2 --version
pip 8.1.1 from /usr/lib/python2.7/dist-packages (python 2.7)
$ pip --version
pip 8.1.1 from /usr/lib/python2.7/dist-packages (python 2.7)
$ pip3 --version
pip 9.0.1 from /usr/local/lib/python3.5/dist-packages (python 3.5)
		

Если вы в процессе столкнулись с приводимой ниже ошибкой:


OSError: [Errno 13] Permission denied:
'/home/pradeeban/.ansible/tmp/ansible-local-24931HCfLEe'
+ log_error 'launch_compass failed'
+ echo -e 'launch_compass failed'
launch_compass failed
		

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

Установка Python, которой снабжён pip может получить отказ если не настроена надлежащим образом. Вы можете проверить это посредством следующих команд:


$ pip2 show virtualenv
Traceback (most recent call last):
  File "/usr/bin/pip2", line 9, in <module>
  load_entry_point('pip==8.1.1', 'console_scripts', 'pip2')()
  File "/usr/lib/python2.7/dist-packages/pip/__init__.py",
  line 215, in main
    locale.setlocale(locale.LC_ALL, '')
  File "/usr/lib/python2.7/locale.py", line 581, in setlocale
    return _setlocale(category, locale)
locale.Error: unsupported locale setting
		

Если ваш вывод аналогичен показанной ошибке, установите свою локализацию посредством приводимых далее команд:


export LC_ALL="en_US.UTF-8"
export LC_CTYPE="en_US.UTF-8"
sudo dpkg-reconfigure locales
		

Конечно, вы можете заменить представленную локализацию en_US.UTF-8 на предпочитаемые вами язык и локализацию.

Если вы выйдите за пределы пространства на последних этапах настройки OPNFV Compass, вы получите отказ с сообщением об ошибке, аналогичным такому:


changed: [localhost] => (item=compass4nfv/compass-deck)
failed: [localhost] (item=compass4nfv/compass-tasks-osa) => {"changed": true, "cmd": "docker load -i \"/dev/opnfv/compass4nfv/work/deploy/installer/compass_dists/compass-tasksosa.tar\"", "delta": "0:00:14.055573", "end": "2017-07-19 17:19:13.758734", "failed": true, "item": "compass4nfv/compass-tasks-osa", "rc": 1, "start": "2017-07-19 17:18:59.703161", "stderr": "Error processing tar file(exit status 1): write /df21d65fec8fc853792311af3739a78e018b098a5aa3b1f6ff67f44b330423b8/layer.tar: no space left on device", "stderr_lines": ["Error processing tar file(exit status 1): write /df21d65fec8fc853792311af3739a78e018b098a5aa3b1f6ff67f44b330423b8/layer.tar: no space left on device"], "stdout": "", "stdout_lines": []}
		

Если ваш компьютер не имеет достаточных памяти или дискового пространства для выполнения данного рецепта, вы можете исполнить его в некотором оптимизированном месте экземпляра, таком как r4.8xlarge в Amazon Elastic Compute Cloud (EC2). Перед запуском данного экземпляра увеличьте своё хранилище установленного по умолчанию тома EBS с 8 ГБ до 1000 ГБ, тем самым вы не выйдите за пределы дискового пространства в процессе своей установки OPNFV.

Многие расширения Python были построены вокруг OPNFV. Одним из примеров является проект SDNVPN (https://wiki.opnfv.org/display/sdnvpn/SDNVPN+project+main+page), который пытается интегрировать виртуальные сетевые компоненты для обеспечения функциональности уровня 2/3 VPN (virtual private network) в OPNFV. Вы можете клонировать имеющийся репозиторий исходного кода SDNVPN для построения его с помощью Python:


$ git clone https://github.com/opnfv/sdnvpn.git
$ cd sdnvpn/
$ python setup.py build
$ sudo python setup.py install
		

Поскольку OPNFV является неким сложным сетевом проектом с вовлечёнными в него кластерами компьютеров, мы можем настроить полезные и интересные сценарии эффективного применения Python в OPNFV.

Обработка пакетов посредством DPDK

Набор средств разработки уровня данных (DPDK, Data Plane Development Kit) является проектом сообщества Linux, имеющий целью предоставления библиотек и драйверов для последующей обработки любым процессором. Библиотеки DPDK могут применяться для реализации tcpdump - в качестве алгоритма перехвата пакетов, а также быстрого и действенного приёма и передачи пакетов за менее чем 80 циклов ЦПУ.

Согласно своему названию, DPDK ограничивает своё назначение имеющимся уровнем данных и не имеет целью предоставлять какой бы то ни было стек, состоящий из сетевых функций. Таким образом, сетевая деятельность промежуточной обработки, такая как безопасность и межсетевое экранирование, а также перенаправление 3 уровня на предусмотрены в архитектуре DPDK. В данном рецепте мы настроим DPDK для быстрой и действенной обработки пакетов.

DPDK разработан на языке C, тем не менее поверх него были построены приложения Python. В данном рецепте мы установим DPDK и заглянем в некий пример приложения Python построенный с помощью DPDK.

Приготовление

Вы можете установить DPDK на своём компьютере воспользовавшись следующим сценарием:


$ sh 13_2_quickstart.sh
		

Данный сценарий займёт несколько минут на настройку и установку DPDK и после успешной установки предоставит следующие строки:


..
Installation in /usr/local/ complete
DPDK Installation Complete.
		

Содержимое данного сценария подробно описывается в последующих шагах.

Установите зависимости pcap, поскольку DPDK полагается на pcap для перехвата пакета на уровне пользователя:


$ sudo apt-get install libpcap-dev
Failure to have pcap in your system will fail the build with the error message "dpdk-stable-17.05.1/drivers/net/pcap/rte_eth_pcap.c:39:18: fatal error: pcap.h: No such file or directory"
		

Выгрузите самую последнюю стабильную версию DPDK с http://dpdk.org/download:


$ wget http://fast.dpdk.org/rel/dpdk-17.05.1.tar.xz
		

Распакуйте и настройте DPDK:


$ tar -xvf dpdk-17.05.1.tar.xz
$ cd dpdk-stable-17.05.1
$ make config T=x86_64-native-linuxapp-gcc DESTDIR=install
Configuration done
		

Включите pcap, поскольку заголовки pcap требуются для необходимого формата файла перехвата:

У вас имеется два варианта построения. Вариант 1 состоит в построении вручную с использованием make (который мы также должны применять в своём сценарии) и Вариант 2 с помощью предоставляемого сценария dpdk-setup.sh:

  • Вариант 1:

    
    $ make
    ..
    == Build app/test-crypto-perf
      CC main.o
      CC cperf_ops.o
      CC cperf_options_parsing.o
      CC cperf_test_vectors.o
      CC cperf_test_throughput.o
      CC cperf_test_latency.o
      CC cperf_test_verify.o
      CC cperf_test_vector_parsing.o
      LD dpdk-test-crypto-perf
      INSTALL-APP dpdk-test-crypto-perf
      INSTALL-MAP dpdk-test-crypto-perf.map
    Build complete [x86_64-native-linuxapp-gcc]
    		
  • Вариант 2:

    
    $ cd usertools
    $ ./dpdk-setup.sh
    ------------------------------------------------
     Step 1: Select the DPDK environment to build
    ------------------------------------------------
    [1] arm64-armv8a-linuxapp-gcc
    [2] arm64-dpaa2-linuxapp-gcc
    [3] arm64-thunderx-linuxapp-gcc
    [4] arm64-xgene1-linuxapp-gcc
    [5] arm-armv7a-linuxapp-gcc
    [6] i686-native-linuxapp-gcc
    [7] i686-native-linuxapp-icc
    [8] ppc_64-power8-linuxapp-gcc
    [9] x86_64-native-bsdapp-clang
    [10] x86_64-native-bsdapp-gcc
    [11] x86_64-native-linuxapp-clang
    [12] x86_64-native-linuxapp-gcc
    [13] x86_64-native-linuxapp-icc
    [14] x86_x32-native-linuxapp-gcc
    ...
    		

Выберите одну из предыдущих 14 опций для построения. Я воспользовался опцией 12 в своём построении. Вы можете настроить соответствия HugePages применив опции 18 и 19 в данном сценарии установки или применить следующие команды:


$ sudo mkdir -p /mnt/huge
$ sudo mount -t hugetlbfs nodev /mnt/huge
$ sudo su
$ echo 64 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
		

Теперь вы можете установить DPDK применив следующую команду:


$ sudo make install
		

Как это сделать

После установки вы можете проверить DPDK с помощью простого приложения следую приводимой ниже команде:


$ make -C examples RTE_SDK=$(pwd) RTE_TARGET=build O=$(pwd)/build/examples
		

usertools представляет собой пакет из нескольких написанных на Python утилит. Например, исполнение cpu_layout.py представляет следующий вывод на моём компьютере:


$ cd usertools
$ python cpu_layout.py
===============================================
Core and Socket Information (as reported by '/sys/devices/system/cpu')
===============================================
cores = [0, 1, 2, 3]
sockets = [0]
       Socket 0
       --------
Core 0 [0, 1]
Core 1 [2, 3]
Core 2 [4, 5]
Core 3 [6, 7]
		

Это сообщение о схеме имеющихся четырёх ядер моего ноутбука. Вы можете получить аналогичный вывод, базирующийся на вашей операционной системе.

Дополнительные сетевые примеры или утилиты можно обнаружить внутри папки build/example. Многие продукты построены для расширения или усиления DPDK. Cisco TRex является неким генератором обмена, разработанном на C и Python поверх DPDK. Вы можете настроить его локально с помощью следующей команды:


$ wget http://trex-tgn.cisco.com/trex/release/latest
$ tar -xvf latest
$ cd v2.27/
		

Внутри полученной папки 2.27 вы найдёте сценарий Python для исполнения TRex на основе DPDK. Например, вы можете запустить демон хозяина при помощи Python следующим образом:


$ sudo python master_daemon.py start
Master daemon is started
$ sudo python master_daemon.py show
Master daemon is running
		

Как это работает

DPDK является набором библиотек и модулей для разработки имеющегося уровня данных. Он эксплуатирует многие популярные инструменты и приложения, такие как pcap для перехвата всех пакетов. Многие из пользовательских инструментов и сценариев настройки написаны на Python, к тому же несколько библиотек написаны на Python для расширения DPDK. Имеющиеся примеры DPDK можно найти в build/example для усиления имеющегося ядра DPDK чтобы программировать свой уровень данных.

Входящими в состав пакета приложениями (как это именует DPDK) являются: bond, ethtool, ip_pipeline, kni, l2fwd-jobstats, l3fwd-acl, link_status_interrupt, netmap_compat, qos_meter, rxtx_callbacks, tep_termination, vmdq, cmdline, exception_path, ipsec-secgw, l2fwd, l2fwd-keepalive, l3fwd-power, load_balancer, packet_ordering, qos_sched, server_node_efd, timer, vmdq_dcb, distributor, helloworld, ipv4_multicast, l2fwd-crypto, l3fwd, l3fwd-vf, multi_process, performance-thread, quota_watermark, skeleton, vhost и vm_power_manager

Синтаксический анализ сообщений BMP при помощи SNAS.io

SNAS (Streaming Network Analytics System, Система потоковой сетевой аналитики), обычно называемая SNAS.io является проектом сообщества Linux, который состоит из инфраструктуры и библиотек для отслеживания и доступа к большому числу объектов, включая маршрутизаторы, одноранговые узлы и префиксы в реальном времени. Первоначально называвшийся OpenBMP, SNAS реализует спецификацию шины сообщений BMP. BMP относится к протоколу мониторинга BGP и путём реализации конкретного протокола BMP SNAS взаимодействует с имеющимися устройствами BMP, такими как маршрутизаторы.

SNAS имеет некий API Python, который делает возможной для вас разработку приложений Python поверх SNAS для сообщений BMP. SNAS также состоит из разработанного на Python преобразователя mrt2bmp, который считывает файлы MRT (Multi-threaded Routing Toolkit) маршрутизатора и одновременно отправляет сообщения BMP. Рабочими потоками такого преобразователя SNAS являются: Router | MRT | MRT2BMP | OpenBMP collector | Kafka message bus | MySQL consumer. Вы можете найти дополнительную информацию об этом проекте по ссылке https://github.com/OpenBMP.

Приготовление

Вначале установим и настроем Apache Kafka и библиотеку SNAS для синтаксического разбора сообщений OpenBMP Kafka:


$ sh 13_3_install.sh
#!/bin/bash
#########################################################
# Книга рецептов сетевого программирования Python, второе издание -- Глава - 13
#########################################################
# Устанавливаем зависимости
sudo apt-get install python-dev python-pip libsnappy-dev
sudo pip install python-snappy kafka-python pyyaml
# Устанавливаем SNAS Python API
git clone https://github.com/OpenBMP/openbmp-python-api-message.git
cd openbmp-python-api-message
sudo pip install .
# Возвращаемся обратно в корневой каталог.
cd ..
# Выгружаем Apache Kafka
wget http://apache.belnet.be/kafka/0.11.0.0/kafka_2.11-0.11.0.0.tgz
tar -xzf kafka_2.11-0.11.0.0.tgz
		

Последуйте приводимому выше сценарию и после выгрузки всех зависимостей установить SNAS и Kafka. Для быстрого запуска сервера Kafka воспользуйтесь приведённым ниже сценарием:


$ sh 13_3 quickstart.sh
#!/bin/bash
###############################################
# Книга рецептов сетевого программирования Python, второе издание -- Глава - 13
###############################################

# Запуск Zookeeper. Для просмотра журнала в реальном времени, введите в терминале: "tail -f zk-server.out".

nohup kafka_2.11-0.11.0.0/bin/zookeeper-server-start.sh
kafka_2.11-0.11.0.0/config/zookeeper.properties > zk-server.out &

# Запуск Kafka-Server. Для просмотра журнала в реальном времени, введите в терминале: "tail -f kafka-server.out".

nohup kafka_2.11-0.11.0.0/bin/kafka-server-start.sh
kafka_2.11-0.11.0.0/config/server.properties > kafka-server.out &
		

Поскольку данный сценарий запускает Kafka и ZooKeeper в режиме nohup {Прим. пер.: с игнорированием сигналов утраты связи SIGHUP}, вам придётся отыскать и уничтожить эти процессы, когда вы пожелаете остановить их. Вы можете обнаружить их посредством:


$ ps -xa | grep java
		

Затем уничтожьте этот процесс применив следующую команду для соответствующего процесса Kafka и ZooKeeper:


$ kill {process-id}
		

Как это сделать

После того, как вы установили API сообщений BMP SNAS и запустили сервер ZooKeeper и сервер Kafka, как это показано выше, вы готовы выполнить некое простое ожидание сообщений BMP.

Вначале запустите клиент Python API сообщений SNAS:


$ python 13_3_log_consumer.py
Connecting to kafka... takes a minute to load offsets and topics, please wait
Now consuming/waiting for messages...

13_3_snas_log_consumer.py is adopted from openbmp-python-apimessage/examples/log_consumer.py.
		

Теперь, если вы исполните приводимую ниже строку из другого терминала и отправите какое- то пустое сообщение нажав клавишу Enter на своей клавиатуре:


$ kafka_2.11-0.11.0.0/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic openbmp.parsed.router
> 
>
		

вы получите следующее сообщение:


$ python 13_3_snas_log_consumer.py --conf="config.yaml"
Connecting to kafka... takes a minute to load offsets and topics, please wait
Now consuming/waiting for messages...
Received Message (2017-07-21 12:17:53.536705) : ROUTER(V: 0.0)
[]
		

Если вы исполните следующую команду, вы обнаружите некий список тем, созданных для BMP 13_3_snas_log_consumer.py:


$ kafka_2.11-0.11.0.0/bin/kafka-topics.sh --list --zookeeper localhost:2181 __consumer_offsets
openbmp.parsed.bmp_stat
openbmp.parsed.collector
openbmp.parsed.l3vpn
openbmp.parsed.ls_link
openbmp.parsed.ls_node
openbmp.parsed.ls_prefix
openbmp.parsed.peer
openbmp.parsed.router
openbmp.parsed.unicast_prefix
		

В Листинге 13.3 приводится простой потребитель журнала BMP, адаптированный под примеры SNAS. Этот листинг опускает ряд строк кода для краткости. Ознакомьтесь с полным кодом в 13_3_snas_log_consumer.py:

 

#!/usr/bin/env python
# Книга рецептов сетевого программирования Python, второе издание -- Глава - 13
# Данная программа оптимизирована под Python 2.7.12.
# SNAS Message API требует для исполнения Python 2.7.
# Она может исполняться во всех прочих версиях с изменениями и/или без них.
# Адаптирована из openbmp-python-api-message/examples/log_consumer.py

import argparse
import yaml
import datetime
import time
import kafka

from openbmp.api.parsed.message import Message
from openbmp.api.parsed.message import BmpStat
from openbmp.api.parsed.message import Collector
from openbmp.api.parsed.message import LsLink
from openbmp.api.parsed.message import LsNode
from openbmp.api.parsed.message import LsPrefix
from openbmp.api.parsed.message import Peer
from openbmp.api.parsed.message import Router
from openbmp.api.parsed.message import UnicastPrefix
from openbmp.api.parsed.message import L3VpnPrefix

def process_message(msg):
    m = Message(msg.value) # Получить тело сообщения kafka.
    t = msg.topic # Gets topic of kafka message.
    m_tag = t.split('.')[2].upper()
    t_stamp = str(datetime.datetime.now())

    # Для различных вариантов тем сообщений BMP. Для краткости опускаем журналирование.
    if t == "openbmp.parsed.router":
       router = Router(m)
       print ('\n' + 'Received Message (' + t_stamp + ') : ' + m_tag + '(V: ' + str(m.version) + ')')
       print (router.to_json_pretty())

    elif t == "openbmp.parsed.peer":
       peer = Peer(m)

    elif t == "openbmp.parsed.collector":
       collector = Collector(m)

    elif t == "openbmp.parsed.bmp_stat":
       bmp_stat = BmpStat(m)

    elif t == "openbmp.parsed.unicast_prefix":
       unicast_prefix = UnicastPrefix(m)

    elif t == "openbmp.parsed.l3vpn":
        l3vpn_prefix = L3VpnPrefix(m)

    elif t == "openbmp.parsed.ls_node":
        ls_node = LsNode(m)

    elif t == "openbmp.parsed.ls_link":
        ls_link = LsLink(m)

    elif t == "openbmp.parsed.ls_prefix":
        ls_prefix = LsPrefix(m)

def main(conf):
    # Включение topics/feeds
    topics = [
        'openbmp.parsed.router', 'openbmp.parsed.peer',
        'openbmp.parsed.collector',
        'openbmp.parsed.bmp_stat', 'openbmp.parsed.unicast_prefix', 'openbmp.parsed.ls_node',
        'openbmp.parsed.ls_link',
        'openbmp.parsed.ls_prefix',
        'openbmp.parsed.l3vpn'
    ]

    # Считывание файла настроек
    with open(conf, 'r') as f:
        config_content = yaml.load(f)

    bootstrap_server = config_content['bootstrap_servers']

    try:
        # соедиенение тем и их привязка
        print ("Connecting to kafka... takes a minute to
        load offsets and topics, please wait")
        consumer = kafka.KafkaConsumer(
            *topics,
            bootstrap_servers=bootstrap_server,
            client_id="dev-testing" + str(time.time()),
            group_id="dev-testing" + str(time.time()),
            enable_auto_commit=True,
            auto_commit_interval_ms=1000,
            auto_offset_reset="largest"
        )
        for m in consumer:
            process_message(m)

    except kafka.common.KafkaUnavailableError as err:
        print ("Kafka Error: %s" % str(err))

    except KeyboardInterrupt:
        print ("User stop requested")

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='SNAS Log Consumer')
    parser.add_argument('--conf', action="store", dest="conf", default="config.yaml")
    given_args = parser.parse_args()
    conf = given_args.conf
    main (conf)
		

Некий файл настройка может быть передан имеющимся параметром --conf. Значением по умолчанию является config.yaml, который просто указывает на определённое по умолчанию расположение сервера Kafka:


bootstrap_servers: localhost:9092
		

Приводимый ниже снимок экрана отображает вывод данной программы Python определённых API сообщений SNAS и брокера Kafka совместно с полным перечнем созданных этой программой Python тем:

 

Рисунок 2


API сообщений SNAS и брокер Kafka

Как это работает

Определены первые девять тем сообщений BMP и программа потребитель журнала SNAS подписана на них через брокер Kafka. Синтаксически разбираемые сообщения BMP включают уведомления router, peer, collector, bmp_stat, unicast_prefix, l3vpn, ls_node, ls_link и ls_prefix. После своего запуска, потребитель журнала ожидает сообщения по одной из этих девяти тем. Когда вы подключаете kafka-console-producer.sh, вы можете отправлять этому брокеру сообщения. Однако все сообщения не будут достигать необходимого журнала потребителя если это не относится к одной из указанных девяти тем. Вы можете эмулировать свои сообщения BMP запустив kafka-console-producer.sh с одной из указанных тем, как мы это сделали в своём примере с флагом --topic openbmp.parsed.router. Все полученные сообщения для данных тем подписки достаточно просто распечатать при помощи to_json_pretty() в некотором цикле if-else для каждой из таких тем.

Управление дронами через беспроводные сети

Повсеместно используемые в наши дни дроны всё чаще применяют контроллеры с возможностью управления ими с земли через сообщения TCP и UDP через некие беспроводные сетевые среды. Dronecode предоставляет некую платформу управления и программирования дронов с симуляцией в какой- то среде песочницы для разработки. Разработанный на Python, Dronecode управляется сообществом Linux. В данном рецепте мы исполним простейшую имитация дрона. С более интересными рецептами можно ознакомиться, следуя за их вебсайтом (https://www.dronecode.org).

Приготовление

Dronekit для своей работы требует Python 2.7. Установите Dronekit и Dronekit симулятор SITL (Software in the Loop) с помощью pip Python:


$ pip install dronekit
$ pip install dronekit-sitl
		

Как это сделать

В данном примере мы выполним симуляцию некого простого дрона с помощью dronekit-sitl. Данный API симулятора совместим с API Dronekit, который на самом деле управляет настоящими дронами. Следовательно, вы можете разработать его и очень легко выполнить симуляцию и изготовление, как это было с нашими предыдущими рецептами в имитации Mininet.

Вначале, пержде чем запустить в каком- то терминале 13_4_dronekit_sitl_simulation.py, выполните dronekit-sitl:


$ dronekit-sitl copter-3.3 --home=-45.12,149.22,544.55,343.55
os: linux, apm: copter, release: 3.3
SITL already Downloaded and Extracted.
Ready to boot.
Execute: /home/pradeeban/.dronekit/sitl/copter-3.3/apm --
home=-45.12,149.22,544.55,343.55 --model=quad
Started model quad at -45.12,149.22,544.55,343.55 at speed 1.0
bind port 5760 for 0
Starting sketch 'ArduCopter'
Serial port 0 on TCP port 5760
Starting SITL input
Waiting for connection ....
		

Листинг 13.4 предоставляет некую простейшую имитацию какого- то дрона, которая может подключиться к конкретному дрону или, как в нашем случае, исполнить некую эмуляцию, воспользовавшись доступным сетевым соединением TCP:

 

#!/usr/bin/env python
# Книга рецептов сетевого программирования Python, второе издание -- Глава - 13
# Данная программа оптимизирована под Python 2.7.12.
# SNAS Message API требует для исполнения Python 2.7.
# Она может исполняться во всех прочих версиях с изменениями и/или без них.

import dronekit_sitl
from dronekit import connect, VehicleMode

# Подключиться к определённому по умолчанию sitl, если он исполняется.
sitl = dronekit_sitl.start_default()
connection_string = sitl.connection_string()

# Подключиться к Изделию (Vehicle).
print("Connected: %s" % (connection_string))
vehicle = connect(connection_string, wait_ready=True)

print ("GPS: %s" % vehicle.gps_0)
print ("Battery: %s" % vehicle.battery)
print ("Last Heartbeat: %s" % vehicle.last_heartbeat)
print ("Is Armable?: %s" % vehicle.is_armable)
print ("System status: %s" % vehicle.system_status.state)
print ("Mode: %s" % vehicle.mode.name)

# закрыть объект изделия перед выходом из сценария
vehicle.close()
print("Completed")
		

Последующий код отображает исполнение Dronekit:


$ python 13_4_dronekit_sitl_simulation.py
Starting copter simulator (SITL)
SITL already Downloaded and Extracted.
Ready to boot.
Connected: tcp:127.0.0.1:5760
>>> APM:Copter V3.3 (d6053245)
>>> Frame: QUAD
>>> Calibrating barometer
>>> Initialising APM...
>>> barometer calibration complete
>>> GROUND START
GPS: GPSInfo:fix=3,num_sat=10
Battery: Battery:voltage=12.587,current=0.0,level=100
Last Heartbeat: 0.862903219997
Is Armable?: False
System status: STANDBY
Mode: STABILIZE
Completed
		

Приводимый далее снимок экрана отображает исполнение и нашего Dronekit, и симулятора:

 

Рисунок 3


DroneKit и его симуляция

Приводимые ниже строки выводятся в основном терминальном окне SITL, отражая имеющееся соединение TCP:


bind port 5762 for 2
Serial port 2 on TCP port 5762
bind port 5763 for 3
Serial port 3 on TCP port 5763
Closed connection on serial port 0
		

Данный рецепт показывает установленные по умолчанию значения имитации и соединение с данным SITL по установленному порту, а также закрытие исполнения в нём самом после его завершения.

Как это работает

Данный рецепт инициализирует некий простейший дрон и выводит его состояние. Вы можете исполнять его для установки его параметров и динамического изменения их значений. Дополнительные примеры Dronekit можно найти на http://python.dronekit.io/examples/.

Создание кластеров PNDA

PNDA (http://pnda.io/) является масштабируемой платформой аналитики больших данных для сетевых сред и служб от сообщества Linux. Для PNDA требуется некий действительно работающий кластер. PNDA предлагает сценарии Python (https://github.com/pndaproject/pnda-aws-templates) для развёртывание её в Amazon EC2.

Приготовление

Создайте некий сегмент (bucket) S3 из https://s3.console.aws.amazon.com/s3/home?region=eu-west-1. Мы применяем в данном рецепте в качестве своего региона по умолчанию EU (Ireland). Приложения PNDA будут размещены в этом сегменте. Замените pnda-apps именем своего сегмента S3. Так как данное имя сегмента совместно применяется всеми пользователями в данном регионе, у вас может не быть возможности воспользоваться pnda-apps в качестве своего Bucket name, поскольку оно уже может применяться кем- нибудь:


# S3 container to use for PNDA application packages
PNDA_APPS_CONTAINER: pnda-apps
		
 

Рисунок 4


Создание некоторого сегмента S3 для PNDA

Создайте в https://console.aws.amazon.com/iam/home?#/security_credential некий ключ. Не забудьте выгрузить этот ключ (rootkey.csv):

 

Рисунок 5


Создание ключа доступа

Откройте rootkey.csv и замените следующие значения в pnda_env.yaml. Эти значения появляются три раза. Убедитесь что вы надлежащим образом изменили все их:


AWS_ACCESS_KEY_ID: xxxx
AWS_SECRET_ACCESS_KEY: xxxx
		

Замените PNDA_ARCHIVE_CONTAINER на что-нибудь ещё (более представительное и достаточно длинное чтобы быть уникальным). Однако это сегмент будет создан автоматически.

Создайте некую пару именованных ключей SSH с названием key (https://eu-west-1.console.aws.amazon.com/ec2/v2/home?region=eu-west-1#KeyPairs:sort=keyName). Выгрузите и сохраните свой частный ключ, key.pem.

 

Рисунок 6


Создание и выгрузка частного ключа

Настройте все зависимости и шаблоны AWS:


$ sh 13_5_pnda_aws_setup.sh
#!/bin/bash
###############################################
# Книга рецептов сетевого программирования Python, второе издание -- Глава - 13
###############################################
# Склонируйте Platform Salt
git clone https://github.com/pndaproject/platform-salt.git
cd platform-salt
git checkout release/3.4.1
cd ..
# Склонируйте самый последний выпущенный тег своего шаблона PNDA AWS
git clone git@github.com:pndaproject/pnda-aws-templates.git
cd pnda-aws-templates
git checkout release/3.4.1
# Скопируйте имеющийся пример pnda_env.yaml в свой проект после изменения его в данном рецепте.
cp ../pnda_env.yaml pnda_env.yaml
# Установите зависимости
cd cli
sudo pip install -r requirements.txt
		

Теперь вы можете создать дистрибутив PNDA из своего репозитория PNDA при помощи приводимых ниже сценариев в своём каталоге mirror. Выполните эти команды в своём веб сервере:


$ git clone git@github.com:pndaproject/pnda.git
$ sudo su
$ cd pnda/mirror
$ ./create_mirror.sh
		

Когда построение вашего зеркала завершено, переместите все построенные каталоги в свой каталог mirror-dist (mirror_anaconda, mirror_cloudera и mirror_misc) в некую папку по вашему выбору (мы предполагаем, что наша папка имеет название packages). Теперь у вас имеется зеркалированный PNDA для расположения вашего веб сервера. Измените следующий URI, чтобы он указывал на данное публично доступное зеркало с вашего сайта:


pnda_component_packages:
  # HTTP server containing the compiled binary packages for the components
  # required to provision PNDA
  PACKAGES_SERVER_URI: http://x.x.x.x/packages
		

Вы даже можете разместить это внутри некоторого экземпляра EC2 после установки некоторого веб сервера, такого как Apache2. В таком случае вы будете иметь некие упакованные URI сервера наподобии http://ec2-34-253-229-120.eu-west-1.compute.amazonaws.com/packages/

Как это сделать

Теперь вы можете создать некий кластер PNDA с помощью команд:


$ cd cli
$ python pnda-cli.py create -e <cluster_name> -s <key_name> -f standard -o {no-of-tsdb-instances} -n {no-of-hadoop-data-nodes} -k {no-of-kafkabrokers} -z {no-of-zookeeper-nodes}
		

Замените все соответствующие имена. Например:


$ python pnda-cli.py create -e pnda -s key -f standard -o 2 -n 3 -k 2 -z 3
		

Или всего лишь с одним экземпляром для каждого:


$ python pnda-cli.py create -e pnda -s key -f standard -o 1 -n 1 -k 1 -z 1
		

В настоящее время pnda-cli.py и все прочие сценарии Python в PNDA не поддерживают Python 3, поскольку они написаны на Python2. Рекомендуется применять Python 2.7. Это будет снабжено подробными сообщениями в процессе вашей установки и временем исполнения в самом его окончании.

Как это работает

В данном рецепте pnda-cli.py вначале провереят имеется ли файл pnda_env.yaml и считывает из него все параметры. Он применяет интерфейс boto EC2 (http://boto.cloudhackers.com/en/latest/ec2_tut.html) для выполнения множества задач, таких как соединение с вашим регионом, инициализацию имеющихся экземпляров EC2 и их настройку. Ожидайте что это займёт несколько минут, что также зависит от имеющегося соединения между вашим зеркалом и самим экземпляром EC2. Поэтому может быть неплохой идееё на самом деле создать ваш кластер PNDA в некотором регионе, который является ближайшим к вам для минимизации задержки.

В данном рецепте мы изучили как настроить PNDA в AWS. В процессе этого мы также изучили насколько полезным может оказаться Python для столь сложных задач настройки, поскольку мы применили его для считывания файла настроек .yaml и установки некоторого кластера AWS на основе своих настроек.