目录
我们先前用playbook构造过lnmp架构,实现了一键部署四个项目的效果,但是我们是将所有的命令都写入了一个playbook中,我们所需的文件也只是简单的放入了playbook的同级目录,这样很混乱,而roles可以很好解决这一点,使用roles,我们可以很轻松的整理我们的配置文件,更有利于我们写好后排错,或者更改配置,我们再将变量,判断语句,循环语句加上,打造我们用Ansible部署lnmp架构的最终版本!
1.准备工作
|---------|------------------------|------------------------------|
| 主机名称 | 主机IP | 作用 |
| LB01 | 10.0.0.5 172.168.1.5 | 七层负载均衡,Keepalived高可用,https证书 |
| LB02 | 10.0.0.6 172.168.1.6 | 七层负载均衡,Keepalived高可用,https证书 |
| Web01 | 10.0.0.7 172.168.1.7 | Nginx、php服务、存放代码文件 |
| Web02 | 10.0.0.8 172.168.1.8 | Nginx、php服务、存放代码文件 |
| NFS | 10.0.0.31 172.168.1.31 | 存放静态资源 |
| Backup | 10.0.0.41 172.168.1.41 | 存放静态数据的备份,实时同步NFS的代码内容 |
| MySQL | 10.0.0.51 172.168.1.51 | 存放动态数据 |
| Ansible | 10.0.0.61 172.168.1.61 | 使用Ansible作为控制机 |
2.重构思路
用roles和不用roles的逻辑其实是一样的,要根据服务器的功能,先收集服务器所需要的文件,再进行安装,传输文件,启动服务或重启服务等操作。只是我们这次不必担心命名问题,因为不同的服务或不同功能的服务器所需要的配置文件会被放到不同的目录,不会冲突。
roles这个角色,可以根据同类服务器的功能定义,也可以通过服务去定义,因为我们是一键部署所有服务和项目,也不存在指定部署服务的需求,如果通过服务来定义,也容易出现需要很多when判断的情况,如果用同类功能的服务器定义角色,可能会出现同一条命令需要反复编写的情况,自行选择,我采取根据同类功能服务器去定义我们的roles角色。
3.管理机操作
(1)添加目标客户机至主机列表
[root@Ansible roles]# cat hosts
[lb_group]
lb01 ansible_ssh_host=172.168.1.5
lb02 ansible_ssh_host=172.168.1.6
[web_group]
web01 ansible_ssh_host=172.168.1.7
web02 ansible_ssh_host=172.168.1.8
[nfs]
172.168.1.31
[backup]
172.168.1.41
[mysql]
172.168.1.51
(2)将角色与主机对应
[root@Ansible roles]# cat site.yml
- hosts: all
roles:
- role: basic
- role: lb_group
when: ansible_hostname is match "LB*"
- role: nfs
when: ansible_hostname is match "NFS"
- role: web_group
when: ansible_hostname is match "Web*"
- role: backup
when: ansible_hostname is match "Backup"
- role: mysql
when: ansible_hostname is match "MySQL"
(3)创建各个角色的目录
[root@Ansible roles]# ansible-galaxy init basic
- Role basic was created successfully
[root@Ansible roles]# ansible-galaxy init lb_group
- Role lb_group was created successfully
[root@Ansible roles]# ansible-galaxy init web_group
- Role web_group was created successfully
[root@Ansible roles]# ansible-galaxy init nfs
- Role backup was created successfully
[root@Ansible roles]# ansible-galaxy init backup
- Role backup was created successfully
[root@Ansible roles]# ansible-galaxy init mysql
- Role mysql was created successfully
[root@Ansible roles]# ls
backup hosts mysql site.yml
basic lb_group nfs web_group
(4)basic角色相关操作
[root@Ansible roles]# cat basic/tasks/main.yml
#1.关闭防火墙
#2.关闭selinux
#3.关闭NetworkManager
#4.修改默认的YUM仓库
#5.安装扩展epel源
#6.配置nginxYUM源
#7.安装常用软件命令
#8.时间同步
#9.创建虚拟用户www
#10.加大文件描述符
- name: Disabled Firewalld Server
systemd:
name: firewalld
state: stopped
enabled: no
- name: Disable Selinux
selinux:
state: disabled
- name: Disabled NetworkManager Server
systemd:
name: NetworkManager
state: stopped
enabled: no
- name: Configure YUM Repo
yum_repository:
name: CentOS-Base
description: ALIYUN YUM repo
baseurl: http://mirrors.aliyun.com/centos/$releasever/os/$basearch/
gpgcheck: no
gpgkey: http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
- name: Add repository
yum_repository:
name: epel
description: EPEL YUM repo
baseurl: http://mirrors.aliyun.com/epel/7/$basearch
gpgcheck: no
gpgkey: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
- name: Add repository
yum_repository:
name: nginx
description: Nginx YUM repo
baseurl: http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck: no
gpgkey: https://nginx.org/keys/nginx_signing.key
- name: Install Packages
yum:
name: "{{ item }}"
state: present
loop:
- vim
- tree
- lrzsz
- wget
- unzip
- net-tools
- ntpdate
- bash-completion.noarch
- bash-completion-extras.noarch
- name: ntpdate
cron:
name: "ntpdate"
minute: '*/5'
job: '/usr/sbin/ntpdate ntp1.aliyun.com &>/dev/null'
- name: Create Group www
group:
name: www
gid: 666
- name: Create www User
user:
name: www
group: www
uid: 666
shell: /sbin/nologin
create_home: false
- name: Set sysctl file limiits
pam_limits:
dest: "{{ item.dest }}"
domain: '*'
limit_type: "{{ item.limit_type }}"
limit_item: "{{ item.limit_item }}"
value: "{{ item.value }}"
loop:
- { dest: '/etc/security/limits.conf',limit_type: 'soft',limit_item: 'nofile', value: '65535' }
- { dest: '/etc/security/limits.conf',limit_type: 'hard',limit_item: 'nofile', value: '65535'}
(5)lb_group角色相关操作
[root@Ansible roles]# cat /ansible/roles/lb_group/tasks/main.yml
#1.组内安装nginx,删除default.conf
#2.lb01、lb02配置nginx.conf
#3.lb01、lb02配置proxy_params
#4.lb01和lb02配置七层负载均衡
#5.lb01、lb02开启nginx
#6.lb01、lb02安装keepalived
#7.lb01、lb02分别配置keepalived文件
#8.传送lb01防止脑裂的脚本文件,并在lb01上做与lb02的免密钥
#9.lb01、lb02开启keepalived
- name: install nginx
yum:
name: nginx
state: present
- name: delete default.conf
file:
name: /etc/nginx/conf.d/default.conf
state: absent
- name: configure nginx.conf
template:
src: nginx.conf.j2 #提前准备
dest: /etc/nginx/nginx.conf
- name: copy proxy_params
copy:
src: proxy_params #提前准备
dest: /etc/nginx
- name: copy ssl_key
copy:
src: ssl_key
dest: /etc/nginx
- name: configure proxy_7 to lb01 and lb02
template:
src: proxy_7.conf.j2 #提前准备
dest: /etc/nginx/conf.d/proxy_7.conf
notify: restart nginx
- name: start nginx
systemd:
name: nginx
state: started
enabled: yes
- name: install keepalive
yum:
name: keepalived
state: present
- name: configure keepalived
template:
src: keepalived.conf.j2 #提前准备
dest: /etc/keepalived/keepalived.conf
notify: restart keepalived
- name: copy check_split_brain.sh to lb01
copy:
src: check_split_brain.sh #提前准备
dest: /etc/keepalived/check_split_brain.sh
when: ansible_hostname is match "LB01"
- name: start keepalive
systemd:
name: keepalived
state: started
提前准备的文件、变量、handlers
[root@Ansible lb_group]# ls files/
check_split_brain.sh proxy_params ssl_key
[root@Ansible lb_group]# ls templates/
keepalived.conf.j2 nginx.conf.j2 proxy_7.conf.j2
[root@Ansible lb_group]# cat vars/main.yml
user: www
[root@Ansible lb_group]# cat handlers/main.yml
- name: restart nginx
systemd:
name: nginx
state: restarted
- name: restart keepalived
systemd:
name: keepalived
state: restarted
(6)nfs角色相关操作
[root@Ansible roles]# cat nfs/tasks/main.yml
- name: install nfs server
yum:
name: nfs-utils
state: present
- name: configure nfs server
template:
src: exports
dest: /etc/exports
notify: restart nfs server
- name: create directory data/...
file:
path: "{{ item }}"
state: directory
owner: www
group: www
mode: 0755
loop: "{{ directory_list }}"
- name: start nfs server
systemd:
name: nfs
state: started
enabled: yes
#实时同步
- name: install rsync inotify-tools
yum:
name:
- rsync
- inotify-tools
state: present
- name: mkdir server
file:
path: /server
state: directory
- name: tar xf sersync.tar.gz
unarchive:
src: sersync2.5.4_64bit_binary_stable_final.tar.gz
dest: /server
- name: mv GNU-Linux-x86/ sersyncd
command:
cmd: mv /server/GNU-Linux-x86 /server/sersyncd
become: true
- name: copy confxml.xml to nfs
copy:
src: confxml.xml
dest: /server/sersyncd/confxml.xml
- name: copy rsync.pass
copy:
src: rsync.pass
dest: /etc/rsync.pass
mode: "0600"
- name: ./sersync2 -dr
command: cd /server/sersyncd/ && ./sersync2 -dr
提前准备的文件、变量、handlers
[root@Ansible roles]# ls nfs/templates/
exports
[root@Ansible roles]# cat nfs/vars/main.yml
directory_list:
- /data/wordpress
- /data/wecenter
- /data/phpshe
- /data/kod
share_ip : 172.168.1.0/24
[root@Ansible roles]# cat nfs/handlers/main.yml
- name: restart nfs server
systemd:
name: nfs
state: restarted
(7)web_group角色相关操作
[root@Ansible roles]# cat web_group/tasks/main.yml
#1.安装nginx,php,nfs
#2.配置nginx.conf conf.d文件,并监控
#3.配置php.ini www.conf,并监控
#4.开启nginx和php
#5.创建代码目录,导入代码文件,更改代码文件的权限
#6.挂载存放静态文件的目录到nfs
- name: install nginx
yum:
name: nginx
state: present
- name: tar php.tar.gz
unarchive:
src: php71.tar.gz #准备
dest: /root
- name: localinstall rpm
yum:
name:
- /root/autoconf-2.69-11.el7.noarch.rpm
- /root/automake-1.13.4-3.el7.noarch.rpm
- /root/libevent-2.0.21-4.el7.x86_64.rpm
- /root/libjpeg-turbo-1.2.90-8.el7.x86_64.rpm
- /root/libmcrypt-2.5.8-13.el7.x86_64.rpm
- /root/libmemcached-1.0.16-5.el7.x86_64.rpm
- /root/libtool-ltdl-2.4.2-22.el7_3.x86_64.rpm
- /root/libX11-1.6.7-3.el7_9.x86_64.rpm
- /root/libX11-common-1.6.7-3.el7_9.noarch.rpm
- /root/libXau-1.0.8-2.1.el7.x86_64.rpm
- /root/libxcb-1.13-1.el7.x86_64.rpm
- /root/libXpm-3.5.12-1.el7.x86_64.rpm
- /root/libxslt-1.1.28-6.el7.x86_64.rpm
- /root/mod_php71w-7.1.33-1.w7.x86_64.rpm
- /root/pcre-devel-8.32-17.el7.x86_64.rpm
- /root/perl-Data-Dumper-2.145-3.el7.x86_64.rpm
- /root/perl-Test-Harness-3.28-3.el7.noarch.rpm
- /root/perl-Thread-Queue-3.02-2.el7.noarch.rpm
- /root/php71w-cli-7.1.33-1.w7.x86_64.rpm
- /root/php71w-common-7.1.33-1.w7.x86_64.rpm
- /root/php71w-devel-7.1.33-1.w7.x86_64.rpm
- /root/php71w-embedded-7.1.33-1.w7.x86_64.rpm
- /root/php71w-fpm-7.1.33-1.w7.x86_64.rpm
- /root/php71w-gd-7.1.33-1.w7.x86_64.rpm
- /root/php71w-mbstring-7.1.33-1.w7.x86_64.rpm
- /root/php71w-mcrypt-7.1.33-1.w7.x86_64.rpm
- /root/php71w-mysqlnd-7.1.33-1.w7.x86_64.rpm
- /root/php71w-opcache-7.1.33-1.w7.x86_64.rpm
- /root/php71w-pdo-7.1.33-1.w7.x86_64.rpm
- /root/php71w-pear-1.10.4-1.w7.noarch.rpm
- /root/php71w-pecl-igbinary-2.0.5-1.w7.x86_64.rpm
- /root/php71w-pecl-memcached-3.0.4-1.w7.x86_64.rpm
- /root/php71w-pecl-mongodb-1.5.3-1.w7.x86_64.rpm
- /root/php71w-pecl-redis-3.1.6-1.w7.x86_64.rpm
- /root/php71w-process-7.1.33-1.w7.x86_64.rpm
- /root/php71w-xml-7.1.33-1.w7.x86_64.rpm
state: present
- name: install nfs-utils
yum:
name: nfs-utils
state: present
- name: configure nginx.conf
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: restart nginx
- name: configure conf.d
copy:
src: conf.d/
dest: /etc/nginx/conf.d
notify: restart nginx
- name: configure php.ini
copy:
src: php.ini
dest: /etc/php.ini
notify: restart php-fpm
- name: configure www.conf
copy:
src: www.conf
dest: /etc/php-fpm.d/www.conf
notify: restart php-fpm
- name: start nginx
systemd:
name: nginx
state: started
enabled: yes
- name: start php-fpm
systemd:
name: php-fpm
state: started
enabled: yes
- name: tar code.tar.gz
unarchive:
src: code.tar.gz
dest: /
creates: /code
- name: chown -R www.www code
file:
path: /code
owner: www
group: www
- name: Mount wordpress_NFS Server
mount:
src: 172.168.1.31:/data/wordpress
path: /code/wordpress/wp-content/uploads
fstype: nfs
opts: defaults
state: mounted
- name: Mount wecenter_NFS Server
mount:
src: 172.168.1.31:/data/wecenter
path: /code/wecenter/uploads
fstype: nfs
opts: defaults
state: mounted
- name: Mount phpshe_NFS Server
mount:
src: 172.168.1.31:/data/phpshe
path: /code/phpshe/data
fstype: nfs
opts: defaults
state: mounted
- name: mount kod server
mount:
src: 172.168.1.31:/data/kod
path: /code/kod/data
fstype: nfs
opts: defaults
state: mounted
提前准备的文件、变量、handlers
[root@Ansible roles]# ls web_group/files/
code.tar.gz conf.d php71.tar.gz php.ini www.conf
[root@Ansible web_group]# ls templates/
nginx_.conf.j2
[root@Ansible web_group]# cat vars/main.yml
user: www
[root@Ansible web_group]# cat handlers/main.yml
- name: restart nginx
systemd:
name: nginx
state: restarted
- name: restart php-fpm
systemd:
name: php-fpm
state: restarted
(8)backup角色相关操作
[root@Ansible roles]# cat backup/tasks/main.yml
- name: Install Rsync Server
yum:
name: rsync
state: present
- name: Copy Srsync Configure File
template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
loop:
- { src: rsyncd.conf.j2, dest: /etc/rsyncd.conf,mode: '0644' }
- { src: rsync.passwd.j2, dest: /etc/rsync.passwd,mode: '0600' }
notify: restart rsyncd
- name: Create Dir "{{ rsync_dir }}"
file:
path: /{{ rsync_dir }}
state: directory
owner: "{{ rs_user }}"
group: "{{ rsg_user }}"
- name: Start Rsync Server
systemd:
name: rsyncd
state: started
enabled: yes
- name: mkdir /data
file:
name: "{{ item }}"
state: directory
owner: www
group: www
loop:
- /data
- /bash
- name: copy rsync_all.sh
copy:
src: rsync_all.sh
dest: /bash/rsync_all.sh
提前准备的文件、变量、handlers
[root@Ansible roles]# ls backup/files/
rsync_all.sh
[root@Ansible backup]# ls templates/
rsyncd.conf.j2 rsync.passwd.j2
[root@Ansible backup]# cat vars/main.yml
rs_user: www
rsg_user: www
pass: 123456
rsync_dir: /backup
[root@Ansible backup]# cat handlers/main.yml
- name: restart rsyncd
systemd:
name: rsyncd
state: restarted
(9)mysql角色相关操作
[root@Ansible roles]# cat mysql/tasks/main.yml
- name: Install mariadb mysql-python redis
yum:
name:
- mariadb-server
- MySQL-python
- redis
state: present
- name: Start httpd Server
systemd:
name: mariadb
state: started
enabled: yes
- name: Copy all.sql to Mysql
copy:
src: all.sql
dest: /root/all.sql
- name: import all.sql
mysql_db:
login_host: localhost
login_port: 3306
login_user: root
name: all
state: import
target: /root/all.sql
- name: Restart MariaDB Server
systemd:
name: mariadb
state: restarted
- name: copy redis.conf to mysql
copy:
src: redis.conf
dest: /etc/redis.conf
- name: start and redis
systemd:
name: redis
state: started
enabled: yes
提前准备的文件、变量、handlers
[root@Ansible roles]# ls mysql/files/
all.sql redis.conf
(10)执行测试(密钥分发+检查playbook语法+执行playbook)
[root@Ansible ~]# cd /bash/
[root@Ansible bash]# sh batchSendKey.sh #执行密钥分发,要在bash目录执行
[root@Ansible bash]# ansible-playbook --syntax-check /ansible/roles/site.yml
playbook: /ansible/roles/site.yml
[root@Ansible roles]# ansible-playbook -i hosts /ansible/roles/site.yml
-----密钥分发与主机列表-----
[root@Ansible bash]# cat batchSendKey.sh
#!/bin/bash
if [ ! -f ~/.ssh/id_rsa ];then
ssh-keygen -t rsa
else
echo "id_rsa has created ..."
fi
while read line
do
user="root"
ip=`echo $line | cut -d " " -f 1`
passwd="1"
expect <<EOF
set timeout 10
spawn ssh-copy-id -i /root/.ssh/id_rsa.pub $user@$ip
expect {
"yes/no" { send "yes\n";exp_continue }
"password" { send "$passwd\n" }
}
expect "password" { send "$passwd\n" }
EOF
done < hostlist.txt
[root@Ansible bash]# cat hostlist.txt
172.168.1.5
172.168.1.6
172.168.1.7
172.168.1.8
172.168.1.31
172.168.1.41
172.168.1.51
172.168.1.52
运行完后浏览器访问网页查看项目是否正常访问,模拟脑裂等等操作,检查剧本执行结果。