Рубрики
Uncategorized

Kubernetes на руке: тематическое исследование

В Krakensystems мы работаем с различными устройствами IoT. Они наш основной инфр … С тегами Kubernetes, Arm, Casestudy, DevOps.

В Krakensystems мы работаем с различными устройствами IoT. Они являются нашей основной инфраструктурой для сбора данных и отправки их для дальнейшего агрегирования трубопроводов. На данный момент они реализованы как черные устройства Beaglebone, процессор ARMV7L Hard Float, AM335X 1 ГГц ARM® Cortex-A8 и только 512 МБ ОЗУ. В этом блоге мы освещаем вариант использования и обоснование использования Kubernetes на таких недостаточных устройствах.

Эти устройства выполняют простые услуги. Чтение Modbus Registers, или протокола XBEE, или прикрепление к OBD (встроенная диагностика для транспортных средств), анализ данных, сериализация в формате ProtoBuf и отправка на автобус.

Критерии дизайна и реализация

Формат развертывания

Мы хотим развернуть программное обеспечение в качестве неизменного бинарного/контейнера. Из -за процесса сборки C ++ загадочная настройка в Krakensystems и множество общих библиотечных зависимостей, настройка контейнера имеет наибольший смысл для этого варианта использования. Статический двоичный файл также является жизнеспособной альтернативой, но это потребует рефакторирования C ++, наша текущая система сборки, написанная как коллекция сценариев Bash/Makefile, работающая около 15 минут от 0, и около нескольких минут на CI после кэширования.

Другим решением было развертывание услуг голой металл. В этой настройке наследия была специальная общая библиотечная папка на услугу, и мы сделали Ld_library_path Объединение для управления общим управлением библиотекой, победив в первую очередь общие библиотеки. Тем не менее, из -за создания системы текущего состояния, создаваемого статическим бинарным был (DEV) трудоемким.

Kubernetes с решением для управления контейнерами идеально подходит для нашего варианта использования. Nomad или Plain Old Docker/Cri-O/RKT также удовлетворит этот критерий дизайна. Статические двоичные файлы с SystemD также являются удовлетворительным выбором, если это было просто сделать в настоящем состоянии кодовой базы.

Мониторинг

Узел и сервис мониторинг Aliveny имеет решающее значение. Нам требуется какой -то агент, работающий на узле и отправив, что я жив в какую -то систему, вместе со зрелым конвейером оповещения. Консул является одним из решений. У Kubernetes есть этот вне коробки, и вместе с Правилами оповещения Прометея казались естественным соответствием. Мы также используем Prometheus/Grafana/Alertmanager на протяжении всей нашей инфраструктуры, что сделало этот вариант более привлекательным.

Кроме того, проверка здоровья и готовности к готовности не особенно полезна для устройств Edge, так как сбой процесса сигнализирует о проблеме. Они не являются серверным компонентом, требующим принятия клиентских подключений.

Тем не менее, в будущем мы планируем представить проверки на сфере услуг в качестве механизма сбоя в случае, если служба не отправляет данные на шину сообщения — ее основная цель.

Оставшаяся инфраструктура Ascalia находится на Kubernetes, поэтому она имела смысл повторно использование тех же инструментов и настройки для наших устройств Edge. Менее разные движущиеся части всегда лучше и приводят к эксплуатационной простоте, несмотря на то, что Kubernetes не прост в эксплуатации.

Обновления

Устройства Edge — это не статичные острова, которые навсегда отдыхают в Тихом океане. Код часто изменяется, и конфигурация еще чаще.

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

Конфигурация устройства на крае хранится в RDBMS, Postgres в этом случае. Наличие оправы с краями 100 -х или 1000 -х годов, опрашивавших RDBMS для простых паров ключей/значения, не получится. Кроме того, нет уведомлений о стиле Push от RDBMS в обновлении ключей. Таким образом, нам нужен дополнительный слой между ними.

Мы повторно используем сервер API Kubernetes, и он поддерживает ключ/значение и т. Д. Мы определили каждое устройство Edge как объект CRD (определение пользовательского ресурса), поддерживающую богатую и специфичную для домена информацию. Kubernetes также сервер как примитивное управление запасами, дополняющее реальную поддержку Django для операций (т. Е. Мне все равно, что Django делает, пока обновляет правильные конечные точки отдыха в API Kubernetes)

В будущем, возможно, службы Edge должны наблюдать за самим хранилищем ключей/значения, будь то сервер API Kube и т. Д., Консул, Riak, Redis или любая другая реализация общих ключей/значения.

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

Настройка Wireguard VPN

Поскольку мы используем решение VPN Wireguard, нам нужно, чтобы IP/общедоступный IP -адрес клиентского сервера синхронизировал асинхронно. Это влечет за собой наличие дополнительного агента на Edge Device, который вы должны следить, отслеживать и убедиться, что он жив.

Нам также нужно хранить общедоступный ключ автономного устройства и легкий осмотр для этих ключей/настроек. CRD Kubernetes естественны для этой роли. Мы повторно используем магазин поддержки ETCD, имеем хороший RBAC на этих объектах, и мы определили пользовательские столбцы принтера для более легкого управления узлами VPN.

Мы использовали следующие внутренние инструменты с открытым исходным кодом:

Короче говоря, мы загрузили в Wireguard VPN с помощью WG-CNI-роли. Это также установило CNI на основе Wireguard для использования в нашем кластере Kubernetes.

Роль WG-CNI создала наши пользовательские CRD-манифесты, представляющие клиента/серверы в топологии VPN Wireguard.

После применения манифестов мы запустили оператор Wireguard Daemonset, поддерживая узлы синхронизации с дальнейшими дополнениями/удалением.

Первоначальное развертывание

Это не без проблем. Мы использовали Kubespray как зрелое решение для развертывания Kubernetes. Это единственное полное решение для развертывания металла. Будучи на основе Ansible, мы знакомы с этим и можем легко расширить его, если это необходимо … и это было необходимо.

Мы столкнулись с множеством проблем:

  • Отсутствующая поддержка на руке
  • По умолчанию изображение паузы не поддерживает руку
  • Отсутствует CPUSET (обновление ядра до 4.19 LTS решило его)
  • Становитесь в проблемах космоса несколько раз
  • Фланелевая не хватает многоартной поддержки в Kubespray ((до того, как мы перешли на Wireguard CNI навсегда))

Большинство из них отслеживаются в следующем выпуске/PRS:

Вопросы:

PRS:

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

Первоначальный анализ производительности

