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



Так уж вышло, что я устроился преподавателем на один бесплатный курс для школьников по разработке под Android, спонсируемый одной крупной корпорацией, и, естественно, мне потребовалось осваивать соответствующую технику в количестве 25 ноутбуков, 25 планшетов, 2 стационарных компьютеров и сенсорной панели. До недавнего времени ноутбуки использовались с ОС Windows 8.1, но мало кого устраивала производительность и стабильность работы этой ОС при разработке в Eclipse и Android Studio. После одного года под Windows, наше руководство решило все ноутбуки перевести на Xubuntu 14.04, чтобы разрешить эти сложности. Был подготовлен образ, настроенный под конкретную модель ноутбуков, что у нас использовалась, и со всеми необходимыми программами. Накатил и работай. Одна беда — не было предусмотрено никакого решения для централизованного управления конфигурацией. На мой логичный вопрос по этому поводу был дан ответ, что внедрение подобной системы усложняет процедуру установки Linux на ноутбуки и, поскольку в образе уже все сделано как надо, никаких изменений после его установки вносить не понадобится. (ох уж эти оптимисты!)

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

На Хабре уже немало писали о Puppet, в том числе и инструкции, как его установить и настроить с нуля. Я нашел целых 3 штуки. Однако 1-я описывает какой-то уж слишком сложный случай, 2-я больше сосредоточена на файлах манифестов, чем на самой установке Puppet. 3-я весьма неплоха, я использовал ее как один из источников информации, но, к сожалению, уже устарела. Поэтому решил, заодно с настройкой и статью на хабр разместить. И мне напоминание и для других инструкция.

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

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

Настройка Puppet — объяснение процесса


1. Для начала нам нужно установить управляющий сервер Puppet на учительский компьютер:

sudo apt-get install -y puppetmaster

2. Теперь устанавливаем службу на клиенте:

sudo apt-get install -y puppet

3. Для того, чтобы клиент знал, куда ему подключаться, необходимо добавить следующие строки в /etc/puppet/puppet.conf:

[agent]
server = mysuperserver
node_name = cert
certname = nameofworkstation

Здесь mysuperserver необходимо заменить на доменное имя вашего сервера, а nameofworkstation на имя, которое вы решили присвоить данному конкретному клиенту. Если в вашей организации не настроен DNS, то можно сервер добавить в /etc/hosts для каждого клиента. Это важно! SSL-сертификат, который Puppet в дальнейшем использует, генерируется именно для доменного имени сервера. Если вы в конфигурации пропишете IP, то получите сбой на дальнейших этапах.
4. Далее необходимо выполнять тестовый запуск службы на клиентском компьютере:

puppet agent --test

Клиенту будет отказано в соединении по причине отсутствия сертификата, но при этом он создаст на сервере запрос на выдачу сертификата.
5. Соответствующей командой удовлетворяем этот запрос:
puppet cert sign nameofworkstation
Здесь на месте nameofworkstation будет то имя, что вы прописали для клиента ранее при выполнении 3-го пункта. Список всех имеющихся у сервера на данный момент запросов о выдаче сертификата можно посмотреть командой puppet cert --list.
6. После этого на клиенте повторно выполняем команду:

puppet agent --enable
puppet agent --test

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

Готовые скрипты и инструкция


Наконец, представляю вам 2 готовых скрипта, которые я использовал у себя. Серверный скрипт:

#!/bin/bash
echo =============================================
echo Устанавливаем сервер puppet
echo =============================================
    apt-get install -y puppetmaster
echo =============================================
COMMAND=nope
while [ "$COMMAND" != "end" ]
do
    echo =============================================
    echo Запустите скрипт client.sh на следующем ноутбуке. Когда ноутбук попросит вас об этом, нажмите [ENTER] здесь, чтобы авторизовать клиента. Нажмите Ctrl+C, если вы закончили работу.
    echo =============================================
        COMMAND=`read`
    echo =============================================
    echo Авторизуем клиента
    echo =============================================
    puppet cert sign --all
done  

Клиентский скрипт:

#!/bin/bash
# поменяйте эти 2 переменные для соответствия вашему окружению
MASTER_IP=192.168.0.100
SERVER_NAME=server
echo =============================================
echo Генерируем ID машины
echo =============================================
    sudo apt-get install -y uuid
    ID=`uuid`
echo =============================================
echo Добавляем доменное имя $SERVER_NAME для $MASTER_IP
echo =============================================
    echo $MASTER_IP $SERVER_NAME >> /etc/hosts
echo =============================================
echo Устанавливаем puppet
echo =============================================
    sudo apt-get install -y puppet
