В этот раз пост будет технический, про настройку своих компьютеров и контейнеров на GNU/Linux (может быть, не только) и как я воспользовался системой управления конфигурацией Puppet. Если ты не программист, то не спеши пропускать пост, потому что кое в чём тебе полезно будет его прочитать и задуматься.
## Проблема настройки ОС с нуля
Часто ли вам приходится устанавливать операционки, контейнеры, виртуальные машины, настраивать их и загонять туда кучу программ? Мне вот в последнее время да, причём не только себе, но и другим людям. Когда-то это необходимость по учёбе, а иногда просто требуется чистый компьютер/окружение для экспериментов или для установки научного софта.
И вот так бывает, что просто задалбывает всё делать каждый раз с нуля, одно и то же. Конечно, в GNU/Linux дистрибутивах есть пакетные менеджеры, где можно в одну строчку ввести несколько имён пакетов, и нужный софт по порядку установится.
Например, `sudo apt install libreoffice firefox gnuplot-x11` и.т.д. Пусть это и круто, но хочется большего:
* Очень часто ты не помнишь названия всех программ, которые нужны или могут понадобиться в процессе
* Если помогаешь установить и настроить софт друзьям или коллегам, то там может быть другой дистрибутив, в котором пакеты называются по-другому, из-за чего названия нужно вспоминать
* Настройка свежей ОС уходит далеко за установку парочки программ. Нужно крутить конфиги, иногда добавлять репозитории, не забыть запустить какую-то команду и так далее
## Системы управления конфигурацией и что они решают
В какой-то момент надоедает эта возня с настройкой систем. Если будешь постоянно что-то настраивать, то и времени на работу не останется. Хочется один раз разобраться, потом написать файл конфигурации или скрипт. И когда в следующий раз что-то понадобится, то просто его запустить, пойти пить чай и получить через час готовый для работы компьютер.
Для простых задач бывает достаточно написать простенький shell-скрипт, где ты тупо вбиваешь команды, которые запускаются по порядку. Но иногда хочется больше гибкости и **умной системы**, которая часть ответственности возьмёт на себя. Например, даст тебе возможность более красиво описывать настройки, улучшит обработку ошибок, позволит выносить блоки настроек по модулям и так далее.
Такие системы называются *системами управления конфигурацией* (конфигурациями), и товарищи в крупных фирмах ими часто пользуются.
## Ещё немножко комментариев "зачем"
К автоматизации я подхожу с некоторым максимализмом. Роботы должны делать тупую работу, а человек должен заниматься чем-то интересным. И когда мы пользуемся компьютерами, мы пишем программы, чтобы упростить себе жизнь, в чём-то стать свободнее и независимее. Часто за собой замечаю, что с этой технической вознёй стал сам зависим от компьютеров. Это как будто не ты владеешь вещью, а вещь владеет тобой. В какой-то момент я загорелся идеей уменьшить эту зависимость от вещей и от технологий, побороть привязанность к железу и к конкретным настройкам. И это нужно пояснить.
Те из вас, кто интересуется политикой, знает, что, например, на штабы Навального регулярно, раз в несколько месяцев, налетает ОМОН, забирает всю технику и не возвращает её. Я всегда представлял себя на месте работников Фонда Борьбы с Коррупцией и на месте каких-нибудь независимых журналистов.
Вот взяли отобрали у тебя компьютер или украли (или жёсткий диск полетел), а там куча твоей работы за несколько лет, огромная коллекция ценных книг/воспоминаний/музыки/порно, сотни-тысячи строк написанных конфигов и кода. Всё это взяло и исчезло. Разумеется, ты можешь какие-то важные данные хранить в облаке или на каком-то сервере, но привычный режим работы уже нарушен.
Ты берёшь, покупаешь новый компьютер, устанавливаешь на него ОС и тратишь день-два на настройку. А потом ещё пару недель, чтобы всё допилить до конца. А хочется взять комп, накатить туда свежую ОС, набрать пару команд в консоли и быстро (за час-два в зависимости от скорости интернета) получить готовое устройство, прямо как старое. Сразу со всеми данными из облака, со всеми привычными настройками, чтобы можно было взять и продолжить работать.
## Почему не Ansible и не Docker, чем плохи образы
Начнём с **образов**. Казалось бы, если тебе надо часто ставить операционки, то можно просто собрать свою сборку той же Убунты, запихнуть её в iso-образ и пользоваться, когда понадобится. Но тут сразу выползают минусы:
1. В процессе работы у тебя может что-то из настроек меняться, это абсолютно нормально. И на каждый чих, на каждое мелкое изменение придётся этот образ на несколько гигабайт пересоздавать или перезаписывать. Это долго и затратно
2. Образы сами по себе тяжёлые, эти несколько гигов надо просто где-то хранить и не потерять, а ещё наверняка захочется иметь несколько образов на разные случаи жизни, а это значит ещё пару десятков гигабайт
3. Программы имеют свойство иногда "протухать", то есть придётся ещё и устанавливать обновления в образы, а это значит регулярно заниматься пересборкой
4. Если ты ставишь программы другому человеку, то у него какая-то операционка может быть установлена, и удобнее просто накатить нужные программы на уже готовую ОС, чем ставить новую в дуалбут или в виртуалку
Почему не **Docker**? Для разработчика или для большой фирмы есть куча плюсов в использовании Docker, к тому же, там можно не просто использовать образы, но и писать Dockerfile, в котором можно указать кучу разных настроек. Но от Docker я отказался по следующим причинам:
1. Требует запущенного сервиса на компьютере и отдельного обслуживания, просто чтобы можно было что-то запустить изнутри. Опять накладные расходы
2. Вместо того чтобы запускать контейнер в режиме "всё включено", хочется больше гибкости. Например, создать вручную контейнер другой операционки и загнать туда тот же софт. Или установить программы на уже готовую ОС
3. Опять же, когда ставишь проги другим людям, то у них какая-то ось уже стоит, и им проще установить программы без всяких дополнительных слоёв абстракции и без контейнеров
Почему не **Ansible**? Вроде бы, это вообще идеальный вариант. Все настройки в текстовых файлах, кушать не требует, места много тоже не требует. Но мне не очень нравится подход Ansible к описанию настроек: файлы playbook получаются громоздкие, для каждой операционки нужно писать логику отдельно. Ещё там используется "императивный подход", как в обычных скриптах, плюс Ansible больше ориентирован на обслуживание удалённых серверов, а не просто любого компьютера. Хотя, конечно, этот инструмент крут в своей области и позволяет многого достичь, но лично для меня в данной ситуации он не подошёл.
## Как я воспользовался Puppet, с чем его едят
После рассмотрения разных доступных вариантов систем управления конфигурацией я открыл для себя Puppet и через некоторое время понял, что это то что нужно. Puppet позволяет устанавливать пакеты, добавлять в систему файлы, пользователей и крутить любые другие настройки. А ещё там поддерживаются внешние модули, которыми можно делиться с окружающими.
Чтобы создать конфигурацию, нужно написать несколько текстовых файлов и загнать их куда-нибудь в Git-репозиторий (например, на Github). Что самое крутое, в этих файлах настроек ты указываешь не просто последовательность команд, а именно желаемое состояние системы, то есть некоторый результат, который хочется получить в итоге. Puppet, считывая этот рецепт, сам позаботится о том, чтобы запустить нужные команды в нужном порядке.
Вот парочка примеров со [статьи на Хабре]( https://habr.com/ru/company/avito/blog/507346/ ) и на основе документации:
package { 'nginx': # описываем пакет nginx ensure => installed, # он должен быть установлен } ~> service { 'nginx': # описываем сервис nginx ensure => running, # он должен быть запущен enable => true, # его нужно запускать автоматически при старте системы }
Можно устанавливать также Python-пакеты, например
package { 'python-mysql': ensure => installed, name => 'mysql', provider => 'pip' # да, ставим через pip }
Можно пользоваться переменными и добавлять файлы, например
# создание переменных $variable = 'value' file { '/tmp/text': content => $variable, owner => 'root' }
Можно добавлять пользователей и SSH-ключи
$user = 'littlepony' user { $user: name => $user, ensure => present } ssh_authorized_key { 'littlepony@hostname': ensure => present, user => $user, type => 'ssh-rsa', key => 'содержимое ключа' }
И даже указывать задания в Cron
cron { 'logrotate': command => '/usr/sbin/logrotate', user => 'root', hour => [2, 4] }
Поддерживается массивы и циклы, указание зависимостей между ресурсами (например, перед тем как положить файл в папку настроек программы, эта программа должна сначала быть установлена). Мне нравится такой подход к описанию настроек
## Достоинства и недостатки Puppet
Из достоинств отметил бы
+ Сам способ декларативно описывать настройки
+ Возможность для разных операционных систем написать один конфиг, с минимальными правками. Например, я сделал конфиг, который сработает на Ubuntu/Debian и Archlinux/Manjaro примерно одинаково.
+ Куча модулей от сообщества для настройки самых разных параметров системы
Из недостатков
- Ruby не очень быстрый и не очень крутой язык, хотя это не критично
- Модулей от сообщества часто не хватает или они уже протухли, поэтому приходится проявлять смекалку и что-то придумывать самому
- Нужно соблюдать структуру каталогов и классов, из-за чего новичку легко запутаться в собственных модулях
В любом случае, я сделал с Puppet то что давно хотел - описал настройки для своих компьютеров, которые уже приносят пользу. В процессе эти настройки буду дорабатывать и дополнять не только для десктопов, но и для серверов.
## Применение для науки и для своих десктопов
У меня все конфигурации Puppet лежат в Git-репозиториях. Первая, публичная, доступна любому человеку на Github: https://github.com/vit1-irk/lazyinstall-puppet.
Чтобы ей воспользоваться, нужно взять оттуда скрипт с весьма лаконичным названием (см. репозиторий) и запустить его с желаемым ключом. Что есть в наборе `desktop`:
* Мой любимый софт: браузер, текстовые и графические редакторы, некоторые драйвера и полезные утилиты, почтовики и пара мессенджеров, ну и по мелочи. Просто чтобы комфортно было пользоваться компьютером
* Ставится русская локаль и часовой пояс Азия/Иркутск.
* В автозапуск загоняется Nextcloud и KDEConnect, чтобы сразу же синхронизироваться с облаком и со смартфоном
Есть ещё набор `science`, который я предлагаю использовать всем желающим, а особенно тем людям с физфака (и конкретно с космофиза), которые читают этот блог. Набор `science` рассчитан как на обычные компьютеры, так и на серверы. Что через него ставится:
* LaTeX со всеми нужными пакетами, чтобы писать статьи, курсачи и делать презентации в beamer. Редактором выступает Texmaker
* x2goserver, на тот случай если вы хотите запускать графический софт на мощном удалённом серваке, чтобы делать научные расчёты именно там
* Полностью настроенные Jupyter Lab и Jupyter Notebook, чтобы программировать на Python и заниматься анализом данных
* gnuplot, kmplot и Dot (+ модуль Jupyter) для построения графиков и диаграмм, geogebra для решения геометрических задач, Maxima для аналитических вычислений
* Язык R для анализа данных (пока без модуля Jupyter, но в будущем будет)
* Куча питоновских пакетов для анализа данных и вычислений, астрофизики и физики Солнца
* Питоновский модуль apprise для оповещений в мессенджеры или по Email (например, если у вас долгие вычисления и нужно за ними следить)
Для солнечных физиков там есть ещё особенные плюшки:
* Пакет SAOImageDS9 для анализа и просмотра FITS-файлов
* Настроенный GDL (реализация языка IDL) вместе с пакетом IDLAstro
* В питоновских модулях есть готовый для использования Sunpy
На Archlinux GDL мне полностью завести не удалось, но это только пока что, и я над этим работаю. Поэтому солнечникам рекомендуется пользоваться science-набором на Ubuntu или Debian. Если у кого-то есть замечания или предложения что-то включить ещё в научный набор, то с удовольствием приму.
## Вторая, личная конфигурация
Она находится в приватном репозитории под паролем. Там лежат некоторые специфичные для меня самого настройки. Например, SSH-ключи и настройки SSH-сервера, парочка сервисов systemd, ярлыки на рабочий стол и закладки в файловом менеджере. Приведу некоторый кусок кода с приблизительным содержанием, который можете допилить под себя
class personal::soft_services { $user = 'vit01' user { $user: name => $user, ensure => present } # ssh_authorized_key {'всё как в примере выше'} service { 'Syncthing': name => "syncthing@$user", ensure => "running", enable => "true" } class { 'ssh::server': validate_sshd_file => true, options => { 'Match User www-data' => { 'ChrootDirectory' => '%h', 'ForceCommand' => 'internal-sftp', 'PasswordAuthentication' => 'no', 'AllowTcpForwarding' => 'no', 'X11Forwarding' => 'no', }, 'PrintMotd' => 'no', 'PasswordAuthentication' => 'no', 'PermitRootLogin' => 'no', 'Port' => 22, } } $all_path = '/usr/local/bin/:/usr/bin' exec { 'install dot kernel for user': path => $all_path, command => 'install-dot-kernel', onlyif => 'which install-dot-kernel', user => $user } $icon = 'xdg-desktop-icon install --novendor /usr/share/applications' file { "xdg bookmarks": path => "/home/$user/.config/gtk-3.0/bookmarks", content => "file:///home/$user/Nextcloud\nfile:///tmp", owner => $user, ensure => present } $icons = ["firefox.desktop", "emacs.desktop"] $icons.each |String $fname| { exec { $fname: path => $all_path, command => "$icon/$fname", environment => [ "HOME=/home/$user" ], user => "$user" } } }
## На будущее
Всеми возможностями Puppet я не пользуюсь, мне пока достаточно того минимума, который можно увидеть сейчас в репозитории.
Что дальше в планах:
* Если будет свободное время и лишние 800 рублей на эксперименты с VPS, то сделаю воссоздаваемую конфигурацию для своих серверов, чтобы сделать их неубиваемыми.
* Настройки для обычных компов будут дорабатываться, чтобы ещё больше снижать количество телодвижений для приведения всего в рабочий вид
* Хочу такой же инструмент, но для Android-смартфонов (установка софта в том числе из F-Droid). Предлагайте, советуйте, буду искать и пробовать
* Разберусь с GDL на Archlinux и потом включу в настройки GDL-kernel для Jupyter Notebook, чтобы ещё больше облегчить написание IDL-кода солнечным физикам
Кстати, в процессе создания desktop-конфигурации я обнаружил к своему удивлению, что MyPaint и GIMP конфликтуют в репозиториях Debian. Это ужас и недоработочка.
В будущих постах, возможно, расскажу про Singularity-контейнеры, ими пользуется мой научрук.
[https://ii-net.tk/ii/ii-point.php?q=/f/f/alicorn.blog/zvG3oBpUEamdpvEYPGgy
](https://www.deviantart.com/rapidstrike/art/open-horse-development-583519331)
Этот пост в блоге: https://blog.alicorn.tk/posts/puppet-reproducible.html