前言:
借助Ansible自动部署LNAMP,实现高可用nginx反代服务器,中部http+php提供web服务,后端链接同一台mysql数据库
实验环境:
ansible主机:10.0.0.10/8
nginx(主):10.0.0.11/8
nginx(备):10.0.0.12/8
虚拟IP:10.0.0.111/32
http1:10.0.0.21/8
http2:10.0.0.22/8
mysql:10.0.0.30/8
编辑Ansible的hosts文件
####Nginx反代主机地址及变量设置 [agent_server] 10.0.0.11 STATE=MASTER PRIORITY=100 ip_addr=10.0.0.11 10.0.0.12 STATE=BACKUP PRIORITY=95 ip_addr=10.0.0.12 # 注释: STATE为keepalived的配置文件主备配置所需变量 # ip_addr: 为nginx配置文件模板所需的变量 #http服务器组变量配置 [agent_server:vars] package=nginx,keepalived #package这个变量提供nginx反代服务器所需的安装包 web_server1=10.0.0.21 #nginx 配置文件必须调用的后端服务器地址 web_server2=10.0.0.22 ###Web服务器地址及变量配置 [web_server] 10.0.0.21 10.0.0.22 #Web服务器地址及变量配置 [web_server:vars] package=httpd,php,php-mysql dbserver=10.0.0.30 #discuz配置文件所需调用的变量 ###数据库主机配置 [db_server] 10.0.0.30 [dbserver:vars] package=mariadb-server
创建roles目录
# cd /etc/ansible/roles/
# 创建目录所需的角色目录
# mkdir -pv nginx/{tasks,files,templates,handlers,mate,default,vars}
# mkdir -pv httpd/{tasks,files,templates,handlers,mate,default,vars}配置nginx角色
创建tasks任务文件
- name: install nginx & keepalived packages ##包安装
yum: name={{ package }} state=present- name: nginx configuration ##复制nginx配置文件,复制模板至远程主机;配置文件本地放置在template目录
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
- name: keepalived configuration ## keepalived配置文件,复制模板至远程主机
template: src=keepalived.conf.j2 dest=/etc/keepalived/keepalived.conf
- name: nginx service start ##启动nginx服务
service: name=nginx state=started
- name: keepalived service start
service: name=keepalived state=started
- name: copy nginx check script ## 复制nginx服务检测脚本至远程主机
copy: src=chk_nginx.sh dest=/etc/keepalived/
- name: change script mod ## 为脚本文件赋权限
shell: chmod +x /etc/keepalived/chk_nginx.sh创建nginx配置文件模板:
复制nginx配置文件到template目录中以.j2结尾
# cp /etc/nginx/nginx.conf /etc/ansible/roles/nginx/templates/nginx.conf.j2
# vim nginx.conf.j2
http {
...
upstream {{ ip_addr }} { #此处变量为hosts中定义的nginx的IP地址
server {{ web_server1 }}:8080 weight=2 max_fails=3 fail_timeout=5; # web_server后端服务器
server {{ web_server2 }}:8080 weight=1 max_fails=3 fail_timeout=5; # 注意,使用非默认端口一定要指定端口
#此处upstream 定义的主机组的名字不是字符串,是因为字符串的命令会导致discuz时无法加载图片
#若你发现用反向代理访问论坛无法显示图片时,那很可能就和此处的设定有关
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://{{ ip_addr }};
proxy_pass_header User-Agent;
proxy_set_header Host $Host;
# 需要注意的是:以上关于header的两项配置是使用discuz所必须的,否则会出现验证码无法显示等安全问题
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}nginx服务检测脚本:
#!/bin/bash # declare -i i=1 until [ $i -eq 3 ]; do if curl http://127.0.0.1/ &> /dev/null; then exit 0 else systemctl restart nginx.service #自己在测试时最好先注销,看停掉服务是否能够实现地址漂移 sleep 2 let i++ [ $i -eq 3 ] && exit 2 fi done
创建keepalived的配置文件模板:
# cp /etc/keepalived/keepalived.conf nginx/templates/keepalived.conf.j2 # vim nginx/templates/keepalived.conf.j2
创建keepalived的配置文件模板
# vim keepalived.conf.j2
! Configuration File for keepalived
global_defs {
notification_email { # 收件人邮箱地址配置
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
# 发件人配置
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id {{ ansible_nodename }} #ansible的facts变量,变量值为主机名
}
## 定义nginx健康状态检测脚本
vrrp_script chk_nginx {
script "/etc/keepalived/chk_nginx.sh" #
interval 2 # 每两秒执行一次脚本
priority -5 # 脚本返回失败时,优先级减5,weight -5 也可实现地址漂移,但成功率不高
#脚本的作用是:当检测nginx服务不在线时,将返回失败的状态给keepalived,然后keepalived自减权重,地址就会产生漂移
}
vrrp_instance VI_1 {
state {{ STATE }} # 主机初始状态变量
interface eno16777736 # 提供服务的地址接口
virtual_router_id 51 # 路由ID,主备必须一致(0-255取值范围
priority {{ PRIORITY }} # Hosts中事先定义了优先级变量
advert_int 1 # 心跳报文发送频率(秒)
authentication {
auth_type PASS # 认证方式
auth_pass 9998 # 认证密码 (建议使用随即字符串)
}
virtual_ipaddress {
10.0.0.111/32 # 提供服务的IP地址,此地址在主备之间流动
}
}
track_script { # 调用上面定义的脚本
chk_nginx
}配置httpd角色
创建httpd的tasks任务文件
- name: install httpd & php php-mysql
yum: name={{ package }} state=present
- name: httpd configration
template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
- name: httpd service startd
service: name=httpd state=started
- name: copy Discuz to web server
copy: src=Discuz_X3.1_SC_UTF8.zip dest=/var/www/html/
- name: unzip Discuz
shell: "cd /var/www/html; unzip -oq Discuz_X3.1_SC_UTF8.zip; mv upload bbs" # 命名为bbs较为简短
- name: configure Discuz
template: src=config_global_default.php.j2 dest=/var/www/html/bbs/config/config_global_default.php
- name: change Discuz files owner & mod
shell: "chown -R apache:apache /var/www/html/{bbs,utility}; chmod 755 -R /var/www/html/{bbs,utility}"提供httpd配置文件模板:
# cp /etc/httpd/conf/httpd.conf httpd/templates/httpd.conf.j2 Listen 8080
Discuz配置文件在压缩包中提取,3.1版本配置文件路径为
upload/config/config_global_default.php
解压之后修改配置
$_config[‘db‘][1][‘dbhost‘] = ‘{{ db_server }}‘; # mysql或mariadb数据库主机(使用变量替换)
$_config[‘db‘][1][‘dbuser‘] = ‘discuz‘; # mysql数据库用户名
$_config[‘db‘][1][‘dbpw‘] = ‘magedu‘; # mysql数据库密码
$_config[‘db‘][1][‘dbcharset‘] = ‘utf8‘; # 数据库字符集
$_config[‘db‘][1][‘pconnect‘] = 0; # 是否允许持久连接(0表示不启用)
$_config[‘db‘][1][‘dbname‘] = ‘discuz‘; # mysql数据名称
$_config[‘db‘][1][‘tablepre‘] = ‘pre_‘;配置mariadb角色
创建tasks任务文件
roles]# mkdir -pv mariadb/{tasks,files,templates,handlers,mate,default,vars}
# vim mariadb/tasks/mail.yml
#!/bin/bash
#
mysql -e "create database discuz"
web_server="10.0.0.21 10.0.0.22"
for i in $web_server; do
mysql -e "grant all on discuz.* to discuz@$i identified by ‘magedu‘"
done
~提供mariadb配置文件模板
# cp /etc/my.cnf mariadb/templates/my.cnf.j2 [mysqld]datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock# Disabling symbolic-links is recommended to prevent assorted security riskssymbolic-links=0skip_name_resolve = ON # 取消主机名反解innodb_file_per_table = ON # 使用innodb引擎
创建playbook调用角色
nginx
- hosts: agent_server remote_user: root tasks: roles: - nginx
httpd
- hosts: web_server remote_user: root tasks: roles: - httpd
mariadb
- host: db_server remote_user: root tasks: roles: - mariadb
未完待续。。。。
原文:http://wscto.blog.51cto.com/11249394/1785329