[实验] Apache + Pacemaker 网站服务高可用的实现

纪念:站主于 2019 年 8 月完成了此开源实验,并将过程中的所有命令经过整理和注释以后,形成以下教程

注意:

在实现 Apache + Pacemaker 网站服务高可用之前要先安装 Pacemaker 集群

正文:

步骤一:Pacemaker 高可用网站服务的解析

1.1 集群本身需要的服务

需要额外一台服务器提供 NFS 远程目录服务

1.2 本 Pacemaker 高可用网站服务的特点

1) 使用其他服务器提供的 NFS 服务器作为网站的网页目录
2) 提供网站 服务
3) 提供虚拟 IP 地址服务
4) 以上三项服务器都实现高可用
5) 唯一的单点故障在于额外的那台服务器提供的 NFS 远程目录服务器

步骤二:前期准备

2.1 在所有集群服务器上安装 httpd

(在所有集群服务器上执行以下步骤)

# yum -y install httpd

2.2 确保 httpd 不会被 SELinux 限制

(在所有集群服务器上执行以下步骤)

# setsebool -P httpd_use_nfs 1

(补充:这里是要求 SELinux 的布尔值让 httpd 也可以使用 NFS 服务)

2.3 确保 httpd 没有启动

(在所有集群服务器上执行以下步骤)

# systemctl stop httpd
# systemctl disable httpd

步骤三:部署 Pacemaker 的网站高可用服务

3.1 在 网站资源组中创建名为 webip 的虚拟 IP 地址资源

(只在一台集群里的服务器上执行以下步骤)

# pcs resource create webip IPaddr2 ip=192.168.0.20 cidr_netmask=24 --group=web

3.2 在 网站资源组中创建名为 webnfs 挂载其他服务器的 NFS 服务的资源

(只在一台集群里的服务器上执行以下步骤)

# pcs resource create webnfs Filesystem device=192.168.8.21:/content directory=/var/www/html fstype=nfs options=ro --group web

