【运维知识进阶篇】用Ansible Roles重构LNMP架构(Linux+Nginx+Mariadb+PHP),实现4个项目一键部署!

我们先前用playbook构造过lnmp架构,实现了一键部署四个项目的效果,但是我们是将所有的命令都写入了一个playbook中,我们所需的文件也只是简单的放入了playbook的同级目录,这样很混乱,而roles可以很好解决这一点,使用roles,我们可以很轻松的整理我们的配置文件,更有利于我们写好后排错,或者更改配置,我们再将变量,判断语句,循环语句加上,打造我们用Ansible部署lnmp架构的最终版本!

准备工作

主机名称 主机IP(外网、内网) 作用
LB01 10.0.0.5、172.16.1.5 七层负载均衡、keepalived高可用,https证书
LB02 10.0.0.6、172.16.1.6 七层负载均衡、keepalived高可用,https证书
Web01 10.0.0.7、172.16.1.7 Nginx、php服务、存放代码文件
Web02 10.0.0.8、172.16.1.8 Nginx、php服务、存放代码文件
NFS 10.0.0.31、172.16.1.31 存放静态资源
Backup 10.0.0.41、172.16.1.41 存放静态数据的备份、实时同步NFS的代码内容
MySQL 10.0.0.51、172.16.1.51 存放动态数据
Ansible 10.0.0.61、172.16.1.61 使用Ansible作为控制机

重构思路

用roles和不用roles的逻辑其实是一样的,要根据服务器的功能,先收集服务器所需要的文件,再进行安装,传输文件,启动服务或重启服务等操作。只是我们这次不必担心命名问题,因为不同的服务或不同功能的服务器所需要的配置文件会被放到不同的目录,不会冲突。

roles这个角色,可以根据同类服务器的功能定义,也可以通过服务去定义,因为我们是一键部署所有服务和项目,也不存在指定部署服务的需求,如果通过服务来定义,也容易出现需要很多when判断的情况,如果用同类功能的服务器定义角色,可能会出现同一条命令需要反复编写的情况,自行选择,我采取根据同类功能服务器去定义我们的roles角色。

管理机操作

1、添加目标客户机至主机列表

[root@Ansible roles]# cat hosts 
[lb_group]
lb01 ansible_ssh_host=172.16.1.5
lb02 ansible_ssh_host=172.16.1.6

[web_group]
web01 ansible_ssh_host=172.16.1.7
web02 ansible_ssh_host=172.16.1.8

[nfs]
172.16.1.31

[backup]
172.16.1.41

[mysql]
172.16.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.16.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.16.1.31:/data/wordpress
    path: /code/wordpress/wp-content/uploads
    fstype: nfs
    opts: defaults
    state: mounted
- name: Mount wecenter_NFS Server
  mount:
    src: 172.16.1.31:/data/wecenter
    path: /code/wecenter/uploads
    fstype: nfs
    opts: defaults
    state: mounted
- name: Mount phpshe_NFS Server
  mount:
    src: 172.16.1.31:/data/phpshe
    path: /code/phpshe/data
    fstype: nfs
    opts: defaults
    state: mounted 
- name: mount kod server
  mount:
    src: 172.16.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 <

运行完后浏览器访问网页查看项目是否正常访问,模拟脑裂等等操作,检查剧本执行结果。


我是koten,10年运维经验,持续分享运维干货,感谢大家的阅读和关注!

你可能感兴趣的:(进阶运维知识,运维知识分享,ansible,saltstack,nginx,linux,自动化)