Русский
Русский
English
Статистика
Реклама

Devops

Sentry удаленый мониторинг багов в фронтенд приложениях React

03.07.2020 10:08:54 | Автор: admin

Мы изучаем использование Sentry с React.



Эта статья является частью серии, начинающейся с сообщения об ошибках Sentry на примере: Часть 1.


Реализация React


Сначала нам нужно добавить новый проект Sentry для этого приложения; с сайта Sentry. В этом случае мы выбираем React.


Мы вновь реализуем наши две кнопки, Hello и Error, приложение с React. Мы начинаем с создания нашего стартового приложения:


npx create-react-app react-app

Затем мы импортируем пакет Sentry:


yarn add @sentry/browser

и инициализируем его:


react-app / src / index.js


...import * as Sentry from '@sentry/browser';const RELEASE = '0.1.0';if (process.env.NODE_ENV === 'production') {  Sentry.init({    dsn: 'https://303c04eac89844b5bfc908ceffc6757c@sentry.io/1289887',    release: RELEASE,  });}...

Наблюдения:


  • Во время разработки у нас есть другие механизмы для наблюдения за проблемами, например консоль, поэтому мы включаем Sentry только для производственных сборок

Затем мы реализуем наши кнопки Hello и Error и добавляем их в приложение:


react-app / src / Hello.js


import React, { Component } from 'react';import * as Sentry from '@sentry/browser';export default class Hello extends Component {  state = {    text: '',  };  render() {    const { text } = this.state;    return (      <div>        <button          onClick={this.handleClick}        >          Hello        </button>        <div>{text}</div>      </div>    )  }  handleClick = () => {    this.setState({      text: 'Hello World',    });    try {      throw new Error('Caught');    } catch (err) {      if (process.env.NODE_ENV !== 'production') {        return;      }      Sentry.captureException(err);    }  }}

react-app / src / MyError.js


import React, { Component } from 'react';export default class MyError extends Component {  render() {    return (      <div>        <button          onClick={this.handleClick}        >          Error        </button>      </div>    )  }  handleClick = () => {    throw new Error('Uncaught');  }}

react-app / src / App.js


...import Hello from './Hello';import MyError from './MyError';class App extends Component {  render() {    return (      <div className="App">        ...        <Hello />        <MyError />      </div>    );  }}export default App;

Проблема (Исходные Карты)


Мы можем протестировать Sentry с производственной сборкой, введя:


yarn build

и из build папки введите:


npx http-server -c-1

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



Служба Sentry объясняет это, вытягивая исходные карты для уменьшенного пакета после получения ошибки. В этом случае мы бежим от localhost (недоступного службой Sentry).


Решения (Исходные Карты)


Решение этой проблемы сводится к запуску приложения с общедоступного веб-сервера. Одна простая кнопка ответа на него, чтобы использовать сервис GitHub Pages (бесплатно). Шаги для использования обычно следующие:


  1. Скопируйте содержимое папки build в папку docs в корневом каталоге репозитория.


  2. Включите GitHub Pages в репозитории (из GitHub), чтобы использовать папку docs в master ветви


  3. Перенесите изменения на GitHub



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


"homepage": "https://larkintuckerllc.github.io/hello-sentry/"

Окончательная версия запущенного приложения доступна по адресу:


https://larkintuckerllc.github.io/hello-sentry/


Иллюстрация Пойманных Ошибок


Давайте пройдем через нажатие кнопки Hello.



С ошибкой, появляющейся следующим образом:



Наблюдения:


  • Этот отчет об ошибке не может быть более ясным, BRAVO.

Иллюстрация Неучтенных Ошибок


Аналогично, давайте пройдем через нажатие кнопки Error.



С ошибкой, появляющейся следующим образом:



Лучшая обработка неучтенных ошибок (рендеринг)


Введение Границ Ошибок

Ошибка JavaScript в части пользовательского интерфейса не должна нарушать работу всего приложения. Чтобы решить эту проблему для пользователей React, React 16 вводит новое понятие "границы ошибок".

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



Новое поведение для необнаруженных ошибок

Это изменение имеет важное значение. Начиная с React 16, ошибки, которые не были пойманы какой-либо границей ошибок, приведут к размонтированию всего дерева компонентов React.

Dan Abramov Error Handling in React 16

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


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


react-app / src / MyRenderError


import React, { Component } from 'react';export default class MyRenderError extends Component {  state = {    flag: false,  };  render() {    const { flag } = this.state;    return (      <div>        <button          onClick={this.handleClick}        >          Render Error        </button>        { flag && <div>{flag.busted.bogus}</div> }      </div>    )  }  handleClick = () => {    this.setState({      flag: true,    });  }}

Наблюдение:


  • При нажатии кнопки, React будет отображаться flag.busted.bogus, которая порождает ошибку


  • Без границы ошибки все дерево компонентов будет размонтировано



Затем мы пишем наш код границы ошибки (использует новый метод жизненного цикла componentDidCatch); это, по сути, пример, приведенный в статье Дэна Абрамова:


react-app / src / ErrorBoundary.js


import React, { Component } from 'react';import * as Sentry from '@sentry/browser';export default class ErrorBoundary extends Component {  constructor(props) {    super(props);    this.state = { hasError: false };  }  componentDidCatch(err, info) {    this.setState({ hasError: true });    Sentry.captureException(err);  }  render() {    if (this.state.hasError) {      return <h1>Something went wrong.</h1>;    }    return this.props.children;  }}

Наконец, мы используем этот компонент:


react-app / src / App.js


...import MyRenderError from './MyRenderError';class App extends Component {  render() {    return (      <ErrorBoundary>        <div className="App">          ...        </div>      </ErrorBoundary>    );  }}...

При этом нажатие кнопки Render Error отображает резервный пользовательский интерфейс и сообщает об ошибке Sentry.




Завершение


Надеюсь, вам было это полезно.


P.S. Телеграм чат по Sentry https://t.me/sentry_ru

Подробнее..

Перевод Высокопроизводительный TSDB benchmark VictoriaMetrics vs TimescaleDB vs InfluxDB

26.06.2020 12:10:59 | Автор: admin

VictoriaMetrics, TimescaleDB и InfluxDB были сравнены в предыдущей статье по набору данных с миллиардом точек данных, принадлежащих 40K уникальным временным рядам.


Несколько лет назад была эпоха Zabbix. Каждый bare metal сервер имел не более нескольких показателей использование процессора, использование оперативной памяти, использование диска и использование сети. Таким образом метрики с тысяч серверов могут поместиться в 40 тысяч уникальных временных рядов, а Zabbix может использовать MySQL в качестве бэкенда для данных временных рядов :)


В настоящее время один node_exporter с конфигурациями по умолчанию предоставляет более 500 метрик на среднем хосте. Существует множество экспортеров для различных баз данных, веб-серверов, аппаратных систем и т. д. Все они предоставляют множество полезных показателей. Все больше и больше приложений начинают выставлять различные показатели на себя. Существует Kubernetes с кластерами и pod-ами, раскрывающими множество метрик. Это приводит к тому, что серверы выставляют тысячи уникальных метрик на хост. Таким образом, уникальный временной ряд 40K больше не является высокой мощностью. Он становится мейнстримом, который должен быть легко обработан любой современной TSDB на одном сервере.


Что такое большое количество уникальных временных рядов на данный момент? Наверное, 400К или 4М? Или 40м? Давайте сравним современные TSDBs с этими цифрами.


Установка бенчмарка


TSBS это отличный инструмент бенчмаркинга для TSDBs. Он позволяет генерировать произвольное количество метрик, передавая необходимое количество временных рядов, разделенных на 10 флаг -scale (бывший -scale-var). 10 это количество измерений (метрик), генерируемых на каждом хосте, сервере. Следующие наборы данных были созданы с помощью TSBS для бенчмарка:


  • 400K уникальный временной ряд, 60 секунд интервал между точками данных, данные охватывают полные 3 дня, ~1.7B общее количество точек данных.


  • 4M уникальный временной ряд, интервал 600 секунд, данные охватывают полные 3 дня, ~1.7B общее количество точек данных.


  • 40M уникальный временной ряд, интервал 1 час, данные охватывают полные 3 дня, ~2.8 B общее количество точек данных.



Клиент и сервер были запущены на выделенных экземплярах n1-standard-16 в облаке Google. Эти экземпляры имели следующие конфигурации:


  • vCPUs: 16


  • ОЗУ: 60 ГБ


  • Хранение: стандартный жесткий диск емкостью 1 ТБ. Он обеспечивает пропускную способность чтения/записи 120 Мбит/с, 750 операций чтения в секунду и 1,5К операций записи в секунду.



TSDBs были извлечены из официальных образов docker и запущены в docker со следующими конфигурациями:


  • VictoriaMetrics:


    docker run -it --rm -v /mnt/disks/storage/vmetrics-data:/victoria-metrics-data -p 8080:8080 valyala/victoria-metrics
    

  • Значения InfluxDB (- e необходимы для поддержки высокой мощности. Подробности смотрите в документации):


    docker run -it --rm -p 8086:8086 \-e INFLUXDB_DATA_MAX_VALUES_PER_TAG=4000000 \-e INFLUXDB_DATA_CACHE_MAX_MEMORY_SIZE=100g \-e INFLUXDB_DATA_MAX_SERIES_PER_DATABASE=0 \-v /mnt/disks/storage/influx-data:/var/lib/influxdb influxdb
    

  • TimescaleDB (конфигурация была принята из этого файла):



MEM=`free -m | grep "Mem" | awk {print $7}`let "SHARED=$MEM/4"let "CACHE=2*$MEM/3"let "WORK=($MEM-$SHARED)/30"let "MAINT=$MEM/16"let "WAL=$MEM/16"docker run -it  rm -p 5432:5432 \--shm-size=${SHARED}MB \-v /mnt/disks/storage/timescaledb-data:/var/lib/postgresql/data \timescale/timescaledb:latest-pg10 postgres \-cmax_wal_size=${WAL}MB \-clog_line_prefix="%m [%p]: [%x] %u@%d" \-clogging_collector=off \-csynchronous_commit=off \-cshared_buffers=${SHARED}MB \-ceffective_cache_size=${CACHE}MB \-cwork_mem=${WORK}MB \-cmaintenance_work_mem=${MAINT}MB \-cmax_files_per_process=100

Загрузчик данных был запущен с 16 параллельными потоками.


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


400К уникальных временных рядов


Давайте начнем с простых элементов 400К. Результаты бенчмарка:


  • VictoriaMetrics: 2,6М точек данных в секунду; использование оперативной памяти: 3 ГБ; окончательный размер данных на диске: 965 МБ


  • InfluxDB: 1.2M точек данных в секунду; использование оперативной памяти: 8.5 GB; окончательный размер данных на диске: 1.6 GB


  • Timescale: 849K точек данных в секунду; использование оперативной памяти: 2,5 ГБ; окончательный размер данных на диске: 50 ГБ



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


Ниже приведены графики использования процессора (CPU) для каждого из TSDBs во время бенчмарка:



Выше скриншот: VictoriaMetrics Загрузка CPU при тесте вставки для уникальной метрики 400K.



Выше скриншот: InfluxDB Загрузка CPU при тесте вставки для уникальной метрики 400K.



Выше скриншот: TimescaleDB Загрузка CPU при тесте вставки для уникальной метрики 400K.


VictoriaMetrics использует все доступные vCPUs, в то время как InfluxDB недостаточно использует ~2 из 16 vCPUs.


Timescale использует только 3-4 из 16 vCPUs. Высокие доли iowait и system на TimescaleDB графике временных масштабов указывают на узкое место в подсистеме ввода-вывода (I/O). Давайте посмотрим на графики использования пропускной способности диска:



Выше скриншот: VictoriaMetrics Использование пропускной способности диска при тесте вставки для уникальных показателей 400K.



Выше скриншот: InfluxDB Использование пропускной способности диска при тесте вставки для уникальных показателей 400K.



Выше скриншот: TimescaleDB Использование пропускной способности диска при тесте вставки для уникальных показателей 400K.


VictoriaMetrics записывает данные со скоростью 20 Мбит/с с пиками до 45 Мбит/с. Пики соответствуют большим частичным слияниям в дереве LSM.


InfluxDB записывает данные со скоростью 160 МБ/с, в то время как 1 ТБ диск должен быть ограничен пропускной способностью записи 120 МБ/с.


TimescaleDB ограничена пропускной способностью записи 120 Мбит/с, но иногда она нарушает этот предел и достигает 220 Мбит/с в пиковых значениях. Эти пики соответствуют провалам недостаточной загрузки процессора на предыдущем графике.


Давайте посмотрим на графики использования ввода-вывода (I/O):



Выше скриншот: VictoriaMetrics Использование ввода-вывода при тесте вставки для 400K уникальных метрик.



Выше скриншот: InfluxDB Использование ввода-вывода при тесте вставки для 400K уникальных метрик.



Выше скриншот: TimescaleDB Использование ввода-вывода при тесте вставки для 400K уникальных метрик.


Теперь ясно, что TimescaleDB достигает предела ввода-вывода, поэтому он не может использовать оставшиеся 12 vCPUs.


4M уникальные временные ряды


4M временные ряды выглядят немного вызывающе. Но наши конкуренты успешно сдают этот экзамен. Результаты бенчмарка:


  • VictoriaMetrics: 2,2М точек данных в секунду; использование оперативной памяти: 6 ГБ; окончательный размер данных на диске: 3 ГБ.


  • InfluxDB: 330К точек данных в секунду; использование оперативной памяти: 20,5 ГБ; окончательный размер данных на диске: 18,4 ГБ.


  • TimescaleDB: 480K точек данных в секунду; использование оперативной памяти: 2,5 ГБ; окончательный размер данных на диске: 52 ГБ.



Производительность InfluxDB упала с 1,2 млн точек данных в секунду для 400К временного ряда до 330 тыс. точек данных в секунду для 4M временного ряда. Это значительная потеря производительности по сравнению с другими конкурентами. Давайте посмотрим на графики использования процессора, чтобы понять первопричину этой потери:



Выше скриншот: VictoriaMetrics Использование CPU при тесте вставки для уникального временного ряда 4M.



Выше скриншот: InfluxDB Использование CPU при тесте вставки для уникального временного ряда 4M.



Выше скриншот: TimescaleDB Использование CPU при тесте вставки для уникального временного ряда 4M.


VictoriaMetrics использует почти всю мощность процессора (CPU). Снижение в конце соответствует оставшимся LSM слияниям после вставки всех данных.


InfluxDB использует только 8 из 16 vCPUs, в то время как TimsecaleDB использует 4 из 16 vCPUs. Что общего у их графиков? Высокая доля iowait, что, опять же, указывает на узкое место ввода-вывода.


TimescaleDB имеет высокую долю system. Полагаем, что высокая мощность привела ко многим системным вызовам или ко многим minor page faults.


Давайте посмотрим на графики пропускной способности диска:



Выше скриншот: VictoriaMetrics Использование полосы пропускания диска для вставки 4M уникальных метрик.



Выше скриншот: InfluxDB Использование полосы пропускания диска для вставки 4M уникальных метрик.



Выше скриншот: TimescaleDB Использование полосы пропускания диска для вставки 4M уникальных метрик.


VictoriaMetrics достигали предела 120 МБ/с в пик, в то время как средняя скорость записи составляла 40 МБ/с. Вероятно, во время пика было выполнено несколько тяжелых слияний LSM.


InfluxDB снова выжимает среднюю пропускную способность записи 200 МБ/с с пиками до 340 МБ/с на диске с ограничением записи 120 МБ/с :)


TimescaleDB больше не ограничена диском. Похоже, что он ограничен чем-то еще, связанным с высокой долей системной загрузки CPU.


Давайте посмотрим на графики использования IO:



Выше скриншот: VictoriaMetrics Использование ввода-вывода во время теста вставки для уникального временного ряда 4M.



Выше скриншот: InfluxDB Использование ввода-вывода во время теста вставки для уникального временного ряда 4M.



Выше скриншот: TimescaleDB Использование ввода-вывода во время теста вставки для уникального временного ряда 4M.


Графики использования IO повторяют графики использования полосы пропускания диска InfluxDB ограничен IO, в то время как VictoriaMetrics и TimescaleDB имеют запасные ресурсы ввода-вывода IO.


40М уникальные тайм серии


