企业级自动化运维工具Ansible

[TOC]

一、介绍

1、自动化运维发展历程

  1. 手动运维阶段

特点:

  • 早期计算机时代:主要依赖运维人员手动管理服务器等。
  • 集中管理和人工操作:系统更新、配置、监控、故障排查等任务全部手动完成。
  • 局限性:效率低下、容易出现人为错误,且无法应对大规模环境。

典型场景:小型数据中心,几台服务器,运维人员使用SSH等手动登录服务器进行操作。

  1. 脚本化运维阶段

特点

  • 自动化初步萌芽:运维人员开始使用Shell、Python、Perl等脚本语言来实现部分重复性任务的自动化,如批量部署、日志收集、监控和报警等。
  • 自定义脚本和工具:企业根据需求编写自定义脚本来简化日常运维工作,减少手动操作。

典型场景:通过Shell脚本实现批量管理、定时任务调度等,减轻重复性工作负担。

  1. 运维工具化阶段

特点:

  • 引入专用运维工具:随着IT基础设施的复杂化,运维工具逐渐普及。常见工具如Puppet、Ansible、SaltStack等开始出现,提供了标准化的自动化运维能力。
  • 集中式管理:通过工具的集中式管理能力,运维人员可以统一管理多台服务器,实现大规模环境下的自动化部署、配置管理和系统更新。

典型应用:使用Puppet进行配置管理,Ansible进行批量操作,SaltStack进行大规模部署。

  1. 容器化和微服务运维阶段

特点:

  • 容器化:随着Docker和Kubernetes等技术的普及,运维自动化进入了容器化时代。基础设施以容器为单位进行管理,运维流程更加简化和标准化。
  • 微服务架构:应用被拆解为独立的微服务,运维需要应对大量的分布式服务,自动化工具集成了容器编排、服务发现、动态伸缩等功能。
  • 持续集成和持续交付(CI/CD):Jenkins、GitLab CI等工具与Kubernetes和Docker相结合,实现了自动化的应用交付和部署。

典型应用:Kubernetes用于容器编排,结合CI/CD流水线实现自动化应用发布和扩展。

2、自动化运维工具对比

  • Puppet:基于 Ruby 开发,采用 C/S 架构,扩展性强,基于SSL,远程命令执行相对较弱;
  • SaltStack:基于 Python 开发,采用 C/S 架构,相对 puppet 更轻量级,配置语法使用YAML,使得配置脚本更简单.需要配置客户端以及服务器端。每台被控制节点需要安装agent;
  • Ansible:基于Python开发,分布式,无需客户端,轻量级,配置语法使用YAML语言,更强的远程命令执行操作。

3、Ansible简介

ansible是自动化运维工具,基于Python开发、分布式、无需客户端、轻量级。实现了批量系统配置、批量程序部署、批量运行命令等功能。

ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。

1
2
3
4
5
6
7
Ansible特性
1)、no agents:不需要在被管控主机上安装任何客户端,更新时,只需在操作机上进行一次更新即可(不用安装客户端。分布式的)
2)、no server:无服务器端,使用时直接运行命令即可
3)、modules in any languages:基于模块工作,可使用任意语言开发模块
4)、yaml,not code:使用yaml语言定制剧本playbook
5)、ssh by default:基于SSH工作
6)、strong multi-tier solution:可实现多级指挥

1567243310363

1
2
3
4
5
connection plugins:连接插件,负责和被监控端实现通信,默认使用SSH连接。
host inventory:主机清单,是一个配置文件里面定义监控的主机。
modules : 模块,核心模块、command模块、自定义模块等。
plugins : modules功能的补充,包括连接插件,邮件插件等。
playbook:编排,定义 Ansible 多任务配置文件,非必需。

二、ansible安装

1. 环境准备

  1. 初始化工作
1
2
3
4
5
6
7
8
9
#>>> 本地解析
$ cat /etc/hosts
192.168.174.20 ansible-server
192.168.174.21 ansible-web01
192.168.174.22 ansible-web02

#>>> 关闭防火墙及selinux
$ systemctl disable --now firewalld && setenforce 0
$ sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
  1. ansible-server生成SSH密钥对
1
2
3
4
5
6
7
8
#>>> 生成密钥
[root@ansible-server ~]# ssh-keygen