(注意:这里的 Filesystem 指的是其他服务器搭建的 NFS 服务,这个服务需要提前搭建好,可以参考 https://eternalcenter.com/nfs/ 里的内容)

3.3 在网站资源组中创建名为 webserver 的网站资源

(只在 1 台集群里的服务器上执行以下步骤)

# pcs resource create webserver apache configfile="/etc/httpd/conf/httpd.conf" statusurl="http://127.0.0.1/server-status" --group web

[内容] Apache 的使用 (开启网页目录结构)

内容一:开启 Apache 目录结构的目的

默认安装了 Apache 之后,被访问的网页只会显示一张 Apache 的欢迎页面或者 404
有时候我们需要让网页现实网页根目录中的文件和目录,用于提供 http 下载等功能,这个时候就需要开启 Apache 的目录结构

内容二:开启 Apahce 目录结构的方法

# vim /etc/httpd/conf.d/welcome.conf

将其中的:

......
Options -Indexes 
......

修改为:

......
Options +Indexes 
......

[工具] Shell 半自动化部署 LNMP 平台 + SSL (CentOS Linux 7 版)

介绍

基本信息

作者:朱明宇
脚本名称:半自动化部署 LNMP 平台 + SSL
作用:半自动化安装 LNMP,即 Nginx、Mariadb、PHP、php-fpm,实现 HTTPS

使用方法

为了安全起见,设置系统用户和数据库用户和数据库权限的工作请按照脚本最后的步骤进行手动设置

注意

1. 执行本脚本之前请确保 Nginx、PHP、网站程序文件、SQL、SSL 的公钥、SSL 的私钥、shell、本脚本 8 个文件,如果是新建网站的话,不用准备 SQL 文件
2. Nginx 文件:请将 Nginx 源码安装包放在 /root/
3. PHP 文件:请将 PHP 源码安装包放在 /root/
4. 网站程序文件:请将网站程序文件的名字中包含“eternalcenter-backup-”字段,并且是 tar 包,并放在 /root/
5. SQL 文件:如果是恢复网站的话,请将备份的数据文件 *.sql 放在 /root/,注意这是一个 MySQL 备份文件
6. SSL 的公钥文件和 SSL 私钥文件:请将网站安全证书的公钥和私钥分别命名为:eternalcenter.com.crt 和 eternalcenter.com.key,并放在 /root/
7. shell 文件:请将监控脚本命名为 port_monitoring.sh 并放在 /root/
8. 除此之外 /root/ 目录下请不要放任何文件
9. 服务器的系统需要是 CentOS 7 版本
10. 服务器系统要配置好可用的软件源(最好是软件数量最多的官方版本)
11. 服务器要能够连接外网

补充

1. Nginx 下载网址:https://nginx.org/
2. PHP 下载网址:https://www.php.net/downloads.php
3. WordPress 是一款开源的 php 网站程序,建议使用,下载网址:https://cn.wordpress.org/download/
4. 网站安全证书的公钥和私钥可以在这里申请:https://freessl.cn/

其他

  运行此脚本所需要的文件如下,请尽量使用图中的命名规则给他们命名,并将他们全部放在 /root/ 目录下,请保证 /root/ 下有且仅有这些文件,并以 root 的身份运行,否则脚本会执行失败。其中:

  eternalcenter-backup-2019-08-12-13.sql 指的是 mariadb 的数据库备份文件,如果是新建网站的话可以不要。

  eternalcenter-backup-2019-08-13.tar 指的是网页程序的压缩包,必须是 tar 格式,如果是新建的网站的话,这个也可以换成,新网站的网页程序。

  eternalcenter.com.crt 指的是网站的公钥,需要单独申请,方法可以在搜索引擎上搜索。

  eternalcenter.com.key 指的是网站的私钥,需要单独申请,方法可以在搜索引擎上搜索。

  install.sh 就是指的本脚本。

  nginx-1.16.0.tar.gz 指的是 nginx 的源码安装包,这里的 -1.16.0.tar.gz 可以任意命名,只用保证这个文件名字里包含 nginx 就行了,这个文件可以在 nginx 官网上下载。

  php-7.2.2-.tar.xz 指的是 php 的源码安装包,同样 这里的 -7.2.2-tar.xz 可以任意命名,只用保证这个文件名字包含 php 就行了,这个文件可以在 php 官网上下载。

  port_monitoring.sh 只是一个监控端口的脚本,可以不要,使用者可以根据自我需求写一个,站主是通过这个脚本定期检查并自动启动需要启动但是没有启动的端口,关闭不需要但是启动了的端口。

脚本

#!/bin/bash

# variable initialization
cd
nginxp=`ls | grep "nginx"`
phpp=`ls | grep "php"`
webp=`ls | egrep "eternalcenter-backup-.*tar$"`
nginxr=${nginxp%%.tar*}
phpr=${phpp%%.tar*}


# upgrade system
yum makecache
yum -y update

yum clean all
yum repolist


# remove useless software
yum -y remove php*

yum -y remove mariadb*

systemctl stop postfix
yum -y remove postfix

systemctl stop chronyd
yum -y remove chrony

yum -y update


# install dependency package
yum -y install gcc pcre-devel openssl-devel libxml2-devel curl-devel libpng libpng-devel


# install nginx
cd
tar -xvf $nginxp -C /root/
cd $nginxr

useradd -s /sbin/nologin nginx
./configure --user=nginx --group=nginx --with-http_ssl_module
make && make install
echo 'worker_processes  1;

events {
    worker_connections  65536;
}

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       80;
        limit_req zone=one burst=5;
        server_name www.eternalcenter.com eternalcenter.com;

        rewrite ^/(.*)$ https://eternalcenter.com/$1 permanent;
      
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        }

    server {
        listen       443 ssl;
        server_name www.eternalcenter.com eternalcenter.com;

        if ($request_method !~ ^(GET|POST)$){
        return 444;
        }

        ssl_certificate      /usr/local/nginx/ssl/eternalcenter.com.crt;
        ssl_certificate_key  /usr/local/nginx/ssl/eternalcenter.com.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location ~ \.php$ {
            fastcgi_pass 127.0.0.1:9000;
            include fastcgi.conf;
        } 

        location / {
        root html;
        index index.php index.html index.htm;
        }

        location ~ ^/\.user\.ini {
        deny all;
        }
    
        location ~*\.(jpd|jpeg|gif|png|css|js|ico|xml)$ {
        expires 30d;
        }

        error_page  404              /404.html;
        }

        gzip on;
	gzip_min_length 1000;
	gzip_comp_level 4;
	gzip_types text/plain test/css application/json application/x-javascript text/xml application/xml
	application/xml+rss text/javascripts;

	client_header_buffer_size 1k;
	large_client_header_buffers 4 4k;

	open_file_cache max=2000 inactive=20s;
	open_file_cache_valid  60s;
	open_file_cache_min_uses 5;
	open_file_cache_errors off;

}' > /usr/local/nginx/conf/nginx.conf
cd
mkdir /usr/local/nginx/ssl
mv eternalcenter.com.crt /usr/local/nginx/ssl
mv eternalcenter.com.key /usr/local/nginx/ssl

# install php
cd
tar -xvf $phpp -C /root/
cd $phpr
useradd -s /sbin/nologin php-fpm 
./configure --with-config-file-path=/usr/local/php/etc --enable-fpm --with-fpm-user=php-fpm --with-fpm-group=php-fpm --prefix=/usr/local/php --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --enable-mysqlnd --enable-mbstring --with-curl --with-gd --with-zlib
make && make install
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf
chown -R php-fpm:php-fpm /usr/local/nginx/html/

# install mariadb
yum -y install mariadb mariadb-server mariadb-devel
sed -i "/^datadir/a log_bin=ec" /etc/my.cnf
sed -i "/^datadir/a binlog_format="mixed"" /etc/my.cnf
sed -i "/^datadir/a server_id=51" /etc/my.cnf
systemctl enable mariadb

# deploy web software
cd
rm -rf /usr/local/nginx/html/*
mkdir websoftcache
tar -xvf $webp -C websoftcache
cd websoftcache
websoftcachen=`ls | wc -l`

if [ $websoftcachen -ne 1 ];then
        cd
        tar -xvf $webp -C /usr/local/nginx/html/
else
        webdir=`ls`
        cd $webdir
        mv * /usr/local/nginx/html/
fi

chown -R php-fpm:php-fpm /usr/local/nginx/html

# recover database
systemctl start mariadb
cd
mysql -uroot < *.sql &> /dev/null
systemctl stop mariadb

# set the concurrency number accepted by the system to 65535
echo '* soft nofile 65535
* hard nofile 65535' >> /etc/security/limits.conf

# open firewall port
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --add-port=443/tcp --permanent
systemctl restart firewalld

# move the monitoring scripts that need to be used regularly to the specified location(/root/shell/port_monitoring.sh you need to write it yourself)
mkdir /shell
mv port_monitoring.sh /shell
chmod u+x /shell/*

# set up regular automatic running monitoring script(/root/shell/port_monitoring.sh you need to write it yourself)
echo '*/1 * * * * root /shell/port_monitoring.sh' >> /etc/crontab

# add another user(for data backup)
useradd zhumingyu
mkdir /cache
chown -R zhumingyu:zhumingyu /cache

# delete redundant files
cd
rm -rf *

# restart the server
reboot

[步骤] Linux 时间同步的设置 (通过 NTP 实现)

注意:

从 CentOS 7.2&RHEL 7.0 开始实现时间同步的程序默认从 NTP 换成了 Chrony 。 NTP 也可以继续使用,但是需要单独安装 NTP 的安装包。

步骤一:系统环境要求

服务器系统要配置好可用的软件源

步骤二:确保 NTP 已经安装

# yum -y install ntp

步骤三:确保系统会使用 Chrony 或 NTP 的时间同步

# timedatectl set-ntp true
# timedatectl
               Local time: Fri 2020-06-12 09:52:30 EDT
           Universal time: Fri 2020-06-12 13:52:30 UTC
                 RTC time: Fri 2020-06-12 13:51:52
                Time zone: America/New_York (EDT, -0400)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

(补充:此时 NTP service 的状态可能还不是 active 状态)

步骤四:修改配置文件

# vim /etc/sysconfig/ntp

将部分内容修改如下:

......
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst

(说明:在配置文件的末尾添加要进行时间同步的服务器)

步骤五:重启客户端的 NTP 服务

# service ntpd restart

步骤六:显示客户端时间同步的状态

6.1 通过 NTP 命令显示

# ntpq -p


补充:
1) 此命令可能会显示多行,每一行显示一个时钟源的状态
2) 最左边有一个星号 “*” 的行代表目前正在被使用的时钟源,这代表这个时钟源可以被使用且最精确

6.2 通过 timedatectl 命令显示

# timedatectl
               Local time: Fri 2020-06-12 09:52:30 EDT
           Universal time: Fri 2020-06-12 13:52:30 UTC
                 RTC time: Fri 2020-06-12 13:51:52
                Time zone: America/New_York (EDT, -0400)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

(补充:如果 NTP 时间同步正常,则此时 NTP service 的状态肯定是 active 状态)

[步骤] Red Hat Satellite 客户端设置 (软件源)

步骤一:软件源所对应的系统版本设置

1.1 显示客户端服务器现在正在使用的软件源库所对应的系统版本

(只在 client servers 上执行以下步骤)

# subscription-manager release --show

1.2 显示客户端服务器所有可以使用的软件源所对应的系统版本

(只在 client servers 上执行以下步骤)

# subscription-manager release –-list

步骤二:修改客户端服务器的软件源对应的系统版本

2.1 修改对应系统版本的格式

(只在 client servers 上执行以下步骤)

# subscription-manager release --set=<system version number>

2.2 修改对应系统版本的案例

(只在 client servers 上执行以下步骤)

# subscription-manager release -–set=7.5 

(补充:这里的 7.5 是 1 个系统的版本号)

(注意:这里如果低版本的系统选择了高版本的软件源库,则在更新软件的过程中可能会直接升级系统)

步骤三:在选择了 1 个系统版本之后选择里面的软件源

3.1 显示软件源

3.1.1 显示客户端服务器目前正在使用的软件源

(只在 client servers 上执行以下步骤)

# subscription-manager repos --list-enable
3.1.2 显示客户端服务器所有可以用的软件源和正在使用的软件源

(只在 client servers 上执行以下步骤)

# subscription-manager repos --list

3.2 让客户端服务器启用 1 个软件源

3.2.1 启用 1 个软件源的格式

(只在 client servers 上执行以下步骤)

# subscription-manager repos --enable=<software source name>
3.2.2 启用 1 个软件源的案例

(只在 client servers 上执行以下步骤)

# subscription-manager repos --enable=rhel-7-server-satellite-tools-6.3-rpms

(补充:这里以启动 rhel-7-server-satellite-tools-6.3-rpms 软件源为例)

3.3 让客户端服务器禁用 1 个软件源

3.3.1 禁用 1 个软件源的格式

(只在 client servers 上执行以下步骤)

# subscription-manager repos --disable=<software source name>
3.3.2 禁用 1 个软件源的案例

(只在 client servers 上执行以下步骤)

# subscription-manager repos –disable=rhel-7-server-satellite-tools-6.2-rpms

(补充:这里以禁止 rhel-7-server-satellite-tools-6.3-rpms 软件源为例)

3.4 让客户端服务器同时启用或禁用 1 个或多个软件源

# subscription-manager repos --enable=rhel-8-for-x86_64-baseos-rpms;subscription-manager repos --enable=rhel-8-for-x86_64-appstream-rpms;subscription-manager repos --disable=satellite-tools-6.10-for-rhel-8-x86_64-rpms

(补充:这里以启动 rhel-8-for-x86_64-baseos-rpms;subscription-manager 软件源和 rhel-8-for-x86_64-appstream-rpms;subscription-manager 软件源,禁用 satellite-tools-6.10-for-rhel-8-x86_64-rpms 软件源为例)

3.5 刷新所有的设置

# subscription-manager refresh