40М уникальные временные ряды были слишком большими для InfluxDB :(


Результаты бечмарка:


  • VictoriaMetrics: 1,7М точек данных в секунду; использование оперативной памяти: 29 ГБ; использование дискового пространства: 17 ГБ.


  • InfluxDB: не закончил, потому что для этого требовалось более 60 ГБ оперативной памяти.


  • TimescaleDB: 330К точек данных в секунду, использование оперативной памяти: 2,5 ГБ; использование дискового пространства: 84GB.



TimescaleDB показывает исключительно низкое и стабильное использование оперативной памяти 2,5 ГБ столько же, сколько и для уникальных метрик 4M и 400K.


VictoriaMetrics медленно увеличивались со скоростью 100 тысяч точек данных в секунду, пока не были обработаны все 40М метрических имен с метками. Затем он достиг устойчивой скорости вставки 1,5-2,0М точек данных в секунду, так что конечный результат составил 1,7М точек данных в секунду.


Графики для 40М уникальных временных рядов аналогичны графикам для 4М уникальных временных рядов, поэтому давайте их пропустим.


Выводы


  • Современные TSDBs способны обрабатывать вставки для миллионов уникальных временных рядов на одном сервере. В следующей статье мы проверим, насколько хорошо TSDBs выполняет выбор по миллионам уникальных временных рядов.


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


  • Узкое место ввода-вывода действительно существует, особенно в хранилищах без SSD, таких как виртуализированные блочные устройства облачных провайдеров.


  • VictoriaMetrics обеспечивает наилучшую оптимизацию для медленных хранилищ с низким уровнем ввода-вывода. Он обеспечивает наилучшую скорость и наилучшую степень сжатия.



Загрузите односерверный образ VictoriaMetrics и попробуйте его на своих данных. Соответствующий статический двоичный файл доступен на GitHub.


Подробнее о VictoriaMetrics читайте в этой статье.


Обновление: опубликована статья, сравнивающая производительность вставки VictoriaMetrics с InfluxDB с воспроизводимыми результатами.


Обновление#2: Читайте также статью о вертикальной масштабируемости VictoriaMetrics vs InfluxDB vs TimescaleDB.


Обновление #3: VictoriaMetrics теперь с открытым исходным кодом!


Телеграм чат: https://t.me/VictoriaMetrics_ru1

Подробнее..

Перевод Как использовать grok exporter для создания метрик prometheus из неструктурированных журналов

30.06.2020 10:05:46 | Автор: admin

Здесь будет перевод 2 постов про grok exporter.


Первый перевод: Как использовать grok exporter для создания метрик prometheus из неструктурированных журналов


Поговорим о grok exporter. В этой статье я объясню, как можно использовать grok exporter для создания метрик prometheus из неструктурированных журналов.



Grok популярен для обработки журналов в массовом ELK стеке (ElasticSearch, Logstash, Kibana) и благодаря Fabian Stber для разработки grok exporter.


Вот официальная документация grok exporter => https://github.com/fstab/grok_exporter


Шаг 1: Установите Grok exporter


Давайте получим готовый zip файл grok exporter от https://github.com/fstab/grok_exporter/releases.


  1. Перейдите в раздел релизы (releases) и нажмите на последнюю версию (теперь это v0.2.7).
  2. Затем загрузите zip-файл, соответствующий вашей операционной системе. Моя операционная система это 64-битный Linux. Такова будет команда.

wget https://github.com/fstab/grok_exporter/releases/download/v0.2.7/grok_exporter-0.2.7.linux-amd64.zip

  1. Распакуйте файл и перейдите в извлеченный каталог.
  2. Затем выполните команду ниже, чтобы запустить grok exporter.

[root@localhost grok_exporter-0.2.7.linux-amd64]# ./grok_exporter -config ./config.ymlStarting server on http://localhost.localdomain:9144/metrics

Теперь вы можете посмотреть примеры метрик по адресу http://localhost.localdomain:9144/metrics.


Шаг 2: Давайте обработаем некоторые пользовательские журналы


Давайте исследуем некоторые примеры журналов с Grok exporter. Вот несколько случайных журналов, сделанных мной.


30.07.2016 04:33:03 10.3.4.1 user=Nijil message="logged in"30.07.2016 06:47:03 10.3.4.2 user=Alex message="logged failed"30.07.2016 06:55:03 10.3.4.2 user=Alex message="logged in"30.07.2016 07:03:03 10.3.4.3 user=Alan message="logged in"30.07.2016 07:37:03 10.3.4.1 user=Nijil message="logged out"30.07.2016 08:47:03 10.3.4.2 user=Alex message="logged out"30.07.2016 14:34:03 10.3.4.3 user=Alan message="logged out"

Как вы уже могли догадаться, журнал показывает активность входа пользователя в поле. Теперь мне нужно создать метрику Prometheus из этого.


На Шаге 1 вы, возможно, заметили путь config.xml, который упоминается в стартовой команде grok exporter. Откройте конфигурационный файл и замените содержимое нижеприведенными данными.


global:    config_version: 2input:    type: file    path: ./example/nijil.log  # Specify the location of the your log    readall: true              # This should be True if you want to read whole log and False if you want to read only new lines.grok:    patterns_dir: ./patterns    metrics:    - type: counter      name: user_activity      help: Counter metric example with labels.      match: "%{DATE} %{TIME} %{HOSTNAME:instance} user=%{USER:user} message=\"%{GREEDYDATA:data}\""      labels:          user    : '{{.user}}'server:    port: 9144

Схема вышеприведенной конфигурации сделана внизу.


global:    # Config versioninput:    # How to read log lines (file or stdin).grok:    # Available Grok patterns.metrics:    # How to map Grok fields to Prometheus metrics.server:    # How to expose the metrics via HTTP(S).

Шаг 3: Настройка сердца Grok exporter


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


metrics:    - type: counter      name: user_activity      help: Counter metric example with labels.      match: "%{DATE} %{TIME} %{HOSTNAME:instance} user=%{USER:user} message=\"%{GREEDYDATA:data}\""      labels:          user    : '{{.user}}'

Синтаксис шаблона grok это %{SYNTAX:SEMANTIC}, где SYNTAX это имя шаблона, который будет соответствовать журналу, а SEMANTIC это имя поля для присвоения значения сопоставленному журналу. Возьмем в качестве примера %{HOSTNAME:instance}, HOSTNAME это шаблон grok, который только удаляет IP-часть из журнала, и эта IP-часть сохраняется в экземпляре (здесь вы можете дать любое имя), который вы можете использовать позже. Вы должны отметить, что каждый SYNTAX имеет свою собственную цель, это означает, что вы не можете отказаться от IP-адреса в журнале с синтаксисом даты. И как следует из названия, DATE, TIME, HOSTNAME, USER и GREEDYDATA обрывки даты, времени, имени хоста и "любого сообщения" соответственно.


Вы можете использовать метки, чтобы решить, какая метрика на основе параметров должна быть сгенерирована. Из приведенной выше конфигурации вы можете понять, что метрика основана на имени пользователя. Обратите внимание, что вам нужно использовать семантику синтаксиса (SEMANTIC of the SYNTAX) для метки. Для метрики должно быть по крайней мере два параметра. Здесь мы имеем имя пользователя в одной оси и количество вхождений пользователя в другую ось. Второй параметр определяется на основе счетчика метрического типа. Как и Счетчик (Counter), у grok exporter есть и другие метрические типы, узнайте о них из официальных документов.


А теперь займитесь grok exporter ./grok_exporter -config ./config.yml и откройте метрики в браузере. Вы увидите метрики, созданные с именем user_activity, как мы указали в конфигурационном файле.


# TYPE user_activity counteruser_activity{user="Alan"} 2user_activity{user="Alex"} 3user_activity{user="Nijil"} 2

Построение этой метрики в виде графика в Prometheus выходит за рамки данной статьи. Но это очень просто, вам просто нужно указать конечную точку метрики в конфигурации prometheus, чтобы Prometheus мог удалить данные Метрики и построить график для вас.


Второй перевод по теме grok exporter


Второй перевод: Получение метрик из журналов Apache с помощью grok exporter


Не все приложения создают полезные метрики, но некоторые из них создают журналы.


Существует класс приложений, которые практически не имеют полезных метрик, однако информацию, которую вы хотели бы иметь, можно найти в журналах. Одним из вариантов решения этой проблемы является экспортер grok. Допустим, вы работали с Apache, вот несколько примеров журналов из типичного access.log:


x.x.x.x - - [20/Jan/2020:06:25:24 +0000] "GET / HTTP/1.1" 200 62316 "http://178.62.121.216" "Go-http-client/1.1"x.x.x.x - - [20/Jan/2020:06:25:25 +0000] "GET / HTTP/1.1" 200 16061 "-" "Go-http-client/1.1"x.x.x.x - - [20/Jan/2020:06:25:25 +0000] "GET / HTTP/1.1" 200 16064 "-" "Go-http-client/1.1"x.x.x.x - - [20/Jan/2020:06:25:25 +0000] "GET /blog/rss HTTP/1.1" 301 3478 "-" "Tiny Tiny RSS/19.2 (adc2a51) (http://personeltest.ru/away/tt-rss.org/)"x.x.x.x - - [20/Jan/2020:06:25:26 +0000] "GET / HTTP/1.1" 200 16065 "-" "Go-http-client/1.1"x.x.x.x - - [20/Jan/2020:06:25:26 +0000] "GET /blog/feed HTTP/1.1" 200 3413 "-" "Tiny Tiny RSS/19.2 (adc2a51) (http://personeltest.ru/away/tt-rss.org/)"x.x.x.x - - [20/Jan/2020:06:25:27 +0000] "GET /feed HTTP/1.1" 200 6496 "-" "Emacs Elfeed 3.2.0"x.x.x.x - - [20/Jan/2020:06:25:27 +0000] "GET / HTTP/1.1" 200 62316 "http://178.62.121.216" "Go-http-client/1.1"

Для начала загрузите:


wget https://github.com/fstab/grok_exporter/releases/download/v1.0.0.RC2/grok_exporter-1.0.0.RC2.linux-amd64.zip

распакуйте


unzip grok_exporter-*.zipcd grok_exporter*amd64

настройке:


cat << 'EOF' > config.ymlglobal:    config_version: 2input:    type: file    path: access.log    readall: truegrok:    patterns_dir: ./patternsmetrics:    - type: counter      name: apache_http_response_codes_total      help: HTTP requests to Apache      match: '%{COMBINEDAPACHELOG}'      labels:          method: '{{.verb}}'          path: '{{.request}}'          code: '{{.response}}'server:    port: 9144EOF

и запустите grok exporter:


./grok_exporter -config config.yml

Если вы посетите нас http://localhost:9144/metrics вы увидите метрику:


# HELP apache_http_response_codes_total HTTP requests to Apache# TYPE apache_http_response_codes_total counterapache_http_response_codes_total{code="200",method="GET",path="/"} 5apache_http_response_codes_total{code="200",method="GET",path="/blog/feed"} 1apache_http_response_codes_total{code="200",method="GET",path="/feed"} 1apache_http_response_codes_total{code="301",method="GET",path="/blog/rss"} 1

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


Чтобы сделать небольшую резервную копию, Grok это способ, которым вы можете анализировать строки журнала в Logstash (Logstash это L в стеке ELK). Соответственно, паттерны были написаны для многих распространенных приложений, включая Apache. Экспортер Grok позволяет вам строить на существующем корпусе шаблонов, а также добавлять свои собственные, чтобы извлекать метрики из журналов. COMMMONAPACHELOG наверху, например, определяется как


COMMONAPACHELOG %{IPORHOST:clientip} %{HTTPDUSER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)

что само по себе опирается на множество других паттернов. Так что вы должны быть рады, что вам не придется писать это самому с нуля. Поля меток предоставляют вам шаблон Go (как показано в шаблонах Prometheus alerting и notification) для доступа к этим значениям.


Помимо подсчета строк журнала, экспортер Grok может позволить вам наблюдать размеры событий, такие как количество байтов в ответах:


    - type: summary      name: apache_http_response_bytes      help: Size of HTTP responses      match: '%{COMMONAPACHELOG}'      value: '{{.bytes}}'

Или датчики, например, когда был последний запрос:


    - type: gauge       name: apache_http_last_request_seconds      help: Timestamp of the last HTTP request      match: '%{COMMONAPACHELOG}'      value: '{{timestamp "02/Jan/2006:15:04:05 -0700" .timestamp}}'

Это происходит с помощью функции метки времени (timestamp) grok exporter, которая в основном является time.Parse из Golang. Разбор. Есть также функция деления (divide), если вам нужно преобразовать миллисекунды в секунды.


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


Телеграм чат по метрикам https://t.me/metrics_ru

Подробнее..

Путь разработчика в SRE зачем идти в инфраструктуру и что из этого выйдет

30.06.2020 20:09:15 | Автор: admin
Около года назад я переквалифицировался из .NET-разработчика в SRE. В этой статье делюсь историей о том, как группа опытных разработчиков отложила в сторону C# и пошла изучать Linux, Terraform, Packer, рисовать NALSD и строить IaC, как мы применяли практики экстремального программирования для управления инфраструктурой компании, и что из этого вышло.




В Додо Пицце больше 600 пиццерий в 13 странах мира, а большая часть процессов в пиццериях управляется с помощью информационной системы Dodo IS, которую мы сами пишем и поддерживаем. Поэтому надёжность и стабильность системы важны для выживания.

Сейчас стабильность и надёжность информационной системы в компании поддерживает команда SRE (Site Reliability Engineering), но так было не всегда.

Предыстория: параллельные миры разработчиков и инфраструктуры


Много лет я развивался как типичный fullstack-разработчик (и немного scrum-мастер), учился писать хороший код, применял практики из Extreme Programming и старательно уменьшал количество WTF в проектах, к которым прикасался. Но чем больше появлялось опыта в разработке ПО, тем больше я осознавал важность надёжных систем мониторинга и трейсинга приложений, качественных логов, тотального автоматического тестирования и механизмов, обеспечивающих высокую надёжность сервисов. И всё чаще стал заглядывать через забор к команде инфраструктуры.

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

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

Бермудский треугольник проблем


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

Проблемы разработчиков


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

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



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

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

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

Сейчас это не сложно. В последние годы появилось огромное количество инструментов, которые позволяют программистам заглянуть в мир эксплуатации и ничего не сломать: Prometheus, Zipkin, Jaeger, ELK стек, Kusto.

Тем не менее у многих разработчиков до сих пор есть серьёзные проблемы с теми, кого называют инфраструктурой/DevOpsами/SRE. В итоге программисты:

Зависят от команды инфраструктуры. Это вызывает боль, недопонимание, иногда взаимную ненависть.

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

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

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

Проблемы инфраструктуры


Сложности есть и на другой стороне.

Сложно управлять десятками сервисов и окружений без качественного кода. У нас в GitHub сейчас больше 450 репозиториев. Часть из них не требует операционной поддержки, часть мертва и сохраняется для истории, но значительная часть содержит сервисы, которые нужно поддерживать. Им нужно где-то хоститься, нужен мониторинг, сбор логов, единообразные CI/CD-пайплайны.

Чтобы всем этим управлять, мы ещё недавно активно использовали Ansible. В нашем Ansible-репозитории было:

  • 60 ролей;
  • 102 плейбука;
  • обвязка на Python и Bash;
  • тесты в Vagrant, запускаемые вручную.

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

Причина крылась в том, что этот код не использовал многие стандартные практики в мире разработки ПО. В нём не было CI/CD-пайплайна, а тесты были сложными и медленными, поэтому всем было лень или некогда запускать их вручную, а уж тем более писать новые. Такой код обречён, если над ним работает более одного человека.

Без знания кода сложно эффективно реагировать на инциденты. Когда в 3 часа ночи в PagerDuty приходит алерт, приходится искать программиста, который объяснит что и как. Например, что вот эти ошибки 500 аффектят пользователя, а другие связаны со вторичным сервисом, конечные клиенты его не видят и можно оставить всё так до утра. Но в три часа ночи программистов разбудить сложно, поэтому желательно самому понимать, как работает код, который ты поддерживаешь.

Многие инструменты требуют встраивания в код приложения. Ребята из инфраструктуры знают, что нужно мониторить, как логировать и на какие вещи обращать внимание для трейсинга. Но встроить это всё в код приложения часто не могут. А те, кто могут, не знают что и как встраивать.

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

Проблемы бизнеса


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

Прямые потери от нестабильности системы, связанной с надёжностью и доступностью.
В 2018 году у нас произошёл 51 критический инцидент, а критичные элементы системы не работали в сумме больше 20 часов. В деньгах это 25 млн. рублей прямых потерь из-за несозданных и недоставленных заказов. А сколько мы потеряли на доверии сотрудников, клиентов и франчайзи, подсчитать невозможно, в деньгах это не оценивается.

Расходы на поддержку текущей инфраструктуры. При этом компания поставила перед нами цель на 2018 год: в 3 раза уменьшить стоимость инфраструктуры в пересчёте на одну пиццерию. Но ни программисты, ни DevOps-инженеры в рамках своих команд не могли даже приблизиться к решению этой задачи. Этому есть причины:

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

И что с этим делать?


Как решить все эти проблемы? Решение мы нашли в книге Site Reliability Engineering от Google. Когда прочли, поняли это то, что нам нужно.

Но есть нюанс чтобы всё это внедрить нужны годы, и с чего-то надо начинать. Рассмотрим исходные данные, которые у нас были изначально.

Вся наша инфраструктура почти полностью живет в Microsoft Azure. Есть несколько независимых кластеров для прода, которые разнесены по разным континентам: Европа, Америка и Китай. Есть нагрузочные стенды, которые повторяют продакшн, но живут в изолированной среде, а также десятки DEV-окружений для команд разработчиков.

Из хороших практик SRE у нас уже были:

  • механизмы мониторинга приложений и инфраструктуры (спойлер: это мы в 2018 думали, что они хорошие, а сейчас уже всё переписали);
  • процессы для дежурств 24/7 on-call;
  • практика ведения постмортемов по инцидентам и их анализ;
  • нагрузочное тестирование;
  • CI/CD-пайплайны для прикладного софта;
  • хорошие программисты, которые пишут хороший код;
  • евангелист SRE в команде инфраструктуры.

Но были и проблемы, которые хотелось решить в первую очередь:

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

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

Есть программисты, а есть инженеры инфраструктуры. Несмотря на то, что у нас достаточно хорошо была развита культура DevOps, всё ещё было это разделение. Два класса людей с абсолютно разным опытом, которые говорят на разных языках и пользуются разными инструментами. Они, конечно, дружат и общаются, но часто не понимают друг друга из-за совершенно разного опыта.

Онбординг SRE-команды


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

На проект мы выделили 4 месяца и поставили три цели:

  1. Обучить программистов тем знаниям и навыкам, которые необходимы для дежурств и операционной деятельности в команде инфраструктуры.
  2. Написать IaC описание всей инфраструктуры в коде. Причём это должен быть полноценный программный продукт с CI/CD, тестами.
  3. Пересоздать всю нашу инфраструктуру из этого кода и забыть про ручное накликивание виртуалок мышкой в Azure.

Состав участников: 9 человек, 6 из них из команды разработки, 3 из инфраструктуры. На 4 месяца они должны были уйти из обычной работы и погрузиться в обозначенные задачи. Чтобы поддерживать жизнь в бизнесе, ещё 3 человека из инфраструктуры остались дежурить, заниматься операционкой и прикрывать тылы. В итоге проект заметно растянулся и занял больше пяти месяцев (с мая по октябрь 2019-го года).

Две составляющие онбординга: обучение и практика


Онбординг состоял из двух частей: обучения и работы над инфраструктурой в коде.

Обучение. На обучение выделялось минимум 3 часа в день:

  • на чтение статей и книг из списка литературы: Linux, сети, SRE;
  • на лекции по конкретным инструментам и технологиям;
  • на клубы по технологиям, например, по Linux, где мы разбирали сложные случаи и кейсы.

Ещё один инструмент обучения внутреннее демо. Это еженедельная встреча, на которой каждый (кому есть, что сказать) за 10 минут рассказывал о технологии или концепции, которую он внедрил в нашем коде за неделю. Например, Вася поменял пайплайн работы с Terraform-модулями, а Петя переписал сборку образов на Packer.

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



Практика. Вторая часть онбординга создание/описание инфраструктуры в коде. Эту часть разделили на несколько этапов.



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

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

Написание кода. Сюда входило само написание кода, создание CI/CD-пайплайнов, тестов и построение процессов вокруг всего этого. Мы написали код, который описывал и умел создавать с нуля нашу дев-инфраструктуру.

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

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

Наши инструменты для IaC
  • Terraform для описания текущей инфраструктуры.
  • Packer и Ansible для создания образов виртуальных машин.
  • Jsonnet и Python как основные языки разработки.
  • Облако Azure, потому что у нас там хостинг.
  • VS Code IDE, для которой создали единые настройки, расширенный набор плагинов, линтеров и прочего, чтобы писать унифицированный код и расшарили их между всеми разработчиками.
  • Практики разработки одна из основных вещей, ради которой затевался весь этот карнавал.


Практики Extreme Programming в инфраструктуре


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

Нет ни одного программиста, который бы не использовал хотя бы несколько из практик Extreme Programming, даже если он об этом не знает. При этом в мире инфраструктуры данные практики обходят стороной, несмотря на то, что они в очень большой степени пересекаются с практиками из Google SRE.

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

Всё могло бы сложиться хорошо, но так не бывает.

Технические и антропогенные проблемы на пути


В рамках проекта было два вида проблем:

  • Технические: ограничения железного мира, недостаток знаний и сырые инструменты, которыми приходилось пользоваться, потому что других нет. Это привычные любому программисту проблемы.
  • Человеческие: взаимодействие людей в команде. Общение, принятие решений, обучение. С этим было хуже, поэтому нужно остановиться подробнее.

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

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

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

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

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

Если хотите собрать именно такую команду, не забудьте позвать сильного Agile- коуча, scrum-мастера, или психотерапевта что больше нравится. Возможно, они помогут.

Итоги онбординга


По итогам проекта онбординга (он завершился в октябре 2019 года) мы:

  • Создали полноценный программный продукт, который управляет нашей DEV-инфраструктурой, с собственным CI-пайплайном, с тестами и прочими атрибутами качественного программного продукта.
  • Удвоили количество людей, которые готовы дежурить и сняли нагрузку с текущей команды. Спустя ещё полгода эти люди стали полноценными SRE. Теперь они могут потушить пожар на проде, проконсультировать команду программистов по НФТ, или написать свою библиотеку для разработчиков.
  • Сместили майндсет в сторону идей SRE. Не только у участников проекта онбординга, но и у тех программистов из продуктовых команд, которые теперь могут разговаривать с нами на одном языке.
  • Сильно устали: и те, кто участвовал в онбординге, и те, кто участвовал в дежурствах.

Вместо выводов: инсайты, не наступайте на наши грабли


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

Инфраструктура пока в прошлом. Когда я учился на первом курсе (15 лет назад) и начинал изучать JavaScript, у меня из инструментов были NotePad ++ и Firebug для отладки. C этими инструментами уже тогда нужно было делать какие-то сложные и красивые вещи.

Примерно так же я ощущаю себя сейчас, когда работаю с инфраструктурой. Текущие инструменты только формируются, многие из них ещё не вышли в релиз и имеют версию 0.12 (привет, Terraform), а у многих регулярно ломается обратная совместимость с предыдущими версиями.

Для меня, как энтерпрайз-разработчика, использовать на проде такие вещи абсурд. Но других просто нет.

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

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

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

Часто под кодом скрываются обычные конфиги и DSL. При этом вся логика происходит где-то глубже, куда нет доступа. Это сильно меняет подход к коду, тестированию и работе с ним.

Не бойтесь пускать разработчиков в инфраструктуру. Они могут привнести полезные (и свежие) практики и подходы из мира разработки ПО. Пользуйтесь практиками и подходами от Google, описанными в книге про SRE, получайте пользу и будьте счастливы.

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

PPS: Эта статья написана по моему выступлению на DevOpsConf осенью 2019 года. С тех пор прошло довольно много времени, и теперь уже точно понятно, что всё было не зря: тойл теперь не съедает бОльшую часть времени инженеров, наша команда теперь может реализовывать крупные долгосрочные проекты по улучшению инфраструктуры в широком смысле, а программисты почти не жалуются на безумных DevOps-инженеров, которые только мешают жить.

PPPS: В этом году конференция, посвящённая DevOps-практикам, будет называться DevOps Live 2020. Изменения коснутся не только названия: в программе будет меньше докладов и больше интерактивных обсуждений, мастер-классов и воркшопов. Рецепты о том, как расти и перестраивать процессы с помощью DevOps-практик. Формат также изменится два блока по два дня и домашние задания между ними.

Чтобы узнать подробнее о том, что будет происходить на DevOps Live и что полезного вынесут инженеры, безопасники, тимлиды и CTO, подписывайтесь на рассылку и следите за публикациями в блоге.
Подробнее..

Блокируем заливку приватных ключей, архивов, больших файлов и не только в Gitlab CE

06.07.2020 10:05:56 | Автор: admin

Git hooks инструмент, помогающий держать в порядке ваш репозиторий. Можно настроить автоматические правила оформления ваших коммитов.


Все вы наверное знаете про pre-commit проверку вашего кода перед коммитом. Но ведь не все можно проверить перед коммитом. Некоторые ограничения хочется использоваться глобально на всем Gitlab.


Кто запутался в pre-commit и pre-receive хуках, в этом посте описываются различия между ними https://blog.gitguardian.com/git-hooks-automated-secrets-detection/ в абзаце "What are git hooks?".


Если у вас Gitlab Enterprise Edition, вы можете настроить хуки, которые описаны в посте через WEB интерфейс.


Но что делать, если у вас Gitlab Community Edition?


В этой статье будут описаны 5 pre-receive хуков, которые выполняются на сервере Gitlab Community Edition:


  • block_confidentials.sh Блокирование отправки приватных ключей и AWS токенов
  • block_file_extensions.sh Блокирование отправки архивов (Regex настраивается)
  • check-large-files.sh Блокирование отправки больших файлов (Размер настраивается)
  • reject-not-allowlist-email.sh Блокирование коммитов с email не из allow списка (Список email доменов настраивается)
  • require-issue.sh Блокирование коммитов без issue в названии (Список issue настраивается)

В основном хуки взяты из репозитория platform-samples в директории pre-receive-hooks (относится к GitHub Enterprise).


Весь исходный код серверных хуков вы можете посмотреть на Github https://github.com/patsevanton/git-server-pre-receive-hooks


Установка на Gitlab


  • Необходимо создать директорию /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d/
  • Скопировать в эту директорию хуки
  • Не забыть выставить права запуска для хуков (chmod +x файл-хука)

Блокирование отправки приватных ключей и AWS токенов


В файле block_confidentials.sh настраиваем список regex_list, который описывает конфиденциальную информацию.


# Define list of REGEX to be searched and blockedregex_list=(  # block any private key file  '(\-){5}BEGIN\s?(RSA|OPENSSH|DSA|EC|PGP)?\s?PRIVATE KEY\s?(BLOCK)?(\-){5}.*'  # block AWS API Keys  'AKIA[0-9A-Z]{16}'  # block AWS Secret Access Key (TODO: adjust to not find validd Git SHA1s; false positives)  # '([^A-Za-z0-9/+=])?([A-Za-z0-9/+=]{40})([^A-Za-z0-9/+=])?'  # block confidential content  'CONFIDENTIAL')

Добавляем в репозиторий приватный ключ, делаем коммит и при git push получаем ошибку.



Блокирование отправки архивов


В файле block_file_extensions.sh настраиваем case *.zip|*.gz|*.tgz, в котором указываются расширения файлов, которые будут блокироваться.


Добавляем в репозиторий zip архив, делаем коммит и при git push получаем ошибку.



Блокирование отправки больших файлов


В файле check-large-files.sh настраиваем параметр maxsize, который указывает размер файла в мегабайтах, выше которого отправка будет блокироваться.


Добавляем в репозиторий файл больше 1 мегабайта, делаем коммит и при git push получаем ошибку.



Блокирование коммитов с email не из allow списка


В файле reject-not-allowlist-email.sh настраиваем список email-доменов, для которых разрешены коммиты.


declare -a DOMAIN_ARRAY=("group1.com" "group2.com")

Меняем почту в git на ту, которой нет в разрешенном списке.


git config user.email user1@group3.com

Добавляем в репозиторий любой файл, делаем коммит и при git push получаем ошибку.



Блокирование коммитов без issue в названии


Этот серверный хук был взят из блога Majilesh.


В файле require-issue.sh настраиваем список commit_format, для которых разрешены коммиты.


commit_format="(JIRA|PROJECTKEY|MULE|ECOM|SAP|XLR-[1-9]+Merge)"

Добавляем в репозиторий любой файл, делаем коммит, в названии которого нет слов из commit_format и при git push получаем ошибку.



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


Telegram чат по Gitlab https://t.me/ru_gitlab

Подробнее..

Никаких кликов интервью с Джессикой Дин о командной строке, автоматизации и DevOps

06.07.2020 12:10:38 | Автор: admin


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


Осенью на нашей конференции DevOops выступала Джессика Дин. Она удивительно разносторонний человек в отношении платформ: обожает Linux, постоянно пользуется Mac и при этом работает в Microsoft. И она очень любит автоматизацию, скрипты и отказ от мышки настолько, что в её дотфайлах уже сотни коммитов.


В трансляции DevOops мы с Михаилом Дружининым (xomyakus) поспрашивали её и об использовании терминала, и о совмещении миров Windows/Linux/Mac, а поскольку дело было на девопс-конференции, к концу разговор свернул ещё и в сторону Kubernetes. А сейчас, прямо перед новым онлайновым DevOops, мне захотелось перевести это интервью на русский, чтобы оно было и в текстовом формате.


Текстовый вариант чуть сокращённый, если предпочитаете посмотреть исходное англоязычное видео, оно вот:



Евгений Трифонов: Я заглянул в твои дотфайлы на GitHub и оказался впечатлён


Джессика Дин: Большое спасибо! Да, это интересный проект, и он продолжает разрастаться, я постоянно добавляю к нему разное. Я фанатка автоматизации, штук, упрощающих любой процесс. Мои дотфайлы так или иначе связаны с этим. Их можно использовать и в Linux, и в Windows Subsystem for Linux (хоть WSL1, хоть WSL2), и на macOS. Они обращаются к 17 разным опенсорсным инструментам. Основная причина, по которой я всем этим занялась упрощение моего рабочего процесса как с точки зрения разработки, так и с точки зрения эксплуатации.


А в последний раз я добавляла туда что-то как спикер, потому что ещё я очень люблю демонстрировать людям реальное демо и код. Я использую VS Code, но зрителям в зале сложно что-то увидеть на тёмном фоне, а у меня обычно включен он, и удобного способа переключаться между профилями не существовало. Поэтому я написала две функции для переключения, чтобы было удобно кодить в тёмном режиме, а потом демонстрировать код со сцены в светлом.


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


Евгений: Мне близки эти идеи, но ощущаю пару проблем. Первая: чем больше всего настраиваю на своём компьютере, тем сложнее мне оказывается при попытке воспользоваться чьим-то чужим, особенно с другой ОС. Наверное, раз твои дотфайлы переносимы между разными ОС, всё проще, но всё же: не было ли такой проблемы?


Джессика: Особо не было. Но ты подкинул мне идею, как я ещё могу улучшить свои дотфайлы. Если я запускаю обычную установку, то ей придётся установить целый набор из упомянутых 17 инструментов. Но тут ещё вопрос, что мне нужно в системе.


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


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


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


Джессика: Порой бывает! У меня даже есть пост со словами Down the Rabbit Hole в заголовке.


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


Действительно, наступает момент, когда ты понимаешь, что решение заняло у тебя слишком много времени. На macOS это оказалось непросто, а если заняться реализацией ещё и для Linux с Windows, то не закончишь никогда. Есть определённые моменты, когда надо спросить себя: Какую пользу я извлеку из этого? Сколько времени сэкономлю, потратив 48 часов на написание штуки, которая экономит каждый раз по три секунды?.


Но ещё есть любопытство, потому что все мы инженеры: Но я ведь уже начал, я не могу сдаться!


Михаил Дружинин: И как тебе удаётся себя остановить?


Джессика: Иногда никак, иногда я пишу до трёх часов ночи! В других случаях я ищу чужой код. Я много занималась опенсорсом, и мне кажется, что мы лучше как инженеры, когда работаем вместе. Я знаю многих, кто любит начинать и писать с нуля и искать свои собственные ответы. Но я добавила в свои дотфайлы 17 других инструментов отчасти потому, что уже есть члены опенсорс-сообщества, у которых уже было что-то нужное мне. Я смогла использовать их код и добавить к нему что-то своё, внеся тем самым собственный вклад.


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


Евгений: У вас там целое сообщество людей, которые смотрят дотфайлы друг друга?


Джессика: Так и есть! Есть треды на Reddit об этом, есть видео в сети.


Ещё меня как-то упомянули в таком треде на Reddit как человека, который работает в Microsoft, пишет дотфайлы под Linux и macOS, выступает о Linux, получал и сертификаты Apple, и звание Windows MVP. Это было собрано в треде под грифом Мы не понимаем. Но я просто люблю работать с другими инженерами и мне неважно, на какой платформе кто работает! Я вношу свой вклад в сообщество dotfiles, до этого делала то же самое с PowerShell (ещё до выхода PowerShell Core, так что это было только для Windows). Сейчас забавно, когда мне приходится снова писать скрипты на PowerShell, столько отличий. Я просто люблю тусоваться в разных сообществах, и dotfiles одно из них.


Евгений: Интересно, что ты любишь Linux и работаешь в Microsoft. В этом нет противоречия, но, наверное, люди часто удивляются?


Джессика: Да! Потому что так было не всегда. Я каким-либо образом связана с Microsoft уже более 10 лет. Изначально работала на их подрядчика. И тогда была совсем другая эпоха с совсем другим руководством компании. Когда я пришла в кампус, у меня были iPhone и Mac и кто-то меня окликнул: Ты случайно не из тех, у кого Mac и iPhone? И я такая, пряча свой рюкзак и комп: Кто-нибудь! Срочно дайте мне Windows Phone! Сбегайте в музей! Я не хочу быть белой вороной! Даже в команде, с которой я работала, подшучивали, потому что меня все знали как любительницу Linux и Apple, хотя в то же время у меня был статус Windows MVP и сертификация.


Я тогда по работе занималась примерно тем же, что и сейчас делаю как advocate, но тогда делала это в онлайне мы называли это вовлечением через социальные сети. Моя работа заключалась в том, чтобы взаимодействовать с сообществом на популярных в IT интернет-ресурсах вроде Reddit и Spiceworks, общаться с теми, у кого были технические вопросы. Это было во времена Microsoft Deployment Toolkit и SCCM. Я помогала людям в этих сообществах, а в то же время была инженером интеграции систем Linux и чинила компьютеры Apple. Так что я всегда пересекала границы платформ. Но тогда это было нетипично.


Сейчас я в Microsoft уже почти 4 года и то, как изменилось направление внутреннего и внешнего развития, взрывает мне мозг каждый день. 10 лет назад я была полезна, работая на подрядчика Microsoft, но из меня вышла бы не очень хорошая сотрудница непосредственно для Microsoft, потому что я любила работать на Linux и Mac, и не собиралась от них отказываться. И 4 года назад они наняли меня после моего выступления о линуксовом веб-сервере. Я такая: Вы в курсе, что я только что говорила про Linux, да? Так что конфликта тут больше нет, хотя и есть определённое прошлое. Это уже совсем другой Microsoft!


Евгений: А что для такого человека, как ты, означало появление Windows Subsystem for Linux? Перевернуло ли это всю твою жизнь? :)


Джессика: Ну, моя главная система для разработки это по-прежнему Mac. Но у меня дома есть и Surface Book. И это действительно сказывается особенно теперь, с WSL 2 и опенсорсным Terminal. У меня может быть и PowerShell, и Ubuntu, и Fedora, и любые другие дистрибутивы, и я могу настраивать разные профили. Я работала с командой WSL с момента его появления.


Мой коллега, Скотт Хансельман, шутил, что он провёл нагрузочное тестирование моего блога, ретвитнув один из моих постов пару лет назад, когда у Windows 10 вышло Fall Creators с обновлением WSL. Шутка была в том, что в блог пришло так много читателей, что он упал и мне пришлось его поднимать. Это был пост о том, как можно взять терминал, дотфайлы, о которых мы говорили, и сделать так, чтобы на WSL всё выглядело идентично тому, что я запускаю на Mac и Ubuntu.


Это взорвало людям мозг. И до сих пор взрывает мозг мне! Мне не пришлось вносить никаких изменений. Код, который я использовала на Ubuntu такой же, какой я использовала на WSL. Поэтому у моих дотфайлов сейчас всего две ветки одна из них называется "WSL", но работает и на Linux, а другая для macOS. Я до сих пор влюбляюсь в свою работу, просто глядя на направление, в котором мы двигаемся. Объединение разработчиков всех платформ.


Евгений: Иногда я ввожу поисковые запросы не в браузере, а в терминале с помощью ddgr. Подозреваю, такой человек, как ты, тоже делает в терминале что-то, что обычно делают иначе?


Джессика: Это правда, особенно в отношении CI/CD-пайплайнов я работаю ещё в DevOps-команде, занимаюсь автоматизацией скриптами, и там могу делать проверки вроде открывается ли такой-то URL. И в моём докладе здесь, на DevOops, есть пример использования curl. Чтобы протестировать такие вещи, я сначала выполняю их локально в терминале до того, как помещу в пайплайн. А в итоге я ощущаю, что могу выполнять такие задачи эффективнее, потому что для меня становится естественным выполнять их из командной строки.


Я уже говорила про мои дотфайлы, что всегда хочу видеть в терминале определённую информацию, и в том числе хочу знать мои внутренний и внешний IP-адреса. Некоторые люди, чтобы узнать свой IP, идут на сайт вроде https://whatismyipaddress.com/. А у меня это просто часть терминала.


Когда-то я не была таким энтузиастом командной строки, и тогда задавала вопрос Зачем тратить столько времени, набирая что-то на клавиатуре. А потом поняла, что если однажды набрал что-то, и оно осталось в истории или было сохранено как функция, то вызвать это гораздо быстрее, чем кликать! Так что теперь мой личный бренд #noclickyclicky.


Михаил: Как ты к этому пришла? Как долго ты шла к осознанию, что печатать быстрее?


Джессика: Примерно 5-6 лет. Работая одновременно и с Linux, и с технологиями Microsoft, я деплоила приложения и с IIS, где было очень много кликанья, и с Linux, где было сплошное печатание. Каждый раз, когда разворачивала на Linux всё шло без проблем, а на IIS всё было гораздо сложнее. В итоге я начала писать скрипты на PowerShell так я ещё дальше зашла в автоматизацию. В общем, это был долгий путь.


Михаил: Какую часть своего рабочего дня ты проводишь в терминале сейчас?