#>>> 查看密钥
[root@ansible-server ~]# ll ~/.ssh/
总用量 8
-rw-------. 1 root root 1679 8月 18 13:33 id_rsa
-rw-r--r--. 1 root root 408 8月 18 13:33 id_rsa.pub
  1. ansible-server传递公钥
1
2
#>>> 传递公钥
[root@ansible-server ~]# for i in ansible-web0{1..2};do ssh-copy-id -i $i;done
  1. 安装
1
2
3
4
5
6
7
8
9
10
11
#>>> 配置EPEL网络yum源
[root@ansible-server ~]# curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo

#>>> 安装ansible
[root@ansible-server ~]# yum install -y ansible

#>>> 查看版本
[root@ansiable-server ~]# ansible --version

#>>> 查看帮助
[root@ansible-server ~]# ansible --help

image-20240818144013877

三、Ansible 文件介绍

1、主配置文件

文件位置:

1
/etc/ansible/ansible.cfg

常用文件内容介绍:

1
2
3
4
5
6
7
8
9
10
11
12
13
#inventory      = /etc/ansible/hosts
#library = /usr/share/my_modules/
#module_utils = /usr/share/my_module_utils/
#remote_tmp = ~/.ansible/tmp
#local_tmp = ~/.ansible/tmp
#plugin_filters_cfg = /etc/ansible/plugin_filters.yml
#forks = 5
#poll_interval = 15
#sudo_user = root
#ask_sudo_pass = True
#ask_pass = True
#transport = smart
#remote_port = 22
  1. #inventory = /etc/ansible/hosts
  • 解释: Ansible 的默认主机清单位置。主机清单列出了目标主机的 IP 地址或主机名。
  1. #library = /usr/share/my_modules/
  • 解释:指定 Ansible 自定义模块的库路径。默认情况下,Ansible 使用内置的模块,但通过设置 library,你可以将自己编写的自定义模块放在 /usr/share/my_modules/ 目录中。
  1. #remote_tmp = ~/.ansible/tmp
  • 解释:指定 Ansible 在远程主机上存储临时文件的路径。默认情况下,Ansible 会在远程主机的 ~/.ansible/tmp 目录中创建临时文件和目录。
  1. #local_tmp = ~/.ansible/tmp
  • 解释:指定 Ansible 在本地主机上存储临时文件的路径。Ansible 会在执行任务时在本地生成临时文件,默认路径是 ~/.ansible/tmp
  1. #plugin_filters_cfg = /etc/ansible/plugin_filters.yml
  • 解释:过滤 Ansible 插件的配置文件路径。这个配置文件控制哪些插件可以加载和使用。
  1. #forks = 5
  • 解释:Ansible 并行处理的最大任务数量。
  1. #poll_interval = 15
  • 解释:Ansible 检查后台任务状态的轮询间隔,单位是秒。默认情况下,Ansible 每隔 15 秒检查一次后台运行的任务状态。
  1. #sudo_user = root
  • 解释:远程主机上执行命令时的默认 sudo 用户。这里配置的是 root 用户,意味着 Ansible 在使用 sudo 提权时会尝试以 root 用户身份执行任务。
  1. #ask_sudo_pass = True
  • 解释:Ansible 将在运行任务时提示输入 sudo 密码。这在目标主机配置了需要输入 sudo 密码的情况下使用。
  1. #ask_pass = True
  • 解释:Ansible 将在运行任务时提示输入 SSH 密码。如果目标主机不使用密钥认证而是通过密码登录,可以启用此项。
  1. #transport = smart
  • 解释:Ansible 与目标主机通信时使用的传输方式。默认的 smart 模式会自动选择最佳的传输方式(通常是基于 SSH)。
  1. #remote_port = 22
  • 解释:Ansible 连接到远程主机时使用的默认 SSH 端口。默认值为 22

2、主机清单

文件位置:

1
/etc/ansible/hosts

官方文档: http://docs.ansible.com/ansible/intro_inventory.html#

Inventory文件通常用于定义要管理主机的认证信息,例如ssh登录用户名、密码以及key相关信息。

1
2
3
4
#>>> 查看配置文件
[root@ansible-server ~]# rpm -qc ansible
/etc/ansible/ansible.cfg
/etc/ansible/hosts #ansible主机清单文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#>>>语法:
[root@ansible-server ~]# vim /etc/ansible/hosts
ansible-web1 # 单独指定主机,可以使用主机名称或IP地址

[webservers] # 主机群组自定义
192.168.174.21 # 未做本地解析的主机地址
192.168.174.22 # 未做本地解析的主机地址

