Развертывание программного обеспечение на VM с помощью инструментов управления конфигурацией

Reduction_GearВ предыдущей статье мы рассмотрели как осуществить выделение виртуальной машины через API системы Cloudstack. В данной статье мы рассмотрим следующие действия по развертыванию программного обеспечения в автоматизированном режиме. В основном, мы будем использовать инструмент Ansible, который позволяет с помощью специальных сценариев конфигураций централизованно управлять программным обеспечением на множестве узлов. В нашей  задаче Ansible позволит нам установить на виртуальную машину инструментарий обработки видео ffmpeg.

Всю статью можно разделить на следующие части:

  1. работа с PKI-ключами доступа на виртуальную машину;
  2. создание конфигурации с помощью Ansible;
  3. применение конфигурации к вновь созданной виртуальной машине.

Начнем с разбора того, каким образом осуществляется управление PKI-ключами OpenSSL с помощью Cloudstack. Сначала, небольшой экскурс и объяснение для чего применяются ключи. PKI — public key infrastructure (инфраструктура открытых ключей) применяется для шифрования потока данных с помощью секретных и публичных ключей, кроме того они применяются для авторизации на сервере SSH, позволяя пользователю не вводить пароль, а использовать пару секретный и публичный ключ для доступа к множеству серверов без пароля. При этом секретный ключ находится у пользователя в надежном месте (на его компьютере), а публичный ключ распространяется по серверам, на которые требуется обеспечить доступ. Данный способ аутентификации превосходит метод аутентификации по паролю.

Cloudstack так же предоставляет поддержку инфраструктуры PKI, суть которой в том, чтобы публичный ключ пользователя оказывался на виртуальной машине сразу же после ее создания. Это позволит зайти на данную машину по SSH по секретному ключу без ввода пароля.

Создание пары ключей и VM, позволяющей авторизоваться по ключам:

Запускаем Cloudmonkey и выполняем следующие команды:

> create sshkeypair name=mykeypair
keypair:
name = mykeypair
fingerprint = 8a:cd:eb:a5:83:54:9c:26:e7:17:fd:40:75:a9:2b:41
privatekey = -----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCZJvWxFNUHP739ANFms3sWXcZfL8dTwc5s8bR/csacnxAL9puy
QjllSx3PkYwIUyvStcnzAjY9ho2QGBtUv3rb8iAbHlVuo/tVuXxqhS3BFwA5HWW8
7TmSKu0IRE8/WgZx2ww7EKV9PD/prJ0N+hAhrFjK+fxd2dTFu3hllbRSpQIDAQAB
AoGAMe6g1f47wiRHFhDJNNm5fL5QKcKTEzyxx5U6Sv8pv/CgM7ZQZtruiZbm/kCu
zhwHwqggUolbE84lo2AosQXI0SG5wshoJFcfjFGurUsAPQJ6lC6pQ0HMsSBm0wwG
X7SwJvZHCwdZXANQZJrt7zL4Pz5TmmJjahPXcYmtKYzULIECQQDNUhl10UsBrezP
Rs2nQJMaxZWIHFCrCgxuzR8/IPYcDtytsxS2lpVxhAW6GEgocNFMDqkqLoPaL7ZH
ozAbHAtFAkEAvvRpaZq28Dd9uSisaQVGAsBvmCUb8tLQR7R4bHoLt+mRrGtt5e7N
wswviD1pa/s6+JVE20W9ouSUXoi4CXXv4QJAY5N1lZYzclUPjFciVgMTVOCObLyO
wuTUssf4Z31s3p62l+dKHGNbhvoobOBp3nMYjnJtyG9WsvKAzK1wHzWyoQJAPugZ
yfZ0CdLeEh96HObl14Y5vS+Mc4RLpTOo8GOMdLv3h4ukmrj/BAtsJT/F+RK8rKPQ
GURyYrVWw4XayxMVQQJBALdXwXoBptTvxiNgtjWXE8DCZr7C7PyMyuI25N+XQJuG
lxT/L4TWbYXPBslPLm/kT73/32ZxCc0UfSeOI9xzk9E=
-----END RSA PRIVATE KEY-----

> deploy virtualmachine serviceofferingid=f49918d3-abe1-47b3-b9b6-53e9839d4fb4 templateid=fe9f83ef-6e8c-42e6-b0a0-8942a621fcb8 zoneid=860117f1-c815-4f0d-bb6f-04955f7de56f keypair=mykeypair

