本章主要记录在测试环境下用ansible部署nginx服务的过程,至于ansible和nginx的具体语法结构和配置本章不做具体讲解,计划在以后的章节里详细和大家分享……
playbook是由一个或多个“play”组成的列表
play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。task实际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作
playbook采用yaml语言编写
playbook核心元素
hosts:执行的远程主机列表’ tasks:任务集
variables:内置变量或自定义变量在playbook中调用
tempaltes 模板,可替换文件中的变量并实现一些简单逻辑的文件
handles 和notify结合使用,由特定条件触发的操作,满足条件方执行,否则不执行
tags标签,指定某条任务执行,用于选择运行playbook中的部分代码。
ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其 确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
roles:
用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中
复杂场景:建议使用roles,代码复用度高
变更指定主机或主机组
如命名不规范维护和传承成本大
某些功能需多个Playbook,通过includes即可实现
roles目录结构:
playbook.yml
roles/
project/ //主项目文件
tasks/ //任务文件
main.yml
files/ //存放由copy或script模块等调用的文件
vars/ //定义变量文件
main.yml
templates/ //模板文件,template模块查找所需要.j2模板文件的目录
main.yml
handlers/ //触发器文件
main.yml
default/ 不常用 //设定默认变量时使用此目录中的main.yml文件
meta/ 不常用 //定义当前角色的特殊设定及其依赖关系
创建role的步骤
(1) 创建以roles命名的目录
(2) 在roles目录中分别创建以各角色名称命名的目录,如webservers等
(3) 在每个角色命名的目录中分别创建files、handlers、meta、tasks、
templates和vars目录;用不到的目录可以创建为空目录,也可以不创建
(4) 在playbook文件中,调用各角色
roles目录结构:
好了简单介绍了一下ansible的playbook用法,现在让我们动手来具体部署编排吧
测试环境规划:
ansible服务器主控端 系统:centos7.6.1810 IP:192.168.131.88
nginx web1服务器受控端: 系统:centos7.7.1908 IP:192.168.131.18 域名:www.lris.com
nginx web1服务器受控端: 系统:centos8.0.1905 IP:192.168.131.38 域名:www.real.com
在ansible服务器端:
#把web服务加入ansible主控机的hosts清单并命名为:asrvc
vim /etc/ansible/hosts #加在文件的最后
[asrvc]
192.168.131.38
192.168.131.18
mkdir /data/playbook/roles/nginx/{tasks,files,templates}
cd /data/playbook/roles/nginx/
#首先我们把需要的配置文件、安装包、模板文件准好,配置文件放置在files文件下,模板文件放置在templates下
#files下,我准备了三个文件:
root@realcentos7:nginx]#ll files/
total 1020
-rwxr-xr-x 1 root root 448 Oct 27 05:52 configure.sh #源码编译config文件
-rw-r--r-- 1 root root 1032630 Oct 27 00:12 nginx-1.16.1.tar.gz #nginx安装包
-rw-r--r-- 1 root root 656 Oct 27 01:53 nginx.service #systemd启动服务文件
#configure文件是我写的一个源码编译安装nginx脚本,具体代码如下:
root@realcentos7:nginx]#cat files/configure.sh
#!/bin/bash
yum -y install gcc pcre-devel openssl-devel zlib-devel &> /dev/null #安装编译相关依赖包
cd /tmp/nginx-1.16.1 #进入到nginx解压包下,这个文件会在ansible执行中生成
./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --with-file-aio &> /dev/null
make &> /dev/null
make install &> /dev/null
#由于两台web服务器分别是centos7和centos8系统,所有我准备了两份模板文件:
root@realcentos7:nginx]#ll templates/
total 8
-rw-r--r-- 1 root root 2941 Oct 27 05:18 nginx7.conf.j2
-rw-r--r-- 1 root root 2941 Oct 27 05:17 nginx8.conf.j2
#nginx.service如下:
root@realcentos7:nginx]#vim files/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/apps/nginx/logs/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /apps/nginx/logs/nginx.pid
ExecStartPre=/apps/nginx/sbin/nginx -t
ExecStart=/apps/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
[Install]
WantedBy=multi-user.target
#在这两个模板配置文件中,我分别设定了两个虚拟主机头,用于区分:
vim templates/nginx7.conf.j2
vim templates/nginx8.conf.j2
注意建议把html页面存放在非root目录以外的地方,因为访问root目录需要权限,在下面的代码的我是放在/data……下
#好了,准备好所有文件后,继续回到playbook模块中,现在我们开始真正编写编排代码
cd /data/playbook/roles/nginx/
root@realcentos7:tasks]#vim copyfile.yml #复制并解压nginx安装包文件
- name: copy and decompression nstall file
unarchive: src=nginx-1.16.1.tar.gz dest=/tmp
root@realcentos7:tasks]#vim compile.yml #执行configure,进行编译安装nginx
- name: Compile the installation
script: /data/playbook/roles/nginx/files/configure.sh #此处写configure.sh脚本文件的绝对路径,
root@realcentos7:tasks]#vim copyconf.yml #复制conf配置文件
- name: copy nginx7.conf file
template: src=nginx7.conf.j2 dest=/apps/nginx/conf/nginx.conf
when: ansible_distribution_major_version == "7" #when条件判断,根据系统版本判断复制上面文件
- name: copy centos8 conf file
template: src=nginx8.conf.j2 dest=/apps/nginx/conf/nginx.conf
when: ansible_distribution_major_version == "8"
root@realcentos7:tasks]#vim copyservice.yml #复制systemd启动文件
- name: copy service file
copy: src=nginx.service dest=/usr/lib/systemd/system
root@realcentos7:tasks]#vim adduser.yml #添加nginx用户
- name: add nginx user
user: name=nginx uid=2000 shell=/sbin/nologin
root@realcentos7:tasks]#vim mkdirhtml.yml #创建网页文件,根据域名和路径创建不同的index.html页面用于区分
- name: create real html page dirctory
shell: mkdir -p /data/nginx/real/{python,docker}
when: ansible_distribution_major_version == "8"
- name: create lris html page dirctory
shell: mkdir -p /data/nginx/lris/{python,docker}
when: ansible_distribution_major_version == "7"
- name: create file for real python html
copy: content='real python\n' dest=/data/nginx/real/python/index.html
when: ansible_distribution_major_version == "8"
- name: create file for real python html
copy: content='real docker\n' dest=/data/nginx/real/docker/index.html
when: ansible_distribution_major_version == "8"
- name: create file for lris python html
copy: content='lris python\n' dest=/data/nginx/lris/python/index.html
when: ansible_distribution_major_version == "7"
- name: create file for real python html
copy: content='lris docker\n' dest=/data/nginx/lris/docker/index.html
when: ansible_distribution_major_version == "7"
root@realcentos7:tasks]#vim start.yml #启动nginx服务,打开80端口
- name: runing service
service: name=nginx state=started enabled=yes
root@realcentos7:tasks]#vim main.yml #main文件定义了上面所有yml文件的执行顺序,需要先执行那部操作,把对应的yml文件写在上面,按照从上到下顺序执行定义的操作
- include: copyfile.yml
- include: compile.yml
- include: adduser.yml
- include: copyconf.yml
- include: copyservice.yml
- include: start.yml
- include: mkdirhtml.yml
写好所有tasks文件后对应的文件结构:
整个nginx目录的结构:
然后我们就可以写最后的playbook执行文件了,因为前面我们几乎把所有要做的和要准备的都完成了,所有最后的执行文件同样很简单:
#看上面的playbook结构图,role_nginx.yml就是我们现在要写的playbook执行文件,注意一定要写在和roles平级的playbook目录下
cd /data/playbook
root@realcentos7:playbook]#vim role_nginx.yml
---
#roles install nginx
- hosts: asrvc #执行的受控主机清单
remote_user: root #远程执行用户名
roles: #角色目录
- role: nginx #执行角色:就是我们上面花了很大功夫下的nginx
这样我们就编排部署好整个规划的nginx服务了,我们可以先测试并执行以下:
#注意主控机和受控机必选先要进行密钥交换,然后才能正常执行ansible任务,不然出现要输入密码的选项会报错
#密钥交换最简单的方法就是:
ssh-keygen #生成密钥
ssh-copy-id 192.168.131.18
ssh-copy-id 192.168.131.18 #拷贝到nginx服务机器上去,同样的在nginx服务机上执行同样的操作,但是只要拷贝到ansible服务机上就是
#在ansible服务端测试:
root@realcentos7:playbook]#ansible-playbook -C role_nginx.yml #-C测试,正常情况下出现黄色和蓝色,出现红色代码则报错
执行部署命令:ansible-playbook role_nginx.yml
正常执行后,nginx服务会直接开启,我们可以在浏览器端测,前提要把上面的域名加入到你本机的hosts文件中
C:\Windows\System32\drivers\etc\hosts 在最后添加下面的ip和对应的域名:
192.168.131.38 www.real.com
192.168.131.18 www.lris.com