Четвер, 9 жовтня 2008 р.

Устанавливаем на Amazon EC2 и Amazon EBS Java-приложение с MySQL

На примере типичного сайта опишу последовательность действий по установке на хостинг Amazon.

Приложение - сайт на Java, который требует большой вычислительной мощности. Поэтому было принято решение сразу запускаться на Amazon. В работе сайт использует на чтение-запись базу MySQL. Сайт будет развернут на одном экземпляре (instance) Elastic Computing Cloud (EC2). База MySQL - на томе (volume) Elastic Block Storage (EBS). Все пользовательские данные будут храниться в MySQL. На диске экземпляра будут храниться настройки, а также скрипт сборки приложения, который будет собирать приложения из внешних источников (например, из репозитария Subversion).

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

Установка утилит EC2 и настройка окружения

  1. Заходим на http://aws-portal.amazon.com, логинимся, покупаем EC2. На страницах нужно будет найти и запомнить Access Key ID, Secret Access Key и Account ID. Также нужно сгенерировать и сохранить файл с сертификатом X.509 (cert-11111111111111.pem) и файл с приватным ключем (pk-11111111111111.pem).
  2. Устанавливаем Amazon EC2 Command-Line Tools.
    1. Скачиваем с Amazon.
    2. Распаковываем в нужное место (например, /usr/ec2).
    3. Прописываем окружение (вариант для Linux): pupkin@local$ export EC2_HOME=/usr/ec2/ec2-api-tools-1.3-19403 pupkin@local$ export PATH=$PATH:$EC2_HOME/bin pupkin@local$ export EC2_PRIVATE_KEY=/home/pupkin/mega-project/ec2/pk-11111111111111.pem pupkin@local$ export EC2_CERT=/home/pupkin/mega-project/ec2/cert-11111111111111.pem
    4. Проверить, правильно ли установлены утилиты можно, выполнив команду ec2-describe-images. Результатом команды будет список доступных для запуска образов виртуальных машин (AMI): pupkin@local$ ec2-describe-images -a IMAGE ami-5586623c 1fm2knh6gyecefa34102-phe-bucket/image.manifest.xml 437711880492 available public i386 machine IMAGE ami-63ec090a 1VYRBPTAGB3GRJD3N902-AMI-082407/image.manifest.xml 681122512140 available public i386 machine IMAGE ami-18cf2a71 1VYRBPTAGB3GRJD3N902-AMI-110407-dev/image.manifest.xml 681122512140 available public i386 machine ...

Настройка экземпляра

В качестве ОС выбираем Ubuntu Linux. За основу берем образ Ubuntu 8.04 LTS Hardy от alestic.com. Дальше доставим туда необходимые Java, MySQL и всё остальное.
  1. Запускаем экземпляр с нужным образом.
    1. Ищем последний по дате нужный образ. Выбираем base (лишнего нам не надо) и 64-битную платформу (нашему сайту будет нужно много памяти). pupkin@local$ ec2-describe-images -a |grep ubuntu |grep alestic |grep 64 IMAGE ami-17d7337e alestic-64/ubuntu-8.04-hardy-base-64-20080924.manifest.xml
    2. Генерируем ключик для доступа к экземпляру по SSH pupkin@local$ ec2-add-keypair pstam-keypair и сохраняем его в файле, например, /home/pupkin/mega-project/ec2/id_rsa-pstam-keypair.
      Если используется OpenSSH, для этого файлы нужно выставить правильные права доступа: pupkin@local$ chmod 600 /home/pupkin/mega-project/ec2/id_rsa-pstam-keypair
    3. Запускаем выбранный экземпляр pupkin@local$ ec2-run-instances ami-17d7337e -k pstam-keypair -t m1.large RESERVATION r-4073a129 701161471898 default INSTANCE i-1b903272 ami-17d7337e pending pstam-keypair 0 m1.large 2008-10-02T12:54:37+0000 us-east-1b aki-b51cf9dc ari-b31cf9da i-1b903272 - это идентификатор экземпляра. Он будет нужен позднее.
      pending - означает, что экземпляр в процессе запуска.

      Ждем 15 секунд, и выполняем команду pupkin@local$ ec2-describe-instances RESERVATION r-4073a129 701161471898 default INSTANCE i-1b903272 ami-17d7337e ec2-75-101-241-247.compute-1.amazonaws.com domU-12-31-39-01-59-41.compute-1.internal running pstam-keypair Статус должен поменяться на running. Если не поменялся - нужно подождать еще.
      Когда статус поменяется на running, в таблице будет видно внешний (ec2-75-101-241-247.compute-1.amazonaws.com) и внутренний (domU-12-31-39-01-59-41.compute-1.internal) адреса экземпляра. Внешний адрес используется для доступа к экземляру из интернета, внутренний - с других инстансов (если такие будут).
  2. Открываем доступ к экземпляру по нужным портам: pupkin@local$ ec2-authorize default -p 22 pupkin@local$ ec2-authorize default -p 80 проверяем pupkin@local$ telnet ec2-75-101-241-247.compute-1.amazonaws.com 22
  3. Логинимся на экземпляр и устанавливаем нужные пакеты pupkin@local$ ssh -i /home/pupkin/mega-project/ec2/id_rsa-pstam-keypair root@ec2-75-101-241-247.compute-1.amazonaws.com root@domU-12-31-39-01-59-41# apt-get update root@domU-12-31-39-01-59-41# apt-get install mysql-server root@domU-12-31-39-01-59-41# apt-get install apache2 root@domU-12-31-39-01-59-41# apt-get install sun-java6-jdk root@domU-12-31-39-01-59-41# apt-get install zabbix-agent root@domU-12-31-39-01-59-41# apt-get install subversion root@domU-12-31-39-01-59-41# apt-get install postfix root@domU-12-31-39-01-59-41# apt-get install mailx Дополнительные пакеты можно будет поставить и позднее, при необходимости.

