Автоматическое развертывание масштабируемого сайта WordPress

Данный мануал поможет создать и развернуть масштабируемый экземпляр WordPress, состоящий из сервера базы данных MySQL, распределенной файловой системы GlusterFS, веб-серверов Nginx и балансировщика нагрузки Nginx. Используя пользовательские данные и метаданные сервера, вы можете автоматизировать развертывание сайта. Сценарий Ruby может облегчит создание масштабируемых сайтов WordPress.

Читайте также: Обзор метаданных сервера

1: Планирование развертывания

Развертывание в этом мануале будет состоять из одного сервера базы данных MySQL, нескольких серверов GlusterFS в кластере, нескольких веб-серверов Nginx и одного балансировщика нагрузки Nginx.

Прежде чем начать, вам нужно точно знать:

  • размер сервера MySQL
  • количество нод GlusterFS
  • размер нод GlusterFS
  • количество нод веб-серверов
  • размер нод веб-серверов
  • размер ноды балансировщика нагрузки
  • домен нового сайта

В дальнейшем вы можете добавить дополнительные ноды или увеличить количество ресурсов этих нод.

2: Развертывание MySQL

Начнем с развертывания сервера MySQL. Для этого нужно создать 64-бинтый сервер Ubuntu 14.04, используя следующие пользовательские данные.

#!/bin/bash
export DEBIAN_FRONTEND=noninteractive;
export PUBLIC_IP=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)
export PRIVATE_IP=$(curl -s http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address)
apt-get update;
apt-get -y install mysql-server;
mysqladmin -u root create wordpress;
mysqladmin -u root password "mysql_password";
sed -i.bak "s/127.0.0.1/$PRIVATE_IP/g" /etc/mysql/my.cnf;
service mysql restart;
mysql -uroot -pmysql_password -e "CREATE USER 'wordpress'@'%' IDENTIFIED BY 'mysql_password'";
mysql -uroot -pmysql_password -e "GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'%'";

Этот сценарий пользовательских данных будет выполнять следующие функции на новом сервере.

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

export DEBIAN_FRONTEND=noninteractive;

Затем с помощью метаданных сервера сценарий собирает внешний и внутренний IP-адрес и присваивает их переменным:

export PUBLIC_IP=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)
export PRIVATE_IP=$(curl -s http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address)

Затем apt устанавливает MySQL.

apt-get update;
apt-get -y install mysql-server;

После этого нужно создать новую базу данных по имени wordpress.

mysqladmin -u root create wordpress;

и установить пароль для root-пользователя MySQL.

mysqladmin -u root password "mysql_password";

Поскольку сервер MySQL будет принимать запросы с веб-серверов, нужно, чтобы он прослушивал внутренний IP-адрес, а не только localhost. Сценарий использует sed для обновления конфигурационного файла MySQL, выполнив поиск и замену, а затем перезапускает сервис.

sed -i.bak "s/127.0.0.1/$PRIVATE_IP/g" /etc/mysql/my.cnf;
service mysql restart;

Затем он создает нового пользователя MySQL по имени wordpress:

mysql -uroot -pmysql_password -e "CREATE USER 'wordpress'@'%' IDENTIFIED BY 'mysql_password'";
mysql -uroot -pmysql_password -e "GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'%'";

Развернув новый сервер с помощью этого сценария пользовательских данных, вы получите настроенный сервер MySQL, который будет прослушивать внутренний IP-адрес, с готовой базой данных и пользователем.

3: Развертывание GlusterFS

Перед развертыванием кластера GlusterFS вам нужно решить, сколько нод в нем должно быть. Для этого есть две переменные. Во-первых, нужно указать размер нод, а затем нужно принять решение о настройке реплики. Этот параметр указывает GlusterFS, сколько копий файла нужно хранить. Например, если replica – 2, то каждый файл дублируется не менее чем на 2 серверах. Это сократит доступное пространство вдвое, поскольку GlusterFS будет сохранять две копии каждого файла, но это обеспечивает хорошую избыточность. Количество создаваемых нод GlusterFS должно быть кратным параметру replica. Для кластера со значением «replica 2» нужно будет создать количество нод, кратное 2 (2, 4, 6 или 8 нод и т.д.).

