+1.13
1 читатель, 109 топиков

Выделенные серверы: новые линейки уже в пути!

С 2000 года команды OVH самостоятельно проектируют и собирают все серверы группы OVH. Фактически, в настоящее время в эксплуатации находится 400 тыс. Серверов, а в 2018 году был собран миллионный сервер! Наши выделенные серверы являются основой всех продуктов OVHcloud. Вот почему мы хотели расширить различные линейки, чтобы улучшить общее впечатление наших клиентов.

Наши новые линейки выделенных серверов вот-вот будут запущены!

Новая линейка выделенных серверов OVH направлена ​​на то, чтобы предложить широкий выбор серверов, которые одновременно являются мощными и простыми в использовании.



В течение последних нескольких месяцев все инженерные группы, задействованные в Bare Metal Product Unit, работали над основами новых выделенных серверов и будущими предложениями. От ценностного предложения нашего портфеля до наших функциональных требований (т.е. технических строительных блоков); от нашей методологии, соблюдения нормативных требований и производственных процессов до стандартов нашего центра обработки данных и отраслевых основ — мы обратились ко всей цепочке создания стоимости! 

Это был важный и очень интересный путь, в ходе которого мы извлекли выгоду из отзывов наших клиентов , интегрировали ограничения масштабируемости и развили операционное превосходство (и наши амбиции!). И поскольку инновации — это наша движущая сила, мы хотели извлечь уроки из наших предыдущих проблем, но при этом, как всегда, использовали новаторский подход! 

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

«Но что такое« голый »сервер?»

«Голый» сервер — это просто физический сервер с одним арендатором. Это то, что отличает его от других форм вычислений, таких как виртуализация, и позволяет клиентам получить доступ к специфическим для оборудования функциям, которые иначе не могли бы быть обеспечены постоянными гарантированными ресурсами или управлялись с помощью уровня виртуализации (гибкость оборудования, данные- интенсивные проекты, вычислительная мощность и т. д.). Каждый сервер может выполнять любой объем работы для клиента или может иметь несколько одновременных пользователей, но его ресурсы полностью посвящены тому, кто его арендует, без какой-либо блокировки!

Краткий обзор производственной цепочки серверов без ОС!



Глобальный подход

Что значит развернуть новый ассортимент? Что ж, для такой компании, как OVH, где «голое железо» составляет огромную площадь в 400 тыс. Серверов в 28 центрах обработки данных — это требует большой организации…

  • Отзывы клиентов и постоянное совершенствование
  • Производительность и инновации
  • Устойчивость и масштабируемость
  • Линия продуктов и варианты использования
  • Качество и бережливое производство
  • Лучшее конкурентное соотношение для наших клиентов!

Эти шесть столпов были нашими ключевыми драйверами при запуске этой феноменальной программы по запуску нашей новой линейки выделенных серверов!

Давайте начнем наше новое путешествие по OVHcloud!

Первый новый модельный ряд из нашего семейства выделенных серверов уже здесь! Его имя — Advance.

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

Многие, многие новые технические функции (материнские платы, процессоры, память, диски, сети, опции и т. Д.) И преимущества встроены в новую линейку, например:

  • Масштабируемая инфраструктура 
  • Более высокая неограниченная пропускная способность сети 
  • Бесплатная частная сеть, входящая в комплект всех серверов: vRack 
  • Сетевые интерфейсы 10 Гбит / с
  • Высокопроизводительные накопители NVMe (корпоративный класс) 
  • Новые возможности индивидуальной настройки привода 
  • Свободное место для хранения резервных копий удаленно от сервера 
  • 256 дополнительных бесплатных IP-адресов 
  • Лучшая защита от DDoS-атак 

Но дело не только в технических улучшениях…

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



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

Кроме того, мы много работали над повышением уровня качества и общей зрелости, перейдя к ключевому стандарту: ISO 27001. Потому что соответствие и качество так же важны, как и производительность! Но об этом мы поговорим в другом посте?…

А теперь следите за обновлениями, ведь это только начало! OVHcloud ускоряется для ВАС.

Выделенные серверы сертифицированы по ISO 27001

14 марта OVH получила сертификат ISO / IEC 27001: 2013 для системы управления информационной безопасностью выделенных серверов.



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



Что такое стандарт и сертификация ISO 27001?

ISO / IEC 27001 — это международный стандарт, который описывает «требования к созданию, внедрению, поддержке и постоянному совершенствованию системы менеджмента информационной безопасности» (СМИБ). Он описывает организационный метод, который обеспечивает конфиденциальность, целостность, доступность и прослеживаемость информационной системы.

Ежедневная безопасность

С самого начала OVH безопасность была одной из основных целей групп, которые проектируют, эксплуатируют и развивают сервисы. СМИБ направлена ​​на обеспечение систематического, сопоставимого и очевидного функционирования средств, реализованных для обеспечения безопасности.

СМИБ — это подход к созданию, поддержанию, мониторингу и обеспечению постоянного улучшения инструментов и процессов для:

  • Выявление и консолидация обязательств OVH с точки зрения информационной безопасности.
  • Установите соответствующие, понятные и последовательные цели информационной безопасности.
  • Внедрение подхода, основанного на оценке рисков, для определения и приоритизации улучшений безопасности.
  • Установите, промышленно внедряйте и используйте меры безопасности.
  • Общайтесь и координируйте свои действия со всеми вовлеченными внутренними и внешними заинтересованными сторонами.

На повседневной основе СМИБ состоит из управления всеми рискованными действиями для службы, такими как права доступа, конфигурации системы и оборудования, обновления программного обеспечения, обновления инфраструктуры, удаление данных, разделение между средами, мониторинг и инциденты. Обеспечение абсолютной безопасности — нереальная цель, но СМИБ помогает быстрее и надежнее выявлять уязвимости, ошибки и сбои. СМИБ обеспечивает быстрое выполнение корректирующих действий, и эти действия отслеживаются с течением времени.

Командные усилия

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

Сертификационный аудит

Сертификационные аудиты проводятся аккредитованными компаниями, в данном случае LNE, аккредитованными COFRAC. Сам аудит проходит в строгом формате и основан на формальных требованиях. Аудит — это вызов для команд, но также и для аудитора. На основе посещений офисов и центров обработки данных, групповых интервью, углубленного анализа документации и наблюдения за системами в течение нескольких недель аудитор должен сформулировать свое мнение об актуальности реализованных мероприятий, их эффективности и, конечно, их соответствие всем требованиям стандарта ISO 27001. Аудитор также определяет возможности улучшения, которые необходимо рассмотреть в конце аудита.

Какой объем?

Объем системы управления информационной безопасностью охватывает предоставление, подключение, оперативную поддержку и вывод из эксплуатации выделенных серверов, выделенных клиентам, ресурсы, предоставляемые клиентам для настройки, использования и мониторинга выделенной инфраструктуры и управления услугами командами OVH. Таким образом, СМИБ сконцентрирована на услугах, предоставляемых заказчику.

Безопасность как код

СУИБ охватывает все физические серверы, управляемые OVH, то есть несколько сотен тысяч серверов в центрах обработки данных группы. Понимание и управление безопасностью эффективным и устойчивым способом в таком широком диапазоне означает согласование каждого решения с принципами стандартизации и автоматизации промышленной модели OVH. В цепочке создания стоимости OVH все повторяющиеся задачи, выполняемые персоналом, должны быть постепенно сокращены. В результате СМИБ и безопасность улучшаются за счет автоматизации повседневной деятельности и разработки инструментов для безопасного управления сервисом. Вмешательство человека должно быть ограничено случаями, требующими глубокого анализа или сложной координации. Эта модель позволяет экспоненциально увеличивать масштаб системы управления при ограничении ресурсов, необходимых для ее работы.

Модульная система управления информационной безопасностью (СУИБ)

В некоторой степени все продукты OVH используют информационные системы для поддержки услуги, и сами они размещаются на выделенных серверах, как и все другие продукты OVH. Определение графика зависимостей и внутренних обязанностей — это своего рода мизансцен. Однако это было предварительным условием для определения четкой и понятной организации безопасности, которая позволила СМИБ эффективно функционировать. Был применен модульный подход, позволяющий сегментировать и структурировать обязанности каждой задействованной команды. Эти отношения регулируются набором внутренних соглашений об обслуживании, определенных и отслеживаемых в СМИБ.

Например, центры обработки данных имеют отдельную СМИБ для обеспечения физической безопасности хостинговых сайтов и безопасности операций центра обработки данных. Эта СМИБ имеет независимую сертификацию и обеспечивает прочную основу для соблюдения требований к услугам.

Сертификация ISMS выделенного сервера основана на сертификации центра обработки данных и распространяется на серверы, размещенные в этих сертифицированных центрах обработки данных. На сегодняшний день это центры обработки данных в Рубе (RBX 2,3,5,6,7), все центры обработки данных в Страсбурге, Богарнуа, Сингапуре и Сиднее. Парижский центр обработки данных (P19), на котором размещена часть информационной системы для поддержки услуги, также затрагивается, хотя в нем нет выделенных серверов, выделенных клиентам. Хотя все серверы компании охвачены СУИБ, сертификация касается только этих центров обработки данных.

Что дальше?

ISO 27001 — это общий стандарт, который решает проблемы большинства наших клиентов и устанавливает структуру и организацию для обеспечения безопасности услуг. Однако он не учитывает соблюдение требований, связанных с конкретным сектором бизнеса. Стандарт ISO 27001 предусматривает возможность добавления дополнительных требований, и для этой цели также разработана СМИБ для выделенных серверов. Таким образом, СМИБ будет постепенно интегрировать новые конкретные меры, чтобы покрыть, например, потребности в размещении персональных данных о здоровье, требования банковского сектора или нормативные особенности государственного сектора в разных странах, где OVH предоставляет услуги.

Параллельно группы работают над расширением периметра сертификации, чтобы включить в него все центры обработки данных группы, в частности центры в Эрите (Великобритания), Лимбурге (Германия), Озарове (Польша) и Гравелайнс (Франция). Цель состоит в том, чтобы предоставить всем клиентам OVH единый уровень гарантии безопасности независимо от выбранного региона центра обработки данных.

Наконец, группы продолжат работу с другими группами продуктов, чтобы завершить каталог сертифицированных продуктов и постепенно распространить его на все предложения OVH «Инфраструктура как услуга».

Понимание анатомии графических процессоров с помощью Pokémon

Поприветствуйте этого прекрасного новорожденного в GPGPU Nvidia Family Ampere

ОБНОВЛЕНИЕ БЛОГА ОТ 14 МАЯ 2020





В предыдущем выпуске …

В нашем предыдущем сообщении блога о глубоком обучении мы объяснили, что эта технология предназначена для массивных параллельных вычислений матриц и что эти вычисления являются упрощенными операциями: + и x.



