HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>Предлагаем вашему вниманию проектную работу одного из студентов OTUS, выполненную им в рамках обучения на курсе "<a>Администратор Linux</a>". Это высокодоступная кластерная файловая система, интегрированная с кластером СУБД, централизованной системой телеметрии, аудита и авторизации.</p>
1 <p>Предлагаем вашему вниманию проектную работу одного из студентов OTUS, выполненную им в рамках обучения на курсе "<a>Администратор Linux</a>". Это высокодоступная кластерная файловая система, интегрированная с кластером СУБД, централизованной системой телеметрии, аудита и авторизации.</p>
2 <h2>1. Описание стенда</h2>
2 <h2>1. Описание стенда</h2>
3 <p>Для развёртывания всех компонент системы использовался Vagrant, с помощью которого разворачивался стенд, состоящий из 7 виртуальных машин: - 1 виртуальная машина - центральный сервер телеметрии, аудита и авторизации; - 6 виртуальных машин - кластерная файловая система, кластер СУБД.</p>
3 <p>Для развёртывания всех компонент системы использовался Vagrant, с помощью которого разворачивался стенд, состоящий из 7 виртуальных машин: - 1 виртуальная машина - центральный сервер телеметрии, аудита и авторизации; - 6 виртуальных машин - кластерная файловая система, кластер СУБД.</p>
4 <p>Для экономии ресурсов совместили 3 узла кластера СУБД с узлами кластерной файловой системы. Для развёртывания всех компонент системы использовался<strong>Ansible</strong>.</p>
4 <p>Для экономии ресурсов совместили 3 узла кластера СУБД с узлами кластерной файловой системы. Для развёртывания всех компонент системы использовался<strong>Ansible</strong>.</p>
5 <p>Названия виртуальных машин: • ns.otus.test (ns) - центральный сервер телеметрии, аудита и авторизации; • master01.otus.test (master01) - узел кластерной ФС, узел кластера СУБД; • master02.otus.test (master02) - узел кластерной ФС, узел кластера СУБД; • master03.otus.test (master03) - узел кластерной ФС, узел кластера СУБД; • node01.otus.test (node01) - узел кластерной ФС; • node02.otus.test (node04) - узел кластерной ФС; • node03.otus.test (node03) - узел кластерной ФС.</p>
5 <p>Названия виртуальных машин: • ns.otus.test (ns) - центральный сервер телеметрии, аудита и авторизации; • master01.otus.test (master01) - узел кластерной ФС, узел кластера СУБД; • master02.otus.test (master02) - узел кластерной ФС, узел кластера СУБД; • master03.otus.test (master03) - узел кластерной ФС, узел кластера СУБД; • node01.otus.test (node01) - узел кластерной ФС; • node02.otus.test (node04) - узел кластерной ФС; • node03.otus.test (node03) - узел кластерной ФС.</p>
6 <h3>1.1 Центральный сервер телеметрии, аудита и авторизации</h3>
6 <h3>1.1 Центральный сервер телеметрии, аудита и авторизации</h3>
7 <p>Для устойчивой работы всех компонент стенда была развёрнута первая виртуальная машина, на которую установили следующие сервисы: •<strong>DNS</strong>- локальный сервер разрешения имён; •<strong>NTP</strong>- локальный сервер точного времени; •<strong>Kerberos</strong>- локальный сервер авторизации; •<strong>Prometheus</strong>- центральный сервер сбора телеметрии; •<strong>Grafana</strong>- сервер визуализации телеметрии; •<strong>Netdata</strong>- центральный сервер сбора и визуализации телеметрии в реальном времени; •<strong>Lizardfs-cgi</strong>- сервер отображения состояния кластерной файловой системы; •<strong>Lizardfs-client</strong>- клиент для подключения к кластерной файловой системе; •<strong>Haproxy</strong>- балансировщик нагрузки на кластер СУБД; •<strong>Etcd</strong>- key-value база данных для кластера СУБД; •<strong>Auditd</strong>- центральный сервер для сбора событий аудита всех компонент системы; •<strong>Nginx</strong>- web-сервер, работающий в режиме reverse-proxy; •<strong>Autofs</strong>- сервиc автомонтирования сетевых ресурсов.</p>
7 <p>Для устойчивой работы всех компонент стенда была развёрнута первая виртуальная машина, на которую установили следующие сервисы: •<strong>DNS</strong>- локальный сервер разрешения имён; •<strong>NTP</strong>- локальный сервер точного времени; •<strong>Kerberos</strong>- локальный сервер авторизации; •<strong>Prometheus</strong>- центральный сервер сбора телеметрии; •<strong>Grafana</strong>- сервер визуализации телеметрии; •<strong>Netdata</strong>- центральный сервер сбора и визуализации телеметрии в реальном времени; •<strong>Lizardfs-cgi</strong>- сервер отображения состояния кластерной файловой системы; •<strong>Lizardfs-client</strong>- клиент для подключения к кластерной файловой системе; •<strong>Haproxy</strong>- балансировщик нагрузки на кластер СУБД; •<strong>Etcd</strong>- key-value база данных для кластера СУБД; •<strong>Auditd</strong>- центральный сервер для сбора событий аудита всех компонент системы; •<strong>Nginx</strong>- web-сервер, работающий в режиме reverse-proxy; •<strong>Autofs</strong>- сервиc автомонтирования сетевых ресурсов.</p>
8 <p>DNS, NTP, Kerberos и Etcd использовались для интеграции сервисов и их компонент.</p>
8 <p>DNS, NTP, Kerberos и Etcd использовались для интеграции сервисов и их компонент.</p>
9 <h3>1.2 Узлы файловой кластерной системы и кластера СУБД</h3>
9 <h3>1.2 Узлы файловой кластерной системы и кластера СУБД</h3>
10 <p>На всех узлах кластера были развёрнуты следующие вспомогательные сервисы: •<strong>NTP</strong>- клиент синхронизации с локальным NTP-сервером; •<strong>Kerberos</strong>- kerberos-клиент; •<strong>Auditd</strong>- клиент auditd; •<strong>Netdata</strong>- клиент сбора телеметрии.</p>
10 <p>На всех узлах кластера были развёрнуты следующие вспомогательные сервисы: •<strong>NTP</strong>- клиент синхронизации с локальным NTP-сервером; •<strong>Kerberos</strong>- kerberos-клиент; •<strong>Auditd</strong>- клиент auditd; •<strong>Netdata</strong>- клиент сбора телеметрии.</p>
11 <p>На узлах master01-master03 развернули роли: •<strong>LizardFS Uraft Master Node</strong>- lizardfs-mfsmaster, lizardfs-uraft; •<strong>PostgreSQL 11</strong>- сервер PostgreSQL 11; •<strong>TimescaleDB</strong>- расширение для PostgreSQL, позволяющее использовать постгрес как TimeseriesDB; •<strong>Patroni</strong>- создание кластера PostgreSQL.</p>
11 <p>На узлах master01-master03 развернули роли: •<strong>LizardFS Uraft Master Node</strong>- lizardfs-mfsmaster, lizardfs-uraft; •<strong>PostgreSQL 11</strong>- сервер PostgreSQL 11; •<strong>TimescaleDB</strong>- расширение для PostgreSQL, позволяющее использовать постгрес как TimeseriesDB; •<strong>Patroni</strong>- создание кластера PostgreSQL.</p>
12 <p>На узлах node01-node03 развернули роли: •<strong>LizardFS Node</strong>- lizardfs-chunkserver, lizardfs-metalogger; •<strong>LVM</strong>- управление томами LVM2.</p>
12 <p>На узлах node01-node03 развернули роли: •<strong>LizardFS Node</strong>- lizardfs-chunkserver, lizardfs-metalogger; •<strong>LVM</strong>- управление томами LVM2.</p>
13 <h3>1.3 Использование стенда</h3>
13 <h3>1.3 Использование стенда</h3>
14 <p>После клонирования репозитория в папке с проектом (otus-homework/project) выполнили vagrant up. После развёртывания стенда стали доступны следующие ресурсы (наружу проброшен порт 8080): • мониторинг ресурсов узлов кластера в реальном времени - http://localhost:8080/netdata/; • мониторинг ресурсов узлов кластера http://localhost:8080/prometheus/; • визуализация телеметрии http://localhost:8080/grafana/: - необходимо выполнить вход (логин/пароль: admin/admin); - необходимо добавить источник данных (datasource): - Name: PostgreSQL; - Host: ns; - Database: postgres; - User/Password: postgres/postgres; - SSL Mode: disable; - Version: 10; - TimescaleDB: checked; - необходимо выполнить импорт тестового Dasboard sample-netdata-dashboard; • мониторинг состояния кластера СУБД http://localhost:8080/haproxy/: - необходимо выполнить вход (логин/пароль: someuser/password); • мониторинг состояния кластерной файловой системы http://localhost:8080/lizardfs/mfs.cgi?masterport=9421&amp;masterhost=master&amp;sections=CS.</p>
14 <p>После клонирования репозитория в папке с проектом (otus-homework/project) выполнили vagrant up. После развёртывания стенда стали доступны следующие ресурсы (наружу проброшен порт 8080): • мониторинг ресурсов узлов кластера в реальном времени - http://localhost:8080/netdata/; • мониторинг ресурсов узлов кластера http://localhost:8080/prometheus/; • визуализация телеметрии http://localhost:8080/grafana/: - необходимо выполнить вход (логин/пароль: admin/admin); - необходимо добавить источник данных (datasource): - Name: PostgreSQL; - Host: ns; - Database: postgres; - User/Password: postgres/postgres; - SSL Mode: disable; - Version: 10; - TimescaleDB: checked; - необходимо выполнить импорт тестового Dasboard sample-netdata-dashboard; • мониторинг состояния кластера СУБД http://localhost:8080/haproxy/: - необходимо выполнить вход (логин/пароль: someuser/password); • мониторинг состояния кластерной файловой системы http://localhost:8080/lizardfs/mfs.cgi?masterport=9421&amp;masterhost=master&amp;sections=CS.</p>
15 <p>Попадаем в ВМ ns-стенда и выполняем kinit (пароль - vagrant):</p>
15 <p>Попадаем в ВМ ns-стенда и выполняем kinit (пароль - vagrant):</p>
16 $ vagrant ssh ns $ echo "vagrant" | kinit $ sudo aureport -x --summary<p>Далее можно заходить на все ноды кластера без ввода пароля.</p>
16 $ vagrant ssh ns $ echo "vagrant" | kinit $ sudo aureport -x --summary<p>Далее можно заходить на все ноды кластера без ввода пароля.</p>
17 <h2>2. Компоненты стенда</h2>
17 <h2>2. Компоненты стенда</h2>
18 <p>Общая схема стенда с разделением ролей:</p>
18 <p>Общая схема стенда с разделением ролей:</p>
19 <h3>2.1 Высокодоступная кластерная файловая система</h3>
19 <h3>2.1 Высокодоступная кластерная файловая система</h3>
20 <p>Для проекта была выбрана кластерная файловая система<strong>LizardFS</strong>. Это распределённая, масштабируемая, отказоустойчивая и высокодоступная файловая система. Она позволяет объединять дисковое пространство, расположенное на многих серверах, в единое пространство имён, которое видно в Unix-подобных системах и системах Windows так же, как и в других файловых системах. LizardFS обеспечивает безопасность файлов, сохраняя все данные во многих репликах на доступных серверах. Её также можно использовать для создания доступного хранилища, поскольку она работает без каких-либо проблем на обычном оборудовании.</p>
20 <p>Для проекта была выбрана кластерная файловая система<strong>LizardFS</strong>. Это распределённая, масштабируемая, отказоустойчивая и высокодоступная файловая система. Она позволяет объединять дисковое пространство, расположенное на многих серверах, в единое пространство имён, которое видно в Unix-подобных системах и системах Windows так же, как и в других файловых системах. LizardFS обеспечивает безопасность файлов, сохраняя все данные во многих репликах на доступных серверах. Её также можно использовать для создания доступного хранилища, поскольку она работает без каких-либо проблем на обычном оборудовании.</p>
21 <p>Отказы дисков и серверов обрабатываются прозрачно, без простоев и потери данных. Если требования к хранилищу растут, можно масштабировать существующую установку LizardFS, просто добавляя новые серверы - в любое время, без простоев. Система автоматически перемещает данные на вновь добавленные серверы, потому что она постоянно заботится о балансировке использования диска на всех подключённых узлах. Удаление серверов так же просто, как добавление нового.</p>
21 <p>Отказы дисков и серверов обрабатываются прозрачно, без простоев и потери данных. Если требования к хранилищу растут, можно масштабировать существующую установку LizardFS, просто добавляя новые серверы - в любое время, без простоев. Система автоматически перемещает данные на вновь добавленные серверы, потому что она постоянно заботится о балансировке использования диска на всех подключённых узлах. Удаление серверов так же просто, как добавление нового.</p>
22 <p><strong>Уникальные функции</strong>: • поддержка многих центров обработки данных и типов носителей, • быстрые снимки, • механизмы QoS, • квоты, • ...</p>
22 <p><strong>Уникальные функции</strong>: • поддержка многих центров обработки данных и типов носителей, • быстрые снимки, • механизмы QoS, • квоты, • ...</p>
23 <p>LizardFS хранит метаданные (например, имена файлов, метки времени изменения, деревья каталогов) и фактические данные отдельно. Метаданные хранятся на серверах метаданных, а данные хранятся на компьютерах, называемых серверами чанков.</p>
23 <p>LizardFS хранит метаданные (например, имена файлов, метки времени изменения, деревья каталогов) и фактические данные отдельно. Метаданные хранятся на серверах метаданных, а данные хранятся на компьютерах, называемых серверами чанков.</p>
24 <h2>Типичная установка состоит из:</h2>
24 <h2>Типичная установка состоит из:</h2>
25 <p>• Как минимум двух серверов метаданных, которые работают в режиме master-slave для восстановления после сбоев. Их роль также заключается в управлении всей установкой, поэтому активный сервер метаданных часто называют главным сервером. Роль других серверов метаданных состоит в том, чтобы просто синхронизировать их с активными главными серверами, поэтому их часто называют теневыми главными серверами. Любой теневой мастер-сервер в любое время готов взять на себя роль активного мастер-сервера.</p>
25 <p>• Как минимум двух серверов метаданных, которые работают в режиме master-slave для восстановления после сбоев. Их роль также заключается в управлении всей установкой, поэтому активный сервер метаданных часто называют главным сервером. Роль других серверов метаданных состоит в том, чтобы просто синхронизировать их с активными главными серверами, поэтому их часто называют теневыми главными серверами. Любой теневой мастер-сервер в любое время готов взять на себя роль активного мастер-сервера.</p>
26 <p>•<strong>Сhunkservers</strong>, серверов хранения данных. Каждый файл делится на блоки, называемые чанками (каждый размером до 64 Мб), которые хранятся на серверах чанков. Предлагаемая конфигурация сервера чанков - это машина с большим дисковым пространством, доступным в конфигурации JBOD или RAID в зависимости от требований. Процессор и оперативная память не очень важны. У вас могут быть всего 2 чанк-сервера (минимум, чтобы ваши данные были устойчивы к любым сбоям диска) или до сотен из них. Типичный чанксервер имеет 8, 12, 16 или даже более жёстких дисков. Каждый файл может распространяться на серверы чанков в определённом режиме репликации: standard, xor или ec.</p>
26 <p>•<strong>Сhunkservers</strong>, серверов хранения данных. Каждый файл делится на блоки, называемые чанками (каждый размером до 64 Мб), которые хранятся на серверах чанков. Предлагаемая конфигурация сервера чанков - это машина с большим дисковым пространством, доступным в конфигурации JBOD или RAID в зависимости от требований. Процессор и оперативная память не очень важны. У вас могут быть всего 2 чанк-сервера (минимум, чтобы ваши данные были устойчивы к любым сбоям диска) или до сотен из них. Типичный чанксервер имеет 8, 12, 16 или даже более жёстких дисков. Каждый файл может распространяться на серверы чанков в определённом режиме репликации: standard, xor или ec.</p>
27 <p>• Клиентов, которые используют данные, хранящиеся в LizardFS. Эти машины используют монтирование LizardFS для доступа к файлам при установке и обработке их так же, как файлы на локальных жёстких дисках. Файлы, хранящиеся в LizardFS, могут быть просмотрены и одновременно доступны как можно большему числу клиентов.</p>
27 <p>• Клиентов, которые используют данные, хранящиеся в LizardFS. Эти машины используют монтирование LizardFS для доступа к файлам при установке и обработке их так же, как файлы на локальных жёстких дисках. Файлы, хранящиеся в LizardFS, могут быть просмотрены и одновременно доступны как можно большему числу клиентов.</p>
28 <p><strong>Режим репликации</strong>каталога или даже файла может быть определён индивидуально: •<strong>Standard</strong>. Режим предназначен для явного определения количества копий фрагментов данных, которые вы хотите сохранить в кластере и на определенной группе узлов. В сочетании с "пользовательскими целями" (goals) это удобно для гео-репликации. •<strong>Xor</strong>. Похож на механизм репликации, известный в RAID5. •<strong>Ec - erasure coding</strong>. Похож на механизм репликации, известный в RAID6.</p>
28 <p><strong>Режим репликации</strong>каталога или даже файла может быть определён индивидуально: •<strong>Standard</strong>. Режим предназначен для явного определения количества копий фрагментов данных, которые вы хотите сохранить в кластере и на определенной группе узлов. В сочетании с "пользовательскими целями" (goals) это удобно для гео-репликации. •<strong>Xor</strong>. Похож на механизм репликации, известный в RAID5. •<strong>Ec - erasure coding</strong>. Похож на механизм репликации, известный в RAID6.</p>
29 <p>Отдельный инструмент для обеспечения высокой доступности -<strong>LizardFS Uraft</strong>, стал доступен OpenSource-сообществу в июле 2018 года. Компонент предназначен для организации высокодоступного кластера файловой системы.</p>
29 <p>Отдельный инструмент для обеспечения высокой доступности -<strong>LizardFS Uraft</strong>, стал доступен OpenSource-сообществу в июле 2018 года. Компонент предназначен для организации высокодоступного кластера файловой системы.</p>
30 <p><strong>Схема развёртывания кластерной ФС:</strong>• устанавливаем мастер-сервера (ноды master01-master03); • устанавливаем компонент высокой доступности uraft (ноды master01-master03); • запускаем uraft, который запускает мастер-сервера на каждой из мастер-нод; • проводятся выборы, где определяется главный мастер-сервер; • ноде, на которой определен главный мастер-сервер; назначается плавающий ip; • остальные мастер-ноды устанавливаются в режим shadow; • устанавливаем и запускаем чанк сервера (ноды node01-node03), которые соединяются с мастер-сервером.</p>
30 <p><strong>Схема развёртывания кластерной ФС:</strong>• устанавливаем мастер-сервера (ноды master01-master03); • устанавливаем компонент высокой доступности uraft (ноды master01-master03); • запускаем uraft, который запускает мастер-сервера на каждой из мастер-нод; • проводятся выборы, где определяется главный мастер-сервер; • ноде, на которой определен главный мастер-сервер; назначается плавающий ip; • остальные мастер-ноды устанавливаются в режим shadow; • устанавливаем и запускаем чанк сервера (ноды node01-node03), которые соединяются с мастер-сервером.</p>
31 <p>В нашем примере на ВМ master01-master03 развёрнуты компоненты lizardfs-mfsmaster, lizardfs-uraft. Для обеспечения высокой доступности используется технология floating ip. При остановке главного мастер-сервера происходят выборы, выбирается новый ведущий мастер, которому назначается плавающий ip.</p>
31 <p>В нашем примере на ВМ master01-master03 развёрнуты компоненты lizardfs-mfsmaster, lizardfs-uraft. Для обеспечения высокой доступности используется технология floating ip. При остановке главного мастер-сервера происходят выборы, выбирается новый ведущий мастер, которому назначается плавающий ip.</p>
32 <p>На ВМ node01-node03 развёрнуты компоненты lizardfs-chunkserver, lizardfs-metalogger, к каждой ноде подключен диск, который смонтирован в систему. В конфигурации сервера чанков он определён, как доступный для работы внутри кластерной файловой системы.</p>
32 <p>На ВМ node01-node03 развёрнуты компоненты lizardfs-chunkserver, lizardfs-metalogger, к каждой ноде подключен диск, который смонтирован в систему. В конфигурации сервера чанков он определён, как доступный для работы внутри кластерной файловой системы.</p>
33 <p>На ВМ ns установлен компонент lizardfs-client, lizardfs-admin, lizardfs-cgiserv, с помощью которых монтируется, управляется и мониторится кластерная файловая система. Также установлен сервис autofs для автоматического монтирования ФС в /data/lizard.</p>
33 <p>На ВМ ns установлен компонент lizardfs-client, lizardfs-admin, lizardfs-cgiserv, с помощью которых монтируется, управляется и мониторится кластерная файловая система. Также установлен сервис autofs для автоматического монтирования ФС в /data/lizard.</p>
34 <p><strong>Пример монтирования ФС</strong>:</p>
34 <p><strong>Пример монтирования ФС</strong>:</p>
35 $ mfsmount -o big_writes,nosuid,nodev,noatime,allow_other -o cacheexpirationtime=500 -o readaheadmaxwindowsize=4096 /mnt<p>Проверка статусов мастер-серверов:</p>
35 $ mfsmount -o big_writes,nosuid,nodev,noatime,allow_other -o cacheexpirationtime=500 -o readaheadmaxwindowsize=4096 /mnt<p>Проверка статусов мастер-серверов:</p>
36 $ for i in {1..3}; do telnet master0$i 9428; done<p>Вывод команды:</p>
36 $ for i in {1..3}; do telnet master0$i 9428; done<p>Вывод команды:</p>
37 Trying 192.168.50.21... Connected to master01. Escape character is '^]'. SERVER ID 0 I'M THE BOOSSSS president=1 state=LEADER term=586 voted_for=0 leader_id=0 data_version=1 loyalty_agreement=0 local_time=3550745 blocked_promote=0 votes=[ 1| 1| 1] heart=[ 0.00| 0.00| 0.00] recv =[ 1| 1| 1] ver =[ 1| 1| 1] Connection closed by foreign host. Trying 192.168.50.22... Connected to master02. Escape character is '^]'. SERVER ID 1 president=0 state=FOLLOWER term=586 voted_for=0 leader_id=0 data_version=1 loyalty_agreement=1 local_time=3567651 blocked_promote=0 Connection closed by foreign host. Trying 192.168.50.23... Connected to master03. Escape character is '^]'. SERVER ID 2 president=0 state=FOLLOWER term=586 voted_for=-1 leader_id=0 data_version=1 loyalty_agreement=1 local_time=3551294 blocked_promote=0 Connection closed by foreign host.<p>Мониторинг состояния файловой системы:</p>
37 Trying 192.168.50.21... Connected to master01. Escape character is '^]'. SERVER ID 0 I'M THE BOOSSSS president=1 state=LEADER term=586 voted_for=0 leader_id=0 data_version=1 loyalty_agreement=0 local_time=3550745 blocked_promote=0 votes=[ 1| 1| 1] heart=[ 0.00| 0.00| 0.00] recv =[ 1| 1| 1] ver =[ 1| 1| 1] Connection closed by foreign host. Trying 192.168.50.22... Connected to master02. Escape character is '^]'. SERVER ID 1 president=0 state=FOLLOWER term=586 voted_for=0 leader_id=0 data_version=1 loyalty_agreement=1 local_time=3567651 blocked_promote=0 Connection closed by foreign host. Trying 192.168.50.23... Connected to master03. Escape character is '^]'. SERVER ID 2 president=0 state=FOLLOWER term=586 voted_for=-1 leader_id=0 data_version=1 loyalty_agreement=1 local_time=3551294 blocked_promote=0 Connection closed by foreign host.<p>Мониторинг состояния файловой системы:</p>
38 <h3>2.2 Кластер СУБД</h3>
38 <h3>2.2 Кластер СУБД</h3>
39 <p>Схема кластера:</p>
39 <p>Схема кластера:</p>
40 <p>Кластер высокой доступности Postgres. Развёртывание кластера идентично выполненной работе в<a>ДЗ 29</a>. Разворачиваемыt компоненты: • PostgreSQL 11; • Patroni; • TimescaleDB. Однако есть дополнения в виде установки двух расширений для использования Postgres в качестве Timeseries DB (об этом ниже).</p>
40 <p>Кластер высокой доступности Postgres. Развёртывание кластера идентично выполненной работе в<a>ДЗ 29</a>. Разворачиваемыt компоненты: • PostgreSQL 11; • Patroni; • TimescaleDB. Однако есть дополнения в виде установки двух расширений для использования Postgres в качестве Timeseries DB (об этом ниже).</p>
41 <p>Устанавливаются расширения TimescaleDB и pg_prometheus. Первое позволяет сохранять в БД временные ряды, используя при этом партиционирование таблиц, второе позволяет взаимодействовать с системой мониторинга Prometheus. Pg_prometheus пришлось собрать вручную (см. архив<a>pg_prometheus.tar.gz</a>) и написать<a>скрипт инсталляции</a>внутрь Postgres.</p>
41 <p>Устанавливаются расширения TimescaleDB и pg_prometheus. Первое позволяет сохранять в БД временные ряды, используя при этом партиционирование таблиц, второе позволяет взаимодействовать с системой мониторинга Prometheus. Pg_prometheus пришлось собрать вручную (см. архив<a>pg_prometheus.tar.gz</a>) и написать<a>скрипт инсталляции</a>внутрь Postgres.</p>
42 <p>Подключение к кластеру (логин/пароль: postgres/postgres):</p>
42 <p>Подключение к кластеру (логин/пароль: postgres/postgres):</p>
43 psql -U postgres -h ns.otus.test<h3>2.3 Мониторинг</h3>
43 psql -U postgres -h ns.otus.test<h3>2.3 Мониторинг</h3>
44 <p>Схема мониторинга:</p>
44 <p>Схема мониторинга:</p>
45 <p>Мониторинг условно разделён на две части: реального времени и пассивный.</p>
45 <p>Мониторинг условно разделён на две части: реального времени и пассивный.</p>
46 <p>В мониторинге реального времени будем использовать<strong>Netdata</strong>. Netdata на всех ВМ отличных от центральной (ns.otus.test) настроим в режиме Stream, чтобы генерируемый поток метрик от каждого хоста пересылался центральному серверу Netdata.</p>
46 <p>В мониторинге реального времени будем использовать<strong>Netdata</strong>. Netdata на всех ВМ отличных от центральной (ns.otus.test) настроим в режиме Stream, чтобы генерируемый поток метрик от каждого хоста пересылался центральному серверу Netdata.</p>
47 <p>Центральный сервер настроим на приём метрик и их визуализацию. Если в нашем кластере происходят аномалии, то будет возможно наблюдать параметры, критичные для системы в реальном времени. У Netdata достаточно широкая функциональность. Конечно, в курсовом проекте её невозможно охватить в полном объеме.</p>
47 <p>Центральный сервер настроим на приём метрик и их визуализацию. Если в нашем кластере происходят аномалии, то будет возможно наблюдать параметры, критичные для системы в реальном времени. У Netdata достаточно широкая функциональность. Конечно, в курсовом проекте её невозможно охватить в полном объеме.</p>
48 <p>Пассивный мониторинг необходим для спокойного анализа причин возникновения проблем, которые привели к негативным последствиям. Для сбора метрик будем использовать возможность Netdata отдавать метрики в формате Prometheus. На ns.otus.test установим и настроим Prometheus, в prometheus.yml определим endpoints для сбора метрик со всех нод стенда. Вместе с Prometheus установим prometheus-postgresql-adapter - службу, с помощью которой метрики будут записываться в базу данных. Как настроить для этого БД, описано выше.</p>
48 <p>Пассивный мониторинг необходим для спокойного анализа причин возникновения проблем, которые привели к негативным последствиям. Для сбора метрик будем использовать возможность Netdata отдавать метрики в формате Prometheus. На ns.otus.test установим и настроим Prometheus, в prometheus.yml определим endpoints для сбора метрик со всех нод стенда. Вместе с Prometheus установим prometheus-postgresql-adapter - службу, с помощью которой метрики будут записываться в базу данных. Как настроить для этого БД, описано выше.</p>
49 <p><strong>Схема работы коллектора метрик:</strong></p>
49 <p><strong>Схема работы коллектора метрик:</strong></p>
50 <p>Рrometheus postgresql adapter также можно настроить на работу в режиме высокой доступности. Внутри БД создаётся несколько таблиц (см. структуру таблиц,<a>документация</a>), куда попадают данные мониторинга.</p>
50 <p>Рrometheus postgresql adapter также можно настроить на работу в режиме высокой доступности. Внутри БД создаётся несколько таблиц (см. структуру таблиц,<a>документация</a>), куда попадают данные мониторинга.</p>
51 <p>Итого, схема работы пассивного мониторинга:<strong>Netdata -&gt; Prometheus -&gt; prometheus-postgresql-adapter -&gt; PostgesSQL+TimescaleDB+pg_prometheus -&gt; Grafana</strong>.</p>
51 <p>Итого, схема работы пассивного мониторинга:<strong>Netdata -&gt; Prometheus -&gt; prometheus-postgresql-adapter -&gt; PostgesSQL+TimescaleDB+pg_prometheus -&gt; Grafana</strong>.</p>
52 <p>На ns.otus.test установим Grafana, создадим для неё демонстрационный dashboard, где будем отображать метрики, получая их с помощью SQL-запросов из БД.</p>
52 <p>На ns.otus.test установим Grafana, создадим для неё демонстрационный dashboard, где будем отображать метрики, получая их с помощью SQL-запросов из БД.</p>
53 <p>Пример SQL-запроса:</p>
53 <p>Пример SQL-запроса:</p>
54 SELECT time_bucket ('1m', time) AS time, avg(value) as load_1m FROM metrics WHERE time BETWEEN $__timeFrom() AND $__timeTo() AND name = 'netdata_users_cpu_system_percentage_average' AND labels @&gt; '{"instance": "ns:19999"}' GROUP BY 1 ORDER BY 1 ASC;<p>Выберем все значения метрики netdata_system_active_processes_processes_average в интервале 10 минут от текущего значения времени c дискретностью 1 минута (time_bucket - функция timescaleDB), для хоста ns сгруппируем и отсортируем полученные значения.</p>
54 SELECT time_bucket ('1m', time) AS time, avg(value) as load_1m FROM metrics WHERE time BETWEEN $__timeFrom() AND $__timeTo() AND name = 'netdata_users_cpu_system_percentage_average' AND labels @&gt; '{"instance": "ns:19999"}' GROUP BY 1 ORDER BY 1 ASC;<p>Выберем все значения метрики netdata_system_active_processes_processes_average в интервале 10 минут от текущего значения времени c дискретностью 1 минута (time_bucket - функция timescaleDB), для хоста ns сгруппируем и отсортируем полученные значения.</p>
55 <p>Готовый пример тестового<a>dashboard</a>.</p>
55 <p>Готовый пример тестового<a>dashboard</a>.</p>
56 <h3>2.4 Аудит</h3>
56 <h3>2.4 Аудит</h3>
57 <p>Аудит системных событий настроен по мотивам<a>ДЗ 14</a>. Все ноды пересылают события аудита на ns.otus.test,<a>список правил</a>аудита генерируется с помощью шаблона.</p>
57 <p>Аудит системных событий настроен по мотивам<a>ДЗ 14</a>. Все ноды пересылают события аудита на ns.otus.test,<a>список правил</a>аудита генерируется с помощью шаблона.</p>
58 <p>Общий краткий отчёт о событиях в кластере:</p>
58 <p>Общий краткий отчёт о событиях в кластере:</p>
59 $ aureport Summary Report ====================== Skipping line 37 in /etc/audit/auditd.conf: too long Range of time in logs: 01/01/1970 03:00:00.000 - 04/30/2019 16:26:52.204 Selected time for report: 01/01/1970 03:00:00 - 04/30/2019 16:26:52.204 Number of changes in configuration: 0 Number of changes to accounts, groups, or roles: 3 Number of logins: 2 Number of failed logins: 0 Number of authentications: 4 Number of failed authentications: 0 Number of users: 2 Number of terminals: 8 Number of host names: 4 Number of executables: 20 Number of commands: 22 Number of files: 30 Number of AVC's: 0 Number of MAC events: 2 Number of failed syscalls: 18015 Number of anomaly events: 0 Number of responses to anomaly events: 0 Number of crypto events: 25 Number of integrity events: 0 Number of virt events: 0 Number of keys: 0 Number of process IDs: 14866 Number of events: 36719<h2>3. Развёртывание инфраструктуры в облаке</h2>
59 $ aureport Summary Report ====================== Skipping line 37 in /etc/audit/auditd.conf: too long Range of time in logs: 01/01/1970 03:00:00.000 - 04/30/2019 16:26:52.204 Selected time for report: 01/01/1970 03:00:00 - 04/30/2019 16:26:52.204 Number of changes in configuration: 0 Number of changes to accounts, groups, or roles: 3 Number of logins: 2 Number of failed logins: 0 Number of authentications: 4 Number of failed authentications: 0 Number of users: 2 Number of terminals: 8 Number of host names: 4 Number of executables: 20 Number of commands: 22 Number of files: 30 Number of AVC's: 0 Number of MAC events: 2 Number of failed syscalls: 18015 Number of anomaly events: 0 Number of responses to anomaly events: 0 Number of crypto events: 25 Number of integrity events: 0 Number of virt events: 0 Number of keys: 0 Number of process IDs: 14866 Number of events: 36719<h2>3. Развёртывание инфраструктуры в облаке</h2>
60 <h3>3.1 Доступ к Яндекс.Облаку</h3>
60 <h3>3.1 Доступ к Яндекс.Облаку</h3>
61 <p>На локальной машине необходимо установить Yandex.Cloud CLI и выполнить начальные настройки:</p>
61 <p>На локальной машине необходимо установить Yandex.Cloud CLI и выполнить начальные настройки:</p>
62 $ curl https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash &amp;&amp; source "/home/otus-user/.bashrc" $ yc init<p>В процессе инициализации cli инструмента будут запрошены доступы Яндекс.Облака. Будет создан файл ~/.config/yandex-cloud/config.yaml с данными для доступа к облаку.</p>
62 $ curl https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash &amp;&amp; source "/home/otus-user/.bashrc" $ yc init<p>В процессе инициализации cli инструмента будут запрошены доступы Яндекс.Облака. Будет создан файл ~/.config/yandex-cloud/config.yaml с данными для доступа к облаку.</p>
63 <h3>3.2 Создание AWS S3 совместимого бакета и сервисного аккаунта</h3>
63 <h3>3.2 Создание AWS S3 совместимого бакета и сервисного аккаунта</h3>
64 <p>В веб-консоли аккаунта Яндекс.Облака создаём объектное хранилище с именем otus-infra, внутри хранилища создаём папку state. К сожалению, cli-инструментов для этих операции на сегодняшний момент нет.</p>
64 <p>В веб-консоли аккаунта Яндекс.Облака создаём объектное хранилище с именем otus-infra, внутри хранилища создаём папку state. К сожалению, cli-инструментов для этих операции на сегодняшний момент нет.</p>
65 <h3>3.3 Пользователь otus-user, ssh-ключ</h3>
65 <h3>3.3 Пользователь otus-user, ssh-ключ</h3>
66 <p>На облачную виртуальную машину будем заходить под пользователем otus-user. Сгенерируем для него ssh-ключи:</p>
66 <p>На облачную виртуальную машину будем заходить под пользователем otus-user. Сгенерируем для него ssh-ключи:</p>
67 $ ssh-keygen -t rsa -b 4096 -f /home/otus-user/.ssh/otus-user-key -q -N ""<h3>3.4 Использование стартового скрипта</h3>
67 $ ssh-keygen -t rsa -b 4096 -f /home/otus-user/.ssh/otus-user-key -q -N ""<h3>3.4 Использование стартового скрипта</h3>
68 <p>Скрипт start.sh создаёт первую машину в облаке, с которой будет разворачиваться инфрастукртура проекта. При создании ВМ устанавливаются необходимые инструменты для дальнейшей работы, генерируется файл metadata.yml. Так же внутрь новой ВМ в домашний каталог otus-user клонируется репозиторий инфраструктуры проекта.</p>
68 <p>Скрипт start.sh создаёт первую машину в облаке, с которой будет разворачиваться инфрастукртура проекта. При создании ВМ устанавливаются необходимые инструменты для дальнейшей работы, генерируется файл metadata.yml. Так же внутрь новой ВМ в домашний каталог otus-user клонируется репозиторий инфраструктуры проекта.</p>
69 <p>Публичная часть ключа otus-user должна быть включена в метаданные создаваемой ВМ.</p>
69 <p>Публичная часть ключа otus-user должна быть включена в метаданные создаваемой ВМ.</p>
70 <p>Metadata - данные, которые будут применены скриптами cloud-init при старте ВМ в Яндекс.Облаке.</p>
70 <p>Metadata - данные, которые будут применены скриптами cloud-init при старте ВМ в Яндекс.Облаке.</p>
71 <p>После старта ВМ необходимо зайти в нее по SSH и выполнить дальнейшую настройку:</p>
71 <p>После старта ВМ необходимо зайти в нее по SSH и выполнить дальнейшую настройку:</p>
72 $ ssh -i ~/.ssh/otus-user-key otus-user@$(yc compute instance get bastion --format json | jq -r '.network_interfaces[].primary_v4_address.one_to_one_nat.address')<h3>3.5 Настройка первой виртуальной машины в облаке</h3>
72 $ ssh -i ~/.ssh/otus-user-key otus-user@$(yc compute instance get bastion --format json | jq -r '.network_interfaces[].primary_v4_address.one_to_one_nat.address')<h3>3.5 Настройка первой виртуальной машины в облаке</h3>
73 <h4>3.5.1 Доступ к Яндекс.Облаку</h4>
73 <h4>3.5.1 Доступ к Яндекс.Облаку</h4>
74 <p>Установим Yandex Cloud CLI:</p>
74 <p>Установим Yandex Cloud CLI:</p>
75 $ curl https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash &amp;&amp; source "/home/otus-user/.bashrc"<p>С локальной машины из ~/.config/yandex-cloud/config.yaml возьмём конфигурацию cli (токен для доступа к Облаку) и перенесём на виртуальную в такой же файл и по такому же пути. Как альтернатива - можно выполнить команду yc init, получить токен и т. д.</p>
75 $ curl https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash &amp;&amp; source "/home/otus-user/.bashrc"<p>С локальной машины из ~/.config/yandex-cloud/config.yaml возьмём конфигурацию cli (токен для доступа к Облаку) и перенесём на виртуальную в такой же файл и по такому же пути. Как альтернатива - можно выполнить команду yc init, получить токен и т. д.</p>
76 <h4>3.5.2 Настройка и инициализация Terraform, импорт ранее созданных ресурсов</h4>
76 <h4>3.5.2 Настройка и инициализация Terraform, импорт ранее созданных ресурсов</h4>
77 <p>Убедимся, что в бакете отсутствует старый стейт Terraform. Если он есть, то его необходимо удалить для дальнейшей корректной работы при создании новой инфраструктуры.</p>
77 <p>Убедимся, что в бакете отсутствует старый стейт Terraform. Если он есть, то его необходимо удалить для дальнейшей корректной работы при создании новой инфраструктуры.</p>
78 <p>В директории с кодом инфраструктуры проекта ~/otus-infra необходимо выполнить инициализацию Terraform.</p>
78 <p>В директории с кодом инфраструктуры проекта ~/otus-infra необходимо выполнить инициализацию Terraform.</p>
79 <p>Для работы Terraform с Яндекс.Облаком необходим провайдер. Провайдер устанавливается автоматически при инициализации в директории с проектом, но для этого необходимы учетные данные из ~/.config/yandex-cloud/config.yaml.</p>
79 <p>Для работы Terraform с Яндекс.Облаком необходим провайдер. Провайдер устанавливается автоматически при инициализации в директории с проектом, но для этого необходимы учетные данные из ~/.config/yandex-cloud/config.yaml.</p>
80 <p>На этапе создания первой ВМ был сгенерирован новый ssh-ключ для доступа к новосоздаваемым ресурсам ~/.ssh/otus-user.pub. Этот ключ необходимо добавить в файл, содержащий метаданные виртуальных машин.</p>
80 <p>На этапе создания первой ВМ был сгенерирован новый ssh-ключ для доступа к новосоздаваемым ресурсам ~/.ssh/otus-user.pub. Этот ключ необходимо добавить в файл, содержащий метаданные виртуальных машин.</p>
81 <p>Инициализация Terraform выполняется с параметрами, так как мы создаем бэкенд, лежащий в объектном хранилище. Команда инициализации выглядит так:</p>
81 <p>Инициализация Terraform выполняется с параметрами, так как мы создаем бэкенд, лежащий в объектном хранилище. Команда инициализации выглядит так:</p>
82 $ terraform init -backend-config="access_key=key_id" -backend-config="secret_key=secret" -backend-config="bucket=state"<p>Необходимо создать сервисного пользователя, назначить ему права на каталог, в котором должна быть развёрнута инфраструктура и находиться уже созданный бакет, а также получить для него ключи доступа.</p>
82 $ terraform init -backend-config="access_key=key_id" -backend-config="secret_key=secret" -backend-config="bucket=state"<p>Необходимо создать сервисного пользователя, назначить ему права на каталог, в котором должна быть развёрнута инфраструктура и находиться уже созданный бакет, а также получить для него ключи доступа.</p>
83 $ yc iam service-account create --name otus-user $ yc iam access-key create --service-account-name otus-user $ yc resource-manager folder add-access-binding **ИМЯ_КАТАЛОГА** --role editor --subject serviceAccount:**service_account_id**<p>Вывод команд будет следующим, здесь нам интересны два ключа key_id, secret и service_account_id, которые необходимо зафиксировать в безопасном месте:</p>
83 $ yc iam service-account create --name otus-user $ yc iam access-key create --service-account-name otus-user $ yc resource-manager folder add-access-binding **ИМЯ_КАТАЛОГА** --role editor --subject serviceAccount:**service_account_id**<p>Вывод команд будет следующим, здесь нам интересны два ключа key_id, secret и service_account_id, которые необходимо зафиксировать в безопасном месте:</p>
84 access_key: ... **key_id:** xxx...xxx **secret:** xxx....xxxxxx<p>Из-за особенностей реализации Яндекс.Облака между назначением прав пользователю на каталог и работой с ним должно пройти примерно 60 секунд.</p>
84 access_key: ... **key_id:** xxx...xxx **secret:** xxx....xxxxxx<p>Из-за особенностей реализации Яндекс.Облака между назначением прав пользователю на каталог и работой с ним должно пройти примерно 60 секунд.</p>
85 <p>В терминологии Terraform мы создаём backend для хранения Terraform state, который необходим, если предполагается совместное использование этого инструмента.</p>
85 <p>В терминологии Terraform мы создаём backend для хранения Terraform state, который необходим, если предполагается совместное использование этого инструмента.</p>
86 <p>На этапе создания стартовой ВМ мы создали виртуальную сеть (my-network) и в ней подсеть (my-subnet). Эти же ресурсы мы описали с помощью терраформ. Заметим, что терраформ ничего не знает о том, что эти ресурсы уже созданы. Поэтому перед развертыванием полной инфраструктуры проекта необходимо выполнить импорт описанных и уже созданных ресурсов:</p>
86 <p>На этапе создания стартовой ВМ мы создали виртуальную сеть (my-network) и в ней подсеть (my-subnet). Эти же ресурсы мы описали с помощью терраформ. Заметим, что терраформ ничего не знает о том, что эти ресурсы уже созданы. Поэтому перед развертыванием полной инфраструктуры проекта необходимо выполнить импорт описанных и уже созданных ресурсов:</p>
87 $ terraform import yandex_vpc_network.my-network network_id $ terraform import yandex_vpc_subnet.my-subnet subnet_id<p>После этого шага всё готово к развёртыванию полной инфраструктуры проекта.</p>
87 $ terraform import yandex_vpc_network.my-network network_id $ terraform import yandex_vpc_subnet.my-subnet subnet_id<p>После этого шага всё готово к развёртыванию полной инфраструктуры проекта.</p>
88 <p>Для выполнения всех вышеперечисленных операций написан скрипт init.sh, его необходимо выполнить в директории с проектом ~/otus-infra. Скрипт генерирует файлы ~/otus-infra/providers.tf и ~/otus-infra/boostrap/metadata.yml с нужными значениями, создаёт сервисного пользователя и инициализирует Terraform с нужными бэкендом, импортирует уже созданные ресурсы.</p>
88 <p>Для выполнения всех вышеперечисленных операций написан скрипт init.sh, его необходимо выполнить в директории с проектом ~/otus-infra. Скрипт генерирует файлы ~/otus-infra/providers.tf и ~/otus-infra/boostrap/metadata.yml с нужными значениями, создаёт сервисного пользователя и инициализирует Terraform с нужными бэкендом, импортирует уже созданные ресурсы.</p>
89 <p>В скрипте в переменную CATALOG необходимо подставить имя каталога в облаке, в котором будет происходить развёртывание инфраструктуры (в новосозданном аккаунте обычно это каталог default).</p>
89 <p>В скрипте в переменную CATALOG необходимо подставить имя каталога в облаке, в котором будет происходить развёртывание инфраструктуры (в новосозданном аккаунте обычно это каталог default).</p>
90 <h4>3.5.3 Развёртывание инфраструктуры проекта</h4>
90 <h4>3.5.3 Развёртывание инфраструктуры проекта</h4>
91 <p>Для создания инфраструктуры:</p>
91 <p>Для создания инфраструктуры:</p>
92 $ terraform plan $ terraform apply<p>Проверяем:</p>
92 $ terraform plan $ terraform apply<p>Проверяем:</p>
93 <p>Дальнейшие шаги состоят в запуске ansible playbooks с нужными ролями для установки кластера LizardFS.</p>
93 <p>Дальнейшие шаги состоят в запуске ansible playbooks с нужными ролями для установки кластера LizardFS.</p>
94 <p><em>Вот и всё. Подробности реализации и исходный код проекта смотрите<a>в репозитории автора</a>. Там же вы найдёте массу полезных ссылок.</em></p>
94 <p><em>Вот и всё. Подробности реализации и исходный код проекта смотрите<a>в репозитории автора</a>. Там же вы найдёте массу полезных ссылок.</em></p>
95  
95