Перейти к главному содержимому

Театр с куклами или как всё собрать и пойти пить чай

В этот раз пост будет технический, про настройку своих компьютеров и контейнеров на 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, считывая этот рецепт, сам позаботится о том, чтобы запустить нужные команды в нужном порядке.

Вот парочка примеров со статьи на Хабре и на основе документации:

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-контейнеры, ими пользуется мой научрук.