自动部署可扩展的WordPress站点
介绍
在本指南中,我们将创建和部署一个可扩展的 WordPress 实例,该实例由 MySQL 数据库服务器、GlusterFS 分布式文件系统、Nginx Web 服务器和 Nginx 负载均衡器组成。 通过使用 user-data 和 Droplet 元数据,我们将自动部署我们的站点。 最后,我们将提供一个 Ruby 脚本,它将自动化整个过程并简化可扩展的 Wordpress 站点的创建。 通过本教程,您将了解在 DigitalOcean 上部署服务时用户数据和 Droplet 元数据的强大功能和灵活性。
第一步——规划我们的部署
我们在本教程中创建的部署将包括一个 MySQL 数据库服务器、集群中的多个 GlusterFS 服务器、多个 Nginx Web 服务器和一个 Nginx 负载均衡器。
在开始之前,我们应该知道:
- 我们将为 MySQL 服务器使用什么大小的 Droplet
- 我们将创建多少个 GlusterFS 节点
- 我们的 GlusterFS 节点的大小
- 我们需要多少个 Web 服务器节点
- 我们将为我们的网络服务器使用什么大小的 Droplets
- 我们将为负载均衡器使用什么大小的 Droplet
- 我们将用于新网站的域名
如果以后需要,我们可以添加其他节点或扩大我们创建的节点。 一旦我们决定了这些细节,我们就可以开始部署我们的站点了。
第二步——部署 MySQL
我们将从部署我们的 MySQL 服务器开始。 为此,我们将使用以下用户数据创建一个默认的 Ubuntu 14.04 x64 Droplet。
#!/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'@'%'";
此用户数据脚本将在我们的新 Droplet 上执行以下功能:
首先,我们导出一个变量,告诉 apt-get
我们在非交互模式下运行,以防止它在安装包时提示任何输入。
export DEBIAN_FRONTEND=noninteractive;
接下来,我们使用 Droplet 元数据来获取 Droplet 的公共和私有 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)
Note: Droplet Meta-Data is not available in NYC1, NYC2, and AMS1 at this time.
然后我们使用 apt
来安装 MySQL 服务器。
apt-get update; apt-get -y install mysql-server;
现在我们需要创建一个名为 wordpress 的新数据库。
mysqladmin -u root create wordpress;
然后我们为我们的 MySQL root 用户设置密码。
mysqladmin -u root password "mysql_password";
因为我们的 MySQL 服务器将接受来自我们的 Web 服务器的查询,所以我们需要让它监听私有 IP 地址,而不是只监听 localhost
。 为此,我们将使用 sed
通过查找和替换来更新 MySQL 配置文件,然后重新启动服务。
sed -i.bak "s/127.0.0.1/$PRIVATE_IP/g" /etc/mysql/my.cnf; service mysql restart;
最后,我们将创建一个名为 wordpress 的新 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'@'%'";
通过使用这个用户数据脚本部署我们的新 Droplet,我们将拥有一个配置的 MySQL 服务器,监听其私有 IP 地址以及我们配置的数据库和用户,而无需通过 SSH 或控制台登录。
第三步——部署 GlusterFS
在部署我们的 GlusterFS 集群之前,我们需要决定我们将部署多少个节点。 这个决定有两个变量。 首先,我们需要决定我们需要多少空间,然后我们需要决定要使用的副本设置。 副本设置告诉 GlusterFS 要存储多少个文件副本。 例如,副本设置为 2 意味着每个文件都在至少 2 台服务器上复制。 这将使我们的可用存储空间减少一半,因为我们为每个文件保留两个副本,但将提供改进的冗余。 我们创建的 GlusterFS 节点的数量必须是副本设置的倍数。 对于副本设置为 2 的集群,我们需要以 2 的倍数创建节点(因此可以接受 2、4、6 或 8 个节点)。
对于此示例,我们将使用副本设置 2 部署一个 4 节点 GlusterFS 集群。
对于我们的前 3 个节点,我们将使用以下用户数据脚本:
#!/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;
然后我们更新我们的 apt
数据库并安装 python-software-properties
,这是为 GlusterFS 添加 PPA 所必需的。
apt-get update; apt-get install -y python-software-properties;
接下来我们将添加 GlusterFS PPA,以便我们可以获取我们的 deb 包。
add-apt-repository -y ppa:gluster/glusterfs-3.5;
然后我们将再次更新我们的 apt
数据库并安装 glusterfs-server。
apt-get install -y glusterfs-server;
对于我们的前三个节点,这就是我们需要做的所有事情。 记下分配给每个新 Droplet 的私有 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;
Note: If you do not want to enable replication you should not include the "replica" setting in your "volume create" command.
这个用户数据脚本的第一部分与我们在其他 GlusterFS 节点上使用的非常相似,尽管我们将新 Droplet 的私有 IP 分配给 $PRIVATE_IP 变量。 但是,一旦安装了 glusterfs-server
,我们就会做一些额外的工作。
首先,我们的脚本将等待 30 秒,让新的 glusterfs-server 启动并可用。
sleep 30
然后我们探测我们之前创建的三个 GlusterFS Droplet,以便将所有四个添加到一个集群中。
gluster peer probe node1_private_ip; gluster peer probe node2_private_ip; gluster peer probe node3_private_ip;
接下来,我们将创建名为“file_store”的 GlusterFS 卷,副本设置为 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;
我们现在有一个分布式文件系统,我们可以在其中保存所有 Web 服务器节点都可以访问的 WordPress 文件。
第四步——部署 Nginx Web 服务器
现在我们已经设置好了数据库服务器和分布式文件系统,我们可以部署我们的 Web 服务器了。 我们将使用以下用户数据脚本来部署我们的第一个 Nginx Web 服务器节点并在我们的 GlusterFS 卷中配置我们的 WordPress 安装。
#!/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)
接下来,我们将更新我们的 apt
数据库并安装 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 条目,以便在 Droplet 启动时自动挂载我们的 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;
然后我们将在我们的 GlusterFS 卷中创建一个名为 www
的文件夹。 该文件夹将充当我们的 Web 根目录。
mkdir /gluster/www;
接下来,我们将从远程服务器拉取一个新的 Nginx 配置文件。 该文件会将我们的 Web 根目录设置为 /gluster/www
并确保将 Nginx 配置为使用 PHP。 您可以在此处查看此配置文件。 一旦我们替换了 Nginx 配置文件,我们将重新启动服务以使此更改生效。
wget https://raw.githubusercontent.com/ryanpq/do-wpc/master/default -O /etc/nginx/sites-enabled/default; service nginx restart;
现在我们将获取最新版本的 WordPress 的副本,将其解压缩并将其内容复制到我们的新 Web 根目录。
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;
最后,我们将确保我们的 web 根目录中的文件归用户 www-data 所有,我们的 Nginx 进程将作为该用户运行。
chown -Rf www-data:www-data /gluster/www;
现在,我们的第一个 Web 服务器节点已全部设置好并准备好接收请求。
由于我们的每个 Web 服务器节点共享相同的 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;
对于我们的其他 Web 节点,我们仍将安装相同的包,安装我们的 GlusterFS 卷并替换我们的 Nginx 配置文件,但我们不需要对我们的 WordPress 实例进行任何设置,因为我们在创建第一个节点时已经这样做了。
第五步——部署我们的负载均衡器
此部署的最后一步是创建我们的负载均衡器。 为此,我们将使用另一个 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 配置。 通过确保 apt
知道我们在非交互模式下运行,我们开始与其他 Droplet 一样。
export DEBIAN_FRONTEND=noninteractive;
然后我们将安装 Nginx:
apt-get update; apt-get -y install nginx;
接下来,我们将在名为 lbconf
的变量中创建新的 Nginx 配置。 在 上游后端 部分中为我们的每个 Web 服务器添加一个条目。
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 以使此配置生效。
service nginx restart;
第六步 - 设置 DNS
现在,在我们通过浏览器访问我们的新 WordPress 站点之前,我们应该为其设置一个 DNS 条目。 我们将通过控制面板执行此操作。
在 DigitalOcean 控制面板中,单击 DNS。 在添加域表单中,输入您的域名并从下拉菜单中选择您的负载均衡器Droplet,然后单击创建域。
为了为您的站点使用 www 子域,您需要在这个新域中创建另一条记录。
点击添加记录,选择CNAME记录类型。 在名称字段中输入 www,在主机名字段中输入 @。 这会将 www 子域的请求定向到与您的主域(负载均衡器 Droplet)相同的位置。
第七步——配置 WordPress
现在我们已经启动了所有的 Droplet 并配置了我们的域,我们可以通过在 Web 浏览器中访问我们新配置的域来访问我们的新 WordPress 站点。
此处将提示我们创建一个用户帐户并为我们的新站点命名。 完成此操作后,我们的部署就完成了,我们可以开始使用新站点了。
第八步——自动化流程
现在我们可以创建我们的 WordPress 部署,而无需通过 ssh 进入 Droplet,我们可以更进一步,使用 DigitalOcean API 自动化这个过程。
基于本教程创建了一个示例 Ruby 脚本,它将提示用户提供相关详细信息,然后自动部署一个新的可扩展 WordPress 实例。 你可以在 GitHub 上找到这个脚本 。
结论
我们现在有一个可扩展的 WordPress 部署,但我们可以采取额外的步骤来确保我们的新站点是安全和稳定的。