[dbservers] # 自定义主机群组
192.168.174.[21:22]

[zabbix] # 自定义主机群组
192.168.174.21:22 # 未做本地解析的主机地址加端口

[redis] # 自定义主机名
ansible-web02 # 经过本地解析的主机名

[servers:children] # 集合多个子群组
zabbix
redis

[webservers01] # 自定义主机群组
ansible-web0[1:2] # 经过本地解析的主机名

# 为一个组指定变量,组内每个主机都可以使用该变量:
[weball:vars] # 设置变量,vars--照写
ansible_ssh_port=2222
ansible_ssh_user=root
ansible_ssh_private_key_file=/root/.ssh/id_rsa
#ansible_ssh_pass=test #也可以定义密码,如果没有互传秘钥可以使用密码。

Ansible Inventory 常见的内置参数:

1567262857205

1
2
3
4
5
6
#>>> 查看组内主机列表:
# 语法:ansible 组名 --list-hosts
[root@ansible-server ~]# ansible webservers --list-host
hosts (2):
192.168.174.21
192.168.174.22

3、测试

Ansible常用命令

1
2
3
4
5
6
7
8
#>>> 列出所有模块
[root@ansible-server ~]# ansible-doc -l

#>>> 查看某个模块帮助用法
[root@ansible-server ~]# ansible-doc ping

#>>> 查看某个模块帮助用法
[root@ansible-server ~]# ansible-doc -s ping
1
2
3
4
5
6
7
8
9
10
11
12
语法:
# ansible <pattern> -m <module_name> -a <arguments>
pattern--主机清单里定义的主机组名、主机名、IP等,all表示所有的主机,支持通配符,正则
-m # 模块名称,默认为command
-a # 传递给模块的参数
-o # 单行显示
-c # 检查,不执行命令
-k # 提示输入ssh连接密码。默认ssh key认证
-v # 详细过程 -vv -vvv更详细

#>>> 示例
[root@ansible-server ~]# ansible webservers -m ping

image-20240818152656146

1
[root@ansible-server ~]# ansible all -m ping -o

image-20240818160505421

使用案例:

1
2
3
4
5
6
7
8
#>>> 指定单台机器:
[root@ansible-server ~]# ansible ansible-web1 -m ping -o

#>>> 同时指定多台机器:
[root@ansible-server ~]# ansible ansible-web1,ansible-web2 -m ping -o

#>>> 指定组名:
[root@ansible-server ~]# ansible webservers1 -m ping -o

4、Ansible执行过程

  1. Ansible 在执行命令之前会加载配置文件(通常位于 /etc/ansible/ansible.cfg)并读取主机清单文件。

  2. Ansible 根据配置文件或命令行参数决定如何连接远程主机。

  3. Ansible 使用模块(module)在远程主机上执行具体任务。Ansible 会将模块发送到远程主机,并通过 Python 解释器或其他指定解释器执行这些模块。但需要注意的是:ansible会将模块或者命令生成对应的临时文件,并将文件通过ssh传输至远程主机的对应执行用户的$HOME/.ansible/tmp/ansible-tmp-随机数字/随机字符串.py文件。并添加执行权限。

  4. 模块执行完成后,Ansible 会收集结果并将其返回到控制节点。每个模块返回的数据为 JSON 格式,Ansible 会将这些数据解析为易读的输出,显示在控制台中。删除临时py文件。并退出。

1
2
3
#>>> 测试
[root@ansible-server ~]# ansible all -m ping -vvv > test.log
[root@ansible-server ~]# grep rm test.log

image-20240818164734639

1
[root@ansible-server ~]# grep rm  test.log

image-20240818164827261

5、Ansible执行颜色分类

  • 绿色:执行成功并且没有改变内容;

  • 黄色:执行成功并且对目标主机做的更改操作;

  • 红色:命令或模块没有执行成功。

6、Ansible中shell模块几乎可以做任何事情,那为什么要有别的那么多模块且写剧本的时候明明可以从头到尾使用shell模块,但是为什么还是要使用别的模块呢?

因为幂等性。在 Ansible 中,幂等性指的是运行相同的剧本或任务多次时,其结果应该是相同的,不会产生副作用或重复更改。也就是说,不论你执行剧本多少次,系统的最终状态都应保持一致,不会改变。