Факт 1. Графические процессоры хороши для (барабанной дроби)…

Как только вы поймете, что глубокое обучение — это просто массовое параллельное умножение и сложение матриц, происходит волшебство. Графические процессоры общего назначения (GPGPU) (то есть графические процессоры или варианты графических процессоров, предназначенные для чего-то другого, кроме графической обработки) идеально подходят для…



Прекрасно, не правда ли? Но почему? Позвольте мне рассказать вам небольшую историю

Факт 2: было время, когда графические процессоры были просто графическими процессорами.

Да, Вы прочли это правильно…

Первые графические процессоры в 90-х годах были разработаны очень линейно. Инженер взял инженерный процесс, используемый для графического рендеринга, и реализовал его на оборудовании.

Для простоты вот как выглядит процесс графического рендеринга:



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

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

Короче говоря, видеокарты изначально были предназначены для графической обработки. Какой сюрприз!

Факт 3: процессоры — это спортивные автомобили, а графические процессоры — массивные грузовики

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

Это полная противоположность логике ЦП, где операции должны выполняться последовательно. В результате GPGPU нуждались в массивно-параллельной архитектуре общего назначения, чтобы иметь возможность обрабатывать все точки (вершины), строить все сетки (тесселяцию), создавать освещение, выполнять преобразование объекта из абсолютной ссылки, применять текстуру и выполнить штриховку (мне, наверное, еще не хватает некоторых частей!). Однако цель этого сообщения не состоит в том, чтобы подробно рассматривать обработку и рендеринг изображений, поскольку мы сделаем это в другом сообщении в будущем.

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

Вот красивое видео от Mythbusters, в котором объясняются две концепции CPU и GPU:


Факт 4: 2006 — NVIDIA убила тейлоризм обработки изображений



Предыдущий метод обработки изображений был реализован с использованием специализированного персонала (оборудования) на каждом этапе производственной линии на фабрике изображений.

Все изменилось в 2006 году, когда NVIDIA решила представить универсальные графические процессоры, использующие арифметические логические единицы (ALU), также известные как ядра CUDA, которые могли выполнять многоцелевые вычисления (что-то вроде вычислений на GPU Жан-Клода Ван Дамма. единицы измерения!).



Даже сегодня современные архитектуры графических процессоров (такие как Fermi, Kepler или Volta) состоят из необщих ядер, называемых модулями специальных функций (SFU), для выполнения высокопроизводительных математических графических операций, таких как sin, косинус, обратное и квадратное root, а также блоки наложения текстуры (TMU) для операций с матрицами большой размерности, участвующих в наложении текстуры изображения.

Факт 5: GPGPU можно просто объяснить с помощью Pokémon!

Поначалу может показаться, что архитектура графического процессора трудна для понимания, но поверьте мне… это не так!

Вот мой подарок вам: Pokédex, который поможет вам понять графические процессоры простым языком.

Micro-Architecture Family

Вот как вы его используете… В основном у вас есть четыре семейства карт:

Эта семья уже многим из вас будет известна. Речь, конечно же, идет о Ферми, Максвелле, Кеплере, Вольте, Ампера и т. Д.



Архитектура семьи

Это центр, где происходит волшебство: оркестровка, кеш, планирование рабочих нагрузок… Это мозг графического процессора.



Многоядерная Units (ака CUDA Cores) Семейный

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



Программирование Модель семьи

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



Как играть?

  • Начните с выбора карты из Micro-Architecture семьи
  • Посмотрите на компоненты, и выберите соответствующую карту из архитектуры семьи
  • Посмотрите на компоненты в семействе Micro-Architecture и выберите их из семейства Multi-Core Units , затем поместите их под карточкой « Архитектура».
  • Теперь, если вы хотите знать , как программировать GPU, место Programming Model — Multi-Core Units специальную карту поверх многоядерных блоков  карт
  • Наконец, поверх специальной карты Programming Model — Multi-Core Units поместите все карты Programming Model  рядом с SM.
  • Тогда у вас должно получиться что-то вроде этого:



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

Ферми


Кеплер


Максвелл


Паскаль


Вольта


Тьюринг


Немного поигравшись с различными микроархитектурами, архитектурами и многоядерными модулями, вы должны увидеть, что графические процессоры так же просты, как и Pokémon!

Как отслеживать свой кластер Kubernetes с помощью OVH Observability

Наши коллеги из команды K8S на прошлой неделе запустили решение OVH Managed Kubernetes, в котором они управляют главными компонентами Kubernetes и создают ваши узлы поверх нашего решения Public Cloud. Я не буду описывать здесь детали того, как это работает, но в блогах уже есть много сообщений об этом ( здесь и здесь, чтобы вы начали).

В команде Prescience мы используем Kubernetes уже больше года. Наш кластер включает 40 узлов, работающих поверх PCI. Мы постоянно запускаем около 800 модулей и в результате генерируем множество показателей.

Сегодня мы рассмотрим, как мы обрабатываем эти метрики для мониторинга нашего кластера Kubernetes, и (что не менее важно!) Как это сделать с вашим собственным кластером.

Показатели OVH

Как и в любой другой инфраструктуре, вам необходимо отслеживать свой кластер Kubernetes. Вам необходимо точно знать, как ведут себя ваши узлы, кластер и приложения после их развертывания, чтобы предоставлять надежные услуги вашим клиентам. Чтобы сделать это с нашим собственным кластером, мы используем OVH Observability.

OVH Observability не зависит от серверной части, поэтому мы можем передавать метрики в одном формате и запрашивать в другом. Он может обрабатывать:

  • Graphite
  • InfluxDB
  • Metrics2.0
  • OpentTSDB
  • Prometheus
  • Warp10

Он также включает управляемую Grafana для отображения показателей и создания панелей мониторинга.

Узлы мониторинга

Первое, что нужно контролировать, — это состояние узлов. Все остальное начинается с этого.

Чтобы контролировать ваши узлы, мы будем использовать Noderig и Beamium, как описано здесь. Мы также будем использовать Kubernetes DaemonSets для запуска процесса на всех наших узлах.



Итак, приступим к созданию пространства имен…

kubectl create namespace metrics


Затем создайте секрет с метриками токена записи, которые вы можете найти в панели управления OVH.

kubectl create secret generic w10-credentials --from-literal=METRICS_TOKEN=your-token -n metrics


Скопируйте metrics.ymlв файл и примените конфигурацию с помощью kubectl

metrics.yml
# This will configure Beamium to scrap noderig
# And push metrics to warp 10
# We also add the HOSTNAME to the labels of the metrics pushed
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: beamium-config
  namespace: metrics
data:
  config.yaml: |
    scrapers:
      nodering:
        url: http://0.0.0.0:9100/metrics
        period: 30000
        format: sensision
        labels:
          app: nodering

    sinks:
      warp:
        url: https://warp10.gra1.metrics.ovh.net/api/v0/update
        token: $METRICS_TOKEN

    labels:
      host: $HOSTNAME

    parameters:
      log-file: /dev/stdout
---
# This is a custom collector that report the uptime of the node
apiVersion: v1
kind: ConfigMap
metadata:
  name: noderig-collector
  namespace: metrics
data:
  uptime.sh: |
    #!/bin/sh
    echo 'os.uptime' `date +%s%N | cut -b1-10` `awk '{print $1}' /proc/uptime`
---
kind: DaemonSet
apiVersion: apps/v1
metadata:
  name: metrics-daemon
  namespace: metrics
spec:
  selector:
    matchLabels:
      name: metrics-daemon
  template:
    metadata:
      labels:
        name: metrics-daemon
    spec:
      terminationGracePeriodSeconds: 10
      hostNetwork: true
      volumes:
      - name: config
        configMap:
          name: beamium-config
      - name: noderig-collector
        configMap:
          name: noderig-collector
          defaultMode: 0777
      - name: beamium-persistence
        emptyDir:{}
      containers:
      - image: ovhcom/beamium:latest
        imagePullPolicy: Always
        name: beamium
        env:
        - name: HOSTNAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: TEMPLATE_CONFIG
          value: /config/config.yaml
        envFrom:
        - secretRef:
            name: w10-credentials
            optional: false
        resources:
          limits:
            cpu: "0.05"
            memory: 128Mi
          requests:
            cpu: "0.01"
            memory: 128Mi
        workingDir: /beamium
        volumeMounts:
        - mountPath: /config
          name: config
        - mountPath: /beamium
          name: beamium-persistence
      - image: ovhcom/noderig:latest
        imagePullPolicy: Always
        name: noderig
        args: ["-c", "/collectors", "--net", "3"]
        volumeMounts:
        - mountPath: /collectors/60/uptime.sh
          name: noderig-collector
          subPath: uptime.sh
        resources:
          limits:
            cpu: "0.05"
            memory: 128Mi
          requests:
            cpu: "0.01"
            memory: 128Mi

Не стесняйтесь менять уровни коллектора, если вам нужна дополнительная информация.

Затем примените конфигурацию с помощью kubectl…

$ kubectl apply -f metrics.yml
# Then, just wait a minutes for the pods to start
$ kubectl get all -n metrics
NAME                       READY   STATUS    RESTARTS   AGE
pod/metrics-daemon-2j6jh   2/2     Running   0          5m15s
pod/metrics-daemon-t6frh   2/2     Running   0          5m14s

NAME                          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE AGE
daemonset.apps/metrics-daemon 40        40        40      40           40          122d


Вы можете импортировать нашу панель управления в свою Grafana отсюда и сразу же просматривать некоторые показатели о ваших узлах.



OVH Метрики

Поскольку OVH Kube — это управляемая служба, вам не нужно контролировать apiserver, etcd или панель управления. Об этом позаботится команда OVH Kubernetes. Поэтому мы сосредоточимся на показателях cAdvisor и показателях состояния Kube.

Самым зрелым решением для динамического считывания метрик внутри Kube (на данный момент) является Prometheus.


В следующем выпуске Beamium мы сможем воспроизвести функции скребка Prometheus.


Чтобы установить сервер Prometheus, вам необходимо установить Helm в кластере…

kubectl -n kube-system create serviceaccount tiller
kubectl create clusterrolebinding tiller \
    --clusterrole cluster-admin \
    --serviceaccount=kube-system:tiller
helm init --service-account tiller


Затем вам нужно создать следующие два файла: prometheus.yml и values.yml.