Настройка Elastic IP

При каждом старте экземпляре ему выдается новый IP-адрес. Чтобы при этом избежать проблем с DNS-ом, закажем также Elastic IP. pupkin@local$ ec2-allocate-address ADDRESS 75.101.137.69 pupkin@local$ ec2-associate-address -i i-1b903272 75.101.137.69 ADDRESS 75.101.137.69 i-1b903272 - это идентификатор экземляра. Если вы его забыли, можно посмотреть командой ec2-describe-instances). Теперь этот адрес можно (и нужно) прописать в DNS, например, связав с именем http://mega-project.pupkin.com.

Настройка EBS

  1. Создаем том. pupkin@local$ ec2-create-volume -s 200 -z us-east-1b us-east-1b - зона, или датацентр Amazon. Её нужно выбрать такой же, в какой запущен экземпляр, чтобы не гонять лишний трафик. Посмотреть зону экземпляра можно командой ec2-describe-instances. Ждем пока поднимется, смотрим информацию о томах: pupkin@local$ ec2-describe-volumes VOLUME vol-2a08ed43 200 us-east-1b available 2008-10-02T15:50:14+0000
  2. Подключаем том к инстансу pupkin@local$ ec2-attach-volume -i i-1b903272 vol-2a08ed43 -d /dev/sdd1
  3. Для новосозданного тома создаём и монтируем файловую систему на экземпляре pupkin@local$ ssh -i /home/pupkin/mega-project/ec2/id_rsa-pstam-keypair root@ec2-75-101-241-247.compute-1.amazonaws.com root@domU-12-31-39-01-59-41# mkfs -t ext3 /dev/sdd1 root@domU-12-31-39-01-59-41# mkdir /mnt/db root@domU-12-31-39-01-59-41# mount /dev/sdd1 /mnt/db

Настройка ПО

  1. MySQL MySQL нужно перенести из папки по умолчание (/var) на EBS в раздел с данными (мы его смонтировали в /mnt/db).
    1. Останавливаем MySQL. root@domU-12-31-39-01-59-41# /etc/init.d/mysql stop * Stopping MySQL database server mysqld
    2. Копируем уже созданную БД. root@domU-12-31-39-01-59-41# mkdir /mnt/db/lib /mnt/db/log root@domU-12-31-39-01-59-41# mv /var/lib/mysql /mnt/db/lib/ root@domU-12-31-39-01-59-41# mv /var/log/mysql /mnt/db/log/ root@domU-12-31-39-01-59-41# test -f /vol/log/mysql/mysql-bin.index && perl -pi -e 's%/var/log/%/vol/log/%' /vol/log/mysql/mysql-bin.index
    3. Правим конфиг. root@domU-12-31-39-01-59-41# vim /etc/mysql/my.cnf Раздел mysqld должен быть таким [mysqld] innodb_file_per_table datadir = /mnt/db/lib/mysql log_bin = /mnt/db/log/mysql/mysql-bin.log max_binlog_size = 1000M log_slow_queries = /mnt/db/log/mysql/mysql-slow.log long_query_time = 10
    4. Запускаем. root@domU-12-31-39-01-59-41# /etc/init.d/mysql start
  2. Собственно сайт
    1. Создаём пользователя, под которым будет работать сайт (если сайт сделан в виде отдельного процесса). root@domU-12-31-39-01-59-41# /usr/sbin/adduser mega-project
    2. Пишем скрипт сборки, который
      • чекаутит последнюю версию сайта из репозитария Subversion;
      • делает сборку;
      • перезапускает сайт из новособранной версии.
    3. Запускаем скрипт, настраиваем конфиги приложения, запускаем приложение. Теперь можно зайти на http://mega-project.pupkin.com/ и посмотреть на работающий сайт :)

Сохраняем образ тома

Чтобы не потерялась проделанная работа, нужно сохранить образ настроеного экземпляра. Сохраненный образ также пригодится, если экземпляр нужно будет перезапустить, для поднятия кластера и др.
  1. Копируем ключи и сертификат - они будут нужны на экземпляре. pupkin@local$ cd /home/pupkin/mega-project/ec2/id_rsa-pstam-keypair pupkin@local$ scp -i id_rsa-pstam-keypair id_rsa-pstam-keypair root@ec2-75-101-241-247.compute-1.amazonaws.com: pupkin@local$ scp -i id_rsa-pstam-keypair pk-11111111111111.pem root@ec2-75-101-241-247.compute-1.amazonaws.com: pupkin@local$ scp -i id_rsa-pstam-keypair cert-11111111111111.pem root@ec2-75-101-241-247.compute-1.amazonaws.com:
  2. Собираем пакет с файлами root@domU-12-31-39-01-59-41# ec2-bundle-vol -e /tmp -d /mnt -k pk-11111111111111.pem -c cert-11111111111111.pem -u <Account ID без символов -> -p mega-project-image -s 1500 1500 - размер образа. На стоимость хранения не оказывает влияния, но при небольших размерах быстрее архивируется (перед хранением) и быстрее стартует экземпляр.
    Размер образа должен быть не меньше, чем размер примонтированной на / файловой системы.
    Если значение размера будет слишком маленьким, команда ec2-bundle-vol может выдать сообщение об ошибке execution failed: "rsync ... "
  3. Заливаем собранный пакет в Amazon Structured Storage Service (S3). root@domU-12-31-39-01-59-41# ec2-upload-bundle -b pupkin-images -m /mnt/mega-project-image.manifest.xml -a <Access Key Id> -s <Secret Access Key>
  4. С локальной машины регистрируем пакет как образ.
  5. pupkin@local$ ec2-register pupkin-images/mega-project-images.manifest.xml Всё, дело сделано :).

Возникшие проблемы и вопросы

  1. Почему-то MySQL сразу при старте начинает сильно загружать процессор. Полечилось перезапуском MySQL.
UPD. При переносе данных MySQL в другую папку нужно также поправить настройки apparmor (в /etc/apparmor.d/usr.sbin.mysqld) и logrotate (в /etc/logrotate.d/mysql-server)

2 коментарі:

gimlet сказав...

Отличная полезная заметка. Сейчас выбираю между vds и сервисом амазона. Как оно в использовании? приятно?

Vasyl Stashuk сказав...

Очень и очень :)

Все новые большие сервисы на нем буду поднимать.

Один из старых сайтов запущен на собственном сервере - так собираюсь переносить на Амазон.

Единственный негатив, который обнаружился при эксплуатации - у сервера Reverse DNS резолвится в прикольное имя, и некоторые параноидальные почтовые сервера не хотят принимать почту. Лечится поднятием отдельного сервера для почты, или использованием бесплатного (например, Google Apps) или платного (например, AuthSMTP) провайдера почты.