而如果我们从头到尾shell的话,是无法保证幂等性的,有的时候可能一些操作之前已经之前过了,如果使用shell的话他还会再给我们执行一次,回显颜色会为黄色。但是如果我们使用的是其对应功能的模块的话,那么他会检查我们之前是否做过这步操作,如果做过他就不会再执行。回显为绿色。

所以这会对运维人员有些许干扰,因为大部分情况我们会根据回显颜色来判断执行的结果。情况严重的话,有可能会产生一些副作用。

ansible中分模块来干不同的事情有点类似于微服务架构,采用分布式,降低了紧密型(解耦),增加了可维护性。

四、Ansible模块使用

1、command模块(默认)

ansiblecommand 模块是最常用的模块之一,它用于在远程主机上运行命令。与 shell 模块不同的是,command 模块执行命令时不会通过 shell 执行,因此不支持管道、重定向等 shell 特性。

1
[root@ansible-server ~]# ansible webservers -m command -a "uptime"

image-20240818165933947

1
[root@ansible-server ~]# ansible webservers  -a "df -Th"

image-20240818165959247

1
[root@ansible-server ~]# ansible webservers  -a "ls "

image-20240818170134686

2、shell模块

​ Ansible 的 shell 模块用于在远程主机上通过 shell 执行命令。与 command 模块不同的是,shell 模块允许你使用所有的 shell 特性,例如管道、重定向、变量扩展等。

1
[root@ansible-server ~]# ansible webservers  -m shell  -a "df -Th | grep root"

image-20240818170522034

3、USER模块

user 模块用于在远程主机上管理用户账户。它能够创建、删除、修改用户以及设置用户的权限、组和密码等。

1
2
3
4
5
#>>> 创建用户
[root@ansible-server ~]# ansible webservers -m user -a "name=maoxiansheng state=present" -o

name # 用户名
state # 创建

image-20240818171306121

1
2
3
4
5
6
#>>> 删除用户
[root@ansible-server ~]# ansible webservers -m user -a "name=maoxiansheng state=absent remove=yes" -o

name # 用户名
state # 删除操作
remove # 慎用!删除用户时,除了删除用户本身,还会删除该用户的相关资源(如用户的家目录及相关文件)。默认情况下,这个选项是 no,即只删除用户而不删除其文件。

image-20240818171430115

1
2
3
4
5
6
7
#>>> 创建用户并设置Shell和主目录
[root@ansible-server ~]# ansible webservers -m user -a "user=mingge home=/home/mingge state=present shell=/bin/bash" -o

name # 用户名
state # 创建
shell # 指定所创建用户shell
home # 指定所创建用户家目录

image-20240818171717360

1
2
3
4
5
6
#>>> 添加用户到指定组
[root@ansible-server ~]# ansible webservers -m user -a "name=feige groups=mingge append=yes password='123'" -o

name # 用户名
groups # 加入指定组
append # 不会删除他已经属于的其他组。即追加到该组,而不是替换原来的组。

image-20240818172331003

4、yum模块

yum 模块用于主要通过 yum 包管理器进行安装、升级、删除和管理仓库。它是处理软件包的一个常见模块,适用于基于 yum 包管理器的 Linux 发行版。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#>>> 安装服务
[root@ansible-server ~]# ansible webservers -m yum -a "name=nginx state=present"

#>>> 删除服务
[root@ansible-server ~]# ansible webservers -m yum -a "name=nginx state=removed"
# 或者
[root@ansible-server ~]# ansible webservers -m yum -a "name=nginx state=absent"

#>>> 升级软件包到最新版本
[root@ansible-server ~]# ansible webservers -m yum -a "name=nginx state=latest"

#>>> 安装指定版本
[root@ansible-server ~]# ansible webservers -m yum -a "name=nginx-1.24.0 state=present"

#>>> 安装多个软件包
[root@ansible-server ~]# ansible webservers -m yum -a "name=git,vim state=present"

5、service模块

service 模块用于管理系统服务,例如启动、停止、重启服务或确保服务处于特定状态。

1
2
3
4
5
6
7
8
9
10
11
#>>> 启动服务
[root@ansible-server ~]# ansible webservers -m service -a "name=nginx state=started"

#>>> 停止服务
[root@ansible-server ~]# ansible webservers -m service -a "name=nginx state=stopped"

#>>> 重启服务
[root@ansible-server ~]# ansible webservers -m service -a "name=nginx state=restarted"

#>>> 启动服务并加入开机自启
[root@ansible-server ~]# ansible webservers -m service -a "name=nginx state=started enabled=yes"

