六、Ansible Role:
1、Role简介:
role:角色,用于层次性、结构化地组织playbook,以便多次复用。role能够根据层次型结构自动装载变量文件、task以及handler等。
2、Role以特定的层级目录结构进行组织,包括:
Ø tasks目录:角色需要执行的主任务文件放置在此目录中,默认的主任务文件名为main.yml。当调用角色时,默认会执行main.yml文件中的任务,也可以将其它需要执行的任务文件通过include的方式包含在tasks/main.yml文件中。
Ø handlers目录:当角色需要调用handler时,默认会在此目录中的main.yml文件中查找对应的handler。
Ø defaults目录:角色会使用到的变量可以写入到此目录中的main.yml文件中,通常defaults/main.yml文件中的变量都用于设置变量的默认值,以便在没有设置对应变量时,变量有默认的值可以使用,定义在defaults/main.yml文件中的变量优先级是最低的。
Ø vars目录:角色会使用到的变量可以写入到此目录中的main.yml文件中,vars/main.yml文件中的变量优先级非常高(除了比“-e”传入的变量优先级低),而defaults/main.yml文件中的变量优先级是最低的。如果只是想提供一个默认的配置,那么可以把对应的变量定义在defaults/main.yml文件中,如果想要确保别人在调用角色时,使用的值就是指定的值,则可以将变量定义在vars/main.yml文件中,因为定义在vars/main.yml文件中的变量优先级非常高,所以其值比较难以被覆盖。
Ø meta目录:如果想要赋予角色一些元数据,则可以将元数据写入到meta/main.yml文件中,这些元数据用于描述角色的相关属性,比如:作者信息、角色主要作用等,也可以在meta/main.yml文件中定义此角色依赖于哪些其它角色,或者改变角色的默认调用设定。
Ø templates目录:角色相关的模板文件(默认以.j2为后缀)可以放置在此目录中。当使用角色相关的模板时,如果没有指定路径,会默认从此目录中查找对应名称的模板文件。
Ø files目录:角色可能会用到的一些其它文件可以放置在此目录中,比如:当定义nginx角色时,需要配置https,那么相关的证书文件就可放置在此目录中。
备注:上述目录并不是都必需的,如果角色中并没有相关的模板文件,那么角色目录中并不用包含templates目录,同理其它目录也一样,一般情况下,至少会有一个tasks目录。
3、实战案例:
(1)nginx节点反代用户请求至2个tomcat节点,实现负载均衡
a、演示环境:
IP |
操作系统 |
主机名 |
安装软件 |
软件版本 |
服务器角色 |
192.168.1.143 |
CentOS 7.6 x86_64 |
ansible |
epel-release、ansible |
2.7.10 |
Ansible主机 |
192.168.1.144 |
CentOS 7.6 x86_64 |
nginx |
epel-release、nginx |
1.12.2 |
被管控主机 |
192.168.1.145 |
CentOS 7.6 x86_64 |
tomcat1 |
jdk、tomcat |
jdk-8u212-linux-x64.rpm apache-tomcat-8.5.40.tar.gz |
被管控主机 |
192.168.1.220 |
CentOS 6.10 x86_64 |
tomcat2 |
jdk、tomcat |
jdk-8u212-linux-x64.rpm apache-tomcat-8.5.40.tar.gz |
被管控主机 |
备注:python版本为2.7.5
b、Ansible主机关闭firewalld和SELinux
c、Ansible主机修改/etc/hosts文件:
# vim /etc/hosts
192.168.1.143 ansible
192.168.1.144 nginx
192.168.1.145 tomcat1
192.168.1.220 tomcat2
d、Ansible主机安装ansible:# yum -y install epel-release # yum -y install ansible
e、Ansible主机配置主机清单文件:
# vim /etc/ansible/hosts,末尾新增如下代码:
[ansrv]
ansible ansible_host=192.168.1.143
[ngxsrv]
nginx ansible_host=192.168.1.144
[tcsrvs]
tomcat1 ansible_host=192.168.1.145
tomcat2 ansible_host=192.168.1.220
f、Ansible主机生成密钥对,基于密钥认证:# ssh-keygen -t rsa -P ""
g、Ansible主机复制公钥至所有被管控主机:
# ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
# ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
# ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
# ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
h、Ansible主机测试连通性:# ansible all -m ping
i、Ansible主机创建roles相关目录结构:
# cd /etc/ansible/roles
# mkdir -pv {chrony,nginx,jdk,tomcat}/{files,templates,tasks,handlers,vars,meta,defaults}
j、配置chrony role:
# vim chrony/tasks/main.yml
- name: stop iptables on centos 6
service: name=iptables state=stopped enabled=no
when: ansible_distribution=="CentOS" and ansible_distribution_major_version=="6"
- name: stop firewalld on centos 7
systemd: name=firewalld.service state=stopped enabled=no
when: ansible_distribution=="CentOS" and ansible_distribution_major_version=="7"
- name: install libselinux-python
yum: name=libselinux-python state=latest
- name: stop selinux
selinux: state=disabled
- name: set hostname
hostname: name={{inventory_hostname}}
- name: edit hosts file
lineinfile: path=/etc/hosts line="{{ansible_host}} {{inventory_hostname}}" state=present backup=yes
- name: install chrony
yum: name=chrony state=latest
- name: install configuration file
copy: src=chrony.conf dest=/etc/ owner=root group=root mode=0644 backup=yes
notify: restart chrony service
tags: chrony configuration file
- name: start chrony service
service: name=chronyd state=started enabled=yes
# vim chrony/files/chrony.conf
server 192.168.1.142 iburst
driftfile /var/lib/chrony/drift
makestep 10 3
rtcsync
local stratum 10
keyfile /etc/chrony.keys
logdir /var/log/chrony
stratumweight 0
noclientlog
logchange 0.5
备注:192.168.1.142为内网NTP服务器
# vim chrony/handlers/main.yml
- name: restart chrony service
service: name=chronyd state=restarted
k、配置nginx role:
# vim nginx/tasks/main.yml
- name: install {{item}}
yum: name={{item}} state=latest
loop:
- epel-release
- nginx
- name: install configuration file
copy: src=nginx.conf dest=/etc/nginx/ owner=root group=root mode=0644 validate="nginx -t -c %s" backup=yes
notify: reload nginx service
tags: nginx configuration file
- name: start nginx service
service: name=nginx state=started enabled=yes
# vim nginx/files/nginx.conf:
Ø 删除listen [::]:80 default_server;
Ø 修改listen 80 default_server;为listen 80;
Ø 在http配置段内、server配置段外新增如下代码:
upstream tcsrvs {
server 192.168.1.145:8080;
server 192.168.1.220:8080;
}
Ø 在server的location /配置段内新增如下代码:
server {
location / {
proxy_pass http://tcsrvs;
}
}
备注:
Ø 由于nginx.conf文件中没有使用到任何变量,所以简单地使用了copy模块,而没有使用template模块
Ø nginx.conf文件从其它CentOS 7.6主机中提取而来
# vim nginx/handlers/main.yml
- name: reload nginx service
service: name=nginx state=reloaded
l、配置jdk role:
# vim jdk/tasks/main.yml
- name: copy jdk
copy: src=jdk-{{version}}-linux-x64.rpm dest=/tmp/ owner=root group=root mode=0644
- name: install jdk
yum: name=/tmp/jdk-{{version}}-linux-x64.rpm state=present
- name: set jdk environment variable
copy: src=jdk.sh dest=/etc/profile.d/ owner=root group=root mode=0644
- name: effect jdk environment variable
shell: source /etc/profile.d/jdk.sh
# vim jdk/files/jdk.sh
export JAVA_HOME=/usr/java/latest
export PATH=$JAVA_HOME/bin:$PATH
备注:软件包jdk-8u212-linux-x64.rpm需要放在jdk/files目录中,使用copy模块复制至被管控节点后再安装
# vim jdk/vars/main.yml
version: 8u212
m、配置tomcat role:
# vim tomcat/tasks/main.yml
- name: unarchive tomcat
unarchive: src=apache-tomcat-{{version}}.tar.gz dest=/usr/local/
- name: create soft link
file: src=/usr/local/apache-tomcat-{{version}} path=/usr/local/tomcat state=link
- name: set tomcat environment variable
copy: src=tomcat.sh dest=/etc/profile.d/ owner=root group=root mode=0644
- name: effect tomcat environment variable
shell: source /etc/profile.d/tomcat.sh
- name: install jsp test page
template: src=test.jsp.j2 dest=/usr/local/tomcat/webapps/ROOT/test.jsp owner=root group=root mode=0640
- name: optimize JVM
blockinfile: path=/usr/local/tomcat/bin/catalina.sh block="JAVA_OPTS='-server -Xms2048m -Xmx2048m'" marker="#{mark} JAVA_OPTS" insertafter="^#!/bin/sh" state=present backup=yes
- name: start tomcat
shell: chdir=/usr/local/tomcat/bin/ nohup ./catalina.sh start &
# vim tomcat/files/tomcat.sh
export CATALINA_HOME=/usr/local/tomcat
export PATH=$CATALINA_HOME/bin:$PATH
备注:软件包apache-tomcat-8.5.40.tar.gz需要放在tomcat/files目录中
# vim tomcat/vars/main.yml
version: 8.5.40
# vim tomcat/templates/test.jsp.j2
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
{{ansible_host}}
n、编写playbook并执行:
# mkdir -pv /playbooks
# vim /playbooks/lb.yml
- hosts: all
remote_user: root
roles:
- chrony
- hosts: ngxsrv
remote_user: root
roles:
- nginx
- hosts: tcsrvs
remote_user: root
roles:
- jdk
- tomcat
# ansible-playbook --syntax-check /playbooks/lb.yml
# ansible-playbook -C /playbooks/lb.yml
# ansible-playbook /playbooks/lb.yml
o、浏览器测试:
192.168.1.144
192.168.1.144/test.jsp,刷新页面,实现负载均衡:
(2)搭建LNMP环境
a、演示环境:
IP |
操作系统 |
主机名 |
安装软件 |
软件版本 |
服务器角色 |
192.168.1.144 |
CentOS 7.6 x86_64 |
ansible |
epel-release、ansible |
2.7.10 |
Ansible主机 |
192.168.1.145 |
CentOS 7.6 x86_64 |
nginx |
epel-release、nginx、php、php-fpm |
1.12.2 |
被管控主机 |
192.168.1.146 |
CentOS 7.6 x86_64 |
mariadb |
mariadb、expect |
10.3.14 |
被管控主机 |
备注:ansible使用的python版本为2.7.5
b、ansible主机关闭firewalld和SELinux
c、ansible主机修改/etc/hosts文件:
# vim /etc/hosts
192.168.1.144 ansible
192.168.1.145 nginx
192.168.1.146 mariadb
d、ansible主机安装ansible:# yum -y install epel-release # yum -y install ansible
e、ansible主机配置主机清单文件:
# vim /etc/ansible/hosts,末尾新增如下代码:
[ansrv]
ansible ansible_host=192.168.1.144
[ngxsrv]
nginx ansible_host=192.168.1.145
[madbsrv]
mariadb ansible_host=192.168.1.146
f、ansible主机生成密钥对,基于密钥认证:# ssh-keygen -t rsa -P ""
g、ansible主机复制公钥至所有被管控主机:
# ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
# ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
# ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
h、ansible主机测试连通性:# ansible all -m ping
i、ansible主机创建roles相关目录结构:
# cd /etc/ansible/roles
# mkdir -pv {chrony,nginx,php,mariadb}/{files,templates,tasks,handlers,vars,meta,defaults}
j、配置chrony role:
# vim chrony/tasks/main.yml
- name: stop firewalld
systemd: name=firewalld.service state=stopped enabled=no
- name: install libselinux-python
yum: name=libselinux-python state=latest
- name: stop selinux
selinux: state=disabled
- name: set hostname
hostname: name={{inventory_hostname}}
- name: edit hosts file
lineinfile: path=/etc/hosts line="{{ansible_host}} {{inventory_hostname}}" state=present backup=yes
- name: install chrony
yum: name=chrony state=latest
- name: install configuration file
copy: src=chrony.conf dest=/etc/ owner=root group=root mode=0644 backup=yes
notify: restart chrony service
tags: chrony configuration file
- name: start chrony service
service: name=chronyd state=started enabled=yes
# vim chrony/files/chrony.conf
server 192.168.1.142 iburst
driftfile /var/lib/chrony/drift
makestep 10 3
rtcsync
local stratum 10
keyfile /etc/chrony.keys
logdir /var/log/chrony
stratumweight 0
noclientlog
logchange 0.5
备注:192.168.1.142为内网NTP服务器
# vim chrony/handlers/main.yml
- name: restart chrony service
service: name=chronyd state=restarted
k、配置nginx role:
# vim nginx/tasks/main.yml
- name: install {{item}}
yum: name={{item}} state=latest
loop:
- epel-release
- nginx
- name: install configuration file
copy: src=nginx.conf dest=/etc/nginx/ owner=root group=root mode=0644 backup=yes
notify: reload nginx service
tags: nginx configuration file
- name: install php test page
copy: src=index.php dest=/usr/share/nginx/html/ owner=root group=root mode=0644
- name: start nginx service
service: name=nginx state=started enabled=yes
# vim nginx/files/nginx.conf:
Ø 删除listen [::]:80 default_server;
Ø 修改listen 80 default_server;为listen 80;
Ø 在server配置段内新增如下代码:
location / {
index index.html index.htm;
}
location ~ \.php$ {
fastcgi_pass 192.168.1.145:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi.conf;
}
备注:
Ø 由于nginx.conf文件中没有使用到任何变量,所以简单地使用了copy模块,而没有使用template模块
Ø nginx.conf文件从其它CentOS 7.6主机中提取而来
# vim nginx/files/index.php
$conn = mysqli_connect("192.168.1.146","testuser","654321");
if ($conn)
echo "Success";
else
echo "Failure";
mysqli_close();
phpinfo();
?>
# vim nginx/handlers/main.yml
- name: reload nginx service
service: name=nginx state=reloaded
l、配置php role:
# vim php/tasks/main.yml
- name: install {{item}}
yum: name={{item}} state=latest
loop:
- php
- php-fpm
- php-mysql
- name: install www configuration file
template: src=www.conf.j2 dest=/etc/php-fpm.d/www.conf owner=root group=root mode=0644 backup=yes
notify: restart php-fpm service
tags: www configuration file
- name: start php-fpm service
service: name=php-fpm state=started enabled=yes
# vim php/templates/www.conf.j2,修改如下代码:
listen = 127.0.0.1:9000 --> listen = {{ansible_host}}:9000
listen.allowed_clients = 127.0.0.1 --> listen.allowed_clients = {{ansible_host}}
user = apache --> user = nginx
group = apache --> group = nginx
# vim php/handlers/main.yml
- name: restart php-fpm service
service: name=php-fpm state=restarted
备注:
Ø www.conf文件从其它CentOS 7.6主机中提取而来
Ø 9000:php-fpm监听的端口
Ø listen.allowed_clients:允许连接的FastCGI客户端IP地址
m、配置mariadb role:
# vim mariadb/tasks/main.yml
- name: create MariaDB-server repository
yum_repository: file=MariaDB name=mariadb description="MariaDB Repo" baseurl=http://mirrors.ustc.edu.cn/mariadb/yum/10.3/centos7-amd64/ gpgkey=http://mirrors.ustc.edu.cn/mariadb/yum/RPM-GPG-KEY-MariaDB gpgcheck=yes enabled=yes owner=root group=root mode=0644 state=present
- name: install {{item}}
yum: name={{item}} state=latest
loop:
- MariaDB-server
- MySQL-python
- expect
- name: install server configuration file
copy: src=server.cnf dest=/etc/my.cnf.d/ owner=root group=root mode=0644 backup=yes
notify: restart mariadb service
tags: server configuration file
- name: start mariadb service
service: name=mariadb state=started enabled=yes
- name: expect mysql_secure_installation
script: mysql_secure_installation.exp
- name: add testuser
mysql_user: login_host=localhost login_user=root login_password=123456 name=testuser host="%" password=654321 priv=*.*:all state=present
tags: add mariadb user
备注:被管控节点中新创建的yum源内容
# cat /etc/yum.repos.d/MariaDB.repo
[mariadb]
name=MariaDB Repo
baseurl=http://mirrors.ustc.edu.cn/mariadb/yum/10.3/centos7-amd64/
gpgkey=http://mirrors.ustc.edu.cn/mariadb/yum/RPM-GPG-KEY-MariaDB
gpgcheck=1
enabled=1
# vim mariadb/files/server.cnf,在[mysqld]配置段下新增如下代码:
[mysqld]
port=3306
socket=/var/lib/mysql/mysql.sock
datadir=/var/lib/mysql
log-error=/var/log/mariadb.log
lower_case_table_names=1
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
symbolic-links=0
# vim mariadb/files/mysql_secure_installation.exp
#!/usr/bin/expect -f
set timeout 5
set password 123456
spawn mysql_secure_installation
expect "Enter current password for root:"
send "\r"
expect "Set root password?"
send "y\r"
expect "New password:"
send "$password\r"
expect "Re-enter new password:"
send "$password\r"
expect "Remove anonymous users?"
send "y\r"
expect "Disallow root login remotely?"
send "n\r"
expect "Remove test database and access to it?"
send "y\r"
expect "Reload privilege tables now?"
send "y\r"
expect eof
# chmod +x mariadb/files/mysql_secure_installation.exp
备注:使用expect实现自动输入,脚本执行方式为# ./mysql_secure_installation.exp
# vim mariadb/handlers/main.yml
- name: restart mariadb service
service: name=mariadb state=restarted
n、编写playbook并执行:
# mkdir -pv /playbooks
# vim /playbooks/lnmp.yml
- hosts: all
remote_user: root
roles:
- chrony
- hosts: ngxsrv
remote_user: root
roles:
- nginx
- php
- hosts: madbsrv
remote_user: root
roles:
- mariadb
# ansible-playbook --syntax-check /playbooks/lnmp.yml
# ansible-playbook -C /playbooks/lnmp.yml
# ansible-playbook /playbooks/lnmp.yml
o、浏览器测试:
192.168.1.145
192.168.1.145/index.php
停止192.168.1.146中的mariadb,刷新页面: