##### Ansible使用环境
- 控制节点
- 安装Ansible软件
- Python环境支持:Python>=2.6
- 必要的模块:如PyYAML等
- 被控节点
- 启用SSH服务
- 允许控制节点登录,通常设置免密登录
- Python环境支持
http://www.ansible.com/
#### 一、环境准备
配置好主机名、IP地址、YUM源。关闭防火墙和SELinux
pubserver挂载rocky镜像
web1添加两块20G硬盘
| 主机名 | IP地址 | 角色 |
| --------- | -------------- | ------------------- |
| pubserver | 192.168.88.240 | 控制节点 |
| web1 | 192.168.88.11 | 被控节点(webserver) |
| web2 | 192.168.88.12 | 被控节点(webserver) |
| db1 | 192.168.88.13 | 被控节点(database) |
#### 二、部署配置、自定义ansible软件YUM源
> 控制节点==服务端
>
> 被控节点==客户端
##### 前置部署(控制节点服务端操作):
安装vsftpd软件并设置开机自启后开启服务,配置网络YUM以及开机自动挂载
刷新网络YUM源,确保通信正常
```shell
yum clean all; yum repoinfo
```
从真机上传ansible相关软件到pubserver主机
```shell
[root@真机 ~]# scp /linux-soft/s2/zzg/ansible_soft/* root@192.168.88.240:/var/ftp/rpms/
```
##### 开始部署:
安装createrepo命令包
```shell
yum -y install createrepo_c
```
创建软件仓库信息
```shell
createrepo /var/ftp/rpms/
```
验证软件仓库下确保有repodata目录
增加自定义YUM源配置,在文件最后追加ansible源
```shell
[ansible-rpms]
name=ansible-rpms
baseurl="ftp://192.168.88.241/rpms"
enabled=1
gpgcheck=0
```
刷新网络YUM源
同步repo文件到所有被控节点
```shell
for i in 192.168.88.1{1..3}
do
scp /etc/yum.repos.d/ftp_Yum.repo root@$i:/etc/yum.repos.d/
done
```
控制节点安装Ansible(服务端)
```shell
yum -y install ansible
```
查看安装版本
```shell
ansible --version
```
配置控制节点的hosts本地主机名解析文件,确保控制节点通过主机名访问到被控节点
```shell
vim /etc/hosts
192.168.88.241 pubserver
192.168.88.11 web1
192.168.88.12 web2
192.168.88.13 db1
```
连接,测试hosts文件配置正确
```shell
for i in pubserver web1 web2 db1
do
ping -c 2 $i
done
```
配置控制节点免密登录被控节点
```shell
ssh-keygen -t rsa -f /root/.ssh/id_rsa -N '' #非交互生成秘钥对
```
发送公钥到被控节点
```shell
for i in web1 web2 db1
do
ssh-copy-id root@$i
done
```
验证免密登录
```shell
for i in web1 web2 db1
do
ssh root@$i "hostname"
done
#结果显示web1,web2,db1
```
##### 被控节点Ansible管理环境配置
- 配置目标
- 使用Ansible软件管理多个环境,如开发环境、测试环境、生产环境
- 多用户使用同一个控制节点管理不同主机
- 每个用户有属于自己的配置环境(工作目录)
- Ansible配置文件查找顺序
- 首先检测ANSIBLE_CONFIG变量定义的配置文件
- 其次检查当前目录下的./ansible.cfg文件
- 再次检查当前用户家目录下的~/ansible.cfg文件
- 最后检查/etc/ansible/ansible.cfg文件
- 控制节点配置
> 创建自定义Ansible工作目录,在root家目录下创建ansible文件夹并进入可以自定义名称,以后关于ansible操作均在此目录下进行
配置ansible工具,在刚创建的工作目录下创建ansible.cfg配置文件和inventory清单列表文件
ansible.cfg配置文件修改内容:
```shell
[defaults] #通用配置
inventory = inventory #主机清单列表文件名
host_key_checking = false #不检查主机秘钥,非交互式ssh连接
```
inventory清单列表文件修改内容:
```shell
[webservers] #定义主机组,名称自定义
web[1:2] #[1:2]表示从1到2
[dbservers]
db1
[cluster:children] #cluster为组名,:children为固定写法,表示为cluster的子组
webservers
dbservers
```
在工作目录下确认配置结果
```shell
ansible all --list-hosts #查看所有被控主机列表
ansible webservers --list-hosts #查看webservers组主机列表
ansible dbservers --list-hosts #查看dbservers组主机列表
ansible cluster --list-hosts #查看cluster组主机列表
```
#### 三、Ansible使用方法及常用模块
##### 使用方法
- ad-hoc临时命令
- 在命令行下使用ansible命令调用Ansible模块,实现被控节点远程管理
- 通常用于查询信息或临时简易操作
- Playbook剧本
- 把管理任务以特定的格式编辑在文件中,通过ansible-playbook命令远程管理被控节点
- 通常用于复杂任务设计及远程执行
ad-hoc命令语法格式:ansible [主机、组列表或IP] [参数]
常用参数
| -m | 要执行的模块,默认为command |
| ---- | ------------------------------------------------------------ |
| -a | 模块的参数 |
| -u | ssh连接的用户名,默认用root,ansible.cfg中可以配置 |
| -f | fork多少进程并发处理,默认为5个 |
| -i | 指定hosts主机清单列表文件路径,默认default=/etc/ansible/hosts |
| -M | 要执行的模块路径,默认为/usr/share/ansible |
| -t | 日志输出目录,日志文件名以主机命名 |
| -k | 使用密码登录远程主机,被控节点未做免密登录时可用 |
eg:ansible all -m ping #ping模块用于测试是否可以SSH远程登录被控节点主机
> 返回结果为绿色的SUCCESS状态信息则为成功
>
> 返回结果为红色的UNREACHABLE则为失败
>
> 需要检测管理节点与被控节点网络和是否可以免密登录
Playbook剧本:略——详情看二阶段/3.Ansible/3_Day02.md
##### 模块简介
- Ansible在使用过程中通过模块来完成指定任务
- Ansible模块的本质是一个文件,通常是为实现具体功能的Python脚本
- Ansible已经有很多开发好的模块,可以直接调用,具备开发能力也可以自行开发
- 多数模块都支持使用参数,需要使用的时候指定参数
- 主要学习已有的常用模块的用途及常用参数
> 在Ansible中,模块的幂等性指的是模块执行操作时,如果目标状态已经符合预期,再次执行相同的操作不会产生任何改变,也就是说,模块的执行结果是可重复的,不会因为多次执行而产生不同的结果。这种特性非常重要,因为它可以确保自动化任务的可靠性,避免不必要的数据更改或资源消耗。
模块查询命令使用方法——ansible-doc
```shell
# 列出目前全部可用Ansible模块,按空格键向下翻页,按q退出返回命令行
ansible-doc -l
# 统计已有模块数量,WARNING信息直接忽略即可
ansible-doc -l | wc -l
7214
# 查看包含yum的模块
ansible-doc -l | grep yum
# 查看指定模块的帮助文档,按空格键向下翻页,按q退出返回命令行
ansible-doc yum
```
相关模块:
command模块
> Ansible的默认模块,用于在被控节点(客户端)执行Linux命令,不支持bash特性,如管道、重定向
```shell
ansible web1 -m command -a "hostname" #获取被控节点主机名
ansible web1 -a "ip a s" #获取被控节点IP地址信息
```
shell模块
> 于在被控节点执行Linux命令,支持bash特性
```shell
# 获取IP信息前两行
ansible web1 -m shell -a "ip a s | head -2"
# 将IP地址信息重定向保存到指定文件
ansible web1 -m shell -a "ip a s > /opt/ip.txt"
# 确认重定向结果
ansible web1 -m shell -a "cat /opt/ip.txt"
```
script模块
> 用于在被控节点执行脚本,不局限于Shell脚本
```shell
ansible webservers -m script -a "test.sh" #执行test.sh脚本
```
-------------------------------------
---------------------
file模块
> 用于在被控节点创建文件、目录、链接文件等,还可以修改权限、归属
>
> 幂等性
```shell
## 常用参数
path:指定文件路径
owner:设置文件所有者
group:设置文件所属组
state:状态
touch表示创建文件
directory表示创建目录
link表示创建软链接
absent表示删除
mode:设置权限
src:source的简写,源
dest:destination的简写,目标
#使用file模块创建文件、目录、软链接,但touch特殊创建同一文件只会刷新时间戳
ansible webservers -m file -a "path=/tmp/file.txt state=touch"
ansible web1 -m shell -a "ls -l /tmp | grep txt"
ansible webservers -m file -a "path=/tmp/demo state=directory"
ansible webservers -m file -a "src=/etc/hosts dest=/tmp/hosts.txt state=link"
#使用file模块修改文件权限和归属
ansible webservers -m file -a "path=/tmp/file.txt owner=sshd group=adm mode=0777"
#使用file模块删除被控节点指定文件、目录、软链接
ansible webservers -m file -a "path=/tmp/file.txt state=absent"
ansible webservers -m file -a "path=/tmp/demo state=absent"
ansible webservers -m file -a "path=/tmp/hosts.txt state=absent"
```
copy模块
> 用于将控制节点指定文件发送被被控节点(服务端上传、客户端下载)
```shell
## 常用参数
src:源。控制端的文件路径
dest:目标。被控制端的文件路径
content:内容。需要写到文件中的内容
为
# 使用copy模块发送控制节点指定文件到被控节点指定目录并重命名(如果dest指定到目录则文件名不变)
ansible webservers -m copy -a "src=test.sh dest=/tmp/adduser.sh"
# 使用copy模块发送指定内容到被控节点并存储在文件中
ansible webservers -m copy -a "content='Hello World' dest=/tmp/mytest.txt"
```
fetch模块
> 用于将被控节点指定文件发送到控制节点(服务端下载、客户端上传)
```shell
## 常用参数
src:源。被控制端的文件路径
dest:目标。控制端的文件路径
flat:不生成目录结构,只保留文件到指定目录
# 使用fetch模块收集被控节点指定文件到控制节点(默认在控制节点生成/dest_path/主机名/src_path/file)
ansible webservers -m fetch -a "src=/etc/hostname dest=~/"
# 使用fetch模块收集被控节点指定文件到控制节点(不生成目录结构,只保留文件到指定目录)
ansible web1 -m fetch -a "src=/etc/hosts dest=~/ flat=yes"
```
lineinfile模块
> 用于确保被控节点指定文件内有指定行。用于在远程主机上的文件中插入、替换或删除行,适用于编辑配置文件、脚本等文本文件,确保某些配置或内容的一致性,如添加环境变量、修改配置项等
```shell
## 常用参数
path:待修改的文件路径
line:写入文件的一行内容
regexp:正则表达式,用于查找文件中的内容
# 确保/etc/issue文件中有Hello World行,如果不存在则追加到文件末尾,存在就不会添加
ansible webservers -m lineinfile -a "path=/etc/issue line='Hello World'"
# 替换/etc/issue文件中最后一个带Hello的整行替换成Hello Linux
ansible webservers -m lineinfile -a "path=/etc/issue regexp='Hello' line='Hello Linux'"
```
replace模块
> 用于关键词匹配替换
```shell
## 常用参数
path:待修改的文件路径
replace:将正则表达式查到的内容,替换成replace的内容
regexp:正则表达式,用于查找文件中的内容
# 替换/etc/issue文件中所有Hello的字符串为Hi
ansible webservers -m replace -a "path=/etc/issue regexp='Hello' replace='Hi'"
```
-----------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------
user模块
> 用于实现Linux用户管理
```shell
## 常用参数
name:待创建的用户名
uid:用户ID
group:设置主组
groups:设置附加组
home:设置家目录
password:设置用户密码
state:状态。present表示创建,它是默认选项。absent表示删除
remove:删除家目录、邮箱等。值为yes或true都可以
# 使用user模块创建用户
ansible webservers -m user -a "name=tom"
# 使用user模块创建用户并设置用户属性,group是属组,groups是附加组
ansible webservers -m user -a "name=jim uid=1010 group=adm groups=daemon,root home=/home/jim"
# {{}}是固定格式,表示执行命令
# password_hash()是函数,sha512是加密算法
ansible webservers -m user -a "name=tom password={{'123456'|password_hash('sha512')}}"
ansible webservers -m user -a "name=tom state=absent"
ansible webservers -m user -a "name=jim state=absent remove=true"
```
group模块
> 用于实现Linux组管理
```shell
## 常用参数
name:待创建的组名
gid:组的ID号
state:present表示创建,它是默认选项。absent表示删除
# 使用group模块创建devops组
ansible webservers -m group -a "name=devops"
# 使用group模块删除devops组
ansible webservers -m group -a "name=devops state=absent"
```