# Based on https://github.com/prometheus/prometheus/blob/release-2.2/documentation/examples/prometheus-kubernetes.yml
serverFiles:
  prometheus.yml:
    remote_write:
    - url: "https://prometheus.gra1.metrics.ovh.net/remote_write"
      remote_timeout: 120s
      bearer_token: $TOKEN
      write_relabel_configs:
      # Filter metrics to keep
      - action: keep
        source_labels: [__name__]
        regex: "eagle.*|\
            kube_node_info.*|\
            kube_node_spec_taint.*|\
            container_start_time_seconds|\
            container_last_seen|\
            container_cpu_usage_seconds_total|\
            container_fs_io_time_seconds_total|\
            container_fs_write_seconds_total|\
            container_fs_usage_bytes|\
            container_fs_limit_bytes|\
            container_memory_working_set_bytes|\
            container_memory_rss|\
            container_memory_usage_bytes|\
            container_network_receive_bytes_total|\
            container_network_transmit_bytes_total|\
            machine_memory_bytes|\
            machine_cpu_cores"

    scrape_configs:
    # Scrape config for Kubelet cAdvisor.
    - job_name: 'kubernetes-cadvisor'
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      kubernetes_sd_configs:
      - role: node
      
      relabel_configs:
      - target_label: __address__
        replacement: kubernetes.default.svc:443
      - source_labels: [__meta_kubernetes_node_name]
        regex: (.+)
        target_label: __metrics_path__
        replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
        
      metric_relabel_configs:
      # Only keep systemd important services like docker|containerd|kubelet and kubepods,
      # We also want machine_cpu_cores that don't have id, so we need to add the name of the metric in order to be matched
      # The string will concat id with name and the separator is a ;
      # `/;container_cpu_usage_seconds_total` OK
      # `/system.slice;container_cpu_usage_seconds_total` OK
      # `/system.slice/minion.service;container_cpu_usage_seconds_total` NOK, Useless
      # `/kubepods/besteffort/e2514ad43202;container_cpu_usage_seconds_total` Best Effort POD OK
      # `/kubepods/burstable/e2514ad43202;container_cpu_usage_seconds_total` Burstable POD OK
      # `/kubepods/e2514ad43202;container_cpu_usage_seconds_total` Guaranteed POD OK
      # `/docker/pod104329ff;container_cpu_usage_seconds_total` OK, Container that run on docker but not managed by kube
      # `;machine_cpu_cores` OK, there is no id on these metrics, but we want to keep them also
      - source_labels: [id,__name__]
        regex: "^((/(system.slice(/(docker|containerd|kubelet).service)?|(kubepods|docker).*)?);.*|;(machine_cpu_cores|machine_memory_bytes))$"
        action: keep
      # Remove Useless parents keys like `/kubepods/burstable` or `/docker`
      - source_labels: [id]
        regex: "(/kubepods/burstable|/kubepods/besteffort|/kubepods|/docker)"
        action: drop
        # cAdvisor give metrics per container and sometimes it sum up per pod
        # As we already have the child, we will sum up ourselves, so we drop metrics for the POD and keep containers metrics
        # Metrics for the POD don't have container_name, so we drop if we have just the pod_name
      - source_labels: [container_name,pod_name]
        regex: ";(.+)"
        action: drop
    
    # Scrape config for service endpoints.
    - job_name: 'kubernetes-service-endpoints'
      kubernetes_sd_configs:
      - role: endpoints
      
      relabel_configs:
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
        action: replace
        target_label: __scheme__
        regex: (https?)
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
        action: replace
        target_label: __address__
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
      - action: labelmap
        regex: __meta_kubernetes_service_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace
      - source_labels: [__meta_kubernetes_service_name]
        action: replace
        target_label: kubernetes_name

    # Example scrape config for pods
    #
    # The relabeling allows the actual pod scrape endpoint to be configured via the
    # following annotations:
    #
    # * `prometheus.io/scrape`: Only scrape pods that have a value of `true`
    # * `prometheus.io/path`: If the metrics path is not `/metrics` override this.
    # * `prometheus.io/port`: Scrape the pod on the indicated port instead of the
    # pod's declared ports (default is a port-free target if none are declared).
    - job_name: 'kubernetes-pods'
      kubernetes_sd_configs:
      - role: pod

      relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        target_label: __address__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod_name
      - source_labels: [__meta_kubernetes_pod_node_name]
        action: replace
        target_label: host
      - action: labeldrop
        regex: (pod_template_generation|job|release|controller_revision_hash|workload_user_cattle_io_workloadselector|pod_template_hash)


values.yml
alertmanager:
  enabled: false
pushgateway:
  enabled: false
nodeExporter:
  enabled: false
server:
  ingress:
    enabled: true
    annotations:
      kubernetes.io/ingress.class: traefik
      ingress.kubernetes.io/auth-type: basic
      ingress.kubernetes.io/auth-secret: basic-auth
    hosts:
    - prometheus.domain.com
  image:
    tag: v2.7.1
  persistentVolume:
    enabled: false


Не забудьте заменить свой токен!

Скребок Прометей довольно мощный. Вы можете изменить метку своего временного ряда, оставить несколько, которые соответствуют вашему регулярному выражению, и т. Д. Эта конфигурация удаляет множество бесполезных метрик, поэтому не стесняйтесь настраивать его, если вы хотите увидеть больше метрик cAdvisor (например).

Установите его с помощью Helm…

helm install stable/prometheus \
    --namespace=metrics \
    --name=metrics \
    --values=values/values.yaml \
    --values=values/prometheus.yaml


Добавить добавить секрет базовой аутентификации…

$ htpasswd -c auth foo
New password: <bar>
New password:
Re-type new password:
Adding password for user foo
$ kubectl create secret generic basic-auth --from-file=auth -n metrics
secret "basic-auth" created


Вы можете получить доступ к интерфейсу сервера Prometheus через prometheus.domain.com.



Вы увидите все показатели для своего кластера, хотя только тот, который вы отфильтровали, будет перенесен в метрики OVH.

Интерфейсы Prometheus — хороший способ изучить ваши метрики, поскольку довольно просто отображать и контролировать вашу инфраструктуру. Вы можете найти нашу панель управления здесь.



Метрики ресурсов

Как сказал @ Martin Schneppenheim в этом посте, для правильного управления кластером Kubernetes вам также необходимо отслеживать ресурсы пода.

Мы установим Kube Eagle, который будет извлекать и предоставлять некоторые метрики о запросах и ограничениях ЦП и ОЗУ, чтобы они могли быть получены только что установленным сервером Prometheus.



Создайте файл с именем eagle.yml.

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  labels:
    app: kube-eagle
  name: kube-eagle
  namespace: kube-eagle
rules:
- apiGroups:
  - ""
  resources:
  - nodes
  - pods
  verbs:
  - get
  - list
- apiGroups:
  - metrics.k8s.io
  resources:
  - pods
  - nodes
  verbs:
  - get
  - list
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  labels:
    app: kube-eagle
  name: kube-eagle
  namespace: kube-eagle
subjects:
- kind: ServiceAccount
  name: kube-eagle
  namespace: kube-eagle
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kube-eagle
---
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: kube-eagle
  labels:
    app: kube-eagle
  name: kube-eagle
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: kube-eagle
  name: kube-eagle
  labels:
    app: kube-eagle
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kube-eagle
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8080"
        prometheus.io/path: "/metrics"
      labels:
        app: kube-eagle
    spec:
      serviceAccountName: kube-eagle
      containers:
      - name: kube-eagle
        image: "quay.io/google-cloud-tools/kube-eagle:1.0.0"
        imagePullPolicy: IfNotPresent
        env:
        - name: PORT
          value: "8080"
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        livenessProbe:
          httpGet:
            path: /health
            port: http
        readinessProbe:
          httpGet:
            path: /health
            port: http


$ kubectl create namespace kube-eagle
$ kubectl apply -f eagle.yml


Затем добавьте импорт этой панели управления Grafana (это та же панель, что и Kube Eagle, но перенесена на Warp10).



Теперь у вас есть простой способ контролировать ресурсы вашего модуля в кластере!

Пользовательские показатели

Как Прометей узнает, что ему нужно соскрести куба-орла? Если вы посмотрите на метаданные eagle.yml, вы увидите, что:

annotations:
  prometheus.io/scrape: "true"
  prometheus.io/port: "8080" # The port where to find the metrics
  prometheus.io/path: "/metrics" # The path where to find the metrics


Эти аннотации запустят процесс автоматического обнаружения Prometheus (описанный в prometheus.ymlстроке 114).

Это означает, что вы можете легко добавить эти аннотации к модулям или службам, которые содержат экспортер Prometheus, а затем пересылать эти метрики в OVH Observability. Вы можете найти неполный список экспортеров Прометея здесь.



Объемный анализ

Как вы видели на странице prometheus.yml, мы попытались отфильтровать множество бесполезных показателей. Например, cAdvisor в новом кластере, всего с тремя настоящими производственными модулями, а также со всей системой kube и пространством имен Prometheus, имеет около 2600 метрик на узел. Используя интеллектуальный подход к очистке, вы можете сократить это количество до 126 серий.

Вот таблица, показывающая приблизительное количество метрик, которые вы создадите, в зависимости от количества узлов (N) и количества производственных модулей (P), которые у вас есть:



Например, если вы запустите три узла с 60 подами, вы сгенерируете 264 * 3 + 32 * 60 ~ = 2700 метрик.

NB: модуль имеет уникальное имя, поэтому при повторном развертывании развертывания вы будете каждый раз создавать 32 новых метрики.

(1) Метрики Noderig: os.mem / os.cpu / os.disk.fs / os.load1 / os.net.dropped (in/out) / os.net.errs (in/out) / os.net.packets (in/out) / os.net.bytes (in/out)/ os.uptime

(2) метрики узлов cAdvisor: machine_memory_bytes / machine_cpu_cores

(3) Метрики узлов состояния Kube: kube_node_info

(4) Показатели узлов Kube Eagle: eagle_node_resource_allocatable_cpu_cores / eagle_node_resource_allocatable_memory_bytes / eagle_node_resource_limits_cpu_cores / eagle_node_resource_limits_memory_bytes / eagle_node_resource_requests_cpu_cores / eagle_node_resource_requests_memory_bytes / eagle_node_resource_usage_cpu_cores / eagle_node_resource_usage_memory_bytes

(5) С помощью наших фильтров мы будем отслеживать около пяти system.slices.

(6) Показатели указываются для каждого контейнера. Pod — это набор контейнеров (минимум два): ваш контейнер + контейнер паузы для сети. Таким образом, мы можем рассматривать (2 * 10 + 6) для количества метрик в пакете. 10 показателей из cAdvisor и шесть для сети (см. Ниже) и для system.slice у нас будет 10 + 6, потому что он рассматривается как один контейнер.

(7) cAdvisor предоставит следующие показатели для каждого контейнера :container_start_time_seconds / container_last_seen / container_cpu_usage_seconds_total / container_fs_io_time_seconds_total / container_fs_write_seconds_total / container_fs_usage_bytes / container_fs_limit_bytes / container_memory_working_set_bytes / container_memory_rss / container_memory_usage_bytes