Джессика: Terminal у меня всегда запущен, он всегда открыт в фоне. Я бы сказала, что непосредственно в нём не меньше 50 времени, возможно, больше. А поскольку я пользуюсь DevOps-инструментами, повсюду код: в Codefresh и Azure DevOps Serviсes YAML, в Jenkins Groovy Поэтому у меня ощущение, что я всё время живу либо в командной строке, либо в VS Code, и терминал всегда открыт.


Михаил: Ещё один вопрос, чтобы закрыть эту тему. Vim или Emacs?


Джессика: Vim.


Я знаю некоторых, кто предпочитает Pico, Emacs, nano Не могу представить, зачем может понадобиться работать в nano Я из тех сумасшедших, кто за Vim. А вы как? Vim или Emacs? И в tmux что используете, Ctrl+A или дефолтное Ctrl+B?


Михаил: Vim, Ctrl+B.


Евгений: Vim. К вопросу о нём: другой спикер Себастиан Дашнер сегодня рассказал нам, использует плагин Vimium в браузере и IdeaVim в IntelliJ IDEA. Ты чем-то подобным пользуешься?


Джессика: Нет. Самое нердовское, что я использую это плагин NERDTree. Он добавляет мне файловый менеджер слева и я могу нажать Ctrl+N, чтобы этот менеджер появлялся и скрывался. Ну и ещё я использую таблицу стилей в Vim. У меня есть моя обычная таблица стилей со шрифтами и цветными штуками для терминала, а в Vim свое цветовое оформление. Вроде бы сейчас использую схему wombat Ну, это всё в открытом доступе, можете сами проверить.


Евгени: Мне хочется делать как можно больше с клавиатуры, но хватает ситуаций, когда всё-таки берусь за мышку/тачпэд. А когда идёшь по жизни с девизом #noclickyclicky, какие сценарии могут вынудить всё-таки оторваться от клавиатуры?


Джессика: Мы же уже говорили про DevOps. Если я демонстрирую Azure DevOps и показываю общую картину того, как он работает (а это, по сути, система запуска задач), я открываю то, что мы называем визуальным редактором. Там список задач без всякого YAML, и я пользуюсь мышкой, чтобы его показать В общем, пользуюсь мышью для навигации в браузере, но когда делаю что-то с кодом, мои руки на клавиатуре.


Михаил: Вчера на BOF-сессии о будущем Kubernetes говорили как раз о том, что происходит переход к кликам в браузере, и больше не надо возиться с YAML, больше не нужно быть YAML-разработчиком, спасибо и на этом


Джессика: Прямо как с табуляцией и пробелами!


Михаил: GitHub также выпустил GitHub Actions он тоже визуальный с кликами. Что ты думаешь об этом направлении? Мне кажется, люди так позабудут о клавиатуре.


Джессика: Возможно, это просто говорит моя страсть к командной строке, но если вспомнить, как всё развивалось в последние 10-15 лет, мне кажется, что она никуда не денется.


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


Михаил: Сделать конфигурацию в UI, потом экспортировать в некий код, а потом продолжить что-то с ним делать.


Джессика: Потому что так я могу его ещё и проверить. Я могу разместить его вместе с моим исходным кодом, с моим приложением...


Михаил: посмотреть diff.


Джессика: Да, особенно. Если я собираюсь обновить мой пайплайн, мне нужно посмотреть разницу, что я изменила, особенно если пайплайн сломается. Мне нужна история. Я не уверена, что мы когда-нибудь отойдём от кода. Да, мы будем улучшать и упрощать его, в этом основная цель того же Kubernetes. Он был создан чтобы упрощать. Helm был создан, чтобы упрощать упрощённое. Есть другие инструменты такие как Draft и Skaffold, которые были сделаны, чтобы упростить и его.


В Microsoft у нас есть Azure Dev Spaces, который, судя по роадмапу, в будущем будет работать даже вне Azure, и он был сделан, чтобы работать с ещё большим уровнем абстракции, когда тебе не нужно беспокоиться про Docker или Kubernetes. У тебя просто может быть изолированная песочница. Как разработчице мне не нужно что-либо настраивать и мне не нужно иметь дело с кодом. Мы постоянно работаем над тем, чтобы упростить простое. Мне кажется, мы продолжим двигаться в этом направлении.


Михаил: Как ты думаешь, каким будет следующий конкретный уровень упрощения Kubernetes? На что бы ты поставила?


Джессика: Предсказательница из меня никакая! Я не знаю. Если мы вернёмся в прошлое, виртуализация уже была первым шагом абстракции. Больше не было нужды в физических машинах, теперь можно виртуализировать окружение. Потом при помощи контейнеров виртуализировали ядро и продвинули виртуализацию ещё дальше. Потом оркестрация стала способом управлять и продолжить абстрагировать. У нас есть Serverless. Теперь нас есть возможность объединить Serverless с оркестрацией.


Мне кажется, что дальнейшее направление просто продолжать выводить эту абстракцию к большему упрощению, и это реально очень просто, потому что чем большей абстракции мы достигаем в Kubernetes, тем сложнее всё становится, правильно? Сейчас у меня есть 10 разных микросервисов для одного приложения, в одном из них баг. Как мне провести отладку? Я могу это сделать, используя определенные инструменты и методы, хотя если мы сможем сделать это доступнее, то это именно то направление, куда нам нужно двигаться. Нам нужно быть уверенными, что чем больше мы абстрагируем, тем более полное у нас понимание того, зачем это делать, а почему это делать не надо.


Не всё нужно разбирать до такого мелкого уровня. Не всё надо запускать в Kubernetes. Люди говорят: Kuberenetes во все поля! Зачем? Келси Хайтауэр как-то твитнул, что лучшая часть понимания контейнеров и будущего направления их развития не в том, чтобы понимать, как ими пользоваться, а в том, чтобы понимать, когда ими пользоваться не надо. Мне кажется, это то направление, в котором нам нужно двигаться дальше.


Михаил: Просто перестаньте использовать лямбды, контейнеры, ВМ


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


Другой мой коллега, крупная фигура в Go коммьюнити, Эрик Сент-Мартин, известен своим высказыванием: Kubernetes это не Та Самая Вещь. Это вещь, которая поможет нам достигнуть следующей вещи, а потом та даст добраться до следующей. Это вечно продолжается. Но мы сможем понять, как попасть дальше, только если будем понимать, зачем что-то нам нужно, а почему оно нам не нужно.


Евгений: Вот на этом и остановимся, потому что время на интервью закончилось. Спасибо за ответы!


Уже сегодня в 17:00 стартует новая конференция DevOops: в этот раз в онлайне и пятидневная. Там без слова Kubernetes, конечно, тоже не обойдётся! А ещё будут легенда DevOps Джон Уиллис, ряд докладов про DevOps как культуру, любимец публики Барух Садогурский и многое другое смотрите полную программу, чтобы понять, сколько там актуального лично для вас.
Подробнее..

От Junior до Team Lead за 3 года

02.07.2020 18:23:23 | Автор: admin

Hello, world


Я DevOps-инженер, и я не существую.

Я не существую!?

Потому что DevOps это методология или философия, но никак не специальность. Однако всем в ИТ привычнее закрыть на это глаза и считать, что единороги существуют. Не буду рушить эту по-детски милую и наивную рекрутерскую иллюзию. В компании, в которой я работаю, моя позиция называется Configuration Manager или Инженер Конфигурации Программного Обеспечения. Я думаю, что понятнее вам не стало, да? Окей, давайте по порядку.

Что такое DevOps?


Давайте быстрее, я здесь не молодею

Development+Operations=DevOps

Это если коротко.

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

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

Поэтому взять и выделить DevOps-специалиста с набором обязанностей для достижения Reduce time to market невозможно. Это коллективная работа. Так что чаще всего под DevOps-инженером понимают человека, который делает автоматизацию на проекте, настраивает окружения и мониторинг. Большим плюсом будет, если он будет читать проповеди о культуре взаимодействия, способствовать архитектурным и ретроспективным встречам между разработчиками и отделом эксплуатации. В общем, выступать DevOps-евангелистом.

http://personeltest.ru/away/devopstopologies.ru
devopstopologies.ru

В Романе The Phoenix Project легко и увлекательно рассказывается про этот наш DevOps. Прочёл на одном дыхании.

Начало пути


В ноябре 2016 года я проходил оплачиваемую стажировку в компании ИТСК на позиции Младшего ИТ-Архитектора. В декабре заканчивался 6-месячный срок, после которого меня должны были принять на постоянной основе. Однако за пару месяцев до этого мне сказали:
Если хочешь дальше работать ИТ-архитектором, то нужно иметь 1-2 года опыта работы разработчиком.

Абсолютно адекватное требование. Я бы даже сказал, лет 5 не помешает, но на тот момент я не знал об этом. Я учился на разработчика, и это не вызывало во мне энтузиазма, так что я не искал подобные позиции. И потому предложение пойти писать код, а потом возвращаться, меня не вдохновило. Забавно, конечно, что узнал я о требовании руководства на 5-м из 6-ти месяцев оплачиваемой стажировки.

Я начал подумывать переступить через своё не хочу и устроиться разработчиком, как до меня дошло спросить у друга Серёги, DevOps-инженера:

Я: Серёга, а что ты делаешь на работе?
СЕРЁГА (DEVOPS-ИНЖЕНЕР): Ну там, это.

Бинго! Это же то, что мне нужно. Не разработка, но ИТ, а значит, я в этом что-то понимаю или научусь понимать, я же сам себе ПК собрал. Главное не писать код, упаси C#. Сергей как раз менял место работы в декабре и порекомендовал меня на замену, но даже не позвонили. Тогда я начал самостоятельный поиск.

***

В январе пошёл снег, а я на первый собес, где мне отказали из-за слабого английского. Тогда Серёга снова порекомендовал меня, но на новом месте работы. Меня не стали рассматривать из-за отсутствия опыта. Потом ещё собес с отказом. И тут мне крайне повезло, что есть такая компания, как EPAM с вечерней DevOps-школой и трудоустройством по окончанию обучения. Это большая интернациональная компания, работы в которой навалом, а специалистов конфигурации ПО с мышлением DevOps в то время было ещё меньше чем сейчас. Возможно, что они первые в России открыли подобные курсы, тем более бесплатные.

В феврале прошёл отбор, и в конце месяца началось обучение. Занимались трижды в неделю по вечерам. Отбор в школу прошли 20 человек. ~15 были со стороны, а остальные уже работали в компании. Заявок всего было ~120. Подготовиться к отбору мне помогли курсы по Linux, DB и Python на степике и, конечно же, бакалавриат в ИТМО. А ещё Серёга учил меня, как работать в Jenkins, и вселил уверенность в свои силы.

А вот с этим резюме я искал работу. С поправкой на возраст. Сорян за инглиш. Как умел, братцы. Ну а почему 40 тыс., потому что ниже обычно не давали младшим специалистам в то время. Вот я скромненько и указал нижнюю планку.

Резюме




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

***

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

Так и запишем

И вот в мае Серёга, который тоже не сдавался (потому что я у него занимал деньги), в третий раз порекомендовал меня. В этот раз на новую позицию в T-Systems, где были готовы взять и обучить джуна, который понимает основы. А благодаря школе EPAM я получил нужный базис. Чутка успел подкачать английский, который всё равно был ужасен, но собеседовавший меня мой будущий People Manager, стиснув извилины, смог понять, что же я там плету, вставляя герундий туда, куда приличные люди не вставляют. Спасибо, Илья, что поверил в мой лингвистический и технический потенциал.

Забавно, что в день собеса мой будущий тимлид был в отпуске и ему меня сосватали не глядя.

Иван Степаныч радуется
Иван Степаныч радуется

Junior DevOps


17 мая 2017 года мой первый рабочий день джуном. В команде я и тимлид. Через месяц приняли в команду третьего. Потом разрослись до 6 человек через год.

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

Вот базис начинающего специалиста: Jenkins, Linux Administration, Bash, Git. Потом желательно Docker, Kubernetes и/или OpenShift, Ansible, Python.

Само собой, знать сразу всё невозможно. Например, Docker мне на начальных этапах не был нужен, но понимание концепции от меня ожидали и спрашивали на собеседовании. Да и никто не говорит о глубоком опыте в Linux или, о ужас, попросить установить и настроить Jenkins. Так, уметь тыкать в интерфейс, понимать, как его можно использовать в первом приближении. Обучаешься в процессе решения рабочих задач.

А чем старше проект, тем меньше в нём того, что в желательной части и больше Bash. Всё обмотать длинными спагетти Bash-кода излюбленная автоматизация столь близкого нам прошлого. Как говорится: Знаешь Bash? Тогда Иди работай!.

I'll be bash

Конечно, в мире ИТ каждому инструменту есть альтернатива и не одна. Так что единого стека технологий даже в рамках одной компании не бывает, хотя и стараются. Подготовиться к определённому стеку технологий можно месяца за два неспешного изучения раза 2 в неделю. Ко всему месяца за четыре раза 3 в неделю.

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

Dashboard

Здесь пригодился опыт в HTML, CSS, JavaScript, Python. Но если бы не умел, то и не стал бы делать. Так что на заметку можно взять только Python.

Middle DevOps


Прошло 10 месяцев, и меня повысили до просто инженера. Здесь важно понимать, что в каждой компании своё понимание того кто такой Junior (младший), Middle (средний) и Senior (старший). И разные зарплатные вилки на позиции. Слышал как-то, что в некую компанию взяли парня джуном за зарплату сеньора. Я понятия не имею, правда ли это, но не исключаю подобного.

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

Отдел эксплуатации
Как себе представляет специалиста эксплуатации гуманитарий. P.S. Гуманитарии, я вас люблю

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

А ещё специфика способна сделать больно, если её создавали не вы. Но главное вовремя вспомнить, что мы способны изменить мир, а изменить специфику нет.

Шучу.

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

Senior DevOps


Через год, а именно в апреле 2019 года, я повысился до сеньора-помидора. Как говорится: хочу салат не вижу препятствий. Ещё говорят, что с большой силой приходит большая ответственность. Вообще, справедливо. Только в профессиональной стезе наоборот: сначала ответственность, а потом подтягивается сила и уверенность. То есть сначала нужно иметь смелость замахнуться на слона и уже потом, на пути, дорасти до его ушей.

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

С одной стороны, это этап прокачки вглубь, с другой стороны, так как я стал сеньором уже через два года работы, то мне ещё расширяться и расширяться. Правильнее судить годами. Так вот прокачка вглубь идёт где-то после лет 3-5, если стек не меняется.

Но мир IT изменчивый: сегодня ты пишешь код на Python, а завтра от соискателей требуют прогрессивный Go, поэтому глубинная прокачка всегда сменяется изучением новых инструментов.

Однако побыть сеньором мне не дали

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

Это Гарольд нашёл меня
Это Гарольд нашёл меня

Вы ожидаете, что здесь будет раздел с названием Team Lead DevOps? А нет, повышение так не работает. Повышают не чаще раза в 9 месяцев, но это в моей компании. Где-то повышают раз в полгода, где-то в год. А вообще, спланировать график повышения невозможно наверняка, так как он зависит от твоих успехов и чуткости руководителей. Можно и за два года не получить повышение.

Однако функции тимлида пришлось выполнять уже сейчас. Первые 3-4 месяца было особенно напряжно и непривычно. Куча коммуникаций. Множество задач у всей команды, в которых нужно ориентироваться. Постоянно приходят тестеры и разработчики и что-то спрашивают или просят сделать. А так как на мне большая база знаний, то делегировать без обучения не получается. Написанные инструкции ситуацию не спасают. Среди более опытных коллег ощущаешь себя не на своём месте. Вместе с этим появляются новые микросервисы, где нужна наша помощь. В общем, потно-плотно.

***

В октябре 2019 поехали в Германию, чтобы встретиться с коллегами из Польши и Немеции. Да, я взял на себя роль тимлида, но только лишь питерской команды. Ещё по двое коллег были из этих стран. И формально, тимлид всей команды был в Германии. К сожалению, по большей части формально.

В октябре мы поняли, какой жуткий рассинхрон у нас произошёл.

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

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

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

***

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

Пары, вставай

Так вышло, что он не был DevOps специалистом изначально в проекте. Он начал как разработчик и затем постепенно перешёл в Инженеры Конфигурации ПО. И, вероятно, неожиданно сам для себя стал тимлидом в 2017 году. Так что выбрать DevOps-школу было верным для него решением.

Однако тогда я думал, что причиной послужила ситуация на проекте

***

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

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

Новые обязанности выполнял я, откровенно говоря, не очень. Только отошёл от шока тимлидства в Санкт-Петербурге, как теперь ещё плюс две локации. К тому же полноценным руководителем я себя не ощущал: функции тимлида нигде не описаны, примера для подражания не было. На что опираться?

Поэтому как я могу руководить всеми? Да ещё более опытными иностранными коллегами. К своим я постепенно привык и освоился, а тут новая партия подъехала. И ладно бы партия стандартного калибра, так ведь один из снарядов такой бронебойной силы, что чуть отвернёшься, а у тебя чат 30-ю сообщениями завален от него и новая Bash-портянка готова. Bash это хорошо, Bash это здорово. Однако нужно понимать, когда нужно использовать Bash, а когда другой язык или инструмент.

***

В январе 2020 приехало повышение за июнь. Снова ожидаете Team Lead DevOps заголовка? А не будет его. Тимлид это роль, а не должность. Так что вряд ли вам напишут в трудовую книжку руководительский подвиг в технической команде. Вам нужно в Project Manager'ы для этого идти.

Получается, что тимлидом может быть и джун. А меня повысили до

Expert DevOps


Январь и февраль прошли. Вернулся немецкий тимлид. Наконец-то! , подумал я. За это время у меня сложилась картина, что нужно делать, чтобы повысить нашу эффективность: как правильно создавать дорожную карту, распределять задачи, выстраивать коммуникации, обсуждать, проверять чужие решения.

А я уже представляю, как всё это ему рассказываю. Как он кивает головой, говорит: Sure, и вокруг нас расцветает малина.

Но нифига.

Вернувшись в проект, тимлид не забирает на себя свои обязанности, типа проведение созвона для сбора статуса. Не интересуется задачами коллег. Не инициирует беседу, если видит что-то непонятное для себя. Ведет себя абсолютно пассивно. Я понимаю: первую неделю или две, но ведь уже апрель.

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

И под конец апреля выясняется, что текущий тимлид ещё зимой принял решение уйти в другой проект, где проходил практику от DevOps-школы. Только теперь на позицию специалиста эксплуатации.

Тут мне стало понятно почему он так легко отнёсся к отжиму обязанностей с моей стороны.

Наши дни


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

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

Каковы мои дальнейшие возможности? Их несколько.

  1. Ничего не менять с точки зрения позиции. Продолжать лидить, параллельно изучая новые инструменты и углубляя знания. Рано или поздно дойти до позиции архитектора по DevOps профилю.
  2. Перейти в другую команду и снять с себя роль тимлида. Сосредоточиться на изучении новых инструментов и прокачиваться как инженер. Рано или поздно дойти до позиции архитектора по DevOps профилю и роли тимлида.
  3. Пойти в менеджерскую ветку. Мне предлагали рассмотреть роль Scrum-мастера. Неожиданно, правда? Однако сейчас такой возможности уже нет, ввиду организационной трансформации в компании в матричную структуру. Вообще, это не единственный способ перейти в менеджмент в T-Systems, однако подробности за рамками этой статьи.

Позиция руководителя мне привычна и вызывает больший отклик. Тактики, стратегии, психология и социология one love. Однако здесь важно быть увлечённым проектом/продуктом. Что для меня задача не из простых. Чтобы вы понимали что я за человек: я мог бы открыть точки продажи кофе, пиццерии, производство пластиковых упаковок, свою криптобиржу, однако я не хочу делать то, что или деструктивно, или вредно, или бесполезно. Даже если это окупается моментально или приносит сверхприбыли.

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

Так что или 1-ый или 2-ой вариант. Желаю себе успехов на одном из них!

Ты красавчик!

Послесловие и благодарности


Вообще, я бы хотел стать знаменитым певцом

Directed by
*Играет музыка*

Ну что поделать всему своё время. Сначала научусь петь.

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

Кстати, есть ещё одна возможность стать DevOps-инженером быстро и безболезненно.

В сентябре планируем открыть набор в DevOps-школу в T-Systems. Точнее будет понятно в начале или середине августа. Участие бесплатное и с трудоустройством после успешного завершения. Из требований: Linux на уровне пользователя и английский. В программу обучения входят упомянутые и неупомянутые в статье инструменты: Kubernetes, OpenShift, Jenkins, GitLab, Ansible, стек для мониторинга и ещё немного других полезностей.

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

За мой карьерный путь, наставничество и чуткость руководства благодарю моего бывшего тимлида питерской команды Сергея Жекписова (я капец как многому у тебя научился!), моего пипл менеджера Илью Семерханова, руководителя направления Дмитрия Жаркова и моих коллег, когда-либо работавших вместе со мной.

Сергей Ли, без тебя я бы и не начал этот путь. Ты знаешь мою благодарность, дружище.

Большое спасибо Иномджону Мирджамолову за первое прочтение и предложенные правки в данной статье, а также отделу коммуникаций T-Systems.

Моя текущая команда, вы суперские, мужики! Жму ваши виртуальные руки.
Подробнее..

Капля в море Запуск Drupal в Kubernetes

26.06.2020 20:05:42 | Автор: admin

image


Я работаю в компании Initlab. Мы специализируемся на разработке и поддержке Drupal проектов. У нас есть продукт для быстрого создания Ecommerce решений, основанный на Drupal. В 2019 году мы начали решать задачу построения масштабируемой и отказоустойчивой инфраструктуры для нашего продукта.


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


Часть статьи является переводом статьи Джеффа Герлинга. Со своей стороны добавили более подробное описание вариантов запуска баз данных и отказоустойчивого хранилища в кластере.


Drupal и Docker


image


Drupal и Docker могут работать вместе и хорошим примером тут служат локальные среды разработки, построенные вокруг Docker, такие как Docksal, Ddev, Lando и DrupalVM. Но локальные среды разработки, в которых кодовая база Drupal в основном монтируется, как том в контейнер Docker, сильно отличаются от рабочей среды, где цель состоит в том, чтобы вместить как можно большую часть кода в stateless контейнер.


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


Что такое 12 Factor Apps?


image


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


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


Но 12-факторное приложение это приложение, которое облегчает развертывание и управление в масштабируемой среде:


  • Сохраняет всю свою конфигурацию в декларативном формате, так что нет никаких ручных или неавтоматизированных шагов установки.
  • Не слишком сильно связано с одним типом операционной системы или со сложностями настройки алгоритмического языка и среды выполнения.
  • Может масштабироваться от одного до нескольких реплик с минимальным (в идеале нулевым) вмешательством.
  • Практически одинаково как в производственной, так и в непроизводственной среде.
  • 12-факторному приложению могут потребоваться базы данных, общие файловые системы и другие элементы, но в идеале оно может работать так, что сводит к минимуму затраты при работе с этими элементами.

Условия размещения Drupal в Kubernetes


Чтобы превратить приложение или веб-сайт на Drupal в более безликое 12-факторное приложение, необходимо соблюсти пять главных условий:


  1. База данных должна быть постоянной. Данные должны сохраняться между запусками контейнеров.
  2. Каталог файлов Drupal должен быть постоянным, масштабируемым и общим для всех веб-контейнеров.
  3. Установка Drupal и агрегация CSS и JS должны иметь возможность сохранять данные в каталогах с файлами Drupal-сайта.
  4. Настройки Drupal settings.php и другие важные настройки должны настраиваться установкой значений переменных среды.
  5. Задание cron в Drupal следует запускать через Drush, чтобы иметь возможность запускать его наиболее эффективным и масштабируемым образом.

Выполнение условий размещения Drupal в Kubernetes


1. База данных


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


Управляемый сервис баз данных


Самый простой и наиболее часто применяемый способ использование сервиса управляемых баз данных: AWS RDS Aurora или Cloud SQL в Google Cloud. В этом случае, мы можем подключить свой сайт на Drupal напрямую к управляемой базе данных.


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


Docker образ mysql


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


MySQL Operator


Проект MySQL Operator предназначен для упрощения процесса размещения базы в кластере. Не работает в последних версиях kubernetes, начиная с 1.16. Кроме того, в каждой версии Kubernetes могут вноситься значительные изменения в API, из-за чего проект требуется адаптировать к новым версиям, что разработчики не всегда успевают делать.


Percona XtraDB Cluster Operator


Альтернатива MySQL Operator это решение Percona XtraDB Cluster Operator. Percona XtraDB Cluster объединяет в себе Percona Server для MySQL, работающий с механизмом хранения XtraDB, и Percona XtraBackup с библиотекой Galera, для обеспечения синхронной multi-master репликации.


image


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


Helm chart для MariaDB


Более простым для запуска базы данных в кластере Kubernetes может быть использование Helm chart для MariaDB, которое позволяет развернуть в Kubernetes реплицированный кластер MariaDB. В данном кластере развертывается один master, а остальные slave контейнеры, с которых возможно чтение данных. В отличии от multi-master репликации, при отказе master контейнера будет остановке сервиса, на время запуска нового мастера.


PostgreSQL


Если рассматривать СУБД PostgreSQL, то существует проект Stolon облачный менеджер для обеспечения высокой доступности кластера PostgreSQL.


При деплое баз данных под MySQL или PostgreSQL, в Kubernetes, нужно где-то сохранять файлы с фактическими данных. Наиболее распространенный способ подключить Kubernetes PV (Persistent Volume) к контейнеру MySQL.


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


2. Каталог файлов Drupal


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


  • Когда во время установки Drupal перезаписывается файл settings.php.
  • Когда во время установки Drupal не проходит предварительную проверку установщика, если каталог сайта (например sites/default) не доступен для записи.
  • Если при создании кеша тем Drupal требуется доступ на запись в каталог публичных файлов, чтобы он мог хранить сгенерированные файлы Twig и PHP.
  • Если используется агрегация CSS и JS, Drupal требуется доступ на запись в каталог публичных файлов, чтобы он мог хранить сгенерированные файлы js и css.

Существует несколько вариантов решения этих задач.


NFS


Самое простое решение всех этих задач, позволяющее Drupal масштабировать и запускать более одного экземпляра Drupal это использовать NFS для папки файлов Drupal (например sites/default/files). Однако легче не значит лучше. У NFS есть свои особенности:


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

Облачное хранилище совместимое с S3


Можно использовать сервис хранения типа Amazon S3 в качестве общедоступной файловой системы для своего Drupal сайта, что снизит затраты на поддержку хранилища и повысит его надежность. Для интеграции S3 хранилища с drupal можно использовать, например, модуль S3FS.


Распределенные файловые системы


Также можно использовать распределенные файловые системы, такие как Gluster или Ceph. Однако тут увеличивается сложность поддержки таких решений, которые можно решить в Kubernetes с помощью проекта rook.


Проект Rook


image


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


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


Rook управляет несколькими решениями для хранения, предоставляя общую платформу для всех из них. Rook гарантирует, что все они будут хорошо работать в Kubernetes:


  • Ceph
  • EdgeFS
  • CockroachDB
  • Cassandra
  • NFS
  • Yugabyte DB

3. Установка Drupal


image


Сделать файл settings.php доступным для записи во время установки более сложная задача, особенно если вам нужно установить Drupal, а затем развернуть новый образ контейнера ( что произойдет со всеми записанными значениями settings.php? Они будут удалены при перезапуске контейнера! ). Поэтому решение данной задачи получило отдельный пункт описания особенностей запуска Drupal в Kubernetes.


Пользователи могут устанавливать Drupal через веб-интерфейс мастера установки или автоматически через Drush. В любом случае Drupal во время установки, если еще не установлены все правильные переменные в settings.php, добавляет некоторые дополнительные конфигурации к файлу sites/default/settings.php или создает этот файл, если его не существует.


Следующие параметры должны быть предварительно установлены в settings.php, чтобы Drupal автоматически пропускал экран установки и не требовал записи дополнительных конфигураций в файл settings.php:


// Config sync directory.$config_directories['sync'] = '../config/sync';// Hash salt.$settings['hash_salt'] = getenv('DRUPAL_HASH_SALT');// Disallow access to update.php by anonymous users.$settings['update_free_access'] = FALSE;// Other helpful settings.$settings['container_yamls'][] = $app_root . '/' . $site_path . '/services.yml';// Database connection.$databases['default']['default'] = [  'database' => getenv('DRUPAL_DATABASE_NAME'),  'username' => getenv('DRUPAL_DATABASE_USERNAME'),  'password' => getenv('DRUPAL_DATABASE_PASSWORD'),  'prefix' => '',  'host' => getenv('DRUPAL_DATABASE_HOST'),  'port' => getenv('DRUPAL_DATABASE_PORT'),  'namespace' => 'Drupal\Core\Database\Driver\mysql',  'driver' => 'mysql',]

В данном примере используются переменные окружения (например: DRUPAL_HASH_SALT) с функцией PHP getenv() вместо "жестко" заданных значений в файле. Это позволяет контролировать настройки, которые Drupal использует как при установки, так и для новых контейнеров, которые запускаются после установки Drupal.


В файле Docker Compose, чтобы передать переменные, указываются директива environment для контейнера web/Drupal следующим образом:


services:  drupal:    image: drupal:latest    container_name: drupal    environment:    DRUPAL_DATABASE_HOST: 'mysql'    [...]    DRUPAL_HASH_SALT: 'fe918c992fb1bcfa01f32303c8b21f3d0a0'

А в Kubernetes, когда создаете Drupal Deployment, передать переменные среды можно с помощью envFrom и ConfigMap (предпочтительно), также можно напрямую передавать переменные среды в спецификации контейнера:


---apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: drupal  [...]spec:  template:    [...]    spec:    containers:        - image: {{ drupal_docker_image }}        name: drupal        envFrom:        - configMapRef:            name: drupal-config        env:            - name: DRUPAL_DATABASE_PASSWORD            valueFrom:                secretKeyRef:                name: mysql-pass                key: drupal-mysql-pass

Приведенный выше фрагмент манифеста предполагает, что уже в kubernetes есть ConfigMap с именем drupal-config содержащей все DRUPAL_* переменные, кроме пароля к базе данных, а также секрет, названный mysql-pass, с паролем в ключе drupal-mysql-pass.


На этом этапе, если создаете новую среду с помощью Docker Compose локально или в кластере Kubernetes, можете перейти к установщику пользовательского интерфейса или использовать Drush. При этом не требуется вводить учетные данные базы данных, поскольку эти и другие необходимые переменные уже предварительно настроены.


4. Конфигурация Drupal, управляемая средой


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


5. Выполнение заданий Cron Drupal в Kubernetes


image


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


Внутри Kubernetes не нужно настраивать crontab ни на один из узлов Kubernetes, работающих с сайтами Drupal. И хотя может быть внешняя система, например Jenkins, запускающая задания cron на Drupal сайте, гораздо проще просто запускать Cron Drupal как Kubernetes CronJob, в идеале в том же пространстве имен Kubernetes, что и Drupal.


Самый надежный способ запуска Drupal cron через Drush, но запуск отдельного контейнера Drush через CronJob означает, что CronJob должен запланировать сложный контейнер, работающий как минимум на PHP и Drush. Поды CronJob должны быть максимально легкими, чтобы их можно было планировать на любом системном узле и запускать очень быстро (даже если ваш контейнер Drupal еще не был загружен на этот конкретный узел Kubernetes).


Cron Drupal поддерживает запуск путем посещения URL-адреса, и это самый простой вариант для работы с Kubernetes. Пример настройки CronJob:


---apiVersion: batch/v1beta1kind: CronJobmetadata:  name: drupal-cron  namespace: my-drupal-sitespec:  schedule: "*/1 * * * *"  concurrencyPolicy: Forbid  jobTemplate:    spec:    template:        spec:        containers:        - name: drupal-cron            image: byrnedo/alpine-curl:0.1            args:            - -s            - http://www.my-drupal-site.com/cron/cron-url-token        restartPolicy: OnFailure

URL drupal_cron_url зависит от сайта и можно его найти, посетив страницу /admin/config/system/cron. Убедитесь, что в настройках cron для Run cron every установлено значение Never, чтобы cron запускался только через CronJob Kubernetes.


Можно использовать byrnedo/alpine-curl образ докера, который является чрезвычайно легким всего 5 или 6 МБ так как он основан на Alpine Linux. Большинство других контейнеров, которые есть на базе Ubuntu или Debian, имеют размер, по крайней мере, 30-40 МБ (так что они будут использовать гораздо больше времени, чтобы загрузить первый раз, когда CronJob запускается на новом узле).


Заключение


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

Подробнее..

Перевод Остановитесь!!! Вам не нужны микросервисы

29.06.2020 04:15:17 | Автор: admin

Идет 2020 год. Если вам нужно пояснение, что такое микросервисы лучше потратьте свое драгоценное время на что-то другое. Но если вы впечатлены историями успеха о микросервисах и хотите нырнуть в "панацею" с головой продолжайте читать. Прошу прощения, будет немного длинновато (не очень, прим. переводчика).


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


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


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

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


Впервые о микросервисах я узнал еще в 2013 году, это был ролик на YouTube, где пояснялась архитектура сервисов Netflix. Было весьма впечатляюще, но я пропустил все без сожаления, поскольку это было слишком сложно для меня, человека, который тогда только начал постигать принципы разработки. Скоро это стало навязчивой идеей, поскольку на новом проекте объявили о внедрении микросервисов. Разработка проекта была увлекательной, он до сих пор остается лучшим по кодовой базе из тех, что попадали ко мне.


Честно говоря, широкие возможности модульной разработки были где-то далеко от меня, и я просто добавил дополнительный уровень сложности, будучи невежественным разработчиком, скрывавшимся от DevOps. Спустя пять лет я уже работаю с совершенно новым продуктом и другими людьми. У меня куча проблем, возникших из-за плохо разработанных микросервисов, приправленных тактикой девопсов-любителей (девляпсов?, прим. переводчика). Пелена довольно скоро спала, обнажив хрупкость микросервисов. Также я начал смотреть на всю эту архитектуру более опытным взглядом. Было поздно, но лучше поздно, чем никогда.


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


Ваше приложение достаточно большое, чтобы дробить его на микросервисы?


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



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


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


Нужно ли на самом деле масштабировать отдельные компоненты приложения?


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



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


Есть ли транзакции, распределенные между сервисами?


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


Cервисы REST не имеют состояния по определению, а также не должны участвовать в транзакциях, которые проходят по нескольким сервисам. В мире высокой производительности двухфазный коммит (2PC) ненужное зло. Шаблон SAGA добавляет еще один уровень сложности, к которому вы не будете готовы.


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

Возможно ли иметь распределенные по сервисам транзакции?


Да, конечно.


Стоит ли делать цепочку действий поверх сервисов без состояния (stateless)?


Возможно, не стоит!!


Есть ли нужда в частом общении между сервисами?


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


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


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


Кое-что ещё


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

Следует помнить, что усредненная организация в IT не обладает такими же навыками, как команды инженеров Netflix. mike_pfeiffer

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


  • Внедрение DevOps может быть как полезным, так и вредным. DevOps проверенное и широко распространенное решение, но если вы работаете в маленькой компании, создание команды DevOps может принести больше вреда, чем пользы. Но одно можно сказать точно нельзя поддерживать и управлять микросервисами без команды DevOps.


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


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


  • Сквозное тестирование. Типичное монолитное приложение позволяет запускать и запускать тест практически мгновенно. Наличие нескольких служб с взаимозависимостью задержит тестирование без жизнеспособной оркестровки.


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


  • Устаревшая кодовая база давайте будем честными. Для большинства из нас работа с устаревшей кодовой базой это повседневная деятельность. Это хлеб с маслом большинства организаций. Быстро меняющиеся технологические достижения ставят нас впереди всех, но и в то же время они изолируют нас от устаревшей кодовой базы. Вы уверены, что только что разработанный фреймворк, использующий RabbitMQ, хорошо работает с устаревшим приложением, работающим на AIX?


  • Устранение неполадок каждый сервис будет иметь свой собственный набор файлов журналов для анализа. Больше сервисов = больше файлов.



Заключение


Я здесь, чтобы сказать "Не используйте микросервисы"?


Конечно же, нет!!


Микросервисы заслужили известность. Они решили проблемы, которые считались неразрешимыми. История Netflix по применению микросервисов вдохновила многих. И список определенно не останавливается на Netflix. Uber, SoundCloud и гигантский Amazon вот некоторые примеры, которые у всех на слуху. И не думайте, что истории успеха ограничиваются только потребительскими приложениями. Я имел непосредственный опыт работы с американским гигантом здравоохранения и был очарован возможностями дизайна, каждый раз, когда открывал исходный код.


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


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


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

Подробнее..

Изоляция и бункер (Silos) для хранилищ данных в мультиарендных (multitenant) решениях

01.07.2020 06:12:44 | Автор: admin

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

AWS в качестве платформы для SaaS решений обладает большой вариативностью для хранилищ данных. Но, как и везде, грамотная настройка безопасности, проработка multitenant-архитектуры под неё, настройка различных уровней изоляций требуют определенных знаний и понимания специфики работы.

Multitenant хранилища данных


Управлять multitenant данными удобно с помощью бункеров, Silo. Основная особенность разделение арендных данных (далее tenant) в multitenant решениях SaaS. Но перед тем, как поговорить о конкретных кейсах, затронем немного общей теории.

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

Доступ должен быть только у одного tenant


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

Отраслевые стандарты шифрования и безопасности


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

Настройка производительности на основании подписки tenant


Обычно, провайдеры SaaS рекомендуют общий рабочий процесс для всех tenant. С точки зрения практики, это не всегда может быть удобно по отношению к конкретной бизнес-логике. Поэтому можно сделать по-другом. Каждому tenant присваивают разные наборы свойств и пределы производительности в зависимости от стандарта TIER. Чтобы клиенты получали ту производительность, которая заявлена в соглашении SaaS провайдерам приходиться отслеживать использование индивидуальных tenant. Благодаря этому все клиенты получают равноценный доступ к ресурсам.

Скрытый текст
Естественно, это отразится на счетах клиента. Тот, кто использует больше ресурсов, заплатит больше.

Управление данными


С ростом SaaS-сервиса растет и количество tenant. Если клиент меняет провайдера, чаще всего он хочет, чтобы все данные перезалили на другой ресурс, а старые удалили. Если первое желание можно оспорить, то исполнение второго гарантируется Общими правилами Евросоюза по защите данных. Для корректного исполнения правил, SaaS провайдер должен изначально идентифицировать массивы данных отдельных tenant.

Скрытый текст
Почему стоит упомянуть именно регламент Евросоюза и касается ли он компаний из России?! Да, если жители Евросоюза будут пользоваться услугами компаний, которые собирают персональные данные. А это примерно треть крупных компаний из России. Но подобную тему стоит наверное выделить в отдельную статью и расписать подробнее.

Как превратить обычное Хранилище данных в multitenant


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

  • Соглашение об обслуживании;
  • Шаблоны доступа для чтения и записи;
  • Соответствие нормативам;
  • Расходы.

Но есть ряд общепринятых практик разделения и изоляции данных. Рассмотрим эти кейсы на примере реляционной БД Amazon Aurora.

Секционирование tenant данных в общих хранилищах и инстансах



Таблица используется всеми tenant. Индивидуальные данные разделены и идентифицированы ключом tenant_id. Авторизация в реляционной БД реализована на уровне строк (row-level security). Доступ к приложению работает на основании политики доступа и учитывает конкретный tenant.

Плюсы:

  • Это недорого.

Минусы:

  • Авторизация на уровне базы данных. Это подразумевает несколько механизмов авторизации в рамках решения: AWS IAM и политики БД;
  • Для идентификации tenant придется разработать логику приложения;
  • Без полной изоляции невозможно обеспечить выполнение соглашения TIER об обслуживании;
  • Авторизация на уровне БД ограничивает возможности отслеживания доступа с помощью AWS CloudTrail. Это можно компенсировать только добавлением информации извне. А лучше бы заниматься отслеживанием и устранением неполадок.

Изоляция данных на общих instance



Арендность (tenancy) по-прежнему расшаривается на уровне инстанса. Но при этом бункеризация данных происходит на уровне базы данных. Благодаря этому возможна аутентификация и авторизация AWS IAM.

Плюсы:

  • Это недорого;
  • За аутентификацию и авторизацию полностью отвечает AWS IAM;
  • AWS IAM позволяет вести журнал аудита на AWS CloudTrail без костылей в виде отдельных приложений.

Минусы:

  • Базовые инстансы БД шарятся между tenant, в связи с этим возможен отток ресурсов, что не позволяет полностью исполнить соглашение TIER об обслуживании.

Изоляция инстансов базы данных для tenant



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

Плюсы:

  • AWS IAM обеспечивает как аутентификацию, так и авторизацию;
  • Есть полноценный аудит;
  • Четкое распределение ресурсов между tenant.

Минусы:

  • Изоляция БД и инстансов среди tenant это дорого.

Как реализован доступ приложений к multitenant данным


Обеспечить правильный доступ приложений к данным важнее, чем хранить данные в модели арендной изоляции (tenant), которая соответствует бизнес-требованиям. Это не сложно, если использовать AWS IAM для управления доступом (см. примеры выше). Приложения, которые обеспечивают доступ к данным для tenant также могут использовать AWS IAM. Это можно рассмотреть на примере Amazon EKS.

Чтобы обеспечить доступ к IAM на уровне pod в EKS, прекрасно подойдёт OpenID Connect (OIDC), вместе с аннотациями к учетной записи Kubernetes. В результате произойдет обмен JWT с STS, что создаст временный доступ приложений к необходимым облачным ресурсам. При таком подходе нет необходимости вводить расширенные разрешения для базовых рабочих узлов Amazon EKS. Вместо этого можно настроить только разрешения IAM для учетной записи, связанной с pod. Это делается на основе фактических разрешений приложения, которое работает как часть pod. В итоге получаем полный контроль разрешений приложений и pod.

Скрытый текст
А благодаря тому, что AWS CloudTrail регистрирует каждое обращение EKS pod к API, можно вести детальный журнал событий.

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

Amazon EKS получает доступ к multitenant БД AWS DynamoDB




Пристальней посмотрим на multitenant доступ, как приложение, работающее на Amazon EKS, получает доступ к multitenant базе данных Amazon DynamoDB. Во многих случаях multitenant процессы в Amazon DynamoDB реализуют на уровне таблиц (в соотношении таблиц и tenant 1:1). Как пример рассмотрим принцип AWS IAM (aws-dynamodb-tenant1-policy), который отлично иллюстрирует шаблон доступа, где все данные связаны с Tenant1.

{   ...   "Statement": [       {           "Sid": "Tenant1",           "Effect": "Allow",           "Action": "dynamodb:*",           "Resource": "arn:aws:dynamodb:${region}-${account_id}:table/Tenant1"       }   ]}


Следующий шаг связать эту роль с учетной записью кластера EKS, которая использует OpenID.

eksctl utils associate-iam-oidc-provider \      --name my-cluster \      --approve \      --region ${region}

eksctl create iamserviceaccount \      --name tenant1-service-account \      --cluster my-cluster \      --attach-policy-arn arn:aws:iam::xxxx:policy/aws-dynamodb-tenant1-policy \      --approve \      --region ${region}

Определение pod, содержащее необходимую спецификацию serviceAccountName, поможет использовать новую учетную запись службы tenant1-service-account.

apiVersion: v1kind: Podmetadata: name: my-podspec:serviceAccountName: tenant1-service-account containers: - name: tenant1

Несмотря на то, что учетная запись и политика IAM tenant ориентированы, статичны и управляются с помощью таких инструментов, как Terraform и Ansible, спецификацию pod можно настроить динамично. Если вы используете генератор шаблонов, например, Helm, serviceAccountName можно установить в качестве переменной в соответствующие учетные записи tenant служб. В итоге у каждого tenant будет свое выделенное развертывание одного и того же приложения. Фактически, у каждого tenant должно быть выделенное пространство имен, где и будут запускаться приложения.

Скрытый текст
Эти же методы можно реализовать с помощью Amazon Aurora Serverless, Amazon Neptune и контейнеров Amazon S3.

Заключение


Для SaaS-услуг важно хорошо продумать, как будет осуществляться доступ к данным. Следует учесть требования к хранилищу, шифрованию, производительности и управлению со стороны tenant. В multitenant нет какого-то одного предпочтительного способа разделения данных. Преимуществом выполнения multitenant рабочих нагрузок на AWS является AWS IAM, который можно использовать для того, чтобы упростить контроль доступа к tenant данным. К тому же, AWS IAM поможет настроить доступ приложений к данным в динамическом режиме.

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

Продуктовый разворот от фигачечной к сознательной работе инженеров

02.07.2020 16:18:36 | Автор: admin
Весна 2020 показала, что благодаря DevOps-практикам многие бизнесы смогли быстро перестроить продукты и перейти в онлайн, сохранив работоспособность. Оказалось, что от зрелости практик DevOps зависят не только результаты бизнеса, но и само его выживание.

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

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



Основные измеряемые характеристики DevOps это стабильность работы приложений и производительность IT-команд, от идеи до выкладки фичи на продакшн. Поэтому мы много говорим о time to market и мониторинге и продолжаем технический трек.

А ещё IT-команды состоят из живых людей, которые не только могут выдавать хорошие KPI, а ещё и делают заведомо полезную работу. Ведь если DevOps-подход завоевал популярность в мире, то, наверное, это кому-то нужно. Для вас мы повстречались с Product Owners и бизнесменами, которые не всегда знают, что такое DevOps (как будто мы знаем :D) и расспросили их о том, что же им важно получить от технарей. В чём эта самая польза.

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

Вот какие гипотезы мы проверяли на встречах:

  • TTM важен для интересов Product Owner-а.
  • Стабильность работы приложения влияет на бизнесовые показатели.
  • Разработчики зачастую не согласны с мнением PO о том, что и как делать.
  • TTM помогает проводить CustDev. Речь не о технике интервью, а о поиске и подтверждении потребностей клиентов и построении компании.

Я беседую через с Zoom со своей давней знакомой, которая убеждена, что человеку, который ни разу в жизни не продавал, нечего делать в профессии Product Owner. Она часто появляется в передачах на радио и ТВ, проводит семинары по своей предметной области. Как только режим самоизоляции был облегчён, они с мужем и ребёнком арендовали дом на берегу великолепного озера и на всё лето переехали жить и работать туда. Её компания почти 20 лет на рынке онлайн-услуг. На первом месте по рейтингам в своей предметной области.

Скажи пожалуйста, проводишь ли ты специальную работу по сокращению цикла разработки и запуска фич в продакшн в своей команде?

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

Погоди, 6 часов?! Это...

От первой беседы с командой до пользователя. Т.е. уже на проде.

Зачем тебе такая скорость?

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

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

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

Внезапно я стал экспертом по удалёнке этой весной! (смеётся)

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

Когда мы с техдиром начали эту работу, ещё не были в ходу такие термины, как LTV, customer retention или unit economy. Просто мы представили, что пользователи не очень довольны падением приложения 20% времени...

Во, NPS!

Андрей, не было никакого NPS. Сейчас это технологизированный индикатор того, насколько довольны пользователи. Он не покажет мне деньги. Он не покажет, каково отношение затрат на какой-либо проект и отдачи в деньгах от его реализации.

Тебе именно это отношение важно?

Мне важен рост аудитории. Т.е. её лояльность и приверженность к моему продукту.

Что-то ещё? Как маркетинг связан с аптаймом?

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

Т.е. для тебя сейчас важно, чтобы приложение было доступно.

Сейчас я спокоен, потому что наш аптайм 4,5 девятки. В течение месяца приложение исправно отвечает на 99,995% запросов.

DevOps сделал своё дело, DevOps может...

DevOps ещё и не это может. В какой-то момент мы посчитали, что наш способ развития, через изменения в лаборатории и проверку на фокус-группах, дороже, чем проверка на малых долях аудитории. Вместо того, чтобы разработать прототип, собрать фокус группу и получить одобрение, а потом на живых пользователях увидеть их разочарование, я могу быстро-быстро проверить трипять вариантов на 0,1% пользователей и выбрать лучший.

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

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

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

Поэтому для нас важно управлять техдолгом. Можно сказать, что между бизнесом и IT есть контракт: в течение года не менее 30% времени разработки идёт на разгребание долга. Причём, эти проценты мы считаем совокупно за год. Например, весной 2020 мы перекрыли работу с техдолгом полностью, потому что нам была важна скорость изменения продукта. Нам пришлось искать новые модели использования наших сервисов.

Значит ли это, что за оставшиеся полгода ребята будут уже 40% времени заниматься рефакторингом, изменением архитектуры и выпиливанием костылей, а также работать с производительностью приложения?

Абсолютно.

Дальше Игорь рассказал, что у него появилась возможность работать на опережение. Значительная часть задач направлена на освоение новых технологий и интерфейсов. Первые результаты экспериментов уже доступны пользователям, например общение на естественном языке. При этом на сегодняшний день скорее можно говорить о Research части R&D. Компания осваивает технологии заранее, чтобы использовать момент зрелости технологий искусственного интеллекта для получения конкурентного преимущества.

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

  • Продуктовые. Product owner может включить или отключить фичу, а также раскатать её на заданный процент пользователей или даже конкретный список.
  • Настройки взаимодействия сервисов это зона ответственности разработчиков.
  • Админские, их крутит команда, которая занимается инфраструктурой.

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

Мы также созвонились с ребятами, которые ведут продукт в компаниях, где потенциал для развития DevOps намного больше. Они запускают стартапы или работают на крупного заказчика. Другими словами и больше через боль, они говорили о тех же ценностях для Product Owner-а, что и предыдущие собеседники.

Мы обнаружили, что находки нашего исследования подтверждают те выводы, которые есть в в отчете Google The 2019 Accelerate State of DevOps: Elite performance, productivity, and scaling (версия на русском).

Мы выделили четыре основные ценности для Product Owner-ов при использовании DevOps:

  • Предсказуемость времени реализации фичи и уверенность в качестве софта это необходимая база для активных экспериментов.
  • Надёжность работы прода = деньги. Когда трафик попадает на работающее приложение, то это не только позволяет рационально использовать бюджет на продвижение, но ещё и повышает лояльность пользователей, а значит и долю на рынке.
  • Скорость экспериментов определяет успех как для стартапа, так и для бизнеса со зрелым продуктом. Если стартапу важно быстро обнаружить предпочтения пользователей и удачные ответы на них, то зрелому продукту нужно удержание пользователей, стабильность массовой выручки и research работа на будущее технологий.
  • Доверие к разработчикам и взаимное доверие разработчиков к продакту. Партнёрские отношения между IT подразделением и бизнес юнитами, когда заключается контракт о способах взаимодействия и этот договор исполняют обе стороны. В терминах DevOps это управление техдолгом, поддержка кода в порядке и вовлечение команды в интерес своих пользователей.

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

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

Большинство активностей на конференции сделаем интерактивными, потому что говорящих голов достаточно в интернете. Ведь каждый сознательный инженер может не только найти видео докладов по нужной ему тематике, но и прочитать статьи (например, статьи по следам всех DevOpsConf в профиле Александра Титова).

Наша цель этой осенью дать каждой компании возможность высадить виртуальный десант из Product Owner-ов, техлидов и инженеров всех мастей. Так, чтобы IT-спецназ сориентировался на местности и вернулся в работу с разработанным планом захвата Вселенной!

В следующих статьях расскажем про CTO, разработчиков и безопасников зачем конференция им.
DevOps Live пройдет онлайн 29-30 сентября и 6-7 октября 2020. В онлайне будет всё, за что сообщество любит наши конференции, и при этом мы вместе исследуем новые возможности онлайна.

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

Новый HAProxy Data Plane API два примера программной конфигурации

02.07.2020 10:04:35 | Автор: admin

Новый HAProxy Data Plane API: два примера программной конфигурации


Используйте HAProxy Data Plane API для динамического управления конфигурацией балансировщика нагрузки с помощью HTTP-команд.


Проектирование для высокой доступности почти всегда означает наличие высокого уровня прокси / балансировщика нагрузки. Прокси-сервер предоставляет основные услуги, такие как:


  • обнаружение и удаление неисправных серверов
  • очередь соединений
  • разгрузка шифрования TLS
  • компрессия
  • кэширование