6、file模块

file 模块用于管理文件、目录和符号链接的属性,包括创建、删除、修改权限等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#>>> 创建目录
[root@ansible-server ~]# ansible webservers -m file -a "path=/tmp/mingge state=directory" -o

#>>> 创建文件
[root@ansible-server ~]# ansible webservers -m file -a "path=/tmp/mingge/1.txt state=touch" -o

#>>> 删除目录或者文件
[root@ansible-server ~]# ansible webservers -m file -a "path=/tmp/mingge/1.txt state=absent" -o

#>>> 修改文件权限
[root@ansible-server ~]# ansible webservers -m file -a "path=/tmp/mingge mode=0777" -o

#>>> 修改文件属主和属组
[root@ansible-server ~]# ansible webservers -m file -a "path=/tmp/mingge/ owner=mingge group=mingge" -o

#>>> 创建文件并设置权限
[root@ansible-server ~]# ansible webservers -m file -a "path=/tmp/2.txt state=touch mode=0777 owner=mingge group=mingge" -o

#>>> 创建符号链接
[root@ansible-server ~]# ansible webservers -m file -a "src=/tmp/2.txt dest=/root/2.txt state=link" -o

7、copy模块

copy 模块用于从控制节点将文件或目录复制到目标主机。

常见选项:

  • src:源文件或目录的路径。
  • dest:目标路径。
  • backup:是否在目标上备份现有文件(值为 yes 时备份)。
  • force:是否强制覆盖目标文件(默认为 yes)。
  • mode:设置目标文件或目录的权限(如 0644)。
1
2
3
4
5
#>>> 复制单个文件到远程主机
[root@ansible-server ~]# ansible webservers -m copy -a "src=/etc/hosts dest=/etc/ force=yes" -o

#>>> 复制目录到远程主机
[root@ansible-server ~]# ansible webservers -m copy -a "src=/root/ops dest=/root/ force=yes" -o

注意:如果需要拷贝的目录为空,则无法拷贝至目标主机。

1
2
3
4
5
6
7
8
#>>> 复制文件并修改权限
[root@ansible-server ~]# ansible webservers -m copy -a "src=/root/test dest=/root/test01 mode=0777" -o

#>>> 复制文件并备份现有文件
[root@ansible-server ~]# ansible webservers -m copy -a "src=/root/test dest=/root/test01 backup=yes" -o

#>>> 不覆盖已有文件
[root@ansible-server ~]# ansible webservers -m copy -a "src=/root/test dest=/root/test01 force=no" -o

注意:不覆盖文件代表含义就是。但是需要拷贝的文件在目标主机的路径下存在。则不执行copy

1
2
3
4
5
#>>> 利用字符串生成新文件
[root@ansible-server ~]# ansible webservers -m copy -a "content='name mingge\nage 18\n' dest=/tmp/test.txt" -o

#>>> 查看文件内容
[root@ansible-server ~]# ansible webservers -m shell -a "cat /tmp/test.txt" -o

image-20240818212923301

8、Script模块

script 模块用于在目标主机上执行本地脚本。但需要注意的是script 模块只是在远程主机上执行ansible本地脚本,因此需要确保脚本是可以在远程主机的环境中正确执行的。执行脚本的路径必须是相对于控制节点的路径,而不是远程主机的路径。

1
2
3
4
5
6
7
8
9
10
#>>> 编写测试脚本
cat >> echo.sh <<-EOF
#!/bin/bash
echo "hello.world"
sleep 10
touch test01.txt
EOF

#>>> 执行脚本
[root@ansible-server ~]# ansible webservers -m script -a "./echo.sh" -o

9、archive模块

archive 模块用于在目标主机上创建压缩文件(归档文件)到目标主机的指定目录。它可以将文件或目录打包成 tar、zip 或其他格式。

1
2
3
4
5
#>>> 压缩目录
[root@ansible-server ~]# ansible webservers -m archive -a "path=/root dest=./root.zip format=zip" -o

#>>> 压缩多个目录或文件
[root@ansible-server ~]# ansible webservers -m archive -a "path=/root,/opt,/tmp/test10.txt dest=/tar/lastest.tar.gz" -o

10、unarchive模块

unarchive 模块用于在目标主机上解压存档文件(如 .tar, .zip 等)。也可以将控制主机的压缩包拷贝至目标主机解压或远程的压缩文件,并将其解压到指定的目录中。