Основной контрольный список

  • EMMC монтируется без Atime
  • Использование Binary Armhf ( readelf -a $ (который kubelet | grep TAG_ABI_VFP_ARGS )
  • кошка /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

ИСПОЛЬЗОВАТЬ

debian@bbb-test:~$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 4  0      0   6088  19916 271064    0    0    25    20   17   32 18 12 69  0  0
 0  0      0   6120  19916 271064    0    0     0     0 1334 4098 13 20 67  0  0
 0  0      0   6120  19916 271064    0    0     0     0 1554 4046 13 19 68  0  0
 0  0      0   6120  19924 271056    0    0     0    16  929 2443 10  8 81  1  0
 0  0      0   6120  19924 271064    0    0     0     0 1611 4128 24 20 56  0  0
 0  0      0   6120  19924 271064    0    0     0     0  919 2443  6 11 83  0  0
 0  0      0   5996  19924 271064    0    0     0     0 1240 3312 29 28 42  0  0
 0  0      0   5996  19924 271064    0    0     0     0  958 2417 13  9 77  0  0
 3  0      0   5996  19924 271064    0    0     0     0 1915 5693 28 25 46  0  0
 0  0      0   5996  19924 271064    0    0     0     0 1089 3296 12 18 70  0  0
debian@bbb-test:~$ pidstat 30 1
Linux 4.19.9-ti-r5 (bbb-test)   02/25/2019      _armv7l_        (1 CPU)

04:59:26 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command

04:59:56 PM     0     26749    3.54    1.62    0.00    5.16     0  dockerd
04:59:56 PM     0     26754    0.44    0.37    0.00    0.81     0  docker-containe
04:59:56 PM     0     26784    0.00    0.07    0.00    0.07     0  kworker/u2:2-flush-179:0
04:59:56 PM     0     28814   10.08   10.79    0.00   20.88     0  kubelet
04:59:56 PM     0     29338    0.51    1.15    0.00    1.65     0  kube-proxy
04:59:56 PM   997     29734    1.42    0.37    0.00    1.79     0  consul
04:59:56 PM     0     30867    0.03    0.00    0.00    0.03     0  docker-containe
04:59:56 PM     0     30885    0.47    0.67    0.00    1.15     0  flanneld
04:59:56 PM  1000     31776    0.30    0.07    0.00    0.37     0  mosh-server

Около 30% процессора находится на Kubernetes без какой -либо значимой работы.

iostat -xz 1
sar -n DEV 1
sar -n TCP,ETCP 1

Не показывают значительное давление в сети. SpeedTest-CLI показывает скорости загрузки/загрузки 30 мит, которые более чем достаточно для нашего варианта использования.

Таким образом, есть высокое использование ЦП с низким диском, памятью и сетью.

Анализ производительности

Строка Kubelet показывает, что в замках тратится около 66%:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 65.66    1.671983        5006       334        60 futex
 11.77    0.299775         967       310           epoll_wait
  9.24    0.235263         364       647           nanosleep
  2.58    0.065766          31      2136           clock_gettime
  1.75    0.044623          38      1180        68 read
...
------ ----------- ----------- --------- --------- ----------------
100.00    2.546516                 10290       356 total

Хотя использование PPROF и профили трассировки показали более полезную информацию:

debian@bbb-test:~$ wget http://127.0.0.1:10248/debug/pprof/profile?seconds=120
debian@bbb-test:~$ wget http://127.0.0.1:10248/debug/pprof/trace?seconds=120

Оттуда мы заключили:

  • 25% времени тратится на домашнее хозяйство
  • Изменение по умолчанию 10 с
  • Увеличение периода обновления узлов не значительно повлияло на использование ЦП

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

GODEBUG=gctrace=1,schedtrace=1000
gc 80 @1195.750s 0%: 0.070+217+0.19 ms clock, 0.070+57/63/59+0.19 ms cpu, 24->24->12 MB, 25 MB goal, 1 P

SCHED 1196345ms: gomaxprocs=1 idleprocs=1 threads=18 spinningthreads=0 idlethreads=6 runqueue=0 [0]

В процессе Kubelet нет больших проблем с GC GC GC, таким образом, не проанализировал это дальше. o

debian@bbb-test:~$ sudo perf stat -e task-clock,cycles,instructions,branches,branch-misses,instructions,cache-misses,cache-references
^C
 Performance counter stats for 'system wide':

         16,203.12 msec task-clock                #    1.000 CPUs utilized
     4,332,572,389      cycles                    # 267393.223 GHz                    (71.42%)
       911,023,486      instructions              #    0.21  insn per cycle           (71.40%)
        98,098,648      branches                  # 6054350.923 M/sec                 (71.41%)
        30,116,184      branch-misses             #   30.70% of all branches          (71.44%)
       885,259,275      instructions              #    0.20  insn per cycle           (71.45%)
         6,967,361      cache-misses              #    1.836 % of all cache refs      (57.16%)
       379,417,471      cache-references          # 23416495.155 M/sec                (57.14%)

      16.202385758 seconds time elapsed

Мы наблюдаем 30% частота ошибок в филиале в процессе Кубеле. После дальнейшего анализа это общеобразовательное. Этот дешевый процессор Arm имеет ужасные алгоритмы прогнозирования филиалов.

Улучшения

Мы выполнили следующие улучшения:

  • порезал докер и заменил его плагином CRI. Конкретно мы использовали контейнер
  • Увеличение интервала домашнего хозяйства с 10 до 10 м
  • Выбросьте фланель для Wireguard CNI (в основном нативная маршрутизация)
Average:        0         9    0.00    0.14    0.00    0.24    0.14     -  ksoftirqd/0
Average:        0        10    0.00    0.17    0.00    0.35    0.17     -  rcu_preempt
Average:        0       530    0.00    0.03    0.00    0.00    0.03     -  jbd2/mmcblk1p1-
Average:        0       785    0.00    0.07    0.00    0.21    0.07     -  haveged
Average:        0       818    0.03    0.00    0.00    0.00    0.03     -  connmand
Average:        0       821    4.64    4.47    0.00    0.00    9.12     -  kubelet
Average:        0      1416    0.14    0.07    0.00    0.03    0.21     -  fail2ban-server
Average:        0      1760    0.42    0.69    0.00    0.35    1.11     -  kube-proxy
Average:        0      3436    1.70    0.90    0.00    0.00    2.60     -  containerd
Average:        0      4274    0.07    0.03    0.00    0.07    0.10     -  systemd-journal
Average:        0     17442    0.00    0.38    0.00    0.17    0.38     -  kworker/u2:2-events_unbound
Average:        0     19070    0.00    0.03    0.00    0.00    0.03     -  kworker/0:2H-kblockd
Average:        0     26772    0.00    0.24    0.00    0.28    0.24     -  kworker/0:1-wg-crypt-wg0
Average:        0     28212    0.00    0.31    0.00    0.28    0.31     -  kworker/0:3-events_power_efficient

А в устойчивом состоянии у нас есть заповедник использования ЦП ~ 15% для пособий по мониторингу. Тем не менее, довольно немного, хотя и пригодно для жизни. Возможно, у Cri-O будет более низкий накладной, хотя у Containerd тоже довольно тонкие. Мы исследуем, как мы можем оптимизировать Kubelet для еще более низкого потребления ресурсов, отключив ненужные функции.

Резюме

Подводя итог, запускают ли kubernetes на Edge Devices Sane Choice? Может быть.

Для нас пока все хорошо, все работает с некоторыми значительными, хотя и пригодными для жизни.

Например, попытка установить только прометею node_exporter стреляет в ваш процессор каждый царапев и замедляет все, чтобы ползал для этих нескольких миллисекундов 100 -х годов.

Это оборудование довольно недостаточно, и с плохим прогнозом филиала делает любое программное обеспечение, работающее на нем слабее, чем на сопоставимых архитектурах ARMV8 или x86_64.

В будущем мы постараемся оптимизировать вещи еще дальше, надеясь, что сократит накладные расходы на ЦП Кубеле до более разумного процента. Мы попробовали K3S Rancher без большой разницы ((на самом деле худшая производительность, так как мы не могли изменить интервал домашнего хозяйства))

Есть также Kubeedge Проект, который выглядит многообещающе для Kubernetes на IoT.

использованная литература

Оригинал: «https://dev.to/nmiculinic/kubernetes-on-arm-a-case-study-5ha4»