Как управлять виртуальными машинами, если их много

    После того, как у нас вышли в релиз еще несколько проектов, а количество тикетов в трекере на тему «создать пользователя, развернуть виртуалку, дать доступ» превысило все мыслимые пределы, назрела необходимость что-то менять.
    Задача: организовать рабочее окружение linux для нескольких команд разработчиков и тестировщиков. Общее количество виртуальных машин — три-четыре десятка.

    image


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

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

    Требования к инструментам: open-source, простота настройки и использования, веб-интерфейс, либо мощный пакет утилит для настройки.

    Используемые решения: ubuntu 10.04 и другие версии, proxmox openvz, chef, openldap, GIT, zabbix

    1. Аутентификация.


    Разворачивание openldap. С недавних пор пакет openldap перешел на схему динамического конфигурирования, поэтому вся настройка осуществляется с помощью специальных ldif файлов. Не знаю, хорошо это или плохо, это непривычно и не всегда тривиально как минимум. Для примера можно использовать вот эту статью. По этой же статье при необходимости можно настроить и репликацию LDAP.
    Фронтенд LDAP мы не настраивали, за нас это потом сделала веб-панель управления LAM (v3.4.0). Мы так и не нашли более удобной панели для LDAP. GOSA обладает чуть большим функционалом, но значительно сложней в настройке, остальные продукты откровенно не дотягивают по внешнему виду и функционалу.

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

    Для этого необходимо собрать openssh с патчем LPK (о нем ниже) и подключить схему openssh-lpk_openldap.schema в LDAP
    root:/#cat lpk.ldif
    dn: cn=openssh-lpk,cn=schema,cn=config
    objectClass: olcSchemaConfig
    cn: openssh-lpk
    olcAttributeTypes: {0}( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' DES
    C 'MANDATORY: OpenSSH Public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.
    1.1466.115.121.1.40 )
    olcObjectClasses: {0}( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' DESC
    'MANDATORY: OpenSSH LPK objectclass' SUP top AUXILIARY MAY ( sshPublicKey $
    uid ) )
    root:/#ldapadd -Y EXTERNAL -H ldapi:/// -f lpk.ldif


    Настройка веб-интерфейса LAM тривиальна и не требует особого внимания. Панель после установки способна сама сконфигурировать LDAP фронтенд. В панели в настройках необходимо также подключить модуль SSH Public Key(ldapPublicKey).

    2. SSH


    Из репозитория он не умеет брать публичные ключи из LDAP, мы его научим.
    Почитать о технологии LPK и взять патч можно тут
    root:/#apt-get source ssh
    root:/#cd openssh-5.3p1
    root:/#patch -p1 < contrib-openssh-lpk-5.4p1-0.3.13.patch

    Все, что реджектнулось, а у нас получилось два файла и две строки там, патчим вручную.
    В debian/rules необходимо в двух местах к ../configure добавить
    --with-libs="-lldap" --with-ldflags="-L/usr/lib" --with-cppflags="-I/usr/include -DWITH_LDAP_PUBKEY"

    Для того, чтобы этот пакет успешно встал на рабочую систему и не конфликтовал с рабочей версией из репозитория, есть несколько путей, например:
    • повысить версию пакета
    • поправить debian/control и debian/rules, назвать пакет каким-либо другим именем и попытаться это все собрать.

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

    Вносим изменения в changelog и собираем пакет
    root:/#dch -i
    root:/#dpkg-buildpackage -b

    На выходе мы получим некий ‘openssh.deb’, который способен запросить у LDAP ‘sshPublicKey’ при выполнении некоторых условий.
    Запись user в LDAP
    • с objectclass ‘ldapPublicKey'
    • c objectclass 'posixAccount'
    • с заполненным атрибутом 'sshPublicKey'

    Запись group в LDAP
    • c objectclass 'posixGroup'
    • c атрибутом 'cn' и именем группы в нем
    • с атрибутом 'memberUid', где будут перечислены uid, входящие в эту группу.


    Необходимые настройки в /etc/ssh/sshd_config
    UseLPK yes
    LpkServers ldap://10.10.10.10/ # адрес сервера LDAP
    LpkUserDN ou=People,dc=office # где искать пользователей
    LpkGroupDN ou=group,dc=office # где искать группы
    LpkBindDN cn=admin,dc=office # под каким пользователем биндиться, если не анонимно
    LpkBindPw secret # пароль
    LpkServerGroup developers # каким группам разрешено заходить на этот сервер
    LpkForceTLS no # Если у вас настроен TLS, то включаем.
    LpkSearchTimelimit 3 # Лимиты по поиску и подключению в секундах
    LpkBindTimelimit 3 #
    LpkPubKeyAttr sshPublicKey # что забирать из LDAP

    В зависимости от настроек LDAP тут можно просто закомментировать ненужные параметры.

    3. Развертывание конфигураций.


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

    Пример простого рецепта для конфигурирования Postgres+Postgis
    # Cookbook Name:: postgres
    # Recipe:: default
    package "postgresql" do
    action:install
    options "--force-yes"
    end

    package "postgresql-contrib" do
    action:install
    options "--force-yes"
    end

    package "postgis" do
    action:install
    options "--force-yes"
    end

    package "postgresql-9.0-postgis" do
    action:install
    options "--force-yes"
    end

    script "install_postgis" do
    interpreter "bash"
    user "postgres"
    cwd "/tmp"
    code <<-EOH
    createdb template_postgis
    createlang plpgsql template_postgis
    psql -d template_postgis -f /usr/share/postgresql/9.0/contrib/_int.sql
    psql -d template_postgis -f /usr/share/postgresql/9.0/contrib/postgis-1.5/postgis.sql
    psql -d template_postgis -f /usr/share/postgresql/9.0/contrib/postgis-1.5/spatial_ref_sys.sql
    createuser -s pgsql
    EOH
    end


    Настройка LDAP на клиенте. Здесь мы просто раскладываем на клиентскую машину заранее подготовленные файлы с настройками, чтобы клиент мог авторизоваться в нашем LDAP.
    # Cookbook Name:: openldap
    # Recipe:: auth

    package "nscd" do
    action :upgrade
    end

    package "libnss-ldap" do
    action :upgrade
    end

    package "libpam-ldap" do
    action :upgrade
    end

    service "nscd" do
    supports :status => true, :restart => true, :reload => true
    action [ :restart ]
    end

    service "ssh" do
    supports :status => true, :restart => true, :reload => true
    action [ :restart ]
    end

    script "prepare dirs" do
    interpreter "bash"
    user "root"
    cwd "/tmp"
    code <<-EOH
    mkdir -p /etc/ldap
    EOH
    end

    cookbook_file "/etc/libnss-ldap.conf" do
    source "libnss-ldap.conf"
    mode 0644
    owner "root"
    group "root"
    end

    cookbook_file "/etc/pam_ldap.conf" do
    source "pam_ldap.conf"
    mode 0644
    owner "root"
    group "root"
    end

    cookbook_file "/etc/nsswitch.conf" do
    source "nsswitch.conf"
    mode 0644
    owner "root"
    group "root"
    notifies :restart, resources(:service => "nscd"), :immediately
    end

    %w{ account auth password session }.each do |pam|
    cookbook_file "/etc/pam.d/common-#{pam}" do
    source "common-#{pam}"
    mode 0644
    owner "root"
    group "root"
    notifies :restart, resources(:service => "ssh"), :delayed
    end
    end

    С помощью chef на каждую виртуалку ставим также уже сконфигурированый zabbix-agentd и к нему набор скриптов ZTC. После старта виртуалки zabbix по autodiscovery добавляет ее в пул и сразу присоединяет необходимые шаблоны. Панель управления zabbix у нас тоже прицеплена к LDAP. Единственное, что пришлось тут сделать — скрипт автоматической синхронизации LDAP и пользователей zabbix, мониторинг не умеет создавать пользователей сам.

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

    Панель управления Proxmox, заранее сконфигурированные шаблоны для openvz, LVM storage, позволили нам максимально упростить и ускорить развертывание новых виртуальных машин. Мы контролируем все выделяемые ресурсы, под нагрузкой все ведет себя предсказуемо и стабильно. Стоимость внедрения и обслуживания такой виртуальной машины крайне низка по сравнению с другими системами виртуализации.

    Напомню, что это тестовое и девелоперское окружение, полностью закрытое для внешнего мира, без критичных данных и без необходимости бекапов. Поэтому в этой схеме упущены многие очень важные моменты в плане безопасности и отказоустойчивости. Для production в данной схеме нужно будет думать о сертификатах, TLS, SSL, password policy, о различных механизмах защиты PAM, о sudo, а также о правилах фаервола и групповых политиках.

    Еще немного ссылок:
    LDAP для интернет-проекта
    Chef или как управлять тысячей серверов
    Виртуализация Linux с помощью OpenVZ
    Универсальная система мониторинга Zabbix — введение
    Поделиться публикацией

    Похожие публикации

    Комментарии 36

      +17
      Я вам скажу одно слово libvirt
        –1
        libvirt сильно под rhel/centos заточена.
          +2
          Да ви шо? А как я его использую под gentoo?
            0
            Я не говорю, что оно Centos only, я говорю, что оно сильно на идеологию виртуализации рэдхэта заточено.
              +1
              kvm? Не особо.
                0
                До kvm RH любил зен.
          +7
          Ждём статью про libvirt?
        +5
        Тю, я ожидал чего-то серьёзного. 30-40 машин — это ерунда. Вот когда там сильно за 10000, вот тогда-то начинаются проблемы с управляемостью…
          0
          Вы в «вконтакте» работаете?
            +3
            причём здесь вконтакте?
            зачем им 10к виртуалок?
            скорее хостинг/дц.
              +1
              Тыг, как бы «Селектел», облако, и всё такое. И проблема управляемости — одна из острейших проблем. Грубо говоря, на 10к начинают тормозить казалось бы тривиальные операции и приходится отдельно думать, как бы их сделать быстро.
                0
                вам лучше знать :)
                но разве обычная топология — дерево, не применима?
                узел отвечает за 100 виртуалок-листьев.
                узлы связываются в корень, который при надобности отправляет запросы вниз по дереву.
                имхо, такая система довольно просто масштабируется до определенных пределов (само собой чем сложнее система, тем крупнее аппарат управления — балансировка нагрузки на узлы, мониторинг, ...).
                Но на 10к в теории софтварных проблем с управлением именно виртуалок должно быть не очень много.
                правда, всё это теория :)
                  +1
                  Ага, ага.

                  А теперь вопрос, как будет выглядеть в такой топологии запрос «найди мне машину с именем quququ»? А задача «сделать сеть, которая соединит машину quququ1 с quququ2»?

                  На таких масштабах любой чих — десятки секунд (если не минуты) исполнения.
                    0
                    ну я не знаю же как у вас всё устроено, но я бы реализовал функционал роутинга пакета с инструкциями.
                    Ну и в данной модели достаточно послать четыре пакета:
                    1. data1 = get_data(quququ1)
                    2. data2 = get_data(quququ2)
                    3. add_network(quququ2, data1)
                    4. add_network(quququ1, data2)

                    Пакеты обрабатываются узлами.
                    Роутинг можно сделать и «жадным» — броадкаст по дереву, узел который содержит эту машину отвечает.
                    PS: конечно, я понимаю, что это всё что-то типа разминки для ума, и на самом деле всё сложнее и есть подводные камни.
              +1
              нет.
            • НЛО прилетело и опубликовало эту надпись здесь
                +2
                Планирую, хотя выходит кривовато. Про 10к машин там не будет точно, т.к. это глубоко субъективное и текущее, я про него объективно писать не могу.
              +5
              Это вторая статья, за которую я бы продонейтил.
                +1
                По-моему, речь идет не о виртуальных машинах, которых много, а о linux-машинах, которых много.
                  0
                  chef'у без разницы, что конфигурировать.
                  +1
                  Не пробовали применять следующее решение vagrantup.com/? По сути это набор из ruby-скриптов поверх VirtualBox с интеграцией puppet и chef.
                  Если пробовали, прокомментируйте пожалуйста.
                    +2
                    Мы очень редко используем аппаратную виртуализацию, пока все наши задачи решаются с помощью виртуализации на уровне операционной системы (OpenVZ) и VmwareESX для всего остального. Мой субъективное мнение, что VirtualBox все же пока сыроват, как и vagrant.

                      +1
                      Спасибо.
                      0
                      Используем, vagrant очень удобен для разработки и тестирования chef рецептов.
                      0
                      >>Так как наша инфрастуктура закрыта снаружи, срок жизни виртуальных машин сравнительно небольшой, проблемы безопасности в этом окружении для нас не особо важны, то мы выбрали именно этот путь
                      а на кой тогда все эти пляски с авторизацией по ключам? :)
                        +1
                        Вход без пароля.
                          –1
                          да нет, это понятно. но на мой взгляд вводить пароль, или копировать его из буфера в случае ссш намного удобнее, чем хранить ключ. использование ключей в первую очередь имеет преимущества для повышения безопасности.
                          ладно, в данном случае все это скорее вопрос привычки и предпочтений, не более.
                        0
                        сколько сложностей, а ведь openstack именно для этого и придумали. хотя если не хочется заморачиваться с таким монстром, можно поднять oVirt — там большинство данного функционала можно сделать из коробки, плюс готовая интеграция с Foreman, для управления, деплоймента и пост-конфигурации.
                          0
                          Вы не забывайте, что статья писалась в начале 2011 года и на тот момент блистал только Proxmox, с возможностью кластеризации и возможностью выбора гипервизора из коробки.
                          Openstack писали админы для админов, со всеми вытекающими отсюда последствиями. И при серьезных инсталляциях будет довольно тяжело и дорого его поддерживать. Сейчас ситуация с ним чуть лучше, но на тот момент все это доставляло немало проблем.
                          oVirt — это KVM и RedHat. Плюс надо организовывать сетевое хранилище. Proxmox приятней, проще и функциональней. Как-то так )
                            0
                            oVirt официально перезапустили как раз в 2011, и уже тогда он умел и кластеризацию, и API, и интеграцию с foreman. Там же, из коробки, было три портала — для админов, для пользователей и для продвинутых пользователей, с разделением доступа и возможностей. Сетевое хранилище надо организовывать, само собой, но иначе о каком кластере может быть речь? Аргумент «это KVM и RedHat» я вообще не понимаю — что в этом плохого? На самом деле, единственное в чем проксмокс обошел ovirt даже на сегодняшний день, даже если не смотреть на то что новые фичи в 3.2 все поголовно не поддерживаются и имеют экспериментальный статус, это в поддержке контейнеров. Но и это должно скоро измениться, как только libvirt полностью начнет контролировать LXC

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

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

                        Самое читаемое