1
2
3
4
5
#>>> 将当前主机的压缩包拷贝目标主机并解压,并且修改相关权限
[root@ansible-server ~]# ansible webservers -m unarchive -a 'src=./nginx-1.24.0.tar.gz dest=/usr/local/ owner=root group=root mode=0755' -o

#>>> 查看
[root@ansible-server ~]# ansible webservers -m shell -a "ls -l /usr/local/ | grep nginx"

image-20240818215951506

1
2
3
4
#>>> 将目标主机压缩包解压到指定目录
[root@ansible-server ~]# ansible webservers -m copy -a "src=./nginx-1.24.0.tar.gz dest=/root" -o

[root@ansible-server ~]# ansible webservers -m unarchive -a 'src=/root/nginx-1.24.0.tar.gz dest=/usr/local/ owner=root group=root mode=0755 copy=no' -o

image-20240818220503783

1
2
3
4
5
#>>> 从远程连接下载安装包,并解压到指定目录
[root@ansible-server ~]# ansible webservers -m unarchive -a "src=https://nginx.org/download/nginx-1.27.1.tar.gz dest=/opt owner=root group=root mode=0755 copy=no" -o

#>>> 查看
[root@ansible-server ~]# ansible webservers -m shell -a "ls -l /opt | grep nginx"

image-20240818221117597

11、Fetch模块

fetch 模块用于从远程主机复制文件到本地主机。该模块的主要用途是从目标机器获取文件(如日志、配置文件等)并存储在控制节点的指定位置。目前还没有远程拷贝目录到控制主机的功能。未来可能会实现!记住是可能哟。嘿嘿!

1
2
3
4
5
6
7
8
9
10
11
12
#>>> 将目标主机文件拷贝到当前主机目录下
[root@ansible-server ~]# ansible webservers -m fetch -a "src=/etc/redhat-release dest=/tmp" -o

#>>> 查看本地目录
[root@ansible-server ~]# tree /tmp/
/tmp/
├── 192.168.174.21
│   └── etc
│   └── redhat-release
├── 192.168.174.22
│   └── etc
│   └── redhat-release

12、Hostname模块

hostname 模块用于在远程主机上设置或获取主机名。无法通过命令行设置多个主机名。否则会出现冲突。

1
2
3
4
5
#>>> 修改单个主机的主机名
[root@ansible-server ~]# ansible 192.168.174.21 -m hostname -a "name=web01" -o

#>>> 测试
[root@ansible-server ~]# ansible 192.168.174.21 -m shell -a "hostname"

image-20240818221715339

13、Cron模块

cron 模块用于管理远程主机上的计划任务(cron jobs),可以添加、删除或修改已有的任务。

1
2
3
4
5
#>>> 创建计划任务:周一至周五每天凌晨2点20备份数据库
[root@ansible-server ~]# ansible 192.168.174.22 -m cron -a 'hour=2 minute=20 weekday=1-5 name="backup data mysql" job=/root/mysql_backup.sh'

#>>> 查看
[root@ansible-server ~]# ansible 192.168.174.22 -m shell -a "crontab -l"

image-20240818222648449

1
2
3
4
5
6
7
#>>> 禁用计划任务
[root@ansible-server ~]# ansible 192.168.174.22 -m cron -a 'hour=2 minute=20 weekday=1-5 name="backup data mysql" job=/root/mysql_backup.sh disabled=yes'

# disabled=yes 禁用计划任务

#>>> 查看
[root@ansible-server ~]# ansible 192.168.174.22 -m shell -a "crontab -l"

image-20240818223011478

1
2
3
4
5
#>>> 启动计划任务
[root@ansible-server ~]# ansible 192.168.174.22 -m cron -a 'hour=2 minute=20 weekday=1-5 name="backup data mysql" job=/root/mysql_backup.sh disabled=no'

#>>> 查看
[root@ansible-server ~]# ansible 192.168.174.22 -m shell -a "crontab -l"

image-20240818223116065

1
2
3
4
5
6
7
#>>> 删除计划任务
[root@ansible-server ~]# ansible 192.168.174.22 -m cron -a "name='backup data mysql' state=absent" -o

# state=absent 删除计划任务

#>>> 查看
[root@ansible-server ~]# ansible 192.168.174.22 -m shell -a "crontab -l"

image-20240818223258724

14、Setup模块