echo =============================================
echo Прописываем ваш сервер в конфигурации puppet
echo =============================================
    sudo cat >> /etc/puppet/puppet.conf << EOF
[agent]
server = $SERVER_NAME
node_name = cert
certname = workstation-$ID
EOF
echo =============================================
echo Отправляем сертификат на сервер
echo =============================================
    puppet agent --test
echo =============================================
echo Авторизуйте клиента на сервере и затем нажмите [ENTER], чтобы данный скрипт завершил работу по настройке соединения.
echo =============================================
    read -n 1
echo =============================================
echo Заканчиваем работу
echo =============================================
    puppet agent --enable
    puppet agent --test
echo =============================================
echo Завершено
echo =============================================

Пользоваться ими очень просто:
1. Модифицируете client.sh для соответствия своему окружению: IP-адрес сервера (надо его сделать статическим) и имя сервера (это должно быть имя компьютера, заданное при установке Ubuntu). Это первые 2 переменные в начале файла, надо их поправить.
2. На сервере запускается server.sh, затем на каждом из клиентов client.sh. После этого на сервере нажимаете Enter, чтобы разрешить серверу подписать все сертификаты клиентов.
3. Потом нажимаете Enter на каждом из клиентов, чтобы они повторно подключились к серверу с уже валидным сертификатом и применили все доступные конфигурации.
4. Нажимаете Ctrl+C на сервере, чтобы завершить процесс.
После выполнения этой нехитрой процедуры ноутбуки будут автоматически подключаться к серверу при включении и каждые 10 минут и проверять доступные конфигурации. И, естественно, применять их, если они есть. Красота!
Примечание: На мой взгляд большим минусом клиентского скрипта является то, что если его запустить повторно, он дозаписывает конфиги даже если это уже было сделано раньше. Таким образом, если на какой-то стадии произошла ошибка, то продолжить процесс после устранения ее причин простым повторным выполнением скрипта — плохая идея. В конфигурационных файлах будет бардак. В идеале стоило бы написать скрипт так, чтобы он проверял содержимое конфигурационных файлов и не вносил изменений, если они уже внесены. Однако мой недостаточной уровень владения bash'ем и отсутствие времени, чтобы этот уровень улучшить, не позволили мне преодолеть этот недостаток. Если кому-то это легко и просто дается, рад буду соответствующим поправкам в комментариях.

Установим VNC


Чтож, Puppet мы настроили, как насчет того, чтобы немного воспользоваться его плюшками? Мне лично хочется, чтобы на компьютерах учеников был включен доступ по VNC, чтобы я всегда мог подключиться на компьютер нужного ученика и посмотреть, что он там делает. И, если он делает там что-то, что стоит показать всем студентам, можно было бы вывести содержимое его экрана на интерактивную панель, чтобы другие брали пример. Для достижения этих 2-х целей мы сначала сохраним пароль от VNC в файле /etc/x11vnc.pass при помощи следующей команды (все выполняется на сервере):

sudo x11vnc -storepasswd 1 /etc/x11vnc.pass

Почему вместо серьезного пароля какая-то жалкая единичка? Ну в puppet из репозиториев Ubuntu 14.04 есть два бага (первый и второй), которые приводят к тому, что при помощи него нельзя на клиентские компьютеры закачивать бинарные файлы. Он нормально отправляет только файлы, которые представляют из себя валидный текст в кодировке UTF-8. Пароль — единичка был проверен на тот факт, что его хеш нормально раздается Puppet'ом на клиенты. Можно еще перебором подобрать пароли, хеш которых представляет из себя валидный UTF-8 текст. Я для своего класса такой подобрал. Можете и вы попытаться.

Ну а затем создадим на сервере в папке /etc/puppet/manifests/ файл site.pp следующего содержания:

package { "mc":
    ensure => installed,
}
package { "x11vnc":
    ensure => installed,
}
file { "/etc/x11vnc.pass":
    content => file("/etc/x11vnc.pass"),
    mode => 600,
}
$str = "start on login-session-start
        script
        /usr/bin/x11vnc -xkb -forever -auth /var/run/lightdm/root/:0 -display :0 -rfbauth /etc/x11vnc.pass -rfbport 5900 -bg -o /var/log/x11vnc.log
        end script
        "
file { "/etc/init/x11vnc.conf":
    content => "$str",
    mode => 644,
}

Тут все достаточно очевидно. Скажу лишь кратко, что этот манифест устанавливает пакеты mc и x11vnc, и создает службу, которая автоматически запускает VNC с указанным паролем при появлении экрана входа в систему. (использовал в настройке этот ответ) Обратите внимание, что выбор имени /etc/puppet/manifests/site.pp не моя прихоть. Это путь, в котором Puppet хранит манифест по умолчанию. Опять-таки рад любой конструктивной критике моего самопального манифеста (люблю хабр за конструктивную критику).

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