Задача состоит в том, чтобы поддерживать ваши конфигурации в актуальном состоянии, что особенно сложно, поскольку сервисы перемещаются в контейнеры, и эти контейнеры становятся эфемерными. Доступный начиная с HAProxy 2.0 вы можете использовать новый HAProxy Data Plane API (Перевод: http://personeltest.ru/aways/habr.com/ru/post/508132/), который является современным REST API.


HAProxy Data Plane API дополняет гибкий язык конфигурации HAProxy, который предоставляет строительные блоки для определения простых и сложных правил маршрутизации. Это также идеальное дополнение к существующему Runtime API, которое позволяет запускать, останавливать и пропускать трафик с серверов, изменять вес сервера и управлять проверками работоспособности.


Новый Data Plane API дает вам возможность динамически добавлять и настраивать внешние интерфейсы, внутренние интерфейсы и логику маршрутизации трафика. Вы также можете использовать его для обновления конечных точек ведения журнала и создания фильтров SPOE. По сути, почти весь балансировщик нагрузки может быть настроен с помощью HTTP-команд. В этой статье вы узнаете, как лучше его использовать.


Управление конфигурацией


Обычно при настройке HAProxy вам нужно вручную отредактировать файл конфигурации /etc/haproxy/haproxy.cfg. Этот файл используется для управления всеми функциями балансировщика нагрузки. Он в основном разделен на frontend разделы, определяющие общедоступные IP-адреса, к которым подключаются клиенты, и backend разделы, содержащие вышестоящие сервера, на которые направляется трафик. Но вы можете сделать гораздо больше, в том числе установить глобальные параметры, влияющие на работающий процесс, установить значения по умолчанию, добавить анализ поведения трафика с помощью таблиц флеш-памяти, прочитать файлы карт, определить правила фильтрации с помощью ACL и многое другое.


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


В этом случае крайне важно иметь возможность вызвать HTTP API для динамического обновления определений прокси. В сервисной сетке программное обеспечение Data Plane контролирует прокси и динамически вызывает API конфигурации. HAProxy Data Plane API позволяет интегрировать HAProxy с этими платформами. Более того, API использует API времени выполнения для внесения изменений, которые по возможности не требуют перезагрузки.


Data Plane API использует Go пакеты config-parser и client-native для парсинга конфигурации HAProxy и вызова команд Runtime API соответственно. Вы можете использовать их в своих собственных проектах для интеграции с HAProxy.


Динамическое конфигурирование HAProxy


С помощью Data Plane API вы можете многое сделать. В этом разделе вы узнаете, как создать backend с серверами и frontend, который направляет трафик на него. Но сначала следуйте официальной документации по установке и настройке API.


После того как он будет установлен и запущен, вызовите GET в конечной точке /v1/services/haproxy/configuration/backends, чтобы увидеть уже определенные разделы backend, например:


$ curl --get --user admin:mypassword \    http://localhost:5555/v1/services/haproxy/configuration/backends

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


Вызовите endpoint /v1/services/haproxy/transactions для создания новой транзакции. Для этого потребуется параметр версии в URL, но командам внутри транзакции он не нужен. Всякий раз, когда вызывается команда POST, PUT или DELETE, должна быть включена версия, которая затем записывается в файл конфигурации HAProxy. Это гарантирует, что если несколько клиентов будут использовать API, они избежать конфликтов. Если версия, которую вы передаете, не соответствует версии, указанной в файле конфигурации, вы получите сообщение об ошибке. При использовании транзакции эта версия указывается заранее при ее создании.


$ curl -X POST --user admin:mypassword \       -H "Content-Type: application/json" \       http://localhost:5555/v1/services/haproxy/transactions?version=1

Вы найдете идентификатор транзакции в возвращенном документе JSON:


{"_version":5,"id":"9663c384-5052-4776-a968-abcef032aeef","status":"in_progress"}

Затем используйте endpoint /v1/services/haproxy/configuration/backends, чтобы создать новый бэкэнд, отправив идентификатор транзакции в качестве параметра URL:


$ curl -X POST --user admin:mypassword \       -H "Content-Type: application/json" \       -d '{"name": "test_backend", "mode":"http", "balance": {"algorithm":"roundrobin"}, "httpchk": {"method": "HEAD", "uri": "/", "version": "HTTP/1.1"}}' \            http://localhost:5555/v1/services/haproxy/configuration/backends?transaction_id=9663c384-5052-4776-a968-abcef032aeef

Затем вызовите endpoint /v1/services/haproxy/configuration/servers для добавления серверов в backend:


$ curl -X POST --user admin:mypassword \       -H "Content-Type: application/json" \       -d '{"name": "server1", "address": "127.0.0.1", "port": 8080, "check": "enabled", "maxconn": 30, "weight": 100}' \       "http://localhost:5555/v1/services/haproxy/configuration/servers?backend=test_backend&transaction_id=9663c384-5052-4776-a968-abcef032aeef"

Затем добавьте frontend с помощью endpoint /v1/services/haproxy/configuration/frontends :


$ curl -X POST --user admin:mypassword \       -H "Content-Type: application/json" \       -d '{"name": "test_frontend", "mode": "http", "default_backend": "test_backend", "maxconn": 2000}' \       http://localhost:5555/v1/services/haproxy/configuration/frontends?transaction_id=9663c384-5052-4776-a968-abcef032aeef

У этого frontend еще нет никаких bind операторов. Добавьте одно, используя endpoint /v1/services/haproxy/configuration/binds, как на примере:


$ curl -X POST --user admin:mypassword \       -H "Content-Type: application/json" \       -d '{"name": "http", "address": "*", "port": 80}' \       "http://localhost:5555/v1/services/haproxy/configuration/binds?frontend=test_frontend&transaction_id=9663c384-5052-4776-a968-abcef032aeef"

Затем, чтобы зафиксировать транзакцию и применить все изменения, вызовите endpoint /v1/services/haproxy/transactions/[transaction ID] с помощью PUT, например:


$ curl -X PUT --user admin:mypassword \       -H "Content-Type: application/json" \       http://localhost:5555/v1/services/haproxy/transactions/9663c384-5052-4776-a968-abcef032aeef

Вот как выглядит конфигурация сейчас:


frontend test_frontend    mode http    maxconn 2000    bind *:80 name http    default_backend test_backendbackend test_backend    mode http    balance roundrobin    option httpchk HEAD / HTTP/1.1    server server1 127.0.0.1:8080 check maxconn 30 weight 100

Этот балансировщик нагрузки готов принимать трафик и перенаправлять его на вышестоящий сервер.


Поскольку в спецификации Data Plane API используется OpenAPI, его можно использовать для генерации клиентского кода на многих поддерживаемых языках программирования.


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


Другой пример


Вы увидели простоту и мощь HAProxy Data Plane API. С помощью нескольких HTTP-команд вы можете динамически изменять конфигурацию. Давайте рассмотрим другой пример. Мы создадим ACL, который будет проверять имеет ли заголовок Host значение example.com. Если это так, то строка use_backend будет направлена на другой сервер с именем example_servers. Мы также добавим правило http-request deny, которое будет отклонять любые запросы для пути URL /admin.php, если исходный IP-адрес клиента не находится в сети 192.168.50.20/24.


Сначала используйте endpoint /v1/services/haproxy/transactions для создания новой транзакции и получения ее идентификатора:


$ curl -X POST --user admin:mypassword \       -H "Content-Type: application/json" \        http://localhost:5555/v1/services/haproxy/transactions?version=2{"_version":2,"id":"7d0d6737-655e-4489-92eb-6d29cdd69827","status":"in_progress"}

Затем используйте endpoint /v1/services/haproxy/configuration/backends вместе с идентификатором транзакции, чтобы создать новый backend с именем example_servers:


$ curl -X POST --user admin:mypassword \       -H "Content-Type: application/json" \       -d '{"name": "example_servers", "mode":"http", "balance": {"algorithm":"roundrobin"}}' \       http://localhost:5555/v1/services/haproxy/configuration/backends?transaction_id=7d0d6737-655e-4489-92eb-6d29cdd69827

Используйте endpoint /v1/services/haproxy/configuration/servers для добавления server в backend:


$ curl -X POST --user admin:mypassword \       -H "Content-Type: application/json" \       -d '{"name": "server1", "address": "127.0.0.1", "port": 8081, "check": "enabled", "maxconn": 30, "weight": 100}' \       "http://localhost:5555/v1/services/haproxy/configuration/servers?backend=example_servers&transaction_id=7d0d6737-655e-4489-92eb-6d29cdd69827"

Используйте endpoint /v1/services/haproxy/configuration/acls, чтобы определить ACL с именем is_example, который проверяет, имеет ли заголовок узла значение example.com:


$ curl -X POST --user admin:mypassword \       -H "Content-Type: application/json" \       -d '{"id": 0, "acl_name": "is_example", "criterion": "req.hdr(Host)", "value": "example.com"}' \       "http://localhost:5555/v1/services/haproxy/configuration/acls?parent_type=frontend&parent_name=test_frontend&transaction_id=7d0d6737-655e-4489-92eb-6d29cdd69827"

Используйте /v1/services/haproxy/configuration/backend_switching_rules, чтобы добавить строку use_backend, которая оценивает ACL is_example:


$ curl -X POST --user admin:mypassword \       -H "Content-Type: application/json" \       -d '{"id": 0, "cond": "if", "cond_test": "is_example", "name": "example_servers"}' \       "http://localhost:5555/v1/services/haproxy/configuration/backend_switching_rules?frontend=test_frontend&transaction_id=7d0d6737-655e-4489-92eb-6d29cdd69827"

Используйте endpoint /v1/services/haproxy/configuration/http_request_rules, чтобы добавить правило http-request deny, которое проверяет, является ли путь /admin.php, а исходный IP-адрес клиента не находится в сети 192.168.50.20/24:


$ curl -X POST --user admin:mypassword \       -H "Content-Type: application/json" \       -d '{"id": 0, "cond": "if", "cond_test": "{ path /admin.php } !{ src 192.168.50.20/24 }", "type": "deny"}' \       "http://localhost:5555/v1/services/haproxy/configuration/http_request_rules?parent_type=frontend&parent_name=test_frontend&transaction_id=7d0d6737-655e-4489-92eb-6d29cdd69827"

Затем подтвердите транзакцию, чтобы изменения вступили в силу:


$ curl -X PUT --user admin:mypassword \       -H "Content-Type: application/json" \       http://localhost:5555/v1/services/haproxy/transactions/7d0d6737-655e-4489-92eb-6d29cdd69827

Ваша конфигурация HAProxy теперь выглядит вот так:


frontend test_frontend    mode http    maxconn 2000    bind *:80 name http    acl is_example req.hdr(Host) example.com    http-request deny deny_status 0 if { path /admin.php } !{ src 192.168.50.20/24 }    use_backend example_servers if is_example    default_backend test_backendbackend example_servers    mode http    balance roundrobin    server server1 127.0.0.1:8081 check maxconn 30 weight 100backend test_backend    mode http    balance roundrobin    option httpchk HEAD / HTTP/1.1    server server1 127.0.0.1:8080 check maxconn 30 weight 100

Заключение


В этой статье вы ознакомились с HAProxy Data Plane API, который позволяет полностью настроить HAProxy с использованием современного REST API. Более подробную информацию можно найти в официальной документации (Перевод: http://personeltest.ru/aways/habr.com/ru/post/508132/). У него имеются три мощных функции, которые включают гибкий язык конфигурации HAProxy и API времени выполнения. Data Plane API открывает двери для многостороннего использования, в частности, с использованием HAProxy в качестве уровня прокси в сетке сервиса.


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


Если вам понравилась эта статья и вы хотите быть в курсе похожих тем, подпишитесь на этот блог. Вы также можете подписаться на нас в Твиттере и присоединиться к разговору на Slack. HAProxy Enterprise позволяет легко приступить к работе с Data Plane API, поскольку его можно установить в виде удобного системного пакета. Он также включает в себя надежную и передовую кодовую базу, корпоративный набор дополнений, экспертную поддержку и профессиональные услуги. Хотите узнать больше? Свяжитесь с нами сегодня и скачайте бесплатную пробную версию.


P.S. Телеграм чат HAproxy https://t.me/haproxy_ru

Подробнее..

Готовим PostgreSQL в эпоху DevOps. Опыт 2ГИС. Павел Молявин

07.07.2020 10:10:24 | Автор: admin


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




Работаю я в подразделении, которое занимается веб-разработкой. Команда моя называется Infrastructure & Operations, сокращенно IO. Мы занимаемся поддержкой инфраструктурой для веб-разработки. Предоставляем свои сервисы командам как сервис и решаем все проблемы внутри нашей инфраструктуры.



Stack, который мы используем, технологии очень разнообразные. В основном это Kubernetes, мы пишем на Golang, на Python, на Bash. Из баз данных мы используем Elasticsearch, используем Cassandra и, конечно, используем Postgres, потому что мы его очень любим, это один из базовых элементов нашей инфраструктуры.



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


Мой доклад будет не про внутренности Postgres, не про работу внутри Postgres, а о том, как мы строим инфраструктуру вокруг него. Казалось бы, все просто берешь и делаешь, но на самом деле нет, все гораздо сложнее. Я расскажу об этом.



Начнем с постановки задачи. У нас продуктовые команды пишут приложения. Количество приложений постоянно растет. Приложения раньше мы писали в основном на PHP, Python и на Java Scala. Потихоньку к нам незаметно вползли модные языки типа Golang, без Node.js тоже сейчас никуда, тем более во FrontEnd.


В качестве хранилищ данных для наших приложений мы выбрали Postgres. Были предложения использовать MySQL, Mongo, но в итоге слон всех победил, и мы используем Postgres.



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



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



Команды у нас пытались использовать для установки Postgres и его настройки Ansible. Кто-то, более отважный, использовал Chef, у кого был с ним опыт работы.


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


Соответственно, нагрузка увеличивалась на команды, которые занимались администрированием Postgres. Нагрузка увеличивалась на нас, потому что они тратили свое время для того, чтобы найти проблему. Потом приходили к нам, мы тратили время. В общем, выяснилось, что всего очень много. У нас даже были особо отличившиеся. Во времена 9.4 Postgres умудрялись ставить Postgres 8-ой версии.



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



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



Обязательно мы решили сделать балансировку, потому что коннекты в Postgres ресурс достаточно дорогой. Обязательно нужно сделать pooling, устойчивые балансировщики, т. е. обеспечить, чтобы все работало.



Обязательно сделать резервные копии с приемлемой глубиной хранения, чтобы еще можно было осуществлять point in time recovery. И нужно было сделать обязательную архивацию WAL-файлов.



Нужно было обязательно обеспечить интеграцию с существующими системами мониторинга и логирования.



И поскольку мы придерживаемся парадигмы: infrastructure as code, то мы решили, что наше решение будет выглядеть в виде деплоя. Мы решили написать его на общеизвестном в нашем подразделении инструменте. У нас это был Ansible. И еще мы немножко кое-что написали на Python и Bash мы тоже активно используем.


Основная мысль была такая, чтобы это было некое целостное решение, чтобы наш деплой могла взять любая команда. Могла бы поменять какие-то переменные, поменять секреты, ключи, поменять inventory и развернуть себе отказоустойчивый кластер. Т. е. чтобы по большому счету нужно было нажать кнопку deploy и через некоторое время уже подключаться к готовому кластеру и с ним работать.



И поскольку мы используем корпоративный Gitlab, хотелось, чтобы все это работало через встроенные возможности Gitlab, через continuous integration, continuous delivery. Т. е. чтобы можно было нажать кнопку deploy в репозитории и через некоторое время появлялся бы рабочий кластер.


И теперь мы все эти элементы рассмотрим в отдельности.



Кластер PostgreSQL



  • Мы выбрали PostgreSQL 9.4. Это было примерно 3,5 года назад. Тогда как раз был 9.4 в baseline. 9.6, по-моему, только вышел или его еще не было, я точно не помню. Но мы достаточно быстро наше решение проапгрейдили до 9.6, т. е. оно стало его поддерживать.
  • Для обеспечения репликации мы не стали ничего выдумывать. Выбрали стандартный метод потоковую репликацию. Она наиболее надежная, наиболее известная. С ней особых проблем нет.
  • Для кластеризации мы выбрали менеджер репликации с псевдо HA. Это repmgr от 2ndQuadrant. В защиту repmgr могу сказать. В предыдущие два дня в него летели активно камни, что он не обеспечивает настоящий HA, у него нет фенсинга, но на самом деле за три года эксплуатации я могу сказать, что у нас не было ни одного инцидента, когда переключения failovers произошли неправильно или закончились ошибкой. Т. е. всегда repmgr переключал кластер по делу. Всегда обеспечивал нам надежность. Не без downtime, конечно. Примерно 2 минуты repmgr соображает, что нужно выполнить failover и после этого его выполняет.
  • Для repmgr мы написали кастомный failover_command. Это такая команда, которую repmgr выполняет, когда собирается провести failover, т. е. запромоутить нового мастера. Т. е. запускается специальный скрипт. Он идет на балансировщики, проверяет, что балансировщики работают, что они доступны с нового мастера. И после этого происходит переключение. Т. е. он выполняет failover, переписывает бэкенды на балансировщиках и после этого завершает свою работу. Соответственно, мы получаем нового мастера. И балансировщики подключены к новому мастеру.
  • С репликой в другом ДЦ. У нас основное место присутствия это Новосибирск. Несколько ДЦ в Новосибирске. Но есть площадка в Москве, поэтому нам нужно было обеспечить, чтобы две реплики находились в Москве. Сначала мы их добавили в кластер repmgr.

Но после начала эксплуатации одного из тестовых кластеров, выяснилось, что связь не очень хорошая, постоянные просадки pingа, лаги. В итоге мы отказали от этой идеи. Постоянно в кластере происходили warning, т. е. мониторинг начинал говорит, что что-то в кластере изменилось, давайте проверим, что происходит. Репликация также периодически прерывалась.



В итоге мы сделали вот такую схему, т. е. мы вытащили из repmgr ноды, которые находятся в Москве. Сделали из них обычный hot standby, не стали ничего выдумывать. Они у нас через restore забирают с бэкап-сервера архивы WALs. Соответственно, проблему лага мы не разрешили. Если у нас на мастере начинается активная работа, то понятно, что реплики в Москве немножко отстают.


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



Проблемы. Проблем особых здесь нет. Помимо того, что медленно работает у нас archive_command, потому что сделан через обычный rsync, т. е. журналы с мастера попадают на архив через rsync ssh. Соответственно, если на мастере начинается работа, то это все немножко тормозит. Но с этим мы справимся, потому что, скорее всего, будем переключить архивацию в streaming режим. В общем, не такая это большая проблема.



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



Мы выделили для этого специальные узлы. У них на входе стоит keepalive. У каждого keepalive есть виртуальный адрес, для которого он является мастером. Соответственно, если один keepalive падает, второй получает его адрес как второй, т. е. у него два адреса.


Эти адреса балансируются в DNS через round robin, т. е. когда приложение подключается к кластеру, они получают либо виртуальный адрес первого балансировщика, либо виртуальный адрес второго балансировщика.


Адреса keepalive у нас получает PgBouncer. Отличный pooler, у нас с ним особых проблем нет. Он работает, не доставляет никаких неприятностей. Но у него есть одна проблема. У него бэкенд может быть только один и он должен смотреть на мастера. Поэтому мы поставили у него на бэкенде Pgpool. Нам он понравился тем, что он знает, где в кластере находится мастер, умеет балансировать запросы на чтение, на slave.



Все было классно, хорошо, мы начали его эксплуатировать, но в определенный момент нам пришлось сделать вот так. Потому что с Pgpool у нас были постоянные проблемы. Он периодически без видимых причин выбрасывал мастера из балансировки. Также его встроенный анализатор, который анализирует запросы, периодически не мог определиться запрос на запись, запрос на чтение, т. е. он мог запрос на запись отправить на реплику. Соответственно, мы получаем read only кластер и панику на корабле. В общем, все плохо.



Мы избавились от Pgpool. PgBouncer смотреть теперь только на мастер. Деплой проставляет PgBouncerу бэкенд. И failover_command с будущего мастера переключает адрес бэкенда и делает мягкую перезагрузку PgBouncer. И таким образом PgBouncer всегда смотрит на мастер.


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



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


Соответственно, мы сделали такую же пару. Я тут один нарисовал, потому что он уже не влезал. Мы по такому же подобию сделали балансировщики на чтение. Только на бэкенде у PgBouncer поставили HAProxy, который с помощью специально скрипта ходит в кластер и точно знает, где у него находятся slave и отправляет по round robin запросы на них.


Также у нас приложения начали поддерживать pooling на своей стороне, т. е. начали использовать штуки типа Hikari Pool. И, соответственно, экономить коннекты для балансировщика. И после этого стало еще более хорошо жить.



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



Взяли Barman.


  • Barman у нас делает бэкап базы через cron каждые два дня, когда нагрузка минимальная.
  • Также у нас через archive_command происходит архивация WAL-файлов к Barman, чтобы можно было PITR осуществлять.

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


Недостатки в этой схеме довольно стандартные:


  • Тот же самый archive_command.
  • И требуется очень много места, потому что WAL-файлы мы не сжимаем, потому что экономим процессор, экономим время, чтобы при восстановлении можно было максимально быстро восстановиться.


Мониторинг и логи



  • У нас используется в качестве мониторинга Prometheus. Он использует pool-модель сбора метрик. Т. е. он сам ходит к сервисам и спрашивает их метрики. Соответственно, нам для каждого компонента системы (а это почти все компоненты, которые не умеют отдавать метрики) пришлось найти соответствующий exporter, который будет собирать метрики и отдавать их Prometheus, либо написать самостоятельно.
  • Мы свои exporters пишем на Golang, на Python, на Bash.
  • Мы используем в основном стандартные exporters. Это Node exporter основной системный exporter; Postgres exporter, который позволяет собирать все метрики с Postgres; exporter для PgBouncer мы написали сами на Python. И мы написали еще кастомный Cgroups exporters на Golang. Он нам нужен для того, чтобы четко знать, какое количество ресурсов системных сервер баз данных потратил на обслуживание каждой базы.
  • Собираем мы все системные метрики: это память, процессор, загрузка дисков, загрузка сети.
  • И метрики всех компонентов. В exporterе для Postgres вообще ситуация такая, что вы сами exporterу пишите запросы, которые хотите выполнять в базе. И, соответственно, он вам выполняет их и формирует метрики. Т. е., в принципе, метрики, которые можете добыть из Postgres ограничены только вашей фантазией. Понятно, что нам важно собирать количество транзакций, количество измененных tuples, позицию WAL-файлов для того, чтобы отслеживать постоянно отставание, если оно есть. Обязательно нужно знать, что происходит на балансировщиках. Сколько сессий находятся в каком статусе. Т. е. все-все мы собираем в Prometheus.


Метрики мы смотрим в Grafana. Вот так примерно выглядит график Cgroups с exporterа. Мы всегда можем посмотреть, какая база у нас, сколько процессора употребила за определенное время, т. е. очень удобно.



Как в любой системе мониторинга у нас есть alerts. Alerts в Prometheus занимается AlertManager.



У нас написано большое количество alerts, касательно кластера. Т. е. мы всегда знаем, что у нас начался failover, что failover закончился, что failover закончился успешно или не успешно. И все эти вопросы мы обязательно мониторим. У нас есть alerts, которые либо сигналят нам в почту, либо сигналят в корпоративный Slack, либо звонят по телефону и говорят: Просыпайся, у тебя проблема!.


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


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



С логами у нас не очень богато. У нас в компании используется ELK stack для сбора логов, т. е. мы используем Elasticsearch, Kibana и LogStash. Соответственно, Postgres и все компоненты нашего решения складывают логи на диск в CSV-формате, а с диска их собирает Python Beaver. Есть такой проект. Он их собирает и отдает LogStash. LogStash обогащает какую-то информацию, добавляет информацию к какой команде относится кластер, какой кластер, в общем, вносит какую-то дополнительную информацию.


И после этого в Kibana можно легко логи просматривать и агрегировать, в общем, сортировать и все, что угодно делать.


Также команды нас попросили поставить Pgbadger. Это такая штука, которая позволяет легко и непринужденно анализировать, например, slow логи. Это основное, для чего они хотели эту штуку. Она написана на Perl. Она нам не очень понравилась, потому что под нее нужно было отдельный хост размещать. Мы его в итоге задвинули в Kubernetes. Он у нас работает в Kubernetes. Получает он логи из LogStash. LogStash отдает ему по HTTP логи и в Pgbadger потом можно просматривать, и искать свои медленные запросы. В общем, грустить и выяснять, как это починить.



С деплоем следующая история. Нужно было деплой сделать максимально простым, чтобы инструмент был понятным.


Мы решили написать деплой на Ansible. Хотелось его сделать максимально повторяемым, максимально идемпотентным, чтобы его можно было использовать не только при первоначальном деплое, но и можно было использовать для эксплуатации. Мы хотели автоматизировать все операции, которые могут быть снаружи самого Postgres. В том числе изменение конфигурации в Postgresql.conf, чтобы все-все можно было делать через деплой. Чтобы всегда были версии, чтобы всегда четко можно было по истории репозитория отследить что происходило, и кто вносил изменения.



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


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


И нам пришлось все роли локализовать. Т. е. те, которые раньше мы доставали из интернета, мы их локализовали, потому что Роскомнадзор довольно активизировался. Он постоянно банит хосты GitHub, поэтому мы решили не тащить роли снаружи. И все роли у нас лежат локально в наших репозиториях.


Также мы использовали встроенную возможность Ansible. Это использование для деплоя разные окружения. Т. е. по дефолту в нашем деплое есть testing, production и staging. Под staging мы понимаем такой почти production, но без трафика пользователей. В принципе, используя встроенную возможность Ansible можно добавить какие угодно окружения. Если вам нужно два-три testing, чтобы протестировать какую-то фичу, то вы добавляете в дополнительный environments, добавляете переменные, нажимаете deploy. И после этого у вас есть рабочий кластер.


Ключи, пароли мы храним в секретах. Шифруем все Ansible Vault. Это встроенная в Ansible возможность.


Поскольку мы используем Ubuntu Linux как базовую систему, то все мы ставим из репозиториев. Все, что не предоставлялось в виде пакетов, мы пакетируем и складываем к себе в локальный apt. Это тоже нужно для того, чтобы не иметь проблем, когда Роскомнадзор снова решит что-то забанить и для того, чтобы максимально деплой ускорить, потому что локально все быстрее происходит.


Мы постарались автоматизировать все рутинные операции. Т. е. любое изменение конфигурации: добавление баз, добавление пользователей, добавление real only пользователей, добавление каких-то дополнительных штук в базу, изменение режима в балансировке, потому что у нас одна часть сервисов использует транзакционную балансировку, другой части нужны prepared statements, а они используют сессионную балансировку.


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


Деплой у нас лежит в виде Git-репозитории, как я уже говорил, в нашем внутреннем Gitlab.


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


Также мы написали кастомную обвязку для развертывания кластера в OpenStack. Это очень удобно. Особенно, если вам нужна куча тестингов. Мы можем использовать нативное Openstack API через модуль Ansible, либо через одну штуку в OpenStack, которая называется heat-api, которая позволяет шаблонами запускать машины по несколько штук. Это очень удобно. Если вам нужно в ветке что-то потестировать, вы подключаете эту обвязку, которая позволяет через heat-api разворачивать машинки. Разворачиваете себе кластер. С ним работаете. После говорите: Мне это не надо. Удалить. Это все удаляется, т. е. виртуальные машинки в OpenStack удаляются. Все очень просто и удобно.


Также для железных машин мы написали bootstrap, но это обычный пресет образ. Это встроенная возможность Debian, Ubuntu. Он задает несколько вопросов. У него сделана специальное меню. Задает несколько вопросов про диск, про сеть. После того, как вы закончили, вы имеете ноду, которая уже готова для того, чтобы ее можно было использовать в деплое. Т. е. вы прописываете ее в инвентарь и после этого можете запускать деплой, и все будет хорошо.



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



И последний пункт. Мы используем встроенные возможности Gitlab.



Gitlab умеет запускать специальные jobs. Jobs это отдельные шаги, которые выполняются.



Т. е. у нас отдельными шагами являются syntax check, деплой, тесты. Здесь у нас маленькая схема. После мержа в мастер автоматически запускается pipeline, который производит syntax check, деплоится на тестинг. На тестинге запускаются тесты. После этого, если все Ok, все зеленое, разблокируется ручной запуск деплоя staging и деплоя production.


Ручной запуск у нас сделан, чтобы люди, которые это делают, понимали, что они делают и отдавали отчет, что сейчас будет деплой на testing или на staging или на production.



Подведем итоги. Что же нам удалось? Мы хотели сделать такой инструмент, который будет нам все разворачивать, чтобы получить очень быстро рабочий кластер со всеми интеграциями. В принципе, нам это удалось. Такой деплой мы создали. Нам он очень помогает. Даже при не очень хороших обстоятельствах в течение 15 минут после начала нажатия кнопки deploy, вы получаете рабочий кластер. Вы можете заходить на endpoint и использовать в работе. Соответственно, команды могут его встраивать прямо в pipeline, т. е. полностью с ним работать.



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


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


Мы получили огромный опыт. Разобрались как работают rep managers, балансировка, репликация, Postgres. Это неоценимый опыт, всем советую.


Failover у нас работает. Failover, я бы не сказал, что происходит часто. За три года порядка десяти раз у нас был failover. Failover практически всегда по делу был.


Мы делаем вручную switchover, т. е. это failover вручную. Switchover мы делаем для всяких интересных штук. Например, когда нам нужно было перевести один из кластеров из одного ДЦ в другой, мы просто забутстрапили с помощью деплоя ноду в другом ДЦ. Сделали на нее switchover, переключили балансировщики. И тогда у нас появился рабочий мастер в новом ДЦ практически без downtime, только на время переключения. А для repmgr (Replication Manager) это, по-моему, две минуты дефолтные.



Без falls у нас тоже не обошлось:


  • Мы хотели сделать решение простым, чтобы команды могли его сами использовать. Но тут ничего не вышло. Все равно надо знать нюансы, как все работает внутри, все равно нужно понимать, как работает репликация, как работает rep managers. Именно поэтому количество форков нашего репозитория равно нулю. Команды не занимаются этим. Может быть, это и неплохо, потому что все проблемы мы бы решали.
  • Все равно для каждого кластера приходится что-то допиливать, дописывать. Не удается использовать один и тот же деплой.
  • И от ручных операций тоже не удалось избавиться. Все равно апгрейды, перезапуски Postgres, когда нужно внести какие-то изменения в postgresql.conf, приходится делать вручную. Потому что автоматике это можно доверить, но нужно понимать, что происходит. Без оператора не обойтись. Человек должен понимать, что он делает. Без ручных операций все равно не получается.
  • Обновление это отдельная боль. Это нужно все апгрейдить руками. Балансировщики, например, можно проапгрейдить автоматом, но будет downtime. А без автоматики вручную это можно сделать без downtime.
  • И мы не очень любим собирать пакеты, потому что на это тратится дополнительное время. Нужно делать инфраструктуру для сборки, инфраструктуру для pushes и репозиторий.


У нас в компании довольно активно развивается Kubernetes, поэтому есть ощущение попробовать что-нибудь новое. Например, попробовать запустить отказоустойчивый Postgres в Kubernetes. Для этого мы хотим посмотреть на Stolon, Patroni. Возможно, это будет первым, чем мы займемся.


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


И наше решение мы будем делать апгрейд на PostgreSQL 10-11. Я предвижу, что это будет очень веселое развлечение. Вызов принят, у нас вариантов нет, мы используем наше решение и будем апгрейдиться.




Вопросы


Спасибо за доклад! На разработку всех плейбуков в Ansible, сколько потратилось времени?


Путем проб и ошибок, путем нескольких заваленных кластеров где-то порядка два-три месяца заняло. В команде было 2-3 человека.


Какие-то были особенности именно внедрения Ansible в связке с Postgres, с вашим решением? Например, что-то пришлось кардинально перерабатывать?


Модули писать для Ansible?


Да.


Нет, мы использовали встроенные возможности Ansible, т. е. все модули, которые у него идут внутри.


Спасибо за доклад! Почему на Barman остановились? И насчет апгрейда у меня созрел вопрос еще в самом начале, когда про 9.6 рассказывали. Я увидел, что у вас есть планы на 10 и 11 версию, да?


Не знаю, но почему-то решили выбрать Barman. Он нам понравился тем, что конфигурируется нормально. Т. е. у нас была для него уже написанная роль в Ansible. Мы хотим посмотреть на что-нибудь другое, например, на WAL-G. Но проблема в том, насколько я помню, WAL-G не умеет в диск (Уточнение: уже умеет писать на диск). А у нас требование, чтобы все бэкапы и все-все лежали внутри инфраструктуры. А городить для этого отдельный S3, конечно, можно, но зачем?


Апгрейд мы делали вручную. Мы также подеплоили рядом кластер 9.6. В него смигрировали данные и все. И после этого выкинули 9.4 и у нас все стало хорошо.


Спасибо большое за доклад! Вы сказали, что у вас кластеров несколько. Но приложений по ходу гораздо больше, да?


Да.


По какому принципу новые кластера добавляются помимо staging?


Я понял вопрос. Мы все базы консолидировали в трех больших своих кластерах. У нас там есть testing, staging. И когда приложение работает уже на staging, мы можем понять, что что-то. Допустим, процессинговые базы, про которые я говорил. И такое пускать в кластер не понятно зачем, потому что будет постоянная нагрузка на WALs, будет постоянно большой бэкап. Потому что если бэкап пришел, пока у тебя процессинговая база лежит, ты получаешь . И, в принципе, по профилю нагрузки мы понимаем, что происходит внутри приложения. И после этого решаем дать отдельный кластер этим ребятам. И деплоим кластер, а что делать? Приложения в production все.


Здравствуйте! Спасибо за доклад! У меня немного двойной вопрос. Вы для половины части используете ванильные сборки Postgres?


Да.


Я сейчас тоже использую ванильные, но присматриваюсь к бесплатной части команды Postgres Professional, т. е. Postgres Pro Standard. И коснулась тема, что выбирать для резервного копирования. И них есть утилита pg_probackup, которая похожа на Barman, но у нее есть встроенная проверка бэкапов уже внутри. Почему вы не обратили внимание на эту утилиту?


Я даже не знаю, как вам правильно ответить. В принципе, мы как-то вообще не рассматривали Postgres Proшные штуки. Как-то так получилось. Мы привыкли, что мы сами с усами, строим свои велосипеды. Вроде бы у нас все работает.


Т. е. это выбор каждого: либо городить свой велосипед, либо пойти по проторенному пути.


Да.


Спасибо!


Спасибо большое!

Подробнее..

MLOps Cook book, chapter 1

03.07.2020 10:08:54 | Автор: admin


Всем привет! Я CV-разработчик в КРОК. Уже 3 года мы реализуем проекты в области CV. За это время чего мы только не делали, например: мониторили водителей, чтобы во время движения они не пили, не курили, по телефону не разговаривали, смотрели на дорогу, а не сны или в облака; фиксировали любителей ездить по выделенным полосам и занимать несколько мест на парковке; следили за тем, чтобы работники носили каски, перчатки и т.п.; идентифицировали сотрудника, который хочет пройти на объект; подсчитывали всё, что только можно.


Я все это к чему?


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


Моделируем ситуацию


Представим, что мы устроились в молодую компанию N, деятельность которой связана с ML. Работаем мы над ML (DL, CV) проектом, потом по каким-либо причинам переключаемся на другую работу, в общем делаем перерыв, и возвращаемся к своей или чужой нейроночке.


  1. Наступает момент истины, нужно как-то вспомнить на чем ты остановился, какие гиперпараметры пробовал и, самое главное, к каким результатам они привели. Может быть множество вариантов, кто как хранил информацию по всем запускам: в голове, конфигах, блокноте, в рабочей среде в облаке. Мне довелось видеть вариант, когда гиперпараметры хранились в виде закомментированных строк в коде, в общем полет фантазии. А теперь представьте, что вы вернулись не к своему проекту, а к проекту человека, который покинул компанию и в наследство вам достался код и модель под названием model_1.pb. Для полноты картины и передачи всей боли, представим, что вы еще и начинающий специалист.
  2. Идем дальше. Для запуска кода нам и всем кто будет с ним работать необходимо создать окружение. Часто бывает, что и его нам в наследство также по каким-то причинам не оставили. Это тоже может стать нетривиальной задачей. На этот шаг не хочется тратить время, не так ли?
  3. Тренируем модель (например, детектор автомобилей). Доходим до момента, когда она становится очень даже ничего самое время сохранить результат. Назовем ее car_detection_v1.pb. Потом тренируем еще одну car_detection_v2.pb. Некоторое время спустя наши коллеги или мы сами обучаем ещё и ещё, используя различные архитектуры. В итоге формируется куча артефактов, информацию о которых нужно кропотливо собирать (но, делать мы это будем позже, у нас ведь пока есть более приоритетные дела).
  4. Ну вот и всё! У нас есть модель! Мы можем приступать к обучению следующей модели, к разработке архитектуры для решения новой задачи или можем пойти попить чай? А деплоить кто будет?

Выявляем проблемы


Работа над проектом или продуктом это труд многих человек. А с течением времени люди уходят и приходят, проектов становится больше, сами проекты становятся сложнее. Так или иначе, ситуации из описанного выше цикла (и не только) в тех или иных комбинациях будут встречаться от итерации к итерации. Все это выливается в трату времени, путаницу, нервы, возможно в недовольство заказчика, и в конечном счете в упущенные деньги. Хоть все мы обычно ходим по старым граблям, но полагаю, что никто при этом не хочет раз за разом переживать эти моменты.



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


  • удобно хранить результаты работы;
  • сделать простым процесс вовлечения новых сотрудников;
  • упростить процесс развертывания среды разработки;
  • настроить процесс версионирования моделей;
  • иметь удобный способ валидации моделей;
  • найти инструмент управления состоянием моделей;
  • найти способ доставки моделей в production.

Видимо необходимо придумать workflow, который бы позволял легко и удобно управлять этим жизненным циклом? У такой практики есть название MLOps


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


Можете почитать, что обо всем этом думают ребята из Google. Из статьи понятно, что MLOps, довольно, объемная штука.



Далее в своей статье я опишу лишь часть процесса. Для реализации я воспользуюсь инструментом MLflow, т.к. это open-source проект, для подключения необходимо небольшое количество кода и есть интеграция с популярными ml-фреймворками. Вы можете поискать на просторах интернета другие инструменты, например Kubeflow, SageMaker, Trains и т.д., и возможно, подобрать тот, который лучше подходит под ваши нужды.


"Cтроим" MLOps на примере использования инструмента MLFlow


MLFlow это платформа с открытым исходным кодом для управления жизненным циклом ml моделей (https://mlflow.org/).


MLflow включает четыре компонента:


  • MLflow Tracking закрывает вопросы фиксации результатов и параметров, которые к этому результату привели;
  • MLflow Project позволяет упаковывать код и воспроизвести его на любой платформе;
  • MLflow Models отвечает за деплой моделей в прод;
  • MLflow Registry позволяет хранить модели и управлять их состоянием в централизованном хранилище.

MLflow оперирует двумя сущностями:


  • запуск это полный цикл обучения, параметры и метрики по которым мы хотим регистрировать;
  • эксперимент это тема которой объединены запуски.

Все шаги примера реализованы на операционной системе Ubuntu 18.04.


1. Разворачиваем сервер


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


  • backend store отвечает за хранение информации о зарегистрированных моделях (поддерживает 4 СУБД: mysql, mssql, sqlite, and postgresql);
  • artifact store отвечает за хранение артефактов (поддерживает 7 вариантов хранения: Amazon S3, Azure Blob Storage, Google Cloud Storage, FTP server, SFTP Server, NFS, HDFS).

В качестве artifact store для простоты возьмем sftp сервер.


  • создаем группу
    $ sudo groupadd sftpg
    
  • добавляем пользователя и устанавливаем ему пароль
    $ sudo useradd -g sftpg mlflowsftp$ sudo passwd mlflowsftp 
    
  • корректируем пару настроек доступа
    $ sudo mkdir -p /data/mlflowsftp/upload$ sudo chown -R root.sftpg /data/mlflowsftp$ sudo chown -R mlflowsftp.sftpg /data/mlflowsftp/upload
    
  • добавляем несколько строк в /etc/ssh/sshd_config
    Match Group sftpg ChrootDirectory /data/%u ForceCommand internal-sftp
    
  • перезапускаем службу
    $ sudo systemctl restart sshd
    

В качестве backend store возьмем postgresql.


$ sudo apt update$ sudo apt-get install -y postgresql postgresql-contrib postgresql-server-dev-all$ sudo apt install gcc$ pip install psycopg2$ sudo -u postgres -i# Create new user: mlflow_user[postgres@user_name~]$ createuser --interactive -PEnter name of role to add: mlflow_userEnter password for new role: mlflowEnter it again: mlflowShall the new role be a superuser? (y/n) nShall the new role be allowed to create databases? (y/n) nShall the new role be allowed to create more new roles? (y/n) n# Create database mlflow_bd owned by mlflow_user$ createdb -O mlflow_user mlflow_db

Для запуска сервера необходимо установить следующие python пакеты (советую создать отдельное виртуальное окружение):


pip install mlflowpip install pysftp

Запускаем наш сервер


$ mlflow server  \                 --backend-store-uri postgresql://mlflow_user:mlflow@localhost/mlflow_db \                 --default-artifact-root sftp://mlflowsftp:mlflow@sftp_host/upload  \                --host server_host \                --port server_port

2. Добавляем трекинг


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


Для примера я создал небольшой проект на github на Keras по сегментации всего, что есть в COCO датасете. Для добавления трекинга я создал файл mlflow_training.py.


Вот строки, в которых происходит самое интересное:


def run(self, epochs, lr, experiment_name):        # getting the id of the experiment, creating an experiment in its absence        remote_experiment_id = self.remote_server.get_experiment_id(name=experiment_name)        # creating a "run" and getting its id        remote_run_id = self.remote_server.get_run_id(remote_experiment_id)        # indicate that we want to save the results on a remote server        mlflow.set_tracking_uri(self.tracking_uri)        mlflow.set_experiment(experiment_name)        with mlflow.start_run(run_id=remote_run_id, nested=False):            mlflow.keras.autolog()            self.train_pipeline.train(lr=lr, epochs=epochs)        try:            self.log_tags_and_params(remote_run_id)        except mlflow.exceptions.RestException as e:            print(e)

Здесь self.remote_server это небольшая обвязка над методами mlflow.tracking. MlflowClient (я сделал для удобства), с помощью которых я создаю эксперимент и запуск на сервере. Далее указываю куда должны сливаться результаты запуска (mlflow.set_tracking_uri(self.tracking_uri)). Подключаю автоматическое логирование mlflow.keras.autolog(). На данный момент MLflow Tracking поддерживает автоматическое логирование для TensorFlow, Keras, Gluon XGBoost, LightGBM, Spark. Если вы не нашли своего фреймворка или библиотеки, то вы всегда можете логировать в явном виде. Запускаем обучение. Регистрируем теги и входные параметры на удаленном сервере.


Пара строк и вы, как и все желающие, имеете доступ к информации о всех запусках. Круто?


3. Оформляем проект


Теперь сделаем так, чтобы запустить проект было проще простого. Для этого добавим в корень проекта файл MLproject и conda.yaml.
MLproject


name: flow_segmentationconda_env: conda.yamlentry_points:  main:    parameters:        categories: {help: 'list of categories from coco dataset'}        epochs: {type: int, help: 'number of epochs in training'}        lr: {type: float, default: 0.001, help: 'learning rate'}        batch_size: {type: int, default: 8}        model_name: {type: str, default: 'Unet', help: 'Unet, PSPNet, Linknet, FPN'}        backbone_name: {type: str, default: 'resnet18', help: 'exampe resnet18, resnet50, mobilenetv2 ...'}        tracking_uri: {type: str, help: 'the server address'}        experiment_name: {type: str, default: 'My_experiment', help: 'remote and local experiment name'}    command: "python mlflow_training.py \            --epochs={epochs}            --categories={categories}            --lr={lr}            --tracking_uri={tracking_uri}            --model_name={model_name}            --backbone_name={backbone_name}            --batch_size={batch_size}            --experiment_name={experiment_name}"

MLflow Project имеет несколько свойств:


  • Name имя вашего проекта;
  • Environment в моем случае conda_env указывает на то, что для запуска используется Anaconda и описание зависимостей находится в файле conda.yaml;
  • Entry Points указывает какие файлы и с какими параметрами мы можем запустить (все параметры при запуске обучения автоматически логируются)

conda.yaml


name: flow_segmentationchannels:  - defaults  - anacondadependencies:  - python==3.7  - pip:    - mlflow==1.8.0    - pysftp==0.2.9    - Cython==0.29.19    - numpy==1.18.4    - pycocotools==2.0.0    - requests==2.23.0    - matplotlib==3.2.1    - segmentation-models==1.0.1    - Keras==2.3.1    - imgaug==0.4.0    - tqdm==4.46.0    - tensorflow-gpu==1.14.0

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


4. Запускаем обучение


Клонируем проект и переходим в директорию проекта:


git clone https://github.com/simbakot/mlflow_example.gitcd mlflow_example/

Для запуска вам необходимо установить библиотеки


pip install mlflowpip install pysftp

Т.к. в примере я использую conda_env на вашем компьютере должна быть установлена Anaconda (но и это можно обойти установив все необходимые пакеты самостоятельно и поигравшись с параметрами запуска).


Все подготовительные шаги закончены и мы можем приступить к запуску обучения. Из корня проекта:


$ mlflow run -P epochs=10 -P categories=cat,dog -P tracking_uri=http://server_host:server_port .

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


5. Оцениваем результаты обучения


После окончания обучения мы можем перейти в браузере по адресу нашего сервера http://server_host:server_port



Здесь мы видим список всех экспериментов (слева вверху), а также информацию по запускам (посередине). Мы можем посмотреть более подробную информацию (параметры, метрики, артефакты и какую-то доп. информацию) по каждому запуску.



По каждой метрике мы можем наблюдать историю изменения



Т.е. на данный момент мы можем анализировать результаты в "ручном" режиме, также вы можете настроить и автоматическую валидацию при помощи MLflow API.


6. Регистрируем модель


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



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



Для каждой модели мы можем добавить описание и выбрать одно из трех состояний (Staging, Production, Archived), впоследствии мы при помощи api можем обращаться к этим состояниям, что на ряду с версионированием дает дополнительную гибкость.



У нас также имеется удобный доступ ко всем моделям



и их версиям



Как и в предыдущем пункте все операции можно сделать при помощи API.


7. Деплоим модель


На данном этапе у нас уже есть натренированная (keras) модель. Пример, как можно её использовать:


class SegmentationModel:    def __init__(self, tracking_uri, model_name):        self.registry = RemoteRegistry(tracking_uri=tracking_uri)        self.model_name = model_name        self.model = self.build_model(model_name)    def get_latest_model(self, model_name):        registered_models = self.registry.get_registered_model(model_name)        last_model = self.registry.get_last_model(registered_models)        local_path = self.registry.download_artifact(last_model.run_id, 'model', './')        return local_path    def build_model(self, model_name):        local_path = self.get_latest_model(model_name)        return mlflow.keras.load_model(local_path)    def predict(self, image):        image = self.preprocess(image)        result = self.model.predict(image)        return self.postprocess(result)    def preprocess(self, image):        image = cv2.resize(image, (256, 256))        image = image / 255.        image = np.expand_dims(image, 0)        return image    def postprocess(self, result):        return result

Здесь self.registry это опять небольшая обвязка над mlflow.tracking.MlflowClient, для удобства. Суть в том, что я обращаюсь к удаленному серверу и ищу там модель с указанным именем, причем, самую последнюю production версию. Далее скачиваю артефакт локально в папку ./model и собираю модель из этой директории mlflow.keras.load_model(local_path). Всё теперь мы можем использовать нашу модель. CV (ML) разработчики могут спокойно заниматься улучшением модели и публиковать новые версии.


В заключение


Я представил систему которая позволяет:


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

Данный пример является игрушечным и служит точкой старта для выстраивания вашей собственной системы, которая, возможно, будет включать в себя автоматизацию оценки результатов и регистрации моделей (п.5 и п.6 соответственно) или вы добавите версионирование датасетов, или может ещё что-то? Я пытался донести мысль, что вам нужен MLOps в целом, MLflow лишь средство достижения цели.


Напишите какие проблемы, с которыми вы сталкивались, я не отобразил?
Что бы вы добавили в систему, чтобы она закрывала ваши потребности?
Какие инструменты и подходы используете вы, чтобы закрыть все или часть проблем?


P.S. Оставлю пару ссылок:
github проект https://github.com/simbakot/mlflow_example
MLflow https://mlflow.org/
Моя рабочая почта, для вопросов ikryakin@croc.ru


У нас в компании периодически проводятся различные мероприятия для ИТ-специалистов, например: 8-го июля в 19:00 по МСК будет проходить митап по CV в онлайн-формате, если интересно, то можете принять участие, регистрация здесь .

Подробнее..

Что такое CI (Continuous Integration)

25.06.2020 16:23:50 | Автор: admin
CI (Continuous Integration) в дословном переводе непрерывная интеграция. Имеется в виду интеграция отдельных кусочков кода приложения между собой. Чем чаще мы собираем код воедино и проверяем:

  • Собирается ли он?
  • Проходят ли автотесты?

Тем лучше! CI позволяет делать такие проверки автоматически. Он используется в продвинутых командах разработки, которые пишут не только код, но и автотесты. Его спрашивают на собеседованиях хотя бы понимание того, что это такое. Да, даже у тестировщиков.

Поэтому я расскажу в статье о том, что это такое. Как CI устроен и чем он пригодится вашему проекту.



Содержание




Что такое CI


CI это сборка, деплой и тестирование приложения без участия человека. Сейчас объясню на примере.

Допустим, что у нас есть два разработчика Маша и Ваня. И тестировщица Катя.

Маша пишет код. Добавляет его в систему контроля версий (от англ. Version Control System, VCS). Это что-то типа дропбокса для кода место хранения, где сохраняются все изменения и в любой момент можно посмотреть кто, что и когда изменял.

Потом Ваня заканчивает свой кусок функционала. И тоже сохраняет код в VCS.



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

  1. Собрать билд из исходного кода
  2. Запустить его на тестовой машине

Сборка билда это когда мы из набора файликов исходного кода создаем один запускаемый файл:



Собрать билд можно вручную, но это лишний геморрой: нужно помнить, что в каком порядке запустить, какие файлики зависят друг от друга, не ошибиться в команде Обычно используют специальную программу. Для java это Ant, Maven или Gradle. С помощью сборщика вы один раз настраиваете процесс сборки, а потом запускаете одной командой. Пример запуска для Maven:

mvn clean install

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



Но собрать билд получить приложение для тестирования. Его еще надо запустить! Этим занимается сервер приложения. Серверы бывают разные: wildfly, apache, jetty

Если это wildfly, то нужно:

  1. Подложить билд в директорию standalone/deployments
  2. Запустить сервер (предварительно один раз настроив службу)

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



А вот если убрать из этой схемы человека мы получим CI!



CI это приложение, которое позволяет автоматизировать весь процесс. Оно забирает изменения из репозитория с кодом. Само! Тут есть два варианта настройки:

  • CI опрашивает репозиторий Эй, ку-ку, у тебя есть изменения?? раз в N часов / минут, как настроите.

  • Репозиторий машет CI рукой при коммите: Эй, привет! А у меня обновление тут появилось! (это git hook или аналог в вашей VCS)


Когда CI получило изменения, оно запускает сборку билда и автотесты.

Если сборка провалилась (тесты упали, или не получилось собрать проект), система пишет элекронное письмо всем заинтересованным лицам:

  • Менеджеру проекта (чтобы знал, что делается!)
  • Разработчику, который внес изменения
  • Любому другому как настроите, так и будет.



Если сборка прошла успешно, CI разворачивает приложение на тестовой машине. И в итоге Катька может тестировать новую сборку!



Да, разумеется, один раз придется это все настроить рассказать серверу CI, откуда забирать изменения, какие автотесты запускать, как собирать проект, куда его потом билдить Но зато один раз настроил а дальше оно само!

Автотесты тоже придется писать самим, но чтож поделать =)



Если на пальцах, то система CI (Continuous Integration) это некая программа, которая следит за вашим Source Control, и при появлении там изменений автоматически стягивает их, билдит, гоняет автотесты (конечно, если их пишут).

В случае неудачи она дает об этом знать всем заинтересованным лицам, в первую очередь последнему коммитеру. (с) habr.com/ru/post/352282



Программы CI


Наиболее популярные Jenkins и TeamCity.

Но есть куча других вариаций CruiseControl, CruiseControl.Net, Atlassian Bamboo, Hudson, Microsoft Team Foundation Serve.


Как это выглядит


Давайте посмотрим, как это выглядит с точки зрения пользователя. Я покажу на примере системы TeamCity.

Когда я захожу в систему, я вижу все задачи. Задачи бывают разные:

  • Собрать билд
  • Прогнать автотесты
  • Развернуть приложение на тестовом стенде
  • Прогнать на этом стенде GUI тесты (или тесты Postman-a)
  • Оповестить всех заинтересованных по email о результатах сборки и тестирования

Задачи можно группировать. Вот, скажем, у нас есть проект CDI. Зайдя внутрь, я вижу задачи именно по этому проекту:



  • CDI Archetype и CDI Core это билды. Они проверяют, что приложение вообще собирается. Отрабатывают за пару минут и прогоняются на каждое изменение кода.
  • CDI Core with tests сборка проекта со всеми автотестами, которых, как видно на скрине, 4000+ штук. Тесты идут полчаса, но тоже прогоняются на каждый коммит.

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



Это нужно, чтобы:

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

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



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


Как CI устроен


Как и где CI собирает билд и прогоняет автотесты? Я расскажу на примере TeamCity, но другие системы работают примерно также.

Сам TeamCity ничего не собирает. Сборка и прогон автотестов проходят на других машинах, которые называются агенты:



Агент это простой компьютер. Железка или виртуальная машина, не суть. Но как этот комьютер понимает, что ему надо сделать?

В TeamCity есть сервер и клиент. Сервер это то самое приложение, в котором вы потом будете тыкать кнопочки и смотреть красивую картинку насколько все прошло успешно. Он устанавливается на одну машину.



А приложение-клиент устанавливается на машинах-агентах. И когда мы нажимаем кнопку Run на сервере:



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



Сервер отображает пользователю результат плюс рассылает email всем заинтересованным лицам.

При этом мы всегда видим, на каком конкретно агенте проходила сборка:



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

Допустим, исходно у нас был только один билд-агент Buran. Название может быть абсолютно любым, его придумывает администратор, когда подключает новую машину к TeamCity как билд-агента.

Мы собирали на нем проект, проводили автотесты все работало. А потом закупили вторую машинку и назвали Apollo. Вроде настроили также, как Буран, даже операционную систему одинаковую поставили CentOs 7.



Но запускаем сборку на Apollo падает. Причем падает странно, не хватает памяти или еще чего-то. Перезапускаем на Apollo снова падает. Запускаем на Буране проходит успешно!



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



Мы также можем для каждой сборки настроить список агентов, на которых она может выполняться. Зачем? Например, у нас на половине агентов линукс, а на половине винда. А сборку мы только под одну систему сделали. Или на винде вылезает какой-то плавающий баг, но исправлять его долго и дорого, а все клиенте на линуксе ну и зачем тогда?

А еще бывает, что агентов делят между проектами, чтобы не было драки этот проект использует Бурана и Аполло, а тот Чип и Дейла. Фишка ведь в том, что на одном агенте может выполняться только одно задание. Поэтому нет смысла покупать под агент крутую тачку, сразу кучу тестов там все равно не прогнать.

В итоге как это работает: сначала админ закупает компьютеры под агенты и устанавливает на них клиентское приложение TeamCity. Слишком крутыми они быть не должны, потому что много задач сразу делать не будут.



При этом TeamCity вы платите за количество лицензий на билд-агентов. Так что чем меньше их будет, тем лучше.

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

У нас есть два проекта Единый клиент и Фактор, которые взаимодействуют между собой. Тестировщик Единого клиента может не собирать Фактор локально. Он запускает сборку в TeamCity и скачивает готовый билд из артефактов!

Дальше уже разработчик выбирает, какую сборку он хочет запустить и нажимает Run. Что в этот момент происходит:

1. Сервер TeamCity проверяет по списку, на каких агентах эту сборку можно запускать. Потом он проверяет, кто из этих агентов в данный момент свободен:



Нашел свободного? Отдал ему задачку!



Если все агенты заняты, задача попадает в очередь. Очередь работает по принципу FIFO first in, first out. Кто первый встал того и тапки.



Очередь можно корректировать вручную. Так, если я вижу, что очередь забита сборками, которые запустила система контроля версий, я подниму свою на самый верх. Если я вижу, что сборки запускали люди значит, они тоже важные, придется подождать.



Это нормальная практика, если мощностей агентов не хватает на всей и создается очередь. Смотришь, кто ее запустил:

  • Робот? Значит, это просто плановая проверка, что ничего лишнего не разломалось. Такая может и подождать 5-10-30 минут, ничего страшного
  • Коллега? Ему эта сборка важна, раз не стал ждать планового запуска. Встаем в очередь, лезть вперед не стоит.

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

  • поднять свою очередь на самый верх, чтобы она запустилась на первом же освободившемся агенте
  • зайти на агент, отменить текущую сборку
  • перезапустить ее! Хоть она и попадет в самый низ очереди, но просто отменять сборку некрасиво

2. Агент выполняет задачу и возвращает серверу результат



3. Сервер отрисовывает результат в графическом интерфейсе и сохраняет артефакты. Так я могу зайти в TeamCity и посмотреть в артефактах полные логи прошедших автотестов, или скачать сборку проекта, чтобы развернуть ее локально.

Настоятельно рекомендуется настроить заранее количество сборок, которые CI будет хранить. Потому что если в артефактах лежат билды по 200+ мб и их будет много, то очередной запуск сборки упадет с ошибкой кончилось место на диске:



4. Сервер делает рассылку по email тут уж как настроите. Он может и позитивную рассылку делать сборка собралась успешно, а может присылать почту только в случае неудачи Ой-ей-ей, что-то пошло не так!.


Интеграция с VCS


Я говорила о разных вариантах настройки интеграции CI VCS:

  • CI опрашивает репозиторий Эй, ку-ку, у тебя есть изменения?? раз в N часов / минут, как настроите.

  • Репозиторий машет CI рукой при коммите: Эй, привет! А у меня обновление тут появилось! (это git hook или аналог в вашей VCS)



Но когда какой используется?

Лучше всего, конечно, чтобы система контроля версий оповещала сервер CI. И запускать весь цикл на каждое изменение: собрать, протестировать, задеплоить. Тогда любое изменение кода сразу попадет на тестовое окружение, которое будет максимально актуальным.



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



Но в реальной жизни такая схема редко применима. Только подумайте у вас ведь может быть много проектов, много разработчиков. Каждый что-то коммитит ну хотя бы раз в полчаса. И если на каждый коммит запускать 10 сборок по полчаса очереди в TeamCity никогда не разгребутся!

У нас у одного из продуктов есть core-модуль, а есть 15+ Заказчиков. В каждом свои автотесты. Сборка заказчика это core + особенности заказчика. То есть изменение в корневом проекте может повлиять на 15 разных сборок. Значит, их все надо запустить при коммите в core.

Когда у нас было 4 билд-агента, все-все-все сборки и тесты по этим заказчикам запускались в ночь на вторник. И к 10 утра в TeamCity еще была очередь на пару часов.

Другой вариант закупить много агентов. Но это цена за саму машину + за лицензию в TeamCity, что уже сильно дороже, да еще и каждый месяц платить.

Поэтому обычно делают как:

1. Очень быстрые и важные сборки можно оставить на любой коммит если это займет 1-2 минуты, пусть гоняется.



2. Остальные сборки проверяют, были ли изменения в VCS например, раз в 15 минут. Если были, тогда запускаем.



3. Долгие тесты (например, тесты производительности) раз в несколько дней ночью.





CI в тестировании


Если мы говорим о разработке своего приложения, то тестирование входит в стандартный цикл. Вы или ваши разработчики пишут автотесты, которые потом гоняет CI. Это могут быть unit, api, gui или нагрузочные тесты.



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

Вот, допустим, у вас есть API-тесты в Postman-е. Или GUI-тесты в Selenium. Можно ли настроить цикл CI для них?



Конечно, можно!

CI не ставит жестких рамок типа я работаю только в проектах с автотестами или я работаю только когда есть доступ к исходному коду. Он может смотреть в систему контроля версий, а может и не смотреть. Это необязательное условие!

Написали автотесты? Скажите серверу CI, как часто их запускать и наслаждайтесь результатом =)




Итого


CI непрерывная интеграция. Это когда ваше приложение постоянно проверяется: все ли с ним хорошо? Проходят ли тесты? Собирается ли сборка? Причем все проверки проводятся автоматически, без участия человека.

Особенно актуально для команд, где над кодом одного приложения трудятся несколько разработчиков. Как это бывает? По отдельности части программы работают, а вот вместе уже нет. CI позволяет очень быстро обнаружить такие проблемы. А чем быстрее найдешь тем дешевле исправить.



Отсюда и название постоянная проверка интеграции кусочков кода между собой.
Типичные задачи CI:

  • Проверить, было ли обновление в коде
  • Собрать билд
  • Прогнать автотесты
  • Развернуть приложение на тестовом стенде
  • Прогнать на этом стенде GUI тесты (или тесты Postman-a)
  • Оповестить всех заинтересованных по email о результатах сборки и тестирования




И все это автоматически, без вмешательства человека! То есть один раз настроили, а дальше оно само.

Если в проекте настроен CI, у вас будут постоянно актуальные тестовые стенды. И если в коде что-то сломается, вы узнаете об этом сразу, сервер CI пришлет письмо. А еще можно зайти в графический интерфейс и посмотреть все ли сборки успешные, а тесты зеленые? Оценить картину по проекту за минуту.

См также:
Continuous Integration для новичков

PS больше полезных статей ищите в моем блоге по метке полезное. А полезные видео на моем youtube-канале
Подробнее..

Из песочницы Расширенная настройка web сервера (Nginx Apache2)

01.07.2020 18:14:54 | Автор: admin

В этом руководстве мы рассмотрим процедуру установки и настройки работы двух web-серверов с целью использования преимуществ каждого из них, где Nginx как frontend и Apache как backend.
В этой статье будет идти речь идти речь о настройки сервера с использованием следующих технологиях: Apache2, Nginx, ngx_pagespeed, PHP, PHP-FPM, MariaDB и MemCached.


Nginx


HTTP-сервер и обратный прокси-сервер, почтовый прокси-сервер, а также TCP/UDP прокси-сервер общего назначения.


Установка


Установите пакеты, необходимые для подключения apt-репозитория:


sudo apt install curl gnupg2 ca-certificates lsb-release

Для подключения apt-репозитория для стабильной версии nginx, выполните следующую команду:


echo "deb http://nginx.org/packages/debian `lsb_release -cs` nginx" \    | sudo tee /etc/apt/sources.list.d/nginx.list

Теперь нужно импортировать официальный ключ, используемый apt для проверки подлинности пакетов:


curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -

Проверьте, верный ли ключ был импортирован:


sudo apt-key fingerprint ABF5BD827BD9BF62

Вывод команды должен содержать полный отпечаток ключа 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62:


pub   rsa2048 2011-08-19 [SC] [expires: 2024-06-14]      573B FD6B 3D8F BC64 1079  A6AB ABF5 BD82 7BD9 BF62uid   [ unknown] nginx signing key

Чтобы установить nginx, выполните следующие команды:


sudo apt update && sudo apt install nginx

Настройка


Запускаем nginx


systemctl enable nginx && systemctl start nginx

Проверяем, что пользователь nginx user www-data:


vi /etc/nginx/nginx.conf

Проверим работу веб-сервера. Открываем браузер и вводим в адресной строке http://IP-адрес сервера.


В итоге мы должны увидеть заголовок Welcome to nginx!.


PHP-FPM


FastCGI протоколу взаимодействия веб-сервера с программами. FPM расшифровывается как Fastcgi Process Manager.


Установка


Устанавливаем PHP-FPM:


apt-get install php-fpm

Настройка


Разрешаем автозапуск php-fpm и запускаем его:


systemctl enable php7.3-fpm && systemctl start php7.3-fpm

Обратите внимание, что мы запустили php-fpm версии 7.2. Но установлена может быть и другая версия ее можно узнать по версии php командой php -v.


ngx_pagespeed


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


Установка


Устанавливаем необходимые пакеты:


sudo apt-get install unzip gcc make g++ libpcre3-dev zlib1g-dev build-essential libpcre3 uuid-dev

Настройка


Создаем и переходим в папку, в которой будем собирать ngx_pagespeed:


mkdir /etc/nginx/buildcd /etc/nginx/build

Узнаем текущую версию nginx:


nginx -v

Скачиваем необходимую версию:


wget -qO - http://nginx.org/download/nginx-1.18.0.tar.gz | tar zxfv -

В нашем случае это nginx 1.18


Скачиваем репозиторий с ngx_pagespeed:


git clone https://github.com/pagespeed/ngx_pagespeed.gitcd ngx_pagespeed/git checkout tags/latest-stablecat PSOL_BINARY_URL

Скачиваем папку psol:


psol_url=https://dl.google.com/dl/page-speed/psol/${NPS_VERSION}.tar.gz [ -e scripts/format_binary_url.sh ] && psol_url=$(scripts/format_binary_url.sh PSOL_BINARY_URL)wget ${psol_url}tar zxf 1.13.35.2-x64.tar.gz

Собираем файл ngx_pagespeed.so:


cd ../nginx-1.18.0/./configure --add-dynamic-module=../ngx_pagespeed --with-compatmakels objs/*so

Копируем файл ngx_pagespeed.so:


cd objscp ngx_pagespeed.so /etc/nginx/modules

Apache2


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


Установка


Устанавливаем apache и модуль для php:


apt-get install apache2 libapache2-mod-php

Настройка


Заходим в настройки портов:


vi /etc/apache2/ports.conf

И редактируем следующее:


Listen 127.0.0.1:8080# <IfModule ssl_module>#    Listen 443# </IfModule># <IfModule mod_gnutls.c>#    Listen 443# </IfModule>

мы настроили прослушивание на порту 8080, так как на 80 уже работает NGINX. Также мы закомментировали прослушивание по 443, так как и он будет слушаться NGINX.


Запрещаем mpm_event:


a2dismod mpm_event

по умолчанию, apache2 может быть установлен с модулем мультипроцессовой обработки mpm_event. Данный модуль не поддерживает php 7 и выше.


Разрешаем модуль мультипроцессовой обработки mpm_prefork:


a2enmod mpm_prefork

Разрешаем модуль php:


a2enmod php7.3

Разрешаем модуль rewrite:


a2enmod rewrite

Разрешаем модуль setenvif:


a2enmod setenvif

Разрешаем автозапуск и запускаем службу:


systemctl enable apache2 && systemctl start apache2

Открываем браузер и вводим в адресную строку http://IP-адрес сервера:8080. Мы должны увидеть привычную страницу.


в разделе Server API мы должны увидеть Apache.


Apache2 Real IP


Запросы на apache приходят от NGINX, и они воспринимаются первым как от IP-адреса 127.0.0.1. На практике, это может привести к проблемам, так как некоторым сайтам необходимы реальные адреса посетителей. Для решения проблемы будем использовать модуль remoteip.


Установка


Создаем конфигурационный файл со следующим содержимым:


vi /etc/apache2/mods-available/remoteip.conf

Настройка


Записываем:


<IfModule remoteip_module>  RemoteIPHeader X-Forwarded-For  RemoteIPTrustedProxy 127.0.0.1/8</IfModule>

Активируем модуль:


a2enmod remoteip

Перезапускаем apache:


systemctl restart apache2

Для проверки настройки открываем браузер и вводим в адресную строку http://IP-адрес сервера, где откроется наша страница phpinfo.


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


PHP


Устанавливаем необходимые библиотеки для PHP и PHP-FPM:


apt install php-xml php-intl php-gd php-curl php-zip php-mbstring php-bcmath php-bz2 php-cgi php-cli php-common php-dba php-dev php-enchant php-gmp php-imap php-interbase php-json php-ldap php-odbc php-opcache php-phpdbg php-pspell php-readline php-recode php-sybase php-tidy php-xmlrpc php-xsl

Mysql (Mariadb)


Установка


Установим MariaDB:


apt-get install mariadb-server php-mysql php-mysqli

Настройка


Разрешаем автозапуск и запускаем СУБД:


systemctl enable mariadbsystemctl start mariadb

Зададим пароль для пользователя root:


mysqladmin -u root password

Перезапускаем apache2:


systemctl restart apache2

Создаем и настраиваем пользователя:


mysql -uroot -pmysql> GRANT ALL PRIVILEGES ON *.* TO 'dbuser'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;# ALL PRIVILEGES: предоставляет полные права на использование данных.# *.* : права предоставляются на все базы и все таблицы.# dbuser: имя учетной записи.# localhost: доступ для учетной записи будет предоставлен только с локального компьютера.# password: пароль, который будет задан пользователю.# WITH GRANT OPTION: будут предоставлены дополнительные права на изменение структуры баз и таблиц.

Настраиваем возможность входа в adminer.php


> update user set plugin='' where User='root';> flush privileges;> exit

Перезапускаем:


sudo systemctl restart mariadb.service

Memcached


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


Установка


Для начала, выполняем установку пакетов:


apt-get install memcached php-memcached

Настройка


После разрешаем автозапуск и запускаем сервис кэширования:


systemctl enable memcached && systemctl start memcached

Перезапускаем apache2:


systemctl restart apache2

Для проверки, что модуль memcached появился в PHP, открываем наш сайт в браузере в phpinfo должна появиться новая секция Memcached.


Доступы и настройка находится в файле memcached.conf:


vi /etc/memcached.conf

Проверяем работу:


netstat -tap | grep memcached

Настройка пользователя


Создаем пользователя:


adduser dev

Добавляем пользователя в группу www-data:


adduser dev www-data

Даем права sudo пользователю:


usermod -aG sudo dev

Настройка сайта


Создаем каталог для сайта


Создаем каталог:


mkdir -p /var/www/example.com/{www,tmp}mkdir -p /var/www/example.com/log/{nginx,apache}

Задаем права на папки:


chown -R www-data:www-data /var/www/example.com/wwwchmod -R 775 /var/www/example.com/www

Создаем индексный файл:


vi /var/www/example.com/www/index.php

С содержанием:


<?php phpinfo(); ?>

Настройка сайта


Nginx http


server {    listen       80;    server_name  example.com;    set $root_path /var/www/example.com/www;    access_log /var/www/example.com/log/nginx/access_log;    error_log /var/www/example.com/log/nginx/error_log;    root   $root_path;    gzip  on;    gzip_disable "msie6";    gzip_min_length 1000;    gzip_vary on;    gzip_proxied    expired no-cache no-store private auth;    gzip_types      text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss;    location / {        location ~ [^/]\.ph(p\d*|tml)$ {            try_files /does_not_exists @fallback;        }        location ~* ^.+\.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|ppt|tar|wav|bmp|rtf|js)$ {            try_files $uri $uri/ @fallback;        }        location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {            expires 7d;            access_log off;        }        location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {            add_header Access-Control-Allow-Origin "*";            expires 7d;            access_log off;        }        location = /favicon.ico {            log_not_found off;            access_log off;        }        location = /robots.txt {            log_not_found off;            access_log off;        }        location / {            try_files /does_not_exists @fallback;        }    }    # Если используется PHP    location @fallback {        proxy_pass http://127.0.0.1:8080;        proxy_redirect http://127.0.0.1:8080 /;        proxy_set_header Host $host;        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_set_header X-Forwarded-Proto $scheme;        access_log off;    }    # Если используется PHP-FPM    location @fallback {        index index.php index.html index.htm;         fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;        fastcgi_index index.php;        fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;        include fastcgi_params;        fastcgi_param DOCUMENT_ROOT $root_path;    }}

Создаем ярлык:


ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/example.com

Все запросы будут переводится на локальный сервер по порту 8080, на котором работает apache, кроме обращений к статическим файлам (jpg, png, css и так далее).


apache2


Создаем файл:


vi /etc/apache2/sites-available/example.com.conf

<VirtualHost 127.0.0.1:8080>    Define root_domain example.com    Define root_path /var/www/example.com    ServerName ${root_domain}    ServerAlias www.${root_domain}    DocumentRoot ${root_path}/www    ErrorLog ${root_path}/log/apache/error_log    TransferLog  ${root_path}/log/apache/access_log    <IfModule mod_dir.c>        DirectoryIndex index.php index.html index.htm    </IfModule>    <Directory /var/www/example.com/www>        AllowOverride All        Options Indexes ExecCGI FollowSymLinks        Require all granted    </Directory>    <IfModule setenvif_module>        SetEnvIf X-Forwarded-Proto https HTTPS=on    </IfModule>    <IfModule php7_module>        php_admin_value upload_tmp_dir ${root_path}/tmp        php_admin_value doc_root ${root_path}        php_value open_basedir    ${root_path}:/usr/local/share/smarty:/usr/local/share/pear        php_value post_max_size 512M        php_value upload_max_filesize 512M        php_flag short_open_tag On    </IfModule></VirtualHost>

Создаем ярлык:


ln -s /etc/apache2/sites-available/example.com.conf /etc/apache2/sites-enabled/example.com.conf

Проверяем


Проверяем корректность настроек конфигурационных файлов:


nginx -tapachectl configtest

Перезапускаем веб-сервер:


systemctl reload nginxsystemctl reload apache2

https (Существующий Сертификат)


Создаем файл:


vi /etc/nginx/conf.d/example.com.conf

# Устанавливается только на главный домен, чтобы шел редирект с ip на главный домен.server {    listen 80;    server_name Ваш_ip;    return 301 https://example.com$request_uri;}server {    listen       443 ssl;    ssl on;    ssl_certificate /etc/nginx/ssl/cert.pem;    ssl_certificate_key /etc/nginx/ssl/cert.key;    server_name example.com;    set $root_path /var/www/example.com/www;    access_log /var/www/example.com/log/nginx/access_log;    error_log /var/www/example.com/log/nginx/error_log;    gzip  on;    gzip_disable "msie6";    gzip_min_length 1000;    gzip_vary on;    gzip_proxied    expired no-cache no-store private auth;    gzip_types      text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss    root   $root_path;    location / {        location ~ [^/]\.ph(p\d*|tml)$ {            try_files /does_not_exists @fallback;        }        location ~* ^.+\.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|ppt|tar|wav|bmp|rtf|js)$ {            try_files $uri $uri/ @fallback;        }        location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {            expires 7d;            access_log off;        }        location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {            add_header Access-Control-Allow-Origin "*";            expires 7d;            access_log off;        }        location = /favicon.ico {            log_not_found off;            access_log off;        }        location = /robots.txt {            log_not_found off;            access_log off;        }        location / {            try_files /does_not_exists @fallback;        }    }    # Если используется PHP    location @fallback {        proxy_pass http://127.0.0.1:8080;        proxy_redirect http://127.0.0.1:8080 /;        proxy_set_header Host $host;        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_set_header X-Forwarded-Proto $scheme;        access_log off;    }    # Если используется PHP-FPM    location @fallback {        index index.php index.html index.htm;         fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;        fastcgi_index index.php;        fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;        include fastcgi_params;        fastcgi_param DOCUMENT_ROOT $root_path;    }}

Все запросы будут переводится на локальный сервер по порту 8080, на котором работает apache, кроме обращений к статическим файлам (jpg, png, css и так далее).


Apache2


Создаем файл:


vi /etc/apache2/sites-available/example.com.conf

<VirtualHost 127.0.0.1:8080>    Define root_domain example.com    Define root_path /var/www/example.com    ServerName ${root_domain}    ServerAlias www.${root_domain}    DocumentRoot ${root_path}/www    ErrorLog ${root_path}/log/apache/error_log    TransferLog  ${root_path}/log/apache/access_log    <IfModule mod_dir.c>        DirectoryIndex index.php index.html index.htm    </IfModule>    <Directory /var/www/example.com/www>        AllowOverride All        Options Indexes ExecCGI FollowSymLinks        Require all granted    </Directory>    <IfModule setenvif_module>        SetEnvIf X-Forwarded-Proto https HTTPS=on    </IfModule>    <IfModule php7_module>        php_admin_value upload_tmp_dir ${root_path}/tmp        php_admin_value doc_root ${root_path}        php_value open_basedir    ${root_path}:/usr/local/share/smarty:/usr/local/share/pear        php_value post_max_size 512M        php_value upload_max_filesize 512M        php_flag short_open_tag On    </IfModule></VirtualHost>

Создаем ярлык:


ln -s /etc/apache2/sites-available/example.com.conf /etc/apache2/sites-enabled/example.com.conf

Проверяем


Проверяем корректность настроек конфигурационных файлов:


nginx -tapachectl configtest

Перезапускаем веб-сервер:


systemctl reload nginxsystemctl reload apache2

ngx_pagespeed on


Загрузка динамического модуля PageSpeed


Откройте файл nginx.conf:


vi /etc/nginx/nginx.conf

Добавляем в начало:


load_module modules/ngx_pagespeed.so;

Настраивается PageSpeed в http контексте, поэтому поместите эти директивы в новый файл конфигурации под названием example.com.conf в файле /etc/nginx/conf.d каталог.


# Максимальный размер кэшаpagespeed MessageBufferSize 10240;# Путь к каталогу кэшаpagespeed FileCachePath /var/cache/nginx_pagespeed;server {    listen       80;    server_name example.com;    set $root_path /var/www/example.com/www;    # запуск pagespeed    pagespeed on;    root   $root_path;    # Адрес и директория сайта    pagespeed LoadFromFile "http://www.example.com" "/var/www/example.com/www";    access_log /var/www/example.com/log/nginx/access_log;    error_log /var/www/example.com/log/nginx/error_log;    # Настройки фильтров    pagespeed RewriteLevel CoreFilters;    pagespeed EnableFilters collapse_whitespace,remove_comments;    pagespeed DisableFilters rewrite_images;    gzip  on;    gzip_disable "msie6";    gzip_min_length 1000;    gzip_vary on;    gzip_proxied    expired no-cache no-store private auth;    gzip_types      text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss;    location / {        location ~ [^/]\.ph(p\d*|tml)$ {            try_files /does_not_exists @fallback;        }        location ~* ^.+\.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|ppt|tar|wav|bmp|rtf|js)$ {            try_files $uri $uri/ @fallback;        }        location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {            expires 7d;            access_log off;        }        location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {            add_header Access-Control-Allow-Origin "*";            expires 7d;            access_log off;        }        location = /favicon.ico {            log_not_found off;            access_log off;        }        location = /robots.txt {            log_not_found off;            access_log off;        }        location / {            try_files /does_not_exists @fallback;        }        # правила обработки адресов        location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" {            add_header "" "";        }        location ~ "^/pagespeed_static/" { }        location ~ "^/ngx_pagespeed_beacon$" { }    }    # Если используется PHP        location @fallback {            proxy_pass http://127.0.0.1:8080;            proxy_redirect http://127.0.0.1:8080 /;            proxy_set_header Host $host;            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;            proxy_set_header X-Forwarded-Proto $scheme;            access_log off;       }    # Если используется PHP-FPM        location @fallback {            index index.php index.html index.htm;             fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;            fastcgi_index index.php;            fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;            include fastcgi_params;            fastcgi_param DOCUMENT_ROOT $root_path;       }}

Создаем папку для хранения кэша:


mkdir /var/cache/nginx_pagespeed/chown www-data:www-data /var/cache/nginx_pagespeed/

Проверяем конфигурацию Nginx и применяем настройки:


nginx -tnginx -s reload
Подробнее..

Перевод Гайд по DevOps для начинающих

06.07.2020 18:16:50 | Автор: admin
В чем важность DevOps, что он означает для ИТ-специалистов, описание методов, фреймворков и инструментов.

image

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

Что такое DevOps


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

Слово DevOps является объединением слов разработка (development) и операции (operations). DevOps помогает увеличить скорость доставки приложений и услуг. Это позволяет организациям эффективно обслуживать своих клиентов и становиться более конкурентоспособными на рынке. Проще говоря, DevOps это согласованность между разработкой и ИТ-операциями с более эффективным взаимодействием и сотрудничеством.

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

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

Вызовы для команды разработчиков


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

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


Проблемы, с которыми сталкивается операционная группа


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

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


Как DevOps решает проблемы разработки и операций


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

  • Снизить процент отказов при выпуске новых релизов
  • Увеличить частоту развертывания
  • Достичь более быстрого среднего времени на восстановление в случае выхода нового релиза приложения.
  • Сократить время на исправления


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

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

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


image

Противостояние DevOps, Agile и традиционного IT


DevOps часто обсуждается в связи с другими ИТ-практиками, в частности, гибкой и водопадной ИТ-инфраструктурой.

Agile это набор принципов, ценностей и методов производства программного обеспечения. Так, например, если у вас есть идея, которую вы хотите преобразовать в программное обеспечение, вы можете использовать принципы и ценности Agile. Но это программное обеспечение может работать только в среде разработки или тестирования. Вам нужен простой и безопасный способ быстро и с высокой повторяемостью переносить программное обеспечение в производственную среду, а путь лежит через инструменты и методы DevOps. Гибкая методология разработки программного обеспечения сосредоточена на процессах разработки, а DevOps отвечает за разработку и развертывание самым безопасным и надежным способом.

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

Традиционные процессы Процессы в DevOps
После размещения заказа на новые серверы команда разработчиков работает над тестированием. Оперативная группа работает над обширной документацией, необходимой на предприятиях для развертывания инфраструктуры. После размещения заказа на новые серверы, команды разработчиков и операторов совместно работают над процессами и документооборотом для установки новых серверов. Это позволяет лучше понять требования к инфраструктуре.
Искажена информация о восстановлении после отказа, избыточности, расположении центров обработки данных и требованиях к хранилищам, так как отсутствуют входные данные от команды разработчиков, которая обладает глубокими знаниями в области применения. Подробная информация о преодолении отказа, избыточности, аварийном восстановлении, расположении центров данных и требованиях к хранилищам известна и корректна благодаря вкладу команды разработчиков.
Оперативная группа не имеет представления о прогрессе команды разработчиков. Также она разрабатывает план мониторинга на основе собственных представлений.
Оперативная группа полностью осведомлена о прогрессе, достигнутом командой разработчиков. Она также взаимодействует с командой разработчиков, и они совместно разрабатывают план мониторинга, который удовлетворяет IT и потребности бизнеса. Они также используют инструменты мониторинга производительности приложений (APM).
Нагрузочный тест, проводимый перед запуском приложения, приводит к сбою приложения, что задерживает его запуск. Нагрузочный тест, проводимый перед запуском приложения, приводит к снижению производительности. Команда разработчиков быстро устраняет узкие места, и приложение запускается вовремя.


Жизненный цикл DevOps


DevOps подразумевает принятие определенных общепринятых практик.

Непрерывное планирование


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

Совместное развитие


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

Непрерывное тестирование


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

Непрерывные выпуск и развертывание


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

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

Непрерывный мониторинг


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

Постоянная обратная связь и оптимизация


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

image

Преимущества DevOps


DevOps может способствовать созданию среды, в которой разработчики и операторы работают как одна команда для достижения общих целей. Важной вехой в этом процессе является внедрение непрерывной интеграции и непрерывной доставки (CI/CD). Эти методики позволят командам быстрее выводить программное обеспечение на рынок с меньшим количеством ошибок.

Важными преимуществами DevOps являются:

  • Предсказуемость: DevOps предлагает значительно более низкую частоту отказов при выпуске новых релизов.
  • Поддерживаемость: DevOps обеспечивает легкое восстановление в случае сбоев в новом релизе или отключения приложения.
  • Воспроизводимость: Система контроля версий сборки или кода позволяет восстанавливать более ранние версии по мере необходимости.
  • Более высокое качество: Решение проблем с инфраструктурой улучшает качество разработки приложений.
  • Время выхода на рынок: Оптимизация доставки программного обеспечения сокращает время выхода на рынок на 50%.
  • Снижение риска: Обеспечение безопасности в жизненном цикле программного обеспечения снижает количество дефектов на протяжении всего жизненного цикла.
  • Экономическая эффективность: Стремление к экономической эффективности при разработке программного обеспечения нравится высшему руководству.
  • Устойчивость: Программная система более стабильна, безопасна, а изменения можно проверять.
  • Более крупная кодовая база разбивается на управляемые части: DevOps основан на гибких методах разработки, которые позволяют разбивать большую кодовую базу на более мелкие и управляемые части.


Принципы DevOps


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

Разрабатывайте и тестируйте в среде, похожей на производственную


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

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

Развертывание с воспроизводимыми, надежными процессами


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

Мониторинг и проверка качества работы


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

Усовершенствование циклов обратной связи


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

Dev


  • Планирование: Kanboard, Wekan и другие альтернативы Trello; GitLab, Tuleap, Redmine и другие альтернативы JIRA; Mattermost, Roit.im, IRC и другие альтернативы Slack.
  • Написание кода: Git, Gerrit, Bugzilla; Jenkins и другие инструменты с открытым исходным кодом для CI/CD
  • Сборка: Apache Maven, Gradle, Apache Ant, Packer
  • Тесты: JUnit, Cucumber, Selenium, Apache JMeter


Ops


  • Выпуск, развертывание, операции: Kubernetes, Nomad, Jenkins, Zuul, Spinnaker, Ansible, Apache ZooKeeper, etcd, Netflix Archaius, Terraform
  • Мониторинг: Grafana, Prometheus, Nagios, InfluxDB, Fluentd, и другие, покрытые в этом руководстве


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

В заключение


DevOps это все более популярная методология, целью которой является объединение разработчиков и операторов в единое целое. Она уникальна, отличается от традиционных IT-операций и дополняет Agile (но не является столь же гибкой).

image

Узнайте подробности, как получить востребованную профессию с нуля или Level Up по навыкам и зарплате, пройдя платные онлайн-курсы SkillFactory:




Полезное


Подробнее..

Из песочницы Введение в Traefik 2.0

28.06.2020 22:13:05 | Автор: admin

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


Обратный прокси-сервер (reverse proxy, реверс-прокси) служит для ретрансляции запросов из внешней сети к каким-либо серверам/сервисам внутренней сети (например веб-сервера, БД или файловые хранилища) и позволяет:


  • обеспечить сокрытие структуры внутренней сети и подробностей о находящейся в ней сервисах;
  • осуществлять балансировку нагрузки (load balancing) между экземплярами одного и того же сервиса или серверами с одинаковыми задачами;
  • обеспечить зашифрованное (HTTPS) соединение между клиентом и любым сервисом, в таком случае SSL сессия создается между клиентом и прокси, а между прокси и сервисом во внутренней сети устанавливается незашифрованное HTTP соединение, если сервис поддерживает HTTPS то можно организовать зашифрованное соединение и во внутренней сети;
  • организовать контроль доступа к сервисам (аутентификацию клиента), а также установить файрвол (брандмауэр).

В статье будет описываться использование Traefik в Docker в качестве реверс-прокси для других контейнеров Docker, а также не контейнеризированных сервисов.


image


Введение


Traefik позиционируется разработчиками как Edge Router, то есть можно направить его непосредственно в глобальную сеть одной стороной и во внутреннюю другой. Если у читателя создалось впечатление что таким образом создается единая точка отказа всей системы, то так и есть, но есть несколько моментов: во-первых, Traefik имеет развитый функционал для автоматического восстановления при сбоях; во-вторых, существует Traefik EE платная версия, в которой помимо прочих преимуществ имеется HA (Hight Availability, Высокая доступность), что подразумевает распределение нагрузки между несколькими экземплярами сервиса (узлами), таким образом при отказе одного его задачи перераспределяются на другие узлы, а отказавший узел отключается и затем немедленно вводится обратно в эксплуатацию. В качестве примечания отметим, что в статье будет рассматриваться бесплатная версия Traefik.


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


Список основных провайдеров:


  • Docker
  • Kubernetes
  • Consul Catalog
  • Marathon
  • Rancher
  • File

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


Файл конфигурации Traefik, а также файлы для провайдера File могут быть написаны на TOML либо YAML, в статье будут приведены примеры на YAML так как этот синтаксис больше нравится автору, а какой-либо функциональной разницы между ними нет, а также не составляет трудности переписать файлы на другой формат конфигурации. Traefik будет развернут в Docker. Для развертывания будет использоваться docker-compose, для обеспечения простоты повторного развертывания.


*В статье будут приведены команды для ОС Linux.


Деплой Traefik


Предполагается что у читателя установлены и настроены docker и docker-compose, их установка выходит за рамки этой статьи.


Создадим в домашней папке пользователя папку traefik, в которой будем хранить всю конфигурацию, и перейдем в эту папку


mkdir ~/traefikcd ~/traefik

Для развертывания (деплоя) Traefik создадим файл docker-compose.yml и отредактируем его в любом удобном вам редакторе. Для начала этот файл будет иметь следующий вид:


version: '3'services:  traefik:    image: traefik:v2.2    container_name: traefik    restart: unless-stopped    security_opt:      - no-new-privileges:true    ports:      - 80:80      - 443:443     volumes:      - /etc/localtime:/etc/localtime:ro      - /var/run/docker.sock:/var/run/docker.sock:ro      - ./data/traefik.yml:/traefik.yml:ro

Во внешний мир будут смотреть порты 80 и 443 для HTTP и HTTPS соответственно. Также пробросим в контейнер сокет демона Docker для работы механизма автоматической конфигурации. Конфигурацию Traefik будем описывать в файле traefik.yml находящемся в папке data в текущей директории.


Если для разделения внешней и внутренней сетей используются networks Docker-а, то Traefik должен иметь доступ к внешней сети и ко всем внутренним в которых находятся целевые сервисы.

Создадим и будем постепенно наполнять этот файл.


Для начала опишем точки входа в наш прокси (те самые порты, которые смотрят во внешний мир):


entryPoints:  http:    address: ":80"  https:    address: ":443"

Здесь http и https это просто названия (могут быть любыми, хоть a и b) и были выбраны так для удобства.


Теперь добавим первого провайдера Docker, это делается следующим образом:


providers:  docker:    endpoint: "unix:///var/run/docker.sock"    exposedByDefault: false

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


Следующим шагом развернем весь HTTP трафик в HTTPS (почему это было сделано именно таким образом будет описано дальше):


http:  routers:    http-catchall:      rule: HostRegexp(`{host:.+}`)      entrypoints:      - http      middlewares:      - redirect-to-https  middlewares:    redirect-to-https:      redirectScheme:        scheme: https        permanent: false

Traefik может проксировать не только HTTP трафик, но и просто TCP и UDP, поэтому указываем что этот блок конфигурации относится к http.


Здесь мы встречаем два из трех основных элементов роутинга в Traefik 2 routers (роутеры) и middlewares(промежуточные обработчики), рассмотрим их подробнее.


Роутеры


Рассмотрим на примере описанного выше роутера:


  • http-catchall имя роутера, может быть любым, но обязано быть уникальным в рамках блока http всей конфигурации Traefik;
  • rule: правило, описывает какой трафик попадает в этот роутер, в данном случае описывается HostRegexp, то есть поле Host запроса должно попадать под регулярное выражение .+ (то есть любое), здесь мы видим специфику регулярных выражений в Traefik оно должно быть заключено в фигурные скобки и иметь наименование (host в данном случае), то есть синтаксис имеем вид {name:reg_exp};
  • entrypoints массив описанных ранее точек входа, которые будут использоваться этим роутером, в нашем случае используем только http;
  • middlewares массив промежуточных обработчиков, куда попадает трафик перед передачей к сервису (сервисы будут рассмотрены позднее).

Подробнее о различных видах правил можно прочитать в документации.


Промежуточные Обработчики


  • redirect-to-https имя обработчика, может быть любым, но обязано быть уникальным в рамках блока http всей конфигурации Traefik;
  • redirectScheme тип обработчика, в данном случае изменение схемы запроса;
  • scheme: https вынуждает клиента использовать схему HTTPS при запросе к прокси;
  • permanent: false говорит клиенту что это не навсегда и может измениться в будущем.

Подробнее о различных обработчиках можно прочитать в документации (дальше в статье будет описан ещё один обработчик BasicAuth).


Полностью файл traefik.yml
entryPoints:  http:    address: ":80"  https:    address: ":443"http:  routers:    http-catchall:      rule: hostregexp(`{host:.+}`)      entrypoints:      - http      middlewares:      - redirect-to-https  middlewares:    redirect-to-https:      redirectScheme:        scheme: https        permanent: falseproviders:  docker:    endpoint: "unix:///var/run/docker.sock"    exposedByDefault: false

Таким образом мы получим первую рабочую конфигурацию. Выполняем


sudo docker-compose up -d

И прокси должен подняться, можно почитать логи (sudo docker-compose logs -f) и убедиться, что всё работает.


Let's Encrypt


Поскольку мы хотим использовать HTTPS нам нужно где-то взять SSL сертификаты для сервисов, есть возможность использовать свои сертификаты, но мы настроем автоматическое получение бесплатных сертификатов от Let's Encrypt.


Добавим в конфигурацию (traefik.yml) новый блок:


certificatesResolvers:  letsEncrypt:    acme:      email: postmaster@example.com      storage: acme.json      caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"      httpChallenge:        entryPoint: http

Здесь:


  • letsEncrypt это просто имя резолвера;
  • acme тип резолвера (других типов в общем-то и нет);
  • storage файл, в котором хранятся сведения о полученных сертификатах;
  • httpChallenge тип acme-челенжа, дополнительно указываем параметр точку входа;
  • caServer: "https://acme-staging-v02.api.letsencrypt.org/directory" позволяет использовать не основной сервер Let's Encrypt в тестовых целях, так как основной имеет строгие лимиты API (можно закомментировать, когда наладите получение сертификатов).

Также дополним пункт volumes в файле docker-compose.yml, чтобы сохранять сертификаты при перезапуске контейнера (предварительно создав файл data/acme.json):


    volumes:      - /etc/localtime:/etc/localtime:ro      - /var/run/docker.sock:/var/run/docker.sock:ro      - ./data/traefik.yml:/traefik.yml:ro      - ./data/acme.json:/acme.json

Docker провайдер


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


Для описания конфигурации в Docker Traefik использует метки (labels) контейнеров. Допишем в наш файл docker-compose.yml:


    labels:      - "traefik.enable=true"      - "traefik.http.routers.traefik.entrypoints=https"      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"      - "traefik.http.routers.traefik.tls=true"      - "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"      - "traefik.http.routers.traefik.service=api@internal"      - "traefik.http.services.traefik-traefik.loadbalancer.server.port=888"

Разберем построчно:
traefik.enable=true указываем что Traefik должен обеспечить доступ к этому контейнеру, необходимо для всего остального;
traefik.http.routers.traefik.entrypoints=https создаем новый роутер с точной входа https;
traefik.http.routers.traefik.rule=Host(traefik.example.com) роутер будет жить по адресу traefik.example.com;
traefik.http.routers.traefik.tls=true указываем что используется TLS;
traefik.http.routers.traefik.tls.certresolver=letsEncrypt указываем через какой резолвер получать сертификат;
traefik.http.routers.traefik.service=api@internal указываем, что сервер за этим роутером api@internal, это специальный сервис, созданный по умолчанию, это как раз и есть дашбоард который мы хотели увидеть;
traefik.http.services.traefik-traefik.loadbalancer.server.port=888 издержки интерфейса, без этого не заработает, но можно написать абсолютно любую цифру.


Дашбоард надо включить, для этого добавим в файл traefik.yml:


api:  dashboard: true

На данном этапе можно пересоздать контейнер (нужно так как мы меняли docker-compose.yml):


sudo docker-compose down && sudo docker-compose up -d

Когда всё поднимется можно перейти на traefik.example.com (тут на самом деле должен быть ваш домен, который направлен на хост с Traefik) и увидеть дашборд.


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


Для начала сгенерируем для нас строку с логином и паролем (admin/password)^


$ htpasswd -nb admin passwordadmin:$apr1$vDSqkf.v$GTJOtsd9CBiAFFnHTI2Ds1

Теперь добавим в наш docker-compose.yml новые строчки:


      - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$vDSqkf.v$$GTJOtsd9CBiAFFnHTI2Ds1"      - "traefik.http.routers.traefik.middlewares=traefik-auth"

Заметим, что символы $ из полученной строки мы должны заменить на $$.
traefik.http.middlewares.traefik-auth.basicauth.users=... создаем middleware типа basicauth с параметром users;
traefik.http.routers.traefik.middlewares=traefik-auth указываем что роутер traefik использует только что-то созданный middleware.


Весь docker-compose.yml
version: '3'services:  traefik:    image: traefik:v2.2    container_name: traefik    restart: unless-stopped    security_opt:      - no-new-privileges:true    ports:      - 80:80      - 443:443     volumes:      - /etc/localtime:/etc/localtime:ro      - /var/run/docker.sock:/var/run/docker.sock:ro      - ./data/traefik.yml:/traefik.yml:ro      - ./data/acme.json:/acme.json    labels:      - "traefik.enable=true"      - "traefik.http.routers.traefik.entrypoints=https"      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"      - "traefik.http.routers.traefik.tls=true"      - "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"      - "traefik.http.routers.traefik.service=api@internal"      - "traefik.http.services.traefik-traefik.loadbalancer.server.port=888"      - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$vDSqkf.v$$GTJOtsd9CBiAFFnHTI2Ds1"      - "traefik.http.routers.traefik.middlewares=traefik-auth"

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


Приведем также кофигурацию некого другого сервиса, развернутого через docker-compose (аналогично работает и для обычного docker):


    labels:      - "traefik.enable=true"      - "traefik.http.routers.test.entrypoints=https"      - "traefik.http.routers.test.rule=Host(`test.example.com`)"      - "traefik.http.routers.test.tls=true"      - "traefik.http.routers.test.tls.certresolver=letsEncrypt"      - "traefik.http.services.test-service.loadbalancer.server.port=80"

Здесь одна новая метка traefik.http.services.test-service.loadbalancer.server.port=80 присваиваем этому контенеру имя сервиса test-service и порт 80, он автоматически присоединится к роутеру test, Traefik автоматически постороит маршрут до этого контенера, даже если он находится на другом хосте.


File провайдер


С контейнерами работает, а как быть если есть какой-то сервис работающий на выделенном хосте (пускай IP 192.168.1.222 и порт 8080) и мы его хотим пропустить через этот же прокси, заодно закрыв его с помощью HTTPS. Для этого есть решение.


Добавим в docker-compose.yml ещё один volume:


    volumes:      - /etc/localtime:/etc/localtime:ro      - /var/run/docker.sock:/var/run/docker.sock:ro      - ./data/traefik.yml:/traefik.yml:ro      - ./data/custom/:/custom/:ro      - ./data/acme.json:/acme.json

Пускай описания таких хостов у нас будут лежать в data/custom/ (а что, вдруг ещё появятся).


Добавим в traefik.yml конфигурацию file провайдера для этих файлов:


providers:...  file:    directory: /custom    watch: true

Директория следует из нашего docker-compose.yml, а watch: true значит что Traefik будет автоматически обновлять конфигурацию при обнаружении изменений в этих файлах (помните про обновление конфигурации на лету, вот работает даже для файлов, а не только для оркестраторов).


Перезапускаем Traefik и теперь можно создать файл с описанием нашего отдельного хоста (data/custom/host.yml):


http:  routers:    host:      entryPoints:       - https      service: service-host      rule: Host(`host.example.com`)       tls:        certResolver: letsEncryptservices:    service-host:        loadBalancer:        servers:        - url: http://192.168.1.222:8080/        passHostHeader: true 

Роутер описывался раньше, тут добавилось только service: service-host связь с нашим сервисом, и конфигурация для TLS.


Описание для сервиса имеет вид:


имя_сервиса:  loadBalancer:    servers:    - хосты для балансировки нагрузки    - ...

Дополнительно мы указываем параметр passHostHeader: true чтобы тот хост думал, что он на самом деле смотрит в сеть и прокси нет.


Заключение


Приведем содержание файлов с полученными конфигурациями:


docker-compose.yml
version: '3'services:  traefik:    image: traefik:v2.2    container_name: traefik    restart: unless-stopped    security_opt:      - no-new-privileges:true    ports:      - 80:80      - 443:443     volumes:      - /etc/localtime:/etc/localtime:ro      - /var/run/docker.sock:/var/run/docker.sock:ro      - ./data/traefik.yml:/traefik.yml:ro      - ./data/custom/:/custom/:ro      - ./data/acme.json:/acme.json    labels:      - "traefik.enable=true"      - "traefik.http.routers.traefik.entrypoints=https"      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"      - "traefik.http.routers.traefik.tls=true"      - "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"      - "traefik.http.routers.traefik.service=api@internal"      - "traefik.http.services.traefik-traefik.loadbalancer.server.port=888"      - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$vDSqkf.v$$GTJOtsd9CBiAFFnHTI2Ds1"      - "traefik.http.routers.traefik-secure.middlewares=traefik-auth"

data/traefik.yml
api:  dashboard: trueentryPoints:  http:    address: ":80"  https:    address: ":443"http:  routers:    http-catchall:      rule: hostregexp(`{host:.+}`)      entrypoints:      - http      middlewares:      - redirect-to-https  middlewares:    redirect-to-https:      redirectScheme:        scheme: https        permanent: falseproviders:  docker:    endpoint: "unix:///var/run/docker.sock"    exposedByDefault: false  file:    directory: /custom    watch: truecertificatesResolvers:  letsEncrypt:    acme:      email: postmaster@example.com      storage: acme.json      #caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"      httpChallenge:        entryPoint: http

data/custom/host.yml
http:  routers:    host:      entryPoints:       - https      service: service-host      rule: Host(`host.example.com`)       tls:        certResolver: letsEncryptservices:    service-host:        loadBalancer:        servers:        - url: http://192.168.1.222:8080/        passHostHeader: true 

В статье было описано как настроить Traefik в качестве обратного HTTP прокси при использовании провайдеров Docker и File. Было настроено использование бесплатных SSL сертификатов от Let's Encrypt, настроено принудительное перенаправление клиентов на протокол HTTPS, а также приведен пример настройки аутентификации клиентов прокси перед доступом к сервисам.


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


Бонус. Мониторинг


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


Добавим новую точку входа:
data/traefik.yml:


entryPoints:...  metrics:    address: ":8082"

docker-compose.yml:


    ports:      - 80:80      - 443:443       - 8082:8082

И добавим возможность собирать с этого порта метрики для Prometheus, data/traefik.yml:


metrics:  prometheus:    entryPoint: metrics

Осталось только настроить Prometheus на сбор метрик с traefik_ip:8082.


Приведем содержание файлов с полученными конфигурациями:


docker-compose.yml
version: '3'services:  traefik:    image: traefik:v2.2    container_name: traefik    restart: unless-stopped    security_opt:      - no-new-privileges:true    ports:      - 80:80      - 443:443       - 8082:8082    volumes:      - /etc/localtime:/etc/localtime:ro      - /var/run/docker.sock:/var/run/docker.sock:ro      - ./data/traefik.yml:/traefik.yml:ro      - ./data/custom/:/custom/:ro      - ./data/acme.json:/acme.json    labels:      - "traefik.enable=true"      - "traefik.http.routers.traefik.entrypoints=https"      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"      - "traefik.http.routers.traefik.tls=true"      - "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"      - "traefik.http.routers.traefik.service=api@internal"      - "traefik.http.services.traefik-traefik.loadbalancer.server.port=888"      - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$vDSqkf.v$$GTJOtsd9CBiAFFnHTI2Ds1"      - "traefik.http.routers.traefik-secure.middlewares=traefik-auth"

data/traefik.yml
api:  dashboard: trueentryPoints:  http:    address: ":80"  https:    address: ":443"  metrics:    address: ":8082"metrics:  prometheus:    entryPoint: metricshttp:  routers:    http-catchall:      rule: hostregexp(`{host:.+}`)      entrypoints:      - http      middlewares:      - redirect-to-https  middlewares:    redirect-to-https:      redirectScheme:        scheme: https        permanent: falseproviders:  docker:    endpoint: "unix:///var/run/docker.sock"    exposedByDefault: false  file:    directory: /custom    watch: truecertificatesResolvers:  letsEncrypt:    acme:      email: postmaster@example.com      storage: acme.json      #caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"      httpChallenge:        entryPoint: http
Подробнее..
Категории: Linux , Devops , Docker , Traefik

Из песочницы Развертывание и настройка аутентификации node-red на docker-compose

28.06.2020 10:17:00 | Автор: admin

Развертывание и настройка аутентификации node-red на docker-compose


Развертывания node-red на docker-compose с включением авторизации и использованием docker volume.

Создаем файл docker-compose.yml:

version: "3.7"services:  node-red:    image: nodered/node-red    environment:      - TZ=Europe/Moscow    ports:      - "11880:1880" # 11880 - порт для подключения к контейнеру, 1880 - порт на котором работает node-red внутри контейнера.    volumes:      - "node-red:/data" # node-red - каталог который выделит docker для хранения данных, /data - каталог внутри контейнера.    restart: alwaysvolumes:  node-red: # создание каталога node-red на хосте.

Запускаем контейнер в отладочном режиме (первый запуск должен быть без ключа `-d`, для просмотра ошибок, когда такие появятся):

$ docker-compose up node-redCreating node-red_node-red_1_3e3e59f5e044 ... doneAttaching to node-red_node-red_1_bca4cb987984node-red_1_bca4cb987984 |node-red_1_bca4cb987984 | > node-red-docker@1.0.3 start /usr/src/node-rednode-red_1_bca4cb987984 | > node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS "--userDir" "/data"...

Останавливаем контейнер и запускаем команду для просмотра volume:

$ docker volume lsDRIVER              VOLUME NAMElocal               node-red_node-red

Просматриваем детальную информацию по volume:

$ docker volume inspect node-red_node-red[    {        "CreatedAt": "2020-05-02T18:37:33Z",        "Driver": "local",        "Labels": {            "com.docker.compose.project": "node-red",            "com.docker.compose.version": "1.23.0",            "com.docker.compose.volume": "node-red"        },        "Mountpoint": "/var/lib/docker/volumes/node-red_node-red/_data", # расоложение нашего каталога        "Name": "node-red_node-red",        "Options": null,        "Scope": "local"    }]

Переходим в каталог volume. В этом каталоге уже находятся фйлы которые docker создал при развертывании контейнера.

$ sudo ls /var/lib/docker/volumes/node-red_node-red/_datalib  package.json  settings.js

Нас интересует файл settings.js. Открываем его и ищем кусок кода adminAuth. Раскомментируем его.

 // Securing Node-RED    // -----------------    // To password protect the Node-RED editor and admin API, the following    // property can be used. See http://nodered.org/docs/security.html for details.    adminAuth: {        type: "credentials",        users: [{            username: "admin",            password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",            permissions: "*"        }]    },

В ключ password: надо вставить hash пароля node-red.

Получение hash пароля node-red
На любую машину с node.js установить пакет node-red-admin.

npm i node-red-admin -g

Запустить пакет и задать пароль:

node-red-admin hash-pw


Запускаем контейнер и подключаемся к порту 11880.

http://192.168.0.100:11880/

Должно появиться окно авторизации.

image

Вводим логин-пароль.

Если все работает, перезапускаем контейнер с ключом -d.

$ docker-compose up -d node-red

Как-то так.
Подробнее..
Категории: Devops , Docker , Docker-compose , Node-red , Auth

Из песочницы Происхождение DevOps что кроется в названии?

28.06.2020 14:08:19 | Автор: admin
Привет, Хабр! Представляю вашему вниманию перевод статьи The Origins of DevOps: Whats in a Name? автора Steve Mezak.

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

До 2007: Идеальная цепь событий


До 2007 года серия обстоятельств обстоятельств в конце концов дала рождение тому, что сегодня известно как DevOps.

Бережливое производство уже зарекомендовало себя как лучшую практику. Также известное как производственная система Toyota, бережливое производство стремится к оптимизации процессов в производственном цеху. (Кстати, руководство Toyota изначально вдохновлялось оригинальными методами сборочной линии, представленной Ford Motor Company). Постоянное совершенствование это мантра для бережливого производства. На практике постоянно оцениваются следующие пути:

  1. Поддержка уровня запасов сырья и готовых изделий на минимуме. Бережливое производство означает минимальное количество запасов сырья для производства товаров и минимальное количество уже готовых изделий, ожидающих распределения по заказам или отгрузки.
  2. Минимизация очереди заказов. Идеально, если полученные заказы сразу переходят в состояние завершённых. Ключевой метрикой бережливого производства всегда будет время от поступления заказа до поставки.
  3. Максимизация эффективности производственного процесса. Реорганизация процессов и улучшенная автоматизация объединяются с целью настолько быстрого производства товаров, насколько это возможно. Каждый участок производства на всём пути (резка, сварка, сборка, тестирование и т.д.) оценивается на предмет неэффективности.

В мире IT традиционные методы каскадной модели разработки программного обеспечения уже уступили дорогу быстрым итеративным методам, таким как Agile. Скорость была боевым кличем, даже если качество иногда ухудшалось в погоне за быстрой разработкой и развёртыванием. Примерно так же облачные вычисления, в частности Infrastructure-as-a-Service (IaaS) и Platform-as-a-Service (PaaS) зарекомендовали себя как зрелые решения в процессах и инфраструктуре IT.

Наконец, недавно начали появляться наборы инструментов для Continuous Integration (CI). Представление об инструментах CI было рождено и представлено Гради Бучем ещё в 1991 году в его Методе Буча.

2007-2008: Разочарованный бельгиец


Бельгийский консультант, менеджер проектов и практик Agile Патрик Дебуа принял назначение от министерства правительства Бельгии, чтобы помочь с миграцией центров обработки данных. В частности, он занимался сертификацией и проверкой готовности. Обязанности требовали от него согласовывать действия и выстраивать взаимоотношения между группами разработки программного обеспечения и группами по эксплуатации серверов, баз данных и сетей. Его разочарование по поводу отсутствия сплочённости и стен, разделяющих методы разработки и эксплуатации, заронили в него досаду. Стремление к лучшему скоро привело Дебуа к действию.
В 2008 году на конференции по Agile в Торонто Эндрю Шефер предложил модерировать специально устроенную неформальную встречу для обсуждения темы "Agile-инфраструктура". И только один человек пришёл обсудить тему: Патрик Дебуа. Их дискуссия и обмен идеями продвинули концепцию системного администрирования по Agile. В этом же году Дебуа и Шефер создали умеренно успешную группу Agile Systems Administrator в Google.

2009: Дело о сотрудничестве Dev и Ops


На конференции O'Reilly Velocity два сотрудника Flickr, старший вице-президент по техническим операциям Джон Оллспоу и технический директор Пол Хэммонд, представили ныне знаменитую презентацию 10 развёртываний в день: сотрудничество Dev и Ops во Flickr.

Презентация была в стиле драмы, Оллспоу и Хэммонд разыгрывали сложное взаимодействие между представителями Development и Operations в процессе развёртывания программного обеспечения вместе с поиском виноватых и взаимными обвинениями в духе Это не мой код, это всё твои компьютеры! Их презентация подтвердила, что единственный разумный выход состоит в том, чтобы деятельность по разработке и развёртыванию программного обеспечения была плавной, прозрачной и полностью интегрированной. Со временем эта презентация стала легендарной, и теперь исторически рассматривается как основополагающая веха, когда в индустрии IT возник запрос на методологию, известную сегодня как DevOps.

2010: DevOps в Соединённых Штатах Америки


С ростом числа сторонников, конференция DevOpsDays впервые была проведена в Соединённых Штатах Америки в Маунтин-Вью (Калифорния) сразу же после ежегодной конференции Velocity. Перенесёмся в 2018 год: запланировано более 30 конференций DevOpsDays, включая десятки в Соединённых Штатах.

2013: Проект Феникс


Для многих из нас ещё одним примечательным моментом в истории DevOps стало издание книги Проект Феникс авторства Джина Кима, Кевина Бера и Джорджа Саффорда. В этом романе рассказывается история IT-менеджера, попавшего в безвыходную ситуацию: ему поручили спасти критически важный проект по развитию электронной коммерции, который пошёл не так. Таинственный наставник менеджера член совета директоров, увлечённый методами бережливого производства подсказывает главному герою новые способы осмысления IT и разработки приложений, предвосхищая концепцию DevOps. Кстати, Проект Феникс вдохновил нас написать книгу Переходи на аутсорсинг, иначе... о похожей истории из бизнеса, когда вице-президент по программному обеспечению использует DevOps в ходе разработки нового крупного продукта на аутсорсинге.

DevOps для будущего


Стоит описать DevOps скорее как путешествие или, возможно, устремление, нежели как конечный пункт назначения. DevOps, как и бережливое производство, стремится к постоянному совершенствованию, повышению производительности и эффективности и даже постоянному развёртыванию. Автоматизированные инструменты для поддержки DevOps продолжают развиваться.

Многое было достигнуто с момента создания DevOps в последнее десятилетие, и мы ожидаем увидеть ещё больше в 2018 году и в будущем.
Подробнее..
Категории: Devops

Категории

Последние комментарии

© 2006-2020, personeltest.ru