网站集群批量管理-Ansible-进阶
1. 流程控制
1.1 handlers触发器
应用场景:
1. 一般用于分发配置文件的时候
2. 如果配置文件发生变化则重启服务,如果没有变化则重启
3. 注意事项: handlers放在剧本的最后,否则都会被识别为handlers
没有使用触发器handlers
- hosts: all
tasks:
- name: 分发文件
copy:
src: /etc/exports
dest: /etc/exports
backup: yes
- name: 重启服务
systemd:
name: nfs
state: reloaded
我们发现无论/etc/exports的配置文件内容有没有改变,服务都会重启,这和我们的预期的不一样,我们只希望当配置文件改变时服务重启,配置文件没有改变的时候服务不重启,所以我们使用触发器来完成这个需求
使用触发器handlers
- hosts: all
tasks:
- name: 分发文件
copy:
src: /etc/exports
dest: /etc/exports
backup: yes
notify:
- 重启服务(这里的名字要对应下面触发器里的名字)
handlers:
- name: 重启服务
systemd:
name: nfs
state: reloaded
配置文件未改变则不触发"重启服务" 任务 配置文件发生变化,触发"重启服务"任务
配置文件发生变化,触发"重启服务"任务
1.2 when判断
应用场景:
1. 用于给ans运行的task(模块)设置条件,满足或不满足条件在运行对应的模块
2. when进行判断,一般与变量一起使用
3. when条件一般与facts变量或register变量一起使用
只想在nfs上执行安装软件的操作(debug msg)
- hosts: all
tasks:
- name: 只有nfs上输出信息
debug:
msg: "这是nfs01,正在安装软件"
when: ansible_hostname == "nfs01_xing"
如果系统是centos则 安装sl,cowsay,如果是ubuntu 则安装cmatrix
- hosts: all
tasks:
- name: 在CentOS上安装sl,cowsay
yum:
name: sl,cowsay
state: present
when: ansible_distribution == "CentOS"
- name: 在ubuntu上安装cmatrix
apt:
name: cratrix,lolcat
state: present
when: ansible_distribution == "Ubuntu"
1.3 循环
批量创建文件,批量添加用户,批量启动或重启服务
批量启动服务 rpcbind 然后nfs服务
- hosts: all
tasks:
- name: 重启服务
systemd:
name: "{{ item }}"
state: restarted
loop:
- rpcbind
- nfs
##loop和with_items用法一致
批量添加用户
#oldboy666 2020
#xzb666 2021
#xzb999 2022
- hosts: all
tasks:
- name: add user
user:
name: "{{ item.name }}"
uid: "{{ item.uid }}"
loop:
- {name: 'oldboy666',uid: 2020}
- {name: 'xzb666',uid: 2021}
- {name: 'xzb999',uid: 2022}
2. 剧本调试
2.1 检查语法与单步执行
1. -C 批量 的操作,用户,目录,复制. check 模拟运行,不作出改变,一些变量可能会提示报错,因为-C没有真正运行剧本
2. --syntax-check 只做语法检查,不运行
3. --step 单步运行. y执行这个task,n忽略这个task,c自动运行
2.2 tag标签
1. tag标签类似于超市物品的分类,只不过tag标签是给ansible中的task进行分类,加上标记
2. 运行剧本的时候:
-t 运行的标签,如果多个标签通过","分割
--skip-tags 排除指定的tags,如果多个标签通过","分割
- hosts: backup
tasks:
- name: 01 在backup上部署nfs,rpcbind服务端
yum:
name: nfs-utils,rpcbind
state: present
tags:
- 01.install
- name: 02 修改配置文件
lineinfile:
path: /etc/exports
line: "backup-nfs 172.16.1.0/24(rw,all_squash)"
create: true
tags:
- 02.conf
- name: 03 创建共享目录并修改所有者
file:
path: backup-nfs
owner: nfsnobody
group: nfsnobody
state: directory
tags:
- 03.dir
- name: 04-1 启动服务(注意顺序)
systemd:
name: rpcbind
enabled: yes
state: started
loop:
- rpcbind
- nfs
tags:
- 04.start_srv
- hosts: nfs
tasks:
- name: 01 部署nfs-utils
yum:
name: nfs-utils
state: present
- name: 02 挂载
mount:
src: 172.16.1.41:/backup-nfs
path: /ans-upload
fstype: nfs
state: mounted
#--list-tags显示剧本中所有的tags标签
ansible-playbook -i hosts --list-tags -C 16-tages.yml
#通过-t运行指定的tag标签,多个标签通过,分割
ansible-playbook -i hosts -t 04.start_srv -C 16-tages.yml
2.3 忽略错误
运行剧本的时候,因为重复运行导致的错误提示,并发是真的错误. 比如:目录已经存在,用户已经存在. 在这种情况下,我们可以通过ignore_errors忽略错误,让剧本可以继续运行
ignore_errors: true
3. Jinja2模板
应用场景:
1.进行分发配置文件或文件的时候,需要在文件中使用变量,需要使用jinja2文件 nginx.conf.j2,需要使用template模块进行分发
2. 进行判断
3. 进行循环
3.1 基本使用
分发motd文件,motd文件中包含ans变量(目标文件是/etc/motd)
- hosts: all
tasks:
- name: 用template分发motd文件
template:
src: /templates/motd.j2
dest: /etc/motd
backup: yes
- name: 用copy发motd文件
copy:
src: /templates/motd.j2
dest: /tmp/motd
backup: yes
4. include文件包含
应用场景:
1. 1个ansible剧本内容过多,涉及到多个play(- host:web),可读性变弱,不方便调试
2. 多个小的剧本可以通过include功能合并使用
我们先想好部署nfs服务的部署步骤
##这是写在一个文件中
- hosts: web01
tasks:
- name: 01 安装服务
yum:
name: nfs-utils
state: present
- name: 02 修改配置文件
lineinfile:
path: /etc/exports
line: nfsdata 172.16.1.7(rw)
create: true
- name: 03 创建目录
file:
path: nfsdata
owner: nfsnobody
group: nfsnobody
state: directory
- name: 04 重启服务01
systemd:
name: rpcbind
enabled: yes
- name: 04 重启服务02
systemd:
name: nfs
enabled: yes
- hosts: nfs
tasks:
- name: 01 客户端安装服务
yum:
name: nfs-utils
state: present
- name: 02 创建挂载目录
file:
path: /upload
state: directory
- name: 03 挂载
mount:
src: 172.16.1.7:/nfsdata
path: /upload
fstype: nfs
state: mounted
##下面是我们用include文件将web01和nfs分开
##1.创建nfs服务端文件
vim 18-include-nfs-server.yml
- name: 01 安装服务
yum:
name: nfs-utils
state: present
- name: 02 修改配置文件
lineinfile:
path: /etc/exports
line: nfsdata 172.16.1.7(rw)
create: true
- name: 03 创建目录
file:
path: nfsdata
owner: nfsnobody
group: nfsnobody
state: directory
- name: 04 重启服务01
systemd:
name: rpcbind
enabled: yes
- name: 04 重启服务02
systemd:
name: nfs
enabled: yes
##2.创建nfs客户端文件
vim 19-include-nfs-client.yml
- name: 01 客户端安装服务
yum:
name: nfs-utils
state: present
- name: 02 创建挂载目录
file:
path: /upload
state: directory
- name: 03 挂载
mount:
src: 172.16.1.7:/nfsdata
path: /upload
fstype: nfs
state: mounted
##3.使用include_tasks使用两个文件
cat 20-include-nfs-all.yml
- hosts: web01
tasks:
- include_tasks: 18-include-nfs-server.yml
- hosts: nfs
tasks:
- include_tasks: 19-include-nfs-client.yml
5. Roles
1. 通过使用include_tasks功能,大型剧本,缩小体积,变的更加模块化
2. 我们发现新的问题,handlers,变量文件,发送配置文件(可能是j2文件)存放比较混乱
3. 于是人们发明了一套规范,这个规范是一套剧本目录结构的要求与标准,让我们书写剧本的时候,把剧本的内容和需要的文件,按照目录要求, 分门别类存储
4. 这套规则一般叫roles规则,roles的本质就是规定了1套目录结构,用于书写剧本的
roles官网: Roles — Ansible Community Documentation
5.1 roles方式部署nfs-server端
环境准备:
##1.编写tasks/main.yml部分
- name: 01 安装服务
yum:
name: nfs-utils,rpcbind
state: present
tags:
- 01-install-nfs
- name: 02 修改配置文件
copy:
src: exports
dest: /etc/exports
backup: yes
tags:
- 02-conf
notify:
- restart nfs server
- name: 03 创建共享目录
file:
path: /backup-nfs
owner: nfsnobody
group: nfsnobody
state: directory
tags:
- 03-mkdir
- name: 04 重启服务rpc,nfs
systemd:
name: "{{item}}"
enabled: yes
loop:
- rpcbind
- nfs
tags:
- 04-start-service
- name: 05 分发motd
template:
src: motd.j2
dest: /ect/motd
backup: yes
tags:
- 05-motd
##2. 编写files/exports部分
/backup-nfs/ 172.16.1.0/24(rw,all_squash)
##3. 编写templates/motd.js部分
#######################################
welcome to oldboy elastic linux system
操作需谨慎,删根弹指间.
主机名: {{ ansible_hostname }}
ip地址: {{ ansible_default_ipv4.address }}
内存大小: {{ ansible_memtotal_mb }}
CPU数量: {{ ansible_processor_vcpus }}
核心总数: {{ ansible_processor_cores }}
发行版本: {{ ansible_distribution }}
##4. 编写/handlers/main.yml部分
- name: restart nfs server
systemd:
name: nfs
state: reloaded
5.2 加入变量
1.路径
2.用户
3. uid
3. gid
4.域名/端口
##1. 在group_vars/all/main.yml中加入变量
nfs_share_dir: /backup-v3/
nfs_user: nfsnobody
nfs_user_id: 65534
6. 安全优化
6.1 Vault
应用场景:
1.加密指定的文件: ansible-vault用于加密敏感信息
2.hosts文件 加密
3.变量文件 加密
## 1.对hosts进行加密
ansible-vault encrypt hosts
#New Vault password: 1
#Confirm New Vault password: 1
#Encryption successful
## 2.进行使用
ansible/ansible-playbook --ask-vault-pass -i hosts -C 05-playbook-yml
## 3.彻底解密
ansible-vault decrypt hosts
6.2 优化
性能:
1. ssh连接速度优化,关闭UseDNS,GSSAPIAuthcation
2. 不要让ansible运行交互式的命令,非要用使用命令的非交互模式
3. 需要使用ans,yum安装软件,可以自建本地yum仓库,然后ans安装
4. 调整ansible并发数量( -f 调整并发数量 默认是5 ansible.cfg forks=5,实际调整根据负载情况.)
5. 关闭gather_facts,如果不用facts变量可以关闭,
配置sudo:
##管理端:
egrep -v '^$|#'/etc/ansible/ansible.cfg
sudo_user = ans 被管理端上具有sudo权限的用户
nopasswd: ALL
remote_user = ans 被管理端使用的用户,不指定默认是当前用户/root
remote_port = 22 被管理端ssh端口号
host_key_checking = False
log_path = /var/log/ansible.log
[inventory]
[privilege_escalation]
become=True 开启sudo功能
become_method=sudo 使用sudo命令
become_user=root 普通用户切换为root
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]
##被管理端
ans ALL=(ALL) NOPASSWD: ALL` 密码是1,ssh端口是 22
##重新分发密钥给ans普通用户
ssh-copy-id ans@10.0.0.7
##测试
ansible -i hosts web -m ping