Комментарии (22)


  1. Arslaman
    15.09.2015 14:35

    А что это за курс? И в каком городе?


    1. cepreu4habr
      15.09.2015 14:40
      +2

      IT школа Samsung — благотворительный проект этой компании. Вообще он во многих городах страны проходит. Моя площадка — во Владивостоке.


      1. igor_suhorukov
        15.09.2015 21:36

        Респект вам! Благородное дело делаете с обучением. Тем более под linux)


        1. cepreu4habr
          16.09.2015 00:06
          -3

          Весь респект Иисусу Христу. Он сделал это возможным для меня.


  1. Cosmonaut
    15.09.2015 18:58

    Отличная инструкция, может теперь и у меня руки дойдут. Idea под Linux и правда быстрее работает (как и вся Java в целом). Спасибо! Кармы для плюсов не хватает, сгорела за давностью лет.
    Иван, Иркутск


  1. Meklon
    15.09.2015 20:42

    Благодарю. Добавил в избранное. У меня уже накопилось немалое количество мелких медиа-серверов родственников и всяких NAS. Причём в ряде мест ещё и ip динамический. Мне кажется, puppet будет здесь уместен. Только надо понять, как его корректно в интернет вынести. У меня на купленном домене висит домашний сервер. А на нём nginx с owncloud.


  1. withkittens
    15.09.2015 21:55
    +2

    ОС Windows 8.1, но мало кого устраивала производительность и стабильность работы этой ОС при разработке в Eclipse и Android Studio
    Не холивара для, в чём выражались недостаточные производительность и стабильность ОС? Убунтой проблема решилась?

    П.С. Много девушек участвует? ;) Почему-то в IT их очень мало.


    1. cepreu4habr
      16.09.2015 00:25
      +1

      Сам не сталкивался, но от учителей, учивших в прошлом году, было много отзывов, что Eclipse глючит в связке с ADT. Какие-то неожиданно некомпилирующиеся проекты, проблемы с автоматической генерацией некоторых файлов. При этом с чистой Java Eclipse работал стабильно.
      Когда стали активно переходить на Android Studio оказалось, что под Windows она работает очень медленно. Тут нечего особо рассказывать. Тормоза они и в Африке тормоза. Под Linux она бегает несколько шустрее.
      В моей группе 8 человек из них 3 девочки. Вообще по проекту (все города) суммарная статистика, которую я последний раз получал — 9% от общего числа учащихся это девочки.


  1. alekseyspb
    16.09.2015 00:20
    +1

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


    1. cepreu4habr
      16.09.2015 00:42
      +1

      Почитал про него. Цитата из этой статьи:

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

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


      1. baldr
        16.09.2015 15:27

        А если за это время сменится адрес сервера? Вы можете об этом даже забыть и не вспомнить сразу.


        1. cepreu4habr
          17.09.2015 03:26

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


  1. ComodoHacker
    16.09.2015 09:32
    +1

    Почему сервер должен иметь статический IP? Ведь клиенты обращаются к нему по имени. Да и вообще, не по фен-шую это.


    1. cepreu4habr
      16.09.2015 09:44
      -1

      Это проще в настройке. Я преследовал цель сделать все максимально просто и быстро. Настраивать локальный DNS было бы дополнительной задержкой. Проще статический IP + /etc/hosts. Дешево и сердито.


      1. ComodoHacker
        16.09.2015 17:45

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


        1. cepreu4habr
          17.09.2015 03:28

          Цитата из статьи:

          Если в вашей организации не настроен DNS, то можно сервер добавить в /etc/hosts для каждого клиента.

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


          1. ComodoHacker
            18.09.2015 21:03

            Я про это место:

            1. Модифицируете client.sh для соответствия своему окружению: IP-адрес сервера (надо его сделать статическим)


  1. mobilesfinks
    16.09.2015 11:31

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

    cat /etc/puppet/autosign.conf
    
    *.localdomain
    

    А в puppet.conf нужно прописать:
    autosign = $confdir/autosign.conf


    1. cepreu4habr
      16.09.2015 11:39

      Спасибо! Жаль я раньше этого не знал…


      1. mobilesfinks
        16.09.2015 11:53
        +1

        Рекомендую ещё разобраться с The Foreman
        Очень удобная вещь, хотя бы для работы с фактами и для просмотра отчётов.


  1. IvanIDSolutions
    16.09.2015 13:38

    Коротко и ясно, респект! Попробую развернуть аналогичную конфигурацию, у нас офисе на убунте


  1. baldr
    16.09.2015 15:32

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