(8) cAdvisor предоставит следующие показатели для каждого интерфейса: container_network_receive_bytes_total * per interface / container_network_transmit_bytes_total * per interface

(9) kube-dns / beamium-noderig-metrics / kube-proxy / canal / metrics-server

(10) Показатели модулей Kube Eagle: eagle_pod_container_resource_limits_cpu_cores / eagle_pod_container_resource_limits_memory_bytes / eagle_pod_container_resource_requests_cpu_cores / eagle_pod_container_resource_requests_memory_bytes / eagle_pod_container_resource_usage_cpu_cores / eagle_pod_container_resource_usage_memory_bytes

Вывод

Как видите, отслеживать кластер Kubernetes с помощью OVH Observability очень просто. Вам не нужно беспокоиться о том, как и где хранить свои метрики, и вы можете сосредоточиться на использовании кластера Kubernetes для эффективной обработки бизнес-нагрузок, как это делаем мы в группе обслуживания машинного обучения.

Следующим шагом будет добавление системы предупреждений, чтобы уведомить вас, когда ваши узлы не работают (например). Для этого вы можете использовать бесплатный инструмент OVH Alert Monitoring.

Рекомендации по мониторингу наблюдаемости OVH

В команде OVH Observability (ранее Metrics) мы собираем, обрабатываем и анализируем большую часть данных мониторинга OVH. Он представляет около 500 миллионов уникальных показателей, перемещая точки данных с постоянной скоростью 5 миллионов в секунду.

Эти данные можно классифицировать двумя способами: мониторинг хоста или приложения. Мониторинг хоста в основном основан на аппаратных счетчиках (ЦП, память, сеть, диск…), тогда как мониторинг приложений основан на сервисе и его масштабируемости (запросы, обработка, бизнес-логика…).

Мы предоставляем эту услугу для внутренних команд, которые пользуются тем же опытом, что и наши клиенты. По сути, наша служба Observability — это SaaS с уровнем совместимости (поддерживающим InfluxDB, OpenTSDB, Warp10, Prometheus и Graphite), который позволяет ему интегрироваться с большинством существующих решений. Таким образом, команде, которая привыкла к определенному инструменту или уже развернула решение для мониторинга, не нужно будет тратить много времени или усилий при переходе на полностью управляемую и масштабируемую службу: они просто выбирают токен, используют правильный конечная точка, и все готово. Кроме того, наш уровень совместимости предлагает выбор: вы можете отправить свои данные с помощью OpenTSDB, а затем запросить их в PromQL или WarpScript. Подобное комбинирование протоколов приводит к уникальной совместимости с открытым исходным кодом, которая обеспечивает большую ценность.

Scollector, Snap, Telegraf, Graphite, Collectd…

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

В OVH мы используем наборы показателей, вырезанные лазером. У каждого хоста есть определенный шаблон (веб-сервер, база данных, автоматизация…), который экспортирует заданное количество показателей, которые можно использовать для диагностики работоспособности и мониторинга производительности приложений.

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

Beamium & Noderig — Идеальная посадка

Наши требования были довольно простыми:
Масштабируемость : мониторинг одного узла так же, как мы наблюдаем за тысячами
Laser-Cut : собирать только релевантные метрики
Надежность : мы хотим, чтобы метрики были доступны даже в наихудших условиях
Просто : Несколько компонентов plug-and-play вместо сложных
Эффективность : мы верим в беспроблемный сбор показателей

Первым решением был Beamium

Beamium обрабатывает два аспекта процесса мониторинга: данные приложения слом и показатели пересылки.

Данные приложения собираются в хорошо известном и широко используемом формате Prometheus. Мы выбрали Prometheus, поскольку в то время сообщество быстро росло, и для него было доступно множество инструментальных библиотек. В Beamium есть две ключевые концепции: источники и приемники.

Источники, из которых Beamium будет извлекать данные, — это просто конечные точки HTTP Prometheus. Это означает, что это так же просто, как предоставить конечную точку HTTP и, в конечном итоге, добавить несколько параметров. Эти данные будут направляться в приемники, что позволяет нам фильтровать их во время процесса маршрутизации между источником и приемником. Приемники — это конечные точки Warp 10 ®, куда мы можем отправлять данные.

После очистки метрики сначала сохраняются на диске, а затем направляются в приемник. Механизм переключения диска при отказе (DFO) позволяет выполнять восстановление после сбоя в сети или удаленно. Таким образом, локально мы сохраняем логику вытягивания Prometheus, но децентрализованно, и мы обращаем ее вспять, чтобы протолкнуть для подачи на платформу, которая имеет много преимуществ:

  • поддержка транзакционной логики на платформе метрик
  • восстановление после разделения сети или недоступности платформы
  • двойная запись с согласованностью данных (поскольку в противном случае нет гарантии, что два экземпляра Prometheus будут очищать одни и те же данные с одной и той же меткой времени)

У нас много разных клиентов, некоторые из которых используют хранилище временных рядов для продукта Observability для управления потреблением продукта или транзакционными изменениями при лицензировании. Эти варианты использования не могут быть обработаны с помощью экземпляров Prometheus, которые лучше подходят для мониторинга на основе метрик.



Второй был Noderig

В ходе бесед с некоторыми из наших клиентов мы пришли к выводу, что существующие инструменты нуждаются в определенном уровне знаний, чтобы их можно было использовать в больших масштабах. Например, команда с кластером из 20 тыс. Узлов с Scollector в итоге получит более 10 миллионов метрик только для узлов… Фактически, в зависимости от конфигурации оборудования, Scollector будет генерировать от 350 до 1000 метрик из одного узла.

Это причина создания Noderig. Мы хотели, чтобы он был таким же простым в использовании, как экспортер узлов от Prometheus, но с более детализированным производством метрик по умолчанию.

Noderig собирает метрики ОС (ЦП, память, диск и сеть), используя семантику простого уровня. Это позволяет собирать нужное количество метрик для любого типа хоста, что особенно подходит для контейнерных сред.

Мы сделали его совместимым с пользовательскими сборщиками Scollector, чтобы упростить процесс миграции и обеспечить расширяемость. Внешние сборщики — это простые исполняемые файлы, которые действуют как поставщики данных, собираемых Noderig, как и любые другие показатели.

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



Это работает?

Beamium и Noderig широко используются в OVH и поддерживают мониторинг очень больших инфраструктур. На момент написания мы собираем и храним сотни миллионов показателей с помощью этих инструментов. Так что они определенно работают!

Фактически, в настоящее время мы работаем над выпуском 2.0, который будет доработкой, включающей автообнаружение и горячую перезагрузку.

Рабочие процессы непрерывной доставки и развертывания с CDS

Рабочий процесс CDS — ключевая особенность платформы OVH CI / CD. Этот структурный выбор добавляет дополнительную концепцию к конвейерам и заданиям CI / CD и после более чем трех лет интенсивного использования, безусловно, является важной особенностью.



Прежде чем углубляться в полное объяснение рабочих процессов CDS, давайте рассмотрим некоторые ключевые концепции конвейеров и заданий. Эти концепции взяты из справочника 8 принципов непрерывной доставки.

Основной элемент: «Работа».


Задание состоит из шагов, которые будут выполняться последовательно. J О.Б. выполняется в специальной рабочей области (т.е. файловая система). Новое рабочее пространство назначается для каждого нового запуска задания.



Стандартная сборка работа выглядит следующим образом:



Вы можете использовать «встроенные» действия, такие как checkoutApplication, скрипт, jUnit, загрузка / скачивание артефактов.

  • Действие heckoutApplication клонирует ваш репозиторий Git
  • Действие сценария выполняет вашу команду сборки как «make build».
  • Действие artifactUpload загружает ранее созданные двоичные файлы
  • Действие jUnit анализирует данный XML-файл в формате Junit, чтобы извлечь результаты его тестирования.

Конвейер: как организовать работу с этапами

С CDS конвейер — это не поток заданий. Трубопровод представляет собой последовательность этапов, каждый из которых содержит один или несколько рабочих мест.



Этап   представляет собой набор заданий , которые будут выполняться параллельно . Этапы выполняются последовательно, если предыдущий этап прошел успешно. 

Возьмем реальный вариант использования: конвейер, на котором построена CDS. Этот конвейер состоит из четырех этапов: 



  • Этап «Build Minimal» запущен для всех веток Git. Основная цель этого этапа — скомпилировать Linux-версию двоичных файлов CDS. 
  • Этап «Сборка другой ОС / Arch» запускается только  в основной ветке. На этом этапе компилируются все бинарные файлы, поддерживаемые os / arch: linux, openbsd, freebsd, darwin, windows-386, amd64 и arm.  
  • Этап «Пакет» запущен для всех веток Git. На этом этапе готовится образ докера и пакет Debian.
  • Наконец, запускается этап «Публикация» независимо от ветки Git. 

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

Рабочие процессы CDS: как организовать ваши конвейеры


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

Возьмем пример. Один рабочий процесс для создания и развертывания трех микросервисов:  

  • Создайте каждый микросервис 
  • Разверните их на подготовительной стадии 
  • Запустите интеграционные тесты в тестовой среде 
  • Разверните их в производственной среде, а затем повторно запустите интеграционные тесты в производственной среде.



Для строительной части существует только один конвейер для управления, который используется три раза в рабочем процессе с разными контекстами приложения / среды каждый раз. Это называется «контекст конвейера».

Любое условное ветвление рабочего процесса (например, «автоматическое развертывание в промежуточной среде, только если текущая ветвь Git является главной») может быть выполнено с помощью «условного выполнения», установленного в конвейере.



Давайте посмотрим на реальный вариант использования. Это рабочий процесс, который создает, тестирует и развертывает CDS в производственной среде в OVH ( да, CDS создает и развертывает себя! ):



  1. Для каждого коммита Git запускается рабочий процесс
  2. Пользовательский интерфейс упакован, все двоичные файлы подготовлены, а образы докеров созданы. Задание «UT» запускает модульные тесты. Задание «ИТ» устанавливает CDS в эфемерной среде и запускает в ней интеграционные тесты. Часть 2 автоматически запускается при всех коммитах Git.
  3. В части 3 развертывается CDS в нашей подготовительной среде, а затем запускаются интеграционные тесты. Он запускается автоматически, когда текущая ветвь является главной.
  4. И последнее, но не менее важное: часть 4 развертывает CDS в нашей производственной среде.

Я е есть сбой на трубопроводе, он может выглядеть следующим образом:





Но, конечно же, с помощью CDS Workflows вы не ограничены самыми сложными задачами! Эти два примера демонстрируют тот факт, что рабочие процессы позволяют создавать и развертывать согласованный набор микросервисов. Я ж вам есть потребности более простые, ваши рабочие процессы, конечно, проще.



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

Больше чем “Pipeline as Code”… “Workflow as Code”

С CDS нет никаких компромиссов. Некоторые пользователи предпочитают рисовать рабочие процессы через веб-интерфейс, другие предпочитают писать код на yaml. CDS позволяет делать и то, и другое!

Есть два способа хранить рабочие процессы: либо в базе данных CDS, либо в репозитории Git с исходным кодом. Мы называем это «Рабочий процесс как код».

Это позволяет иметь рабочий процесс в одной ветке, а затем развивать его в другой ветке. CDS создаст экземпляр рабочего процесса на лету на основе кода yaml, присутствующего в текущей ветке.

CDS — это программное обеспечение с открытым исходным кодом OVH, которое можно найти на github.com/ovh/cds, с документацией на ovh.github.io/cds.

Интегрируйте свое частное облако с Active Directory

Федерация  — это бета-функция, предлагаемая всем клиентам OVH Private Cloud с vCenter 6.5 . Если вы хотите принять участие в бета-тестировании, обратитесь в нашу службу поддержки. Это позволяет использовать внешний Microsoft Active Directory в качестве источника аутентификации для доступа к серверу VMware vCenter . Реализация этой функции стало возможным благодаря OvH в команде DevOps , которые разработали инновационный и уникальный API , который добавляет дополнительные возможности для тех , предлагаемых VMware. Действительно, в настоящий момент невозможно настроить источники идентификаторов через собственный API vCenter.



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

Зачем?


По умолчанию права доступа к vCenter в частном облаке управляются непосредственно этим vCenter. Пользователи создаются локально (localos или домен SSO), и все механизмы управления доступом ( RBAC ) управляются службой SSO . Включение федерации делегирует управление пользователями Microsoft Active Directory (AD). В результате сервер vCenter будет взаимодействовать с контроллером домена, чтобы гарантировать, что пользователь, пытающийся подключиться, является тем, кем он себя называет. VCenter сохраняет управление ролями и привилегиями для объектов, которыми он управляет. После настройки федерации можно связать пользователей AD с ролями vCenter, чтобы они могли получать доступ и / или управлять определенными объектами в инфраструктуре (виртуальными машинами, сетями, папками и т. Д.).


Одним из основных применений этого будет облегчение доступа к vCenter для администраторов за счет уменьшения количества учетных записей, необходимых для обслуживания различных элементов инфраструктуры. Кроме того, появится возможность расширить и унифицировать политику управления паролями между Active Directory и vCenter Private Cloud.

Тот факт, что федерацией можно управлять через API OVH, позволяет автоматизировать настройку, а также поддерживать ее в рабочем состоянии. Наконец, очень просто добавить проверки в любой инструмент мониторинга (Nagios, Zabbix, Sensu и т. Д.) Для мониторинга состояния Федерации и прав, назначенных пользователям.

Вот пример простого сценария PowerShell, который будет периодически проверять, находится ли конфигурация федерации в желаемом состоянии:



Архитектура и предпосылки

Поскольку vCenter должен будет взаимодействовать с контроллерами домена, первым шагом будет разрешение потоков между этими элементами. Есть несколько способов достичь этой цели, например, объединить OVHCloud Connectс частным шлюзом . Для изучения всех различных возможностей потребуется целая статья, поэтому мы советуем вам связаться с OVH или одним из наших партнеров, чтобы помочь вам в выборе наиболее подходящей архитектуры. Следующая диаграмма дает вам упрощенный обзор того, как это может выглядеть:



После подключения вам необходимо убедиться, что вы собрали следующую информацию, прежде чем начинать процесс настройки:

  • Ваши учетные данные OVH (ник и пароль)
  • Имя вашего частного облака (в форме 
    pcc-X-X-X-X
    )
  • Необходимая информация об инфраструктуре Active Directory, а именно:
    • Краткое и длинное имя домена Active Directory (например,
      contoso
      и 
      contoso.com
      )
    • IP-адрес контроллера домена
    • Имя пользователя и пароль учетной записи AD с достаточными правами для просмотра каталога
    • Расположение групп и пользователей в иерархии AD как «базовое DN» (пример:) 
      OU = Users, DC = contoso, DC = com
      . Следует отметить, что хотя информация о группе является обязательной, в настоящее время ее невозможно использовать для управления аутентификацией.
    • Список пользователей Active Directory, которых вы хотите привязать к vCenter. Необходимо будет указать имена пользователей в виде username@FQDN.domain (например,
      federation@contoso.com
      )

Обратите внимание, что в настоящее время невозможно иметь несколько пользователей с одним и тем же коротким именем, независимо от того, управляются ли они локально или с помощью Active Directory.

Активация и настройка

После того, как вы соберете всю необходимую информацию, можно будет активировать и настроить Федерацию. Операция будет проходить в три этапа:

  1. Активация связи между Active Directory и частным облаком
  2. Привязка одного или нескольких пользователей AD к частному облаку
  3. Назначение прав пользователям

На данный момент конфигурация доступна только через OVH API, но в среднесрочной перспективе это будет возможно сделать через панель управления OVH.  API предлагает все необходимые параметры для активации, настройки или даже удаления федерации частного облака:



Включение соединения между AD и частным облаком

Перейдите на сайт проводника API и выполните аутентификацию, используя свои учетные данные OVH. Если у вас его еще нет, получите имя (также называемое serviceName в API) своего частного облака, так как оно будет обязательным для всех остальных шагов настройки. Вы можете получить доступ к этой информации, выполнив GET для URI / SpecialCloud:



Включите федерацию, предоставив всю информацию об Active Directory с помощью POST в URI- адресе / SpecialCloud / {serviceName} / federation / activeDirectory . Вся запрашиваемая информация обязательна:



Активация Федерации займет некоторое время и будет происходить в фоновом режиме. Вы можете следить за ходом операции через панель управления OVH:



После завершения вы можете получить идентификатор федерации, отправив запрос GET на URI- адрес / SpecialCloud / {serviceName} / federation / activeDirectory :



Привязка одного или нескольких пользователей AD

Теперь, когда ваш AD объявлен в vCenter Private Cloud, мы сможем привязать к нему пользователей Active Directory. Обратите внимание, что даже если ваши пользователи связаны, с ними не будет связанных ролей vCenter, поэтому они не смогут войти в систему.

Чтобы привязать пользователя, вам нужно будет отправить запрос POST на /dedicatedCloud/{serviceName}/federation/activeDirectory/{activeDirectory}/grantActiveDirectoryUser URI, указав полное имя пользователя:



Убедитесь, что пользователь присутствует в поисковом подразделении, которое вы указали при связывании AD с vCenter. Еще раз, вы можете проверить, что задача импорта выполнена через API или через панель управления:



Вы также должны получить электронное письмо о том, что пользователь был импортирован.

Назначение прав доступа

Последним шагом будет предоставление пользователям прав доступа к различным объектам виртуальной инфраструктуры. Этот шаг не отличается от обычного способа управления правами пользователей частного облака. Это можно сделать через API или панель управления OVH.



Теперь вы должны иметь возможность войти в свой vCenter с пользователями вашего AD и начать управлять своим частным облаком!

В этом посте мы увидели, как активировать опцию «Федерация» и какие преимущества она дает пользователям частного облака OVH. В следующей публикации мы поговорим о еще одной новой функции: Granular Rights. Так что следите за новостями в блоге OVH!

Неожиданный поиск бизнес-аналитики

Бизнес-аналитика (BI) — это способность собирать существенные данные из информационной системы для подачи в хранилище данных (DWH) или озеро данных. Обычно они предоставляют копию данных, которые будут использоваться для приложений бизнес-аналитики. Для подпитки DWH могут применяться разные стратегии. Одна из таких стратегий - Change Data Capture (CDC), которая представляет собой способность фиксировать изменяющиеся состояния из базы данных и преобразовывать их в события, которые можно использовать для других целей. Большинство баз данных предназначены для целей OLTP и хорошо для этого разработаны. Тем не менее, разные варианты использования потребуют одних и тех же данных с разными шаблонами доступа. Эти варианты использования (большие данные, ETL и потоковая обработка и др.) В основном подпадают под Баннер OLAP . Их смешение поставит под угрозу OLTP и производственную среду, поэтому нам нужно включить OLAP ненавязчивым образом.

OVH, как облачный провайдер, управляет многочисленными базами данных как для своих клиентов, так и для собственных нужд. Управление жизненным циклом базы данных всегда включает в себя как поддержание инфраструктуры в актуальном состоянии, так и синхронизацию с циклом разработки, чтобы согласовать программное обеспечение с его зависимостью от базы данных. Например, приложению может потребоваться MySQL 5.0, который затем может быть объявлен как EOL (End Of Life). В этом случае приложение необходимо изменить для поддержки (скажем) MySQL 5.5. Мы не изобретаем велосипед здесь — этим процессом уже несколько десятилетий управляют операторы и команды разработчиков.

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

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

Разработка ненавязчивого процесса сбора измененных данных

Обычно перед тем, как приступить к разработке, рекомендуется определить состояние технологии, поскольку это сэкономит время и укрепит сообщества. Еще в начале 2015 года, когда впервые появился ландшафт CDC ( Debezium , аналогичное решение с открытым исходным кодом, появилось только в конце того же года), единственное существующее решение — Databus — появилось от LinkedIn. Архитектура Databus была довольно сложной, и проект не был очень активным. Кроме того, это не решало наших требований к безопасности, и мы пришли из сильной культуры эксплуатации, поэтому запуск JVM на сервере базы данных был явно непозволительным для наших рабочих групп.

Хотя не существовало программного обеспечения CDC, соответствующего нашим требованиям, в конце концов мы нашли библиотеку репликации binlog, которую можно было бы интегрировать с некоторыми из них в Go. Binlog — это имя MySQL для базы данных WAL.

Наши требования были довольно простыми:

  • Избегайте решений на основе JVM (JVM и контейнеры в то время не работали должным образом, и было бы трудно получить поддержку от Ops)
  • Агент CDC, необходимый для подключения к шлюзу CDC для высокозащищенных сред (а не шлюзу для агентов)
  • Шлюз CDC может контролировать флот своих агентов
  • Агент CDC может фильтровать и сериализовать события, чтобы протолкнуть их с помощью контроля обратного давления.
  • Агент CDC может сбросить БД, чтобы получить первый снимок, поскольку бинлоги не всегда доступны с самого начала.

Вот глобальный дизайн проекта Menura:



Менура — это род лирохвостов : птицы, способные воспроизводить любой звук. Большинство BI связанных компонентов являются «птицы», так как они часть B usiness I ntelligence R & D проекта!