> delete sshkeypair name=keypair
success = true

Первая команда (create sshkeypair) позволяет пару ключей. Вы должны скопировать строки ключа в файл, который будет использоваться для идентификации (например, /home/user/.ssh/id_rsa_cloud.private). На данный файл необходимо установить права 600.

Вторая команда (deploy virtualmachine) создает виртуальную машину с поддержкой данной пары ключей (параметр keypair=mykeypair).

Третья команда (delete sshkeypair) позволяет удалить ключи, если они больше не требуются. Обратите внимание, что Вы можете создавать на каждую выделяемую машину отдельную пару ключей, хотя это может быть неудобно для каких-то приложений.

Теперь мы имеем возможность зайти по SSH на виртуальную машину не только по паролю, который вернется в результатах команды deploy virtualmachine, но и с помощью ключей ssh:

$ ssh -i /home/user/.ssh/id_rsa_cloud.private root@my-vm-ip-address

Для чего вообще нужны эти дополнительные действия, связанные с ключами? Дело в том, что ssh-клиенты не поддерживают (в большинстве своем) авторизацию по паролю, который передается как аргумент или читается со stdout, что связано с воровством паролей. Таким образом единственный адекватный способ авторизации на серверах SSH, подходящий для автоматизации — авторизация по ключам.

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

Мы будем использовать Ansible. На это есть ряд причин:

  1. продукт полностью бесплатный;
  2. Ansible не требует установки агентов на хостах, работая поверх SSH;
  3. позволяет быстро погрузиться в синтаксис конфигураций;
  4. включает огромное количество готовых модулей и позволяет легко реализовать свой, используя язык python (впрочем, можно и не python).

Кроме Ansible существуют другие продукты, которые позволяют управлять конфигурацией, например, Chef, Puppet. Они обладают различными возможностями, достоинствами и недостатками и, в конечном итоге, какой продукт использовать — решать пользователю. Мы выбрали Ansible из-за простоты и низких требований к инфраструктуре.

В данном руководстве мы не ставим цель детально рассказать о том, как использовать Ansible. Скорее, мы приведем пример, который применим в задаче, а дальнейшее изучение инструмента оставляем читателю (воспользуйтесь официальным сайтом — там отличная документация).

Вообще, Ansible требует создания следующих сущностей:

  1. файл реестра серверов (registry);
  2. файлы сценариев (playbook).

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

Обычно Ansible проверяет, что хост уже есть в файле known_hosts, что неудобно для вновь создаваемых виртуальных машин. Для того, чтобы предотвратить данное поведение, можно внести строку host_key_checking = False в файл /etc/ansible/ansible.cfg. Теперь Ansible не будет проверять known_hosts.

Для начала создадим файл реестра серверов:

$ cat > registry
[servers]
server
^D

$ mkdir host_vars
$ cd host_vars
$ cat > server 
---
ansible_ssh_host: 176.120.25.158
ansible_ssh_private_key_file: /root/.ssh/id_rsa_cloud.private
^D

Рассмотрим, что мы видим выше.

  1. Создаем файл реестра и помещаем в него группу [servers] и одну сущность server. Параметры серверов обычно из файла реестра выносят, чтобы его не загромождать.
  2. Создадим каталог host_vars, в котором будем описывать параметры доступа для наших записей.
  3. В каталоге создадим файл server для нашего сервера и поместим в него параметры доступа к нему (ansible_ssh_host, ansible_ssh_private_key_file).

Вот и все, теперь проверим работу:

$ ansible -i registry all -m ping
$ ansible -i registry all -m apt -a "update_cache=yes"
$ ansible -i infrastructure.file all -m apt -a "name=ffmpeg state=installed"

После выполнения первой команды Вы в ответ должны получить pong, что означает успешность соединения. Вторая и третья команды обновляют кэш пакетов и устанавливают ffmpeg из репозиториев. Как видите, ничего сложного.

Надо отметить, что для сложных конфигураций гораздо удобнее использовать файлы конфигураций (playbook) и готовые модули для различных случаев, например:

  1. управление пользователями и sudo;
  2. установка и настройка сервисов (mysql, apache, nginx) с параметрами.

Все эти задачи просто и удобно позволяет выполнять Ansible, кроме того, один раз написанная конфигурация может применяться многократно, что ведет к экономии времени и защите от ошибок.

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