В данном примере кластер GlusterFS будет состоять из 4 нод.

Для первых трех нод используйте такой сценарий:

#!/bin/bash
export DEBIAN_FRONTEND=noninteractive;
apt-get update;
apt-get install -y python-software-properties;
add-apt-repository -y ppa:gluster/glusterfs-3.5;
apt-get update;
apt-get install -y glusterfs-server;

Опять же, сначала устанавливается переменная DEBIAN_FRONTEND, благодаря чему apt знает, что работать нужно в неинтерактивном режиме:

export DEBIAN_FRONTEND=noninteractive;

Затем сценарий обновляет индекс пакетов и устанавливает python-software-properties, с помощью которого добавляется PPA для GlusterFS.

apt-get update;
apt-get install -y python-software-properties;

Затем сценарий добавляет GlusterFS PPA, чтобы иметь возможность загрузить пакет:

add-apt-repository -y ppa:gluster/glusterfs-3.5;

После сценарий обновит индекс пакетов и установит glusterfs-server.

apt-get install -y glusterfs-server;

Так выглядит сценарий для первых трех нод кластера. Обратите внимание на внутренние IP-адреса, присвоенные каждому из этих новых серверов – они понадобятся вам при создании последней ноды GlusterFS и создании тома.

Для последней ноды нужно использовать следующий сценарий пользовательских данных:

#!/bin/bash
export DEBIAN_FRONTEND=noninteractive;
export PRIVATE_IP=$(curl -s http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address)
apt-get update;
apt-get install -y python-software-properties;
add-apt-repository -y ppa:gluster/glusterfs-3.5;
apt-get update;
apt-get install -y glusterfs-server;
sleep 30;
gluster peer probe node1_private_ip;
gluster peer probe node2_private_ip;
gluster peer probe node3_private_ip;
gluster volume create file_store replica 2 transport tcp node1_private_ip:/gluster node2_private_ip:/gluster node3_private_ip:/gluster $PRIVATE_IP:/gluster force;
gluster volume start file_store;

Примечание: Если вы не хотите включать репликацию, удалите параметр «replica» в команде «volume create».

Первый раздел этого сценария очень похож на тот, который использовался для создания предыдущих нод GlusterFS. IP-адрес нового сервера присваивается переменной $PRIVATE_IP. После установки glusterfs-server выполняет дополнительную работу.

Во-первых, сценарий будет ждать 30 секунд для запуска нового glusterfs-server.

sleep 30

Затем он проверяет три ноды GlusterFS, чтобы добавить все четыре в кластер.

gluster peer probe node1_private_ip;
gluster peer probe node2_private_ip;
gluster peer probe node3_private_ip;

Затем он создает том GlusterFS по имени filestore с параметром replica 2 и включает все четыре ноды. Поскольку вы не знаете IP-адрес последней ноды, используйте для нее переменную $PRIVATE_IP.

gluster volume create file_store replica 2 transport tcp node1_private_ip:/gluster node2_private_ip:/gluster node3_private_ip:/gluster $PRIVATE_IP:/gluster force;

Затем сценарий запускает новый том, чтобы сделать его доступным для клиентов:

gluster volume start file_store;

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

4: Развертывание нод Nginx

Теперь сервер базы данных и распределенная файловая система готовы, и вы можете развернуть веб-серверы. Используйте следующий сценарий пользовательских данных для развертывания первой ноды веб-сервера Nginx и настройки установки WordPress внутри тома GlusterFS.

#!/bin/bash
export DEBIAN_FRONTEND=noninteractive;
export PRIVATE_IP=$(curl -s http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address)
apt-get update;
apt-get -y install nginx glusterfs-client php5-fpm php5-mysql;
sed -i s/\;cgi\.fix_pathinfo\=1/cgi\.fix_pathinfo\=0/g /etc/php5/fpm/php.ini;
mkdir /gluster;
mount -t glusterfs gluter_node_private_ip:/file_store /gluster;
echo "gluster_node_private_ip:/file_store /gluster glusterfs defaults,_netdev 0 0" >> /etc/fstab;
mkdir /gluster/www;
wget https://raw.githubusercontent.com/ryanpq/do-wpc/master/default -O /etc/nginx/sites-enabled/default;
service nginx restart;
# Get WordPress Files
wget https://wordpress.org/latest.tar.gz -O /root/wp.tar.gz;
tar -zxf /root/wp.tar.gz -C /root/;
cp -Rf /root/wordpress/* /gluster/www/.;
cp /gluster/www/wp-config-sample.php /gluster/www/wp-config.php;
sed -i "s/'DB_NAME', 'database_name_here'/'DB_NAME', 'wordpress'/g" /gluster/www/wp-config.php;
sed -i "s/'DB_USER', 'username_here'/'DB_USER', 'wordpress'/g" /gluster/www/wp-config.php;
sed -i "s/'DB_PASSWORD', 'password_here'/'DB_PASSWORD', 'mysql_password'/g" /gluster/www/wp-config.php;
sed -i "s/'DB_HOST', 'localhost'/'DB_HOST', 'mysql_private_ip'/g" /gluster/www/wp-config.php;
chown -Rf www-data:www-data /gluster/www;

Этот сценарий немного сложнее, чем предыдущие.

Сначала он устанавливает переменную DEBIAN_FRONTEND и $PRIVATE_IP.

export DEBIAN_FRONTEND=noninteractive;
export PRIVATE_IP=$(curl -s http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address)

После этого он обновляет индекс пакетов и устанавливает Nginx, клиент glusterfs и библиотеки php.

apt-get update;
apt-get -y install nginx glusterfs-client php5-fpm php5-mysql;

Затем сценарий с помощью sed обновляет файл php.ini и устанавливает в переменной cgi.fixpathinfo значение 0.

sed -i s/\;cgi\.fix_pathinfo\=1/cgi\.fix_pathinfo\=0/g /etc/php5/fpm/php.ini;

После этого сценарий создает папку /gluster в корне образа диска и монтирует там том GlusterFS. Далее он создает запись fstab, чтобы том GlusterFS автоматически монтировался при загрузке сервера.

mkdir /gluster;
mount -t glusterfs gluter_node_private_ip:/file_store /gluster;
echo "gluster_node_private_ip:/file_store /gluster glusterfs defaults,_netdev 0 0" >> /etc/fstab;

Затем сценарий создаст папку под названием www в томе GlusterFS. Эта папка будет действовать как корневой каталог веб-сервера.

mkdir /gluster/www;

Далее он загружает новый конфигурационный файл Nginx с удаленного сервера. Этот файл установит корневой каталог веб-сервера в /gluster/www и настроит Nginx для поддержки PHP. Вы можете просмотреть этот конфигурационный файл здесь. После замены конфигурационного файла Nginx нужно перезапустить сервис.

wget https://raw.githubusercontent.com/ryanpq/do-wpc/master/default -O /etc/nginx/sites-enabled/default;

После этого сценарий скопирует последнюю версию WordPress, распакует и переместит ее в новый корневой каталог:

wget https://wordpress.org/latest.tar.gz -O /root/wp.tar.gz;
tar -zxf /root/wp.tar.gz -C /root/;
cp -Rf /root/wordpress/* /gluster/www/.;

Затем нужно скопировать образец конфигурации WordPress в файл wp-config.php.

cp /gluster/www/wp-config-sample.php /gluster/www/wp-config.php;

Сценарий обновит переменные в соответствии с новой средой, снова используя функцию поиска и замены sed.

sed -i "s/'DB_NAME', 'database_name_here'/'DB_NAME', 'wordpress'/g" /gluster/www/wp-config.php;
sed -i "s/'DB_USER', 'username_here'/'DB_USER', 'wordpress'/g" /gluster/www/wp-config.php;
sed -i "s/'DB_PASSWORD', 'password_here'/'DB_PASSWORD', 'mysql_password'/g" /gluster/www/wp-config.php;
sed -i "s/'DB_HOST', 'localhost'/'DB_HOST', 'mysql_private_ip'/g" /gluster/www/wp-config.php;

В конце он убедится, что файлы в корневом каталоге веб-сервера принадлежат пользователю www- data, который будет выполнять процесс Nginx.

chown -Rf www-data:www-data /gluster/www;

Теперь у вас есть первая нода веб-сервера, готовая к отправке запросов.

Поскольку каждая из нод веб-сервера использует один и тот же том GlusterFS для хранения файлов, для создания остальных нод потребуется меньше действий. Используйте следующий сценарий пользовательских данных:

#!/bin/bash
export DEBIAN_FRONTEND=noninteractive;
export PRIVATE_IP=$(curl -s http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address)
apt-get update;
apt-get -y install nginx glusterfs-client php5-fpm php5-mysql;
sed -i s/\;cgi\.fix_pathinfo\=1/cgi\.fix_pathinfo\=0/g /etc/php5/fpm/php.ini;
mkdir /gluster;
mount -t glusterfs gluster_node_private_ip:/file_store /gluster;
echo "gluster_node_private_ip:/file_store /gluster glusterfs defaults,_netdev 0 0" >> /etc/fstab;
mkdir /gluster/www;
wget https://raw.githubusercontent.com/ryanpq/do-wpc/master/default -O /etc/nginx/sites-enabled/default;
service nginx restart;

На дополнительные ноды нужно установить те же пакеты, смонтировать том GlusterFS и заменить конфигурационный файл Nginx, но не нужно настраивать экземпляр WordPress, поскольку это было сделано при создании первой ноды.

5: Развертывание балансировщика нагрузки

Последним шагом в этом развертывании является создание балансировщика нагрузки. Для этой цели можно использовать еще один сервер Nginx. Чтобы настроить эту ноду, нужно использовать следующий сценарий:

#!/bin/bash
export DEBIAN_FRONTEND=noninteractive;
apt-get update;
apt-get -y install nginx;
lbconf="
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.php index.html index.htm;
location / {
proxy_pass  http://backend;
include proxy_params;
}
}
upstream backend  {
ip_hash;
server web_node_1_private_ip
server web_node_2_private_ip
}
"
echo $lbconf > /etc/nginx/sites-enabled/default;
service nginx restart;

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

export DEBIAN_FRONTEND=noninteractive;

Затем сценарий установит Nginx:

apt-get update;
apt-get -y install nginx;

После этого он создаст новый конфигурационный файл Nginx в переменной lbconf. Записи для веб-серверов помещаются в раздел upstream backend:

lbconf="
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.php index.html index.htm;
location / {
proxy_pass  http://backend;
include proxy_params;
}
}
upstream backend  {
ip_hash;
server web_node_1_private_ip
server web_node_2_private_ip
}
"

После этого в переменной lbconf определяется конфигурационный файл Nginx:

echo $lbconf > /etc/nginx/sites-enabled/default;

Последняя строчка сценария перезапускает Nginx.

6: Настройка DNS

Прежде чем попробовать получить доступ к WordPress в браузере, нужно настроить DNS-запись для этого сайта.

Это можно сделать в панели управления хостингом. Чтобы использовать поддомен www, нужно создать дополнительную запись CNAME.

Читайте также: Как настроить имя хоста

7: Настройка WordPress

Теперь можно настроить новый сайт WordPress в браузере.

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

8: Автоматизация развертывания

Теперь вы можете выполнить развертывание WordPress без необходимости в ssh-подключении, пора автоматизировать этот процесс с помощью API.

Для этого можно использовать Ruby-скрипт, который запросит у пользователя соответствующие данные, а затем автоматически развернет новый масштабируемый экземпляр WordPress. Вы можете найти подобный скрипт на GitHub.

Заключение

Развертывание масштабируемого приложения WordPress успешно завершено.

Читайте также:

Tags: , , , ,