setup 模块用于从远程主机收集“事实”,即主机的硬件、网络和操作系统相关的信息。setup 模块会收集诸如 IP 地址、操作系统类型、磁盘空间、内存、环境变量等信息,默认情况下,Ansible 在执行任务时会自动收集这些信息,但也可以通过显式调用 setup 模块来手动收集。

1
2
#>>> 查看主机内核版本
[root@ansible-server ~]# ansible webservers -m setup -a "filter=ansible_kernel"

image-20240818224336209

1
2
#>>> 查看主机ipv4相关信息
[root@ansible-server ~]# ansible webservers -m setup -a "filter=ansible_default_ipv4"

image-20240818224520882

1
2
#>>> 查看内存的总大小
[root@ansible-server ~]# ansible webservers -m setup -a 'filter=ansible_memtotal_mb'

image-20240818224701311

五、ansible-playbook 剧本

1、介绍

playbook是ansible用于配置,部署,和管理被控节点的剧本。通过playbook的详细描述,执行其中的tasks,可以让远端主机达到预期的状态。playbook是由一个或多个”play”组成的列表。 当对一台机器做环境初始化的时候往往需要不止做一件事情,这时使用playbook会更加适合。通过playbook你可以一次在多台机器执行多个指令。通过这种预先设计的配置保持了机器的配置统一,并很简单的执行日常任务。

​ ansible通过不同的模块实现相应的管理,管理的方式通过定义的清单文件(hosts)所管理的主机包括认证的方式连接的端口等。所有的功能都是通过调用不同的模块(modules)来完成不同的功能的。不管是执行单条命令还是play-book都是基于清单文件。

2、playbook格式

playbook由yaml语言编写。YMAL格式是类似于JSON的文件格式,便于人理解和阅读,同时便于书写。 驼峰式

一个剧本里面可以有多个play,每个play只能有一个tasks,每个tasks可以有多个name

1
2
3
4
5
Variables     	# 变量元素,可传递给Tasks/Templates使用;  
Tasks # 任务元素,由模块定义的操作的列表,即调用模块完成任务;
Templates # 模板元素,使用了模板语法的文本文件;
Handlers # 处理器元素,通常指在某事件满足时触发的操作;
Roles # 角色元素

playbook的基础组件:

1
2
3
4
5
6
7
tasks:
- name: 拷贝nginx安装包
copy: src=/opt/nginx-1.24.0.tar.gz dest=/tmp
- name: 解压安装包
unarchive: src=/tmp/nginx-1.24.0.tar.gz dest=/usr/local copy=no
- name: 创建启动用户
user: name=nginx shell=/sbin/nologin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
name: 
定义playbook或者task的名称(描述信息),每一个play都可以完成一个任务。

hosts:
hosts用于指定要执行指定任务的主机。

user:
remote_user则用于指定远程主机上的执行任务的用户

tasks:
任务列表play的主体部分是task list. task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。

vars:
定义变量(如果不使用内部变量需要提前定义)

vars_files:
调用定义变量文件

notify:
任务执行结果如果是发生更改了的则触发定义在handler的任务执行

handlers:
用于当前关注的资源发生变化时采取一定指定的操作

1、hosts

hosts 组件定义了任务要运行在哪些主机或主机组上。hosts 是 Playbook 的核心部分之一,因为它决定了将这些任务分发到哪些远程主机执行。

  1. 语法格式
1
2
3
4
5
---
- hosts: <目标主机或主机组>
tasks:
- name: 示例任务
command: echo "Hello World"
  1. 常见用法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#>>> 指定单个主机
- hosts: server01

#>>> 指定主机组
- hosts: webservers

#>>> 指定IP地址
- hosts: 192.168.174.22

#>>> 指定所有主机
- hosts: all

#>>> 排除特定主机:将在所有主机上运行,除了dbservers组中的主机。
- hosts: all:!dbservers

#>>> 模式匹配:只选择既属于 webservers 组又属于dbservers组的主机。
- hosts: webservers:&dbservers

2、tasks

tasks 组件用于定义一系列将被执行的操作。每个 tasks 列表中的任务都描述了一项操作(如安装软件、修改文件、管理服务等),并且它们是按顺序执行的。

1
2
3
4
5
6
7
8
9
---
- name: test ploybook
hosts: webservers
tasks:
- name: 安装 nginx
yum: name=nginx state=present

- name: 启动并启用 nginx 服务
service: name=nginx state=started enabled=yes

3、示例

