自动化运维工具-Ansible之3-playbook
PlayBook初识
什么是PlayBook?
PlayBook
即"剧本","兵书"之意,PlayBook是由以下部分组成的
play
: 定义的是主机的角色。(主角还是配角,找哪个明星)task
: 定义的是具体执行的任务。(角色的台词和动作)playbook
: 由一个或多个play(角色)组成,一个play(角色)可以包含多个task(台词,动作,大腕每集拍什么)。
简单理解为: 使用不同的模块完成一件事情
在Ansible
中"剧本文件"是以yml
结尾的文件。
在SaltStack
中"剧本文件"是以sls
结尾的文件。
但使用的都是yaml
语法
PlayBook与ad-hoc
特点 | PlayBook | ad-hoc |
---|---|---|
完整性 | √ | ✘ |
持久性 | √ | ✘ |
执行效率 | 低 | 高 |
变量 | 支持 | 不支持 |
耦合度 | 低 | 高 |
-
PlayBook
功能比ad-hoc
更全,是对ad-hoc
的一种编排. -
PlayBook
能很好的控制先后执行顺序,以及依赖关系. -
PlayBook
语法展现更加的直观. -
playbook
可以持久使用,ad-hoc
无法持久使用.
YAML语法
语法 | 描述 |
---|---|
缩进 | YAML使用固定的缩进风格表示层级结构,每个缩进由两个空格组成, 不能使用TAB |
冒号 | 以冒号结尾的除外,其他所有冒号后面所有必须有空格 |
短横线 | 表示列表项,使用一个短横杠加一个空格,多个项使用同样的缩进级别作为同一列表 |
中国:
北京:
上海:
- 浦东新区
- 青浦区
yum:
name: vsftpd
state: present
yum:
name:
- httpd
- nginx
- php-fpm
state: present
PlayBook编写
host:对哪些主机进行操作(演员)
remote_user:使用什么用户执行(通行证)
tasks:具体执行任务(台词和动作)
PlayBook部署httpd
环境准备
- 创建剧本存放目录
[root@m01 ~]# mkdir /etc/ansible/httpd
- 配置主机清单并测试
[root@m01 ~]# vim /etc/ansible/hosts
[web_group]
web01 ansible_ssh_host=10.0.0.7
web02 ansible_ssh_host=10.0.0.8
[root@m01 ~]# ansible web_group -m ping
需求一:安装httpd
[root@m01 ~]# vi /etc/ansible/httpd/httpd.yml
---
- hosts: web_group
# 安装httpd
tasks:
- name: Install httpd Server
yum:
name: httpd
state: present
# 语法检测
[root@m01 ~]# ansible-playbook --syntax-check /etc/ansible/httpd/httpd.yml
playbook: /etc/ansible/httpd/httpd.yml
# 安装测试
[root@m01 ~]# ansible-playbook -C /etc/ansible/httpd/httpd.yml
PLAY [web_group] ***************************************************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************************************************************
ok: [web02]
ok: [web01]
TASK [Install httpd Server] ****************************************************************************************************************************************************************************************************************************************************
changed: [web02]
changed: [web01]
PLAY RECAP *********************************************************************************************************************************************************************************************************************************************************************
web01 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web02 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
需求二:创建网站页面
---
- hosts: web_group
# 安装httpd
tasks:
- name: Install httpd Server
yum:
name: httpd
state: present
# 配置网站页面
- name: Config Httpd Server
copy:
content: oldboy_web_page
dest: /var/www/html/index.html
需求三:启动httpd服务并加入开机自启
---
- hosts: web_group
# 安装httpd
tasks:
- name: Install httpd Server
yum:
name: httpd
state: present
# 配置网站页面
- name: Config Httpd Server
copy:
content: oldboy_web_page
dest: /var/www/html/index.html
# 启动httpd
- name: Start Httpd Server
systemd:
name: httpd
state: started
enabled: yes
需求四:开启防火墙端口
---
- hosts: web_group
# 安装httpd
tasks:
- name: Install httpd Server
yum:
name: httpd
state: present
# 配置网站页面
- name: Config Httpd Server
copy:
content: oldboy_web_page
dest: /var/www/html/index.html
# 启动httpd
- name: Start Httpd Server
systemd:
name: httpd
state: started
enabled: yes
# 启动防火墙
- name: Start Firewalld Server
systemd:
name: firewalld
state: started
enabled: yes
# 开启防火墙的80端口
- name: Config Firewalld Server
firewalld:
service: http
immediate: yes
permanent: yes
state: enabled
打开浏览器访问网站:
http://10.0.0.7
http://10.0.0.8
需求五:不同的主机配置不同的网站
目前来说,想要根据不同主机配置不同的网站,我们可以使用多个play的方式,但是在生产环境中,我们需要写循环,来满足我们的需求,多个play了解即可
---
- hosts: web_group
# 安装httpd
tasks:
- name: Install httpd Server
yum:
name: httpd
state: present
# 启动httpd
- name: Start Httpd Server
systemd:
name: httpd
state: started
enabled: yes
# 启动防火墙
- name: Start Firewalld Server
systemd:
name: firewalld
state: started
enabled: yes
# 开启防火墙的80端口
- name: Config Firewalld Server
firewalld:
service: http
immediate: yes
permanent: yes
state: enabled
# 单独配置web01页面
- hosts: web01
tasks:
- name: Config Httpd Server
copy:
content: oldboy_web01_page
dest: /var/www/html/index.html
# 单独配置web02页面
- hosts: web02
tasks:
- name: Config Httpd Server
copy:
content: oldboy_web02_page
dest: /var/www/html/index.html
打开浏览器访问网站:
http://10.0.0.7
http://10.0.0.8
PlayBook实战
实战一:
部署一个backup
备份服务器的服务端和客户端
- 演员表
主机名 | wanIP | lanIP | 服务 | 角色 |
---|---|---|---|---|
m01 | 10.0.0.61 | 172.16.1.61 | Ansible | 控制端(导演) |
backup | 10.0.0.41 | 172.16.1.41 | rsync服务端 | 被控端(男一) |
web01 | 10.0.0.7 | 172.16.1.7 | rsync客户端 | 被控端(女二) |
web02 | 10.0.0.8 | 172.16.1.8 | rsync客户端 | 被控端(女二) |
- 战前准备
灯光,音响,摄像准备...
yum源,用户,配置文件...
# 创建rsync剧本存放目录
[root@m01 ~]# mkdir rsyncd
# 准备主机清单
[root@m01 ~]# cat > /etc/ansible/hosts <<EOF
[web_group]
web01 ansible_ssh_host=10.0.0.7
web02 ansible_ssh_host=10.0.0.8
[nfs_group]
nfs ansible_ssh_host=10.0.0.31
[backup_group]
backup ansible_ssh_host=10.0.0.41
[nfs_all:children]
web_group
nfs_group
EOF
# 准备rsync配置文件
[root@m01 ~]# cat > /root/rsyncd/rsyncd.j2 <<EOF
uid = www
gid = www
port = 873
fake super = yes
use chroot = no
max connections = 200
timeout = 600
ignore errors
read only = false
list = false
auth users = rsync_backup
secrets file = /etc/rsync.passwd
log file = /var/log/rsyncd.log
#####################################
[backup]
comment = welcome to oldboyedu backup!
path = /backup
EOF
# 准备客户端脚本
[root@m01 ~]# vi /root/rsyncd/client_rsync_backup.j2
#!/usr/bin/bash
# 1.定义变量
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
Host=$(hostname)
Addr=$(ifconfig eth1|awk 'NR==2{print $2}')
Date=$(date +%F)
Dest=${Host}_${Addr}_${Date}
Path=/backup
# 2.创建备份目录
[ -d $Path/$Dest ] || mkdir -p $Path/$Dest
# 3.备份对应的文件
cd / && \
[ -f $Path/$Dest/system.tar.gz ] || tar czf $Path/$Dest/system.tar.gz etc/fstab etc/rsyncd.conf && \
[ -f $Path/$Dest/log.tar.gz ] || tar czf $Path/$Dest/log.tar.gz var/log/messages var/log/secure && \
# 4.携带md5验证信息
[ -f $Path/$Dest/flag ] || md5sum $Path/$Dest/*.tar.gz >$Path/$Dest/flag_$Date
# 5.推送本地数据至备份服务器
export RSYNC_PASSWORD=123456
rsync -avz $Path/ rsync_backup@172.16.1.41::backup
# 6.本地保留最近7天的数据
find $Path/ -type d -mtime +7 | xargs rm -rf
- 编写剧本
# 编写剧本
[root@m01 ~]# cat > /root/rsyncd/rsyncd.yml <<EOF
- hosts: all
tasks:
# 安装rsync
- name: Install Rsyncd Server
yum:
name: rsync
state: present
# 创建www组
- name: Create www Group
group:
name: www
gid: 666
# 创建www用户
- name: Create www User
user:
name: www
group: www
uid: 666
create_home: false
shell: /sbin/nologin
- hosts: backup_group
tasks:
# 推送rsync配置文件
- name: Scp Rsync Config
copy:
src: ./rsyncd.j2
dest: /etc/rsyncd.conf
owner: root
group: root
mode: 0644
# 创建用户密码文件并授权
- name: Create Passwd File
copy:
content: 'rsync_backup:123456'
dest: /etc/rsync.passwd
owner: root
group: root
mode: 0600
# 创建/backup目录
- name: Create backup Directory
file:
path: /backup
state: directory
mode: 0755
owner: www
group: www
recurse: yes
# 启动rsync服务并加入开机启动
- name: Start Rsyncd Server
systemd:
name: rsyncd
state: started
enabled: yes
- hosts: web_group,nfs_group
tasks:
# 创建脚本存放目录
- name: Create scripts Directory
file:
path: /server/scripts
state: directory
mode: 0755
owner: root
group: root
recurse: yes
# 推送客户端脚本
- name: Scp Rsync scripts
copy:
src: ./client_rsync_backup.j2
dest: /server/scripts/client_rsync_backup.sh
owner: root
group: root
mode: 0644
# 加入crontab
- name: Crontab Rsync Backup
cron:
name: "Rsync Backup"
minute: "00"
hour: "01"
job: "/bin/bash /server/scripts/client_rsync_backup.sh &>/dev/null"
EOF
# 检测语法
[root@m01 ~]# ansible-playbook --syntax-check ./rsyncd/rsyncd.yml
playbook: /root/rsyncd/rsyncd.yml
# 测试
[root@m01 ~]# ansible-playbook -C ./rsyncd/rsyncd.yml
PLAY [all] ***********************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [backup]
ok: [web02]
ok: [web01]
TASK [Install Rsyncd Server] *****************************************************************************************************************************************************************************************************************
changed: [backup]
changed: [web02]
changed: [web01]
TASK [Scp Rsync Config] **********************************************************************************************************************************************************************************************************************
changed: [web02]
changed: [web01]
changed: [backup]
TASK [Create www Group] **********************************************************************************************************************************************************************************************************************
changed: [backup]
changed: [web01]
changed: [web02]
TASK [Create www User] ***********************************************************************************************************************************************************************************************************************
changed: [web02]
changed: [web01]
changed: [backup]
TASK [Create backup Directory] ***************************************************************************************************************************************************************************************************************
changed: [web01]
changed: [backup]
changed: [web02]
TASK [Start Rsyncd Server] *******************************************************************************************************************************************************************************************************************
changed: [web01]
changed: [web02]
changed: [backup]
PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
backup : ok=7 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web01 : ok=7 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web02 : ok=7 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
扩展需求:
完成刚开始学架构阶段的rsync的实战案例
实战二:
部署NFS
服务端,提供挂载点给web01
和web02
- 演员表
主机名 | wanIP | lanIP | 服务 | 角色 |
---|---|---|---|---|
m01 | 10.0.0.61 | 172.16.1.61 | Ansible | 控制端(导演) |
nfs | 10.0.0.31 | 172.16.1.31 | nfs服务端 | 被控端(男一) |
web01 | 10.0.0.7 | 172.16.1.7 | nfs客户端 | 被控端(女二) |
web02 | 10.0.0.8 | 172.16.1.8 | nfs客户端 | 被控端(女二) |
- 战前准备
# 创建nfs剧本存放目录
[root@m01 ~]# mkdir nfs
# 准备主机清单
[root@m01 ~]# cat > /etc/ansible/hosts <<EOF
[web_group]
web01 ansible_ssh_host=10.0.0.7
web02 ansible_ssh_host=10.0.0.8
[nfs_group]
nfs ansible_ssh_host=10.0.0.31
[backup_group]
backup ansible_ssh_host=10.0.0.41
[nfs_all:children]
web_group
nfs_group
EOF
# 准备nfs配置文件
[root@m01 ~]# cat > /root/nfs/nfs.j2 <<EOF
/data 10.0.0.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
EOF
- 编写剧本
[root@m01 ~]# cat > /root/nfs/nfs.yml <<EOF
- hosts: nfs_all
tasks:
# 安装nfs
- name: Install nfs-utils
yum:
name: nfs-utils
state: present
# 创建www组
- name: Create www Group
group:
name: www
gid: 666
# 创建www用户
- name: Create www User
user:
name: www
group: www
uid: 666
create_home: false
shell: /sbin/nologin
- hosts: nfs
tasks:
# 推送配置文件
- name: Scp NFS Server
copy:
src: ./nfs.j2
dest: /etc/exports
owner: root
group: root
mode: 0644
# 创建挂载目录并授权
- name: Create data Directory
file:
path: /data
state: directory
owner: www
group: www
mode: 0755
recurse: yes
# 启动nfs-server
- name: Start NFS Server
systemd:
name: nfs-server
state: started
enabled: yes
- hosts: web_group
tasks:
# web01和web02挂载目录
- name: Mount NFS Server
mount:
path: /opt
src: 10.0.0.31:/data
fstype: nfs
opts: defaults
state: mounted
EOF
# 检查语法
[root@m01 ~]# ansible-playbook --syntax-check ./nfs/nfs.yml
playbook: /root/nfs/nfs.yml
# 执行
[root@m01 ~]# ansible-playbook ./nfs/nfs.yml
- 查看web01和web02的挂载情况
[root@web01 ~]# df -h
[root@web02 ~]# df -h
扩展需求:
给web01和web02部署 提交作业代码 后部署nfs,并挂载/var/www/html/upload目录
实战三:
使用playbook
部署一套LAMP
架构。
部署需求:
- 使用yum安装httpd、php、php-mysql、php-pdo、mariadb
- 启动httpd、mariadb服务
- 下载wordpress代码并部署到httpd站点目录
- 演员表
主机名 | wanIP | lanIP | 服务 | 角色 |
---|---|---|---|---|
m01 | 10.0.0.61 | 172.16.1.61 | Ansible | 控制端(导演) |
web01 | 10.0.0.7 | 172.16.1.7 | nfs客户端 | 被控端(男一) |
web02 | 10.0.0.8 | 172.16.1.8 | nfs客户端 | 被控端(男一) |
- 战前准备
# 创建lamp剧本存放目录
[root@m01 ~]# mkdir lamp
# 准备主机清单
[root@m01 ~]# cat > /etc/ansible/hosts <<EOF
[web_group]
web01 ansible_ssh_host=10.0.0.7
web02 ansible_ssh_host=10.0.0.8
[backup_group]
backup ansible_ssh_host=10.0.0.41
[backup_all:children]
web_group
backup_group
[nfs_group]
nfs ansible_ssh_host=10.0.0.31
[nfs_all:children]
web_group
nfs_group
EOF
- 编写剧本
因为这只是一个练习,所以我们将(apache mariadb php全部都写在一个yml文件中,并且放在一个目录下,
注意:在生产中,我们是不会这么做的,我们需要每一个服务单独拎出来,解耦。
[root@m01 ~]# cat > /root/lamp/lamp.yml <<EOF
- hosts: web_group
tasks:
# 安装指定服务
- name: Install httpd mariadb php Server
yum:
name: "{{ packages }}"
vars:
packages:
- httpd
- mariadb-server
- php
- php-mysql
- php-pdo
# 启动httpd服务并加入开机启动
- name: Start httpd Server
systemd:
name: httpd
state: started
enabled: yes
# 启动mariadb服务并加入开机启动
- name: Start httpd Server
systemd:
name: mariadb
state: started
enabled: yes
# 下载wordpress
- name: Get Wordpress Package
get_url:
url: "https://cn.wordpress.org/wordpress-5.4.2-zh_CN.tar.gz"
dest: /var/www/html
# 解压wordpress
- name: Unarchive Wordpress Package
unarchive:
src: /var/www/html/wordpress-5.4.2-zh_CN.tar.gz
dest: /var/www/html
copy: no
EOF
# 检查语法
[root@m01 ~]# ansible-playbook --syntax-check ./lamp/lamp.yml
playbook: /root/lamp/lamp.yml
# 执行
[root@m01 ~]# ansible-playbook ./lamp/lamp.yml
- 打开浏览器访问:
http://10.0.0.7/wordpress/wp-admin/setup-config.php
http://10.0.0.8/wordpress/wp-admin/setup-config.php
扩展需求:
1.使用php连接数据库
2.使用Ansible创建数据库wordpress
#类似于:
create database wordpress
3.使用Ansible创建数据库用户wordpress
#类似于:
grant all on *.* to wordpress@'%' identified by 'oldboy';