Автоматизация плоскости управления BI

Поскольку Menura была развернута на серверах баз данных, она могла отображать доступные базы данных и таблицы в плоскости управления BI , чтобы пользователь мог запросить синхронизацию с заданной таблицей. Протокол управления имел несколько простых задач:

  • Добавить и настроить источник базы данных
  • Управление удаленной конфигурацией
  • Картографический агент / картография таблиц
  • Дамп таблиц базы данных
  • Управление CDC (запуск / остановка синхронизации, фиксация смещений бинлогов…)

В то время gRPC только зарождался, но мы увидели в этом проекте, с его прочной основой, возможность примирить Protobuf, экономичность и языковое разнообразие. Кроме того, возможность настройки RPC с двунаправленной потоковой передачей была интересна с точки зрения реализации соединений клиент-сервер с RPC-серверами, поэтому мы сделали ее основой протокола управления.

gRPC использует буфер протокола как IDL для сериализации структурированных данных. Каждый StreamRequest состоит из заголовка для управления мультитенантностью. Это означает, что если бы наши клиенты решили назвать свои источники одним и тем же именем, мы могли бы выделить управляющие сообщения по арендатору, а не только по источнику. Поэтому мы находим RequestType, как определено в Protobuf v3:

enum RequestType {
 Control_Config       = 0;
 Control_Hearbeat     = 1;
 Control_MySQLClient  = 10;
 Control_MySQLBinlog  = 11;
 Control_Syslog       = 12;
 Control_PgSQLClient  = 13;
 Control_PgSQLWal     = 14;
 Control_PgSQLLogDec  = 15;
 Control_Kafka        = 16; 
 Control_MSSQLClient  = 17;
}


Этот RequestType позволил нам получить исходные плагины со специализированными структурами, которые они ожидают. Обратите внимание, что мы отделили клиентов БД от репликации БД (binlog, WAL…). Основная причина в том, что они не имеют одной и той же области видимости, поэтому библиотеки не совпадают. Поэтому имело смысл держать их отдельно.

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

Эти опасения подтолкнули нас к модульной конструкции агента Menura:



Фильтрация данных
Важной функцией была возможность фильтровать события или столбцы. На то было две причины:

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

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

filter_policy: accept/drop
filter:
 table_a:
 table_b:
   ignored_columns:
     — sensibleColumn


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

Валидации в гетерогенных системах

В некоторых случаях вы можете подтвердить, что обрабатываете аналитическое задание на тех же данных, из которых состоит настоящая база данных. Например, для расчета выручки за определенный период требуются достоверные данные от даты до даты. Проверка состояния репликации между базой данных и озером данных была сложной задачей. На самом деле проверки целостности не реализуются с той же логикой в ​​базах данных или хранилищах, поэтому нам нужен был способ абстрагировать их от собственной реализации. Мы подумали об использовании структуры данных Merkle Tree , чтобы мы могли поддерживать дерево целостности с блоками или строками. Если ключ / значение отличается от базы данных, то это будет отражать глобальный или промежуточный хэш целостности, и нам нужно будет сканировать только листовой блок, который имеет несогласованный хэш между обеими системами.



Соберем все вместе

Как мы уже говорили во введении, CDC настроен на преобразование изменений базы данных в обрабатываемые события. Цель здесь — эффективно и действенно удовлетворять любые бизнес-потребности, требующие данных. Вот два примера того, что мы сделали с данными, которые теперь были доступны в виде событий…

Соединения между базами данных в реальном времени

Пока мы строили озеро данных из реплицированных таблиц, и поскольку этот проект был в основном для целей бизнес-аналитики, мы рассмотрели возможность добавления некоторых аналитических данных в реальном времени на основе той же логики, которую мы используем с пакетными заданиями и заданиями Apache Pig . С 2015 года самой продвинутой структурой обработки потоков является Apache Flink , которую мы использовали для обработки соединений в реальном времени между различными базами данных и таблицами.

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



Мы выбрали Apache Flink по нескольким причинам:

  • Его документация была восхитительной
  • Его основной движок был великолепен и намного превосходил Apache Spark (проекта Tungsten там даже не было).
  • Это был европейский проект , поэтому мы были близки к редактору и его сообществу.

Индексирование в реальном времени

Теперь у нас есть таблица реального времени, загруженная в Apache HBase , и нам нужно было добавить к ней возможность запросов. Хотя HBase был хорош с точки зрения хранения, он не предоставлял никаких возможностей поиска, а его схема доступа не была идеальной для сканирования по критерию поиска.

Здесь Гийом сотворил чудо! Повторно используя Lily , индексатор HBase, предоставляющий концепцию SEP (обработчик побочных эффектов), ему удалось повторно внедрить схему агрегированной таблицы в Lily, чтобы построить отображение типов данных, необходимое для чтения значений байтовых массивов HBase, перед их индексированием в Solr. Теперь у нас была панель мониторинга в реальном времени, представляющая собой агрегированную объединенную таблицу в реальном времени, обработанную на основе сбора данных об изменении в реальном времени. Бум!



Именно тогда мы начали привлекать реальных клиентов к нашему новому решению.

Жить!

Если по-прежнему существует необходимость продемонстрировать, что тестирование в среде моделирования — это не то же самое, что тестирование в производственной среде, эта следующая часть, вероятно, разрешит спор…

После настройки конвейера данных мы обнаружили несколько ошибок в производственной среде. Вот два из них:

Чередующиеся события

Согласно определению MySQL, структура события состоит из заголовка и поля данных.

В репликации на основе строк (RBR), в отличие от репликации на основе операторов (SBR), событие каждой строки реплицируется с соответствующими данными. Операторы DML разделены на две части:

  • А TABLE_MAP_EVENT
  • A ROWS_EVENT(может быть WRITE, UPDATEили DELETE)

Первое событие, TABLE_MAP_EVENTописывает метаданные содержимого второго события. Эти метаданные содержат:

  • Включенные поля
  • Растровые изображения с нулевыми значениями
  • Схема предстоящих данных
  • Метаданные для предоставленной схемы

Второе событие WRITE_ROWS_EVENT(для вставок) содержит данные. Чтобы декодировать его, вам нужно, чтобы предыдущее TABLE_MAP_EVENTсобытие знало, как использовать это событие, сопоставляя соответствующее MYSQL_TYPE_* и считывая количество байтов, ожидаемых для каждого типа.

Иногда некоторые события не обрабатывались должным образом, поскольку несогласованность между метаданными и данными приводила к VARCHARдекодированию DATETIMEзначений как значений и т. Д.

После некоторой отладки выяснилось, что команда DBA добавила триггеры в некоторые таблицы MySQL. Когда несколько дней спустя реплики были перестроены, они унаследовали эти функции и начали регистрировать события, производимые этими триггерами.

Дело в том, что в MySQL триггеры являются внутренними. В binlog каждое событие, исходящее от мастера, отправляется следующим образом:

TableMapEvent_a

TableMapEvent_a
WriteEvent_a
TableMapEvent_b
WriteEvent_b
TableMapEvent_c
WriteEvent_c



a, bи cпредставляет события для разных таблиц schema.tables.


Поскольку триггеры не поступают от ведущего устройства, когда ведомое устройство получает a TableMapEventдля определенной таблицы, оно запускает другой TableMapEvent для специализированной таблицы ( _event). То же самое относится и к WriteEvent.


Когда MySQL запускает событие, он отправляет его в двоичный журнал, поэтому вы закончите мультиплексированием двух TableMapEvents, а затем двух RowsEvents, как показано ниже:
TableMapEvent_a
TableMapEvent_a_event
WriteEvent_a
WriteEvent_a_event
Понял! Когда мы пытались декодировать WriteEvent_a, предыдущее TableMapEvent предназначалось для TableMapEvent_a_event, а не для TableMapEvent_a, поэтому он пытался декодировать событие с неправильной схемой.

Нам нужно было найти способ сопоставить WriteEvent с соответствующим TableMapEvent. В идеале в структуре должен был быть TableID, который мы могли бы использовать для этого. В конце концов, нам просто нужно было буферизовать все TableMapEvents, сделав их доступными для всех RowsEvent, начать чтение RowsEvent, выбрать TableID, а затем получить метаданные Columns из соответствующего TableMapEvent. Исправлена!

Неуловимая десятичная дробь ...
Мы также столкнулись с произвольной ошибкой в ​​библиотеке, из-за которой Menura взорвалась. И снова мы углубились в библиотеку binlog, чтобы шаг за шагом отладить процесс декодирования. Мы определили кортежи таблицы / столбца, чтобы ограничить вывод журнала до более разумной скорости. А RowEventвыглядело так:
DEBUG MR: TableMapEvent.read() : event.TableName = myTable
DEBUG MR: TableMapEvent.read() : columnCount= 16
DEBUG MR: TableMapEvent.read() : Read Next columnTypeDef= [3 3 15 246 0 0 12 0 15 12 12 15 3 3 15 15]
DEBUG MR: readStringLength() : r.Next(int(12))
DEBUG MR: TableMapEvent.read() : ReadStringLength columnMetaDef= [255 0 10 2 40 0 10 0 255 0 255 3]
DEBUG MR: TableMapEvent.read() : columnNullBitMap= [10 198]
DEBUG MR: TableMapEvent.read() : switch columnTypeDef[3]=f6
DEBUG MR: TableMapEvent.read() : switch : case metaOffset+=2
DEBUG MR: TableMapEvent.read() : column.MetaInfo
DEBUG MR: TableMapEvent.read() : column.MetaInfo = [10 2]
В этом журнале есть довольно интересные части процесса декодирования, на которые стоит обратить внимание. В первом столбце представлена ​​следующая схема:
TableMapEvent.read() : Read Next columnTypeDef= [3 3 15 246 0 0 12 0 15 12 12 15 3 3 15 15]
Некоторые из этих типов данных требуют чтения метаданных. Например, вот соответствующий журнал с метаданными столбца:
TableMapEvent.read() : ReadStringLength columnMetaDef= [255 0 10 2 40 0 10 0 255 0 255 3]
Кроме того, NullBitMapважен столбец, так как мы должны знать, какие нулевые значения следует игнорировать при декодировании буфера.

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

DEBUG MR: rowsEvent.read(): pack.Len() BEFORE : 59
DEBUG MR: rowsEvent.read(): Column.MetaInfo: &{246 [10 2] true}
DEBUG MR: rowsEvent.read(): switch column.Type= 246
DEBUG MR: case MYSQL_TYPE_NEWDECIMAL
DEBUG MR: readNewDecimal() precision= 10 scale= 2
DEBUG MR: readNewDecimal() size= 5
DEBUG MR: readNewDecimal() buff=8000000000
DEBUG MR: readNewDecimal() decimalpack=0000000000
DEBUG MR: rowsEvent.read(): pack.Len() AFTER : 54
DEBUG MR: rowsEvent.read(): value : 0
DEBUG MR: rowsEvent.read(): pack.Len() BEFORE : 54
DEBUG MR: rowsEvent.read(): Column.MetaInfo: &{0 [] false}
DEBUG MR: rowsEvent.read(): switch column.Type= 0
Что касается предыдущей схемы, у нас есть 16 столбцов, и согласно документации MySQL наши типы данных предоставляют метаданные, как в следующей таблице:Это дает нам 18 байтов метаданных для схемы этого примера, в отличие от 10 байтов в пакете.Мы также обнаружили, что MySQL явно не отправлял метаданные, необходимые для чтения DECIMALзначений в пакете. Было ли это нормальным поведением?Документация MySQL ясна: чтобы прочитать DECIMALзначение, вам нужны метаданные (точность, масштаб и т. Д.). Период.Однако мы обнаружили, что с этим MYSQL_TYPE_DECIMALобращались как MYSQL_TYPE_NEWDECIMAL.
case MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NEWDECIMAL:
value.value = pack.readNewDecimal(int(column.MetaInfo[0]), int(column.MetaInfo[1]))


Мы отступили и стали искать, как это MYSQL_TYPE_DECIMALреализовано в других библиотеках binlog. Я не был администратором баз данных, но мне показалось странным, что в схеме, использующей DECIMALзначения, на самом деле используются два разных типа данных MySQL.

Хорошо… «Хьюстон, у нас проблема».

Во-первых, никто не внедрял его MYSQL_TYPE_DECIMAL, и по очень веской причине: мы не должны его получать, поскольку он устарел из MySQL, начиная с версии 5.0. Это означало, что в базе данных, лежащей в основе, работала таблица, созданная (в лучшем случае) из MySQL 4.9, в то время как база данных была обновлена ​​без надлежащего ALTER для автоматического преобразования типов данных в MYSQL_TYPE_NEWDECIMAL.

Во-вторых, поскольку у нас нет никакого контроля над базой данных, как нам декодировать MYSQL_TYPE_DECIMAL…

Первая попытка: игнорировать


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

Мы пропустили десятичное значение, но мы могли продолжить чтение других типов данных. Ну, вроде того… Так было лучше, но для того, чтобы читать значения после a MYSQL_TYPE_DECIMALв буфере данных, нам нужно было знать, сколько байтов нужно прочитать.
Вторая попытка: наивный подход (т.е. догадки!)


Десятичное значение — это дробное число, обычно кодируемое как число с плавающей запятой. Например, в DECIMAL(10,2)столбце восемь разрядов целого числа и две цифры дробной части. Целые цифры определяют количество байтов, которые необходимо прочитать. Например, мы читаем четыре байта для целой части и один байт для дробной части. Это было бы так просто… если бы у нас были метаданные.

На практике MySQL не предоставляет никаких метаданных для DECIMALзначений, поэтому мы проигнорировали их в первой итерации, чтобы сохранить другие данные. Вы когда-нибудь пробовали декодировать старые бинлоги с помощью официального инструмента mysqlbinlog? Если бы у вас был MYSQL_TYPE_DECIMALв ваших данных, то он бы перестал там декодировать. Да… MySQL не умеет декодировать собственный формат данных!

Кто-то может возразить, что если MySQL не предоставляет никаких метаданных, это потому, что он хранит их внутри, в фиксированном размере. Ну нет!

Вот как это работает… Десятичные числа в протоколе кодируются как VARCHAR. Я попытался прочитать значение, предполагая, что пробел заполнен, отметил обнаруженную точку и попытался прочитать дробные данные, которые казались последовательными для десятичной дроби. Если это не так, я, в конце концов, не прочитал последний байт в буфере и перешел к следующему типу данных. И это сработало. В течение времени…
DEBUG MR: case MYSQL_TYPE_DECIMAL
DEBUG MR: readOldDecimalV2: byte = 32
DEBUG MR: readOldDecimalV2: continue
DEBUG MR: readOldDecimalV2: byte = 32
DEBUG MR: readOldDecimalV2: continue
DEBUG MR: readOldDecimalV2: byte = 32
DEBUG MR: readOldDecimalV2: continue
DEBUG MR: readOldDecimalV2: byte = 32
DEBUG MR: readOldDecimalV2: continue
DEBUG MR: readOldDecimalV2: byte = 32
DEBUG MR: readOldDecimalV2: continue
DEBUG MR: readOldDecimalV2: byte = 32
DEBUG MR: readOldDecimalV2: continue
DEBUG MR: readOldDecimalV2: byte = 32
DEBUG MR: readOldDecimalV2: continue
DEBUG MR: readOldDecimalV2: byte = 48
DEBUG MR: readOldDecimalV2: start writing
DEBUG MR: readOldDecimalV2: byte = 46
DEBUG MR: readOldDecimalV2: dot found
DEBUG MR: readOldDecimalV2: writing
DEBUG MR: readOldDecimalV2: byte = 48
DEBUG MR: readOldDecimalV2: writing
DEBUG MR: readOldDecimalV2: byte = 48
DEBUG MR: readOldDecimalV2: writing
DEBUG MR: readOldDecimalV2: byte = 32
DEBUG MR: readOldDecimalV2: unread, break
DEBUG MR: readOldDecimalV2: converting to float : 0.00
DEBUG MR: rowsEvent.read(): pack.Len() AFTER : 43
DEBUG MR: rowsEvent.read(): value : 0
Мы надеемся, что мы не встретим следующий тип VARCHAR с длиной, которую можно было бы проанализировать как значение DIGIT, но динамический размер значения DECIMAL означает, что должны быть доступны метаданные для правильного чтения. Другого пути нет.

Третья попытка: когда дело доходит до хорошего раба, компромиссов нет!


Мы спросили себя, что отличает mysqlbinlog от MySQL Slave, когда дело доходит до чтения двоичных журналов. Мы обнаружили, что единственная разница заключалась в том, что истинное ведомое устройство знало DECIMALсхему и связанные с ней метаданные при получении этих данных. Таким образом, ему не пришлось бы ничего гадать — просто прочтите нужное количество байтов в соответствии с известной схемой.

В итоге мы реализовали клиент MySQL в нашем источнике mysqlbinlog, который изначально сбрасывал схемы таблиц для передачи значения NumericScale в библиотеку декодирования. Проблема здесь в том, что строки не идентифицируются в схемах по их ColumnName. MySQL поддерживает OrdinalPositionстолбцы в таблице, но это не идентификатор, указанный в протоколе binlog (это было бы слишком просто!). Вы должны поддерживать свой собственный индекс столбца из схемы, чтобы он соответствовал тому, который вы получите в протоколе binlog. Как только он у вас есть, просто найдите значение десятичной шкалы, чтобы узнать, сколько байтов вам еще нужно прочитать после точки.

Таким образом, библиотека декодирования теперь могла декодировать MYSQL_TYPE_DECIMALиз потока событий binlog. Ура!!!
TL; DR
В итоге создание стека бизнес-аналитики с нуля заняло примерно шесть месяцев. В команду входило 2,5 человека: Алексис Жендронно, Гийом Салоу (который присоединился к нам через три месяца) и я. Он продемонстрировал принцип сбора измененных данных, применяемый к реальным вариантам использования, позволяя в реальном времени получать информацию о продажах, запасах и многом другом, без какого-либо влияния на производственную среду. Команда росла по мере расширения масштабов проекта за счет новых, более требовательных клиентов, таких как группы финансовых услуг и управленческого контроля. Спустя несколько недель нам удалось запустить его на Apache Flink на основе того же конвейера данных, который с тех пор стал надежным источником для расчета доходов и других бизнес-KPI.

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

Вся команда проделала отличную работу, и Димитри Капитан собирается открыть исходный код агента сбора данных, который использовался в предварительных лабораториях: сборщик данных OVH. Если вы заинтересованы в более подробном обсуждении системы отслеживания измененных данных в OVH, не стесняйтесь присоединиться к нам в Gitter команды или написать мне в Twitter.

Получение внешнего трафика в Kubernetes - ClusterIp, NodePort, LoadBalancer и Ingress

За последние несколько месяцев, я действовал в качестве  Защитника Developer для  OVH Managed Kubernetes беты , следуя наши бета - тестеры, получать обратную связь, писать документы и учебники, и в целом помогаю убедиться , продукт соответствует потребностям наших пользователей настолько близко , насколько это возможно.

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



Сегодня мы начнем с одного из самых частых вопросов, которые я задавал  в первые дни бета-тестирования:  как направить внешний трафик в мою службу Kubernetes? Этот вопрос возник часто, когда наши клиенты начали изучать Kubernetes, и когда я попытался ответить на него, я понял, что часть проблемы заключается в огромном количестве  возможных ответов и концепциях, необходимых для их понимания.

С этим вопросом был связан запрос функции : большинству пользователей нужен инструмент балансировки нагрузки Поскольку бета-версия предназначена для подтверждения стабильности продукта и проверки приоритетов набора функций, мы смогли быстро подтвердить 
LoadBalancer
ключевую функцию нашего первого коммерческого выпуска.

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

Это сообщение в блоге представляет собой расширенную версию этого руководства. Надеемся, оно вам пригодится!

Некоторые понятия: ClusterIP, NodePort, Ingress и LoadBalancer

Когда вы начинаете использовать Kubernetes для реальных приложений, один из первых вопросов, который нужно задать, — как получить внешний трафик в вашем кластере. В официальной документации предлагает полное (но довольно сухое) объяснение этой темы, но здесь мы будем объяснять его в более практических, служебной необходимости знать пути.

Есть несколько способов перенаправить внешний трафик в ваш кластер:

1. Использование Kubernetes прокси и ClusterIP: По умолчанию значения Kubernetes ServiceType является ClusterIp, что выставляет Service на кластерной внутренний IP. Чтобы получить доступ к ClusterIp из внешнего источника, вы можете открыть прокси Kubernetes между внешним источником и кластером. Обычно это используется только для разработки.

2. Предоставление сервисов как NodePort: объявление Service as открывает NodePortего на IP-адресе каждого узла на статическом порте (называемом NodePort). Затем вы можете получить доступ к Service извне кластера, запросив :. Это также можно использовать для производства, хотя и с некоторыми ограничениями.

3. Предоставление услуг как LoadBalancer: объявление Service as LoadBalancer предоставляет его внешнему виду с помощью решения балансировки нагрузки поставщика облачных услуг. Облачный провайдер предоставит балансировщик нагрузки для Serviceи сопоставит его с автоматически назначенным NodePort. Это наиболее широко используемый метод в производственной среде.

Использование прокси Kubernetes и ClusterIP

По умолчанию Kubernetes ServiceType это ClusterIp, что выставляет Service на кластерной внутренний IP. Чтобы получить доступ ClusterIp с внешнего компьютера, вы можете открыть прокси Kubernetes между внешним компьютером и кластером.

Вы можете использовать kubectl для создания такого прокси. Когда прокси включен, вы напрямую подключены к кластеру и можете использовать для этого внутренний IP-адрес (ClusterIp) Service.



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

Предоставление услуг как NodePort

Объявление службы как NodePort раскрывает Service IP-адрес каждого узла в NodePort (фиксированный порт для этого Serviceв диапазоне по умолчанию 30000-32767). Затем вы можете получить доступ к Service извне кластера, запросив :. Каждая служба, которую вы развертываете, NodePort будет отображаться в своем собственном порту на каждом узле.



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

Предоставление услуг как LoadBalancer

Объявление службы типа LoadBalancer предоставляет ее внешнему виду с помощью балансировщика нагрузки облачного провайдера. Облачный провайдер предоставит балансировщик нагрузки для Serviceи сопоставит его с автоматически назначенным NodePort. Как трафик от этого внешнего балансировщика нагрузки направляется в Service модули, зависит от поставщика кластера.



Это LoadBalancer лучший вариант для производственной среды, но с двумя оговорками:

  • Все, Service что вы развернете LoadBalancer, получит собственный IP.
  • LoadBalancer Обычно выставлен счет на основании количества выставляемых услуг, которые могут быть дорогими.


В настоящее время мы предлагаем услугу OVH Managed Kubernetes LoadBalancer в качестве бесплатной предварительной версии до конца лета 2019 года.

О чем Ingress?

Согласно официальной документации, Ingress это объект API, который управляет внешним доступом к службам в кластере (обычно HTTP). Так в чем разница между этим и LoadBalancer или NodePort?

Ingress это не тип Service, а объект, который действует как обратный прокси-сервер и единственная точка входа в ваш кластер, который направляет запрос различным службам. Самый простой из них Ingress — это NGINX Ingress Controller, где NGINX берет на себя роль обратного прокси, а также работает как SSL.



Ingress ClusterIP доступен за пределами кластера через прокси Kubernetes NodePort, или LoadBalancer, и направляет входящий трафик в соответствии с настроенными правилами.



Основное преимущество использования Ingress за одним LoadBalancer — это стоимость: вы можете иметь множество услуг за одним LoadBalancer.

Какой мне использовать?

Что ж, это вопрос на миллион долларов, и он, вероятно, вызовет разный ответ в зависимости от того, кого вы спросите!

Вы можете пойти на все 100% LoadBalancer, получив индивидуальную LoadBalancer услугу. Концептуально это просто: каждая служба независима и не требует дополнительной настройки. Обратной стороной является цена (вы будете платить за одну LoadBalancer услугу), а также сложность управления множеством разных IP-адресов.

Вы также можете использовать только один LoadBalancer и Ingress позади него. Все ваши службы будут находиться под одним и тем же IP-адресом, каждая по своему пути. Это более дешевый подход, поскольку вы платите только за одну LoadBalancer, но если ваши услуги не имеют логической взаимосвязи, это может быстро стать хаотичным.

Если вы хотите узнать мое личное мнение, я бы попытался использовать комбинацию из двух…

Подход мне нравится, имеющий LoadBalancer для каждого соответствующего набора услуг, а затем маршрутизации этих услуг используя Ingressпозади LoadBalancer. Например, предположим, что у вас есть два разных API на основе микросервисов, каждый из которых содержит около 10 сервисов. Я бы поставил один LoadBalancerперед другим Ingressдля каждого API, LoadBalancerпоскольку это единственная общедоступная точка входа и Ingressмаршрутизация трафика к различным службам API.

Но если ваша архитектура достаточно сложна (особенно если вы используете микросервисы), вы скоро обнаружите, что управлять всем вручную с помощью LoadBalancer и Ingress довольно громоздко. Если это так, ответом может быть делегирование этих задач сервисной сети…

Что такое сервисная сетка?

Возможно, вы слышали об Istio или Linkerd и о том, как они упрощают создание микросервисных архитектур на Kubernetes, добавляя изящные льготы, такие как A / B-тестирование, канареечные выпуски, ограничение скорости, контроль доступа и сквозную аутентификацию.

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

Когда дело доходит до использования сервисных мешей в Kubernetes, есть о чем поговорить, но, как говорится, это уже история для другого раза…

Глубокое обучение объяснили моей 8-летней дочери

Машинное обучение и особенно глубокое обучение — горячие темы, и вы наверняка встречали модное слово «искусственный интеллект» в СМИ.



Однако это не новые концепции. Первая искусственная нейронная сеть (ИНС) была представлена ​​в 40-х годах. Так почему же в последнее время такой интерес к нейронным сетям и глубокому обучению? 

Мы рассмотрим эту и другие концепции в серии сообщений блога о  графических процессорах и машинном обучении .

YABAIR — еще один блог о распознавании изображений

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

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

Давайте рассмотрим один из самых классических примеров: построение системы распознавания чисел, нейронной сети для распознавания рукописных цифр.

Факт 1: это так же просто, как подсчет

Мы начнем с подсчета, сколько раз маленькие красные фигурки в верхнем ряду можно увидеть на каждой из черных рукописных цифр (в левом столбце).



Теперь давайте попробуем распознать (вывести) новую рукописную цифру, подсчитав количество совпадений с одинаковыми красными формами. Затем мы сравним это с нашей предыдущей таблицей, чтобы определить, какое число имеет больше всего соответствий:



Поздравляю! Вы только что создали простейшую в мире нейросетевую систему для распознавания рукописных цифр.

Факт 2: изображение — это просто матрица

Компьютер рассматривает изображение как матрицу . Черно-белое изображение — это 2D-матрица.

Рассмотрим изображение. Чтобы не усложнять задачу, возьмем небольшое черно-белое изображение цифры 8 с квадратными размерами 28 пикселей.

Каждая ячейка матрицы представляет интенсивность пикселя от 0 (который представляет черный цвет) до 255 (который представляет чистый белый пиксель).

Таким образом, изображение будет представлено в виде следующей матрицы 28 x 28 пикселей.



Факт 3: сверточные слои — это просто сигналы летучей мыши

Чтобы выяснить, какой узор отображается на картинке (в данном случае рукописная цифра 8), мы будем использовать своего рода сигнал летучей мыши / фонарик. В машинном обучении фонарик называется фильтром. Фильтр используется для выполнения классического вычисления матрицы свертки, используемого в обычном программном обеспечении для обработки изображений, таком как Gimp.



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



Факт 4: сопоставление фильтров — это досадно параллельная задача.

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

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



Факт 5: просто повторите операцию фильтрации (свертку матрицы) как можно больше раз.

Мы только что видели, что входное изображение / матрица фильтруется с использованием множественных сверток матриц.

Чтобы повысить точность распознавания изображений, просто возьмите отфильтрованное изображение из предыдущей операции и фильтруйте снова, снова и снова…

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

Это похоже на создание новых слоев абстракции, чтобы получить более четкое и ясное описание фильтра объекта, начиная с простых фильтров и заканчивая фильтрами, которые выглядят как края, колесо, квадраты, кубы,…

Факт 6: свертки матрицы — это просто x и +

Изображение стоит тысячи слов: следующее изображение представляет собой упрощенный вид исходного изображения (8 × 8), отфильтрованного с помощью фильтра свертки (3 × 3). Проекция фонарика (в этом примере фильтр Sobel Gx) дает одно значение.



Пример фильтра свертки (Sobel Gx), примененного к входной матрице (Источник: datascience.stackexchange.com/questions/23183/why-convolutions-always-use-odd-numbers-as-filter-size/23186)

Именно здесь происходит чудо: простые матричные операции сильно распараллелены, что идеально подходит для случая использования универсального графического процессора.

Факт 7. Необходимо упростить и обобщить то, что было обнаружено? Просто используйте max ()

Нам нужно обобщить то, что было обнаружено фильтрами, чтобы обобщить знания .

Для этого мы возьмем образец вывода предыдущей операции фильтрации.

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

Вы можете использовать любую операцию уменьшения, такую ​​как: max, min, average, count, median, sum и т. Д.

Факт 8: сожмите все, чтобы встать на ноги

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

Если целью нейронной сети является обнаружение рукописных цифр, в конце будет 10 классов для сопоставления входного изображения с: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

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

Ниже приведен обзор оригинальной сверточной нейронной сети LeNet-5, разработанной Яном Лекуном, одним из немногих, кто начал использовать эту технологию для распознавания изображений.



Факт 9: Глубокое обучение — это просто Бережливое производство — постоянное улучшение на основе обратной связи

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

Давайте KISS (будьте проще): мы смотрим на выход сети, если предположение (выход 0,1,2,3,4,5,6,7,8 или 9) неверно, мы смотрим, какой фильтр (ы) «сделал ошибку», мы присваиваем этому фильтру или фильтрам небольшой вес, чтобы они не повторили ту же ошибку в следующий раз. И вуаля! Система учится и продолжает совершенствоваться.

Факт 10: все сводится к тому, что глубокое обучение до неловкости параллельно

Обработка тысяч изображений, запуск десятков фильтров, применение понижающей дискретизации, сглаживание вывода… все эти шаги могут выполняться параллельно, что делает систему невероятно параллельной . Как ни странно, на самом деле это совершенно параллельная  проблема, и это просто идеальный вариант использования GPGPU (General Purpose Graphic Processing Unit), которые идеально подходят для массовых параллельных вычислений.

Факт 11: нужно больше точности? Просто иди глубже

Конечно, это немного упрощение, но если мы посмотрим на основное «соревнование по распознаванию изображений», известное как задача ImageNet, мы увидим, что частота ошибок уменьшалась с увеличением глубины нейронной сети. Общепризнано, что, помимо других элементов, глубина сети приведет к большей способности к обобщению и точности.



В заключение

Мы кратко рассмотрели концепцию глубокого обучения применительно к распознаванию изображений. Стоит отметить, что почти каждая новая архитектура для распознавания изображений (медицинская, спутниковая, автономное вождение и т. Д.) Использует одни и те же принципы с разным количеством слоев, разными типами фильтров, разными точками инициализации, разными размерами матриц, разными уловками (например, с изображением увеличение, дропауты, сжатие веса,…). Концепции остались прежними:



Другими словами, мы увидели, что обучение и вывод моделей глубокого обучения сводится к множеству базовых матричных операций, которые можно выполнять параллельно, и это именно то, для чего созданы наши старые добрые графические процессоры (GPU).

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