1. 安装nginx服务,并且发布服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#>>> 切换目录
[root@ansible-server ~]# cd /opt/playbook/

#>>> 编写playbook文件
[root@ansible-server playbook]# vim nginx-install.yaml
---
- hosts: webservers
remote_user: root
tasks:
- name: 安装nginx
yum: name=nginx-1.24.0 state=present
- name: 拷贝发布文件
copy: src=/tmp/index.html dest=/usr/share/nginx/html/
- name: 启动nginx
service: name=nginx state=started enabled=yes

#>>> 测试是否能够正常执行
[root@ansible-server playbook]# ansible-playbook -C nginx-install.yaml

image-20240819203043504

具体字段的含义如下:

  • 192.168.174.21: 目标主机的 IP 地址。
  • ok=4: 有 4 个任务成功执行,没有发生错误。
  • changed=0: 表示没有任何任务更改了目标主机的状态(例如安装软件、修改文件等)。
  • unreachable=0: 表示目标主机是可达的(网络正常),没有主机是不可达的。
  • failed=0: 表示没有任务失败,所有任务都成功完成。
  • skipped=0: 表示没有任务被跳过。
  • rescued=0: 表示没有任务进入救援模式(通常在任务失败时触发)。
  • ignored=0: 表示没有被忽略的任务(例如使用 ignore_errors: yes 忽略的任务)。

2. vars变量引用

vars 用于定义在任务中可以被引用的变量。可以通过两种方式引用变量:使用 或直接通过关键字引用。

1
2
3
4
5
6
7
8
9
10
11
---
- hosts: webservers
remote_user: root

vars:
nginx_version: "1.24.0"
copy_dir: "/tmp"

tasks:
- name: 拷贝安装包到目标主机并解压
unarchive: src=/root/nginx-{{ nginx_version }}.tar.gz dest={{ copy_dir }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
实例二:
[root@ansible-server ~]# cd /etc/ansible/
[root@ansible-server ansible]# vim test.yml #创建文件必须以.yml/.yaml结尾
---
- hosts: webservers1
user: root
tasks:
- name: playbook_test
file: state=touch path=/tmp/playbook.txt
========================================================================
# 参数解释:
hosts: 参数指定了对哪些主机进行操作;
user: 参数指定了使用什么用户登录远程主机操作;
tasks: 指定了一个任务.
name:参数同样是对任务的描述,在执行过程中会打印出来。

1567316641470

1
2
3
4
5
#>>> 检测语法:
[root@ansible-server ansible]# ansible-playbook -C test.yml

#>>> 运行Playbook
[root@ansible-server ansible]# ansible-playbook test.yml #加剧本名称

3. handlers和notify引用

handlers(处理器)和 notify(触发器)用于在某些任务状态发生变化时自动执行特定操作。handlers 只有在被 notify 触发时才会执行,而 notify 会在任务状态为 changed 时触发处理器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
---
- hosts: webservers
remote_user: root

tasks:
- name: Install Nginx
yum:
name: nginx
state: present

- name: Configure Nginx
copy: src=/tmp/default.conf dest=/etc/nginx/conf.d/default.conf backup=yes
notify:
- Restart Nginx

- name: Start Nginx service
service: name=nginx state=started enabled=yes

handlers:
- name: Restart Nginx
service: name=nginx state=restarted

4. item和loop引用

item 通常用于在循环(loop)中遍历列表或字典。它允许任务在多次迭代中使用不同的值。最常见的用法是通过 loop 模块来执行相同的操作多次,但使用不同的参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- hosts: webservers2
remote_user: root
tasks:
- name: install packages
yum: name={{ item }} state=latest #相当于for循环里面的i
loop: #取值 。但是不支持通配符
- httpd
- php
- php-mysql
- php-mbstring
- php-gd

# 或者
- hosts: webservers2
remote_user: root
tasks:
- name: install packages
yum: name={{ item }} state=latest #相当于for循环里面的i
with_items: #取值 。但是不支持通配符
- httpd
- php
- php-mysql
- php-mbstring
- php-gd

with_itemsloop 类似,但 loop 是 Ansible 2.5 及更高版本的推荐使用方法。

5. when判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
- hosts: webservers
remote_user: root
tasks:
- name: Install lrzsz yum
yum:
name: vim-enhanced
state: installed
when: ansible_os_family =="RedHat"

- name: Install lrzsz apt
apt:
name: vim
state: installed
when: ansible_os_family =="Debian"

6. vars_files 变量文件