DevOps自动化运维实践_ansible-playbook的使用

DevOps自动化运维实践_命令行模式使用Ansiblehttps://blog.csdn.net/xiaochenXIHUA/article/details/159720420

一、ansible-playbook的简介

1.1、ansible-playbook的介绍

playbook字面意思(剧本),现实中由演员按照剧本表演,在Ansible中,这次由计算机进行表演,由计算机安装,部署应用,提供对外服务,以及组织计算机处理各种各样的事情。

1.2、为什么需要使用ansible-playbook

执行一些简单的任务,使用命令行模式可以方便的解决问题,但是有时一个设施过于复杂,需要大量的操作时候,执行命令行模式是不适合的,这时最好使用playbook,就像执行shell命令与写shell脚本一样,也可以理解为批处理任务,不过playbook有自己的语法格式。

1.3、ansible-playbook文件的格式

ansible-playbook文件由YAML语言编写。 YAML是一个类似 XML、JSON的标记性语言,YAML强调以数据为中心,并不是以标识语言为重点。因而YAML本身的定义比较简单,号称"一种人性化的数据格式语言"。首先学习了解一下YAML的格式,对后面书写playbook很有帮助。以下为playbook常用到的YAML格式:

序号 yaml常用格式说明
1 大小写敏感
2 使用空格作为嵌套缩进工具,缩进时不允许使用Tab键
3 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
4 使用"-"(横线) + 单个空格:表示单个列表项
5 使用 ":"(冒号) + 空格:表示单个键值对
6 使用"{}"表示一个键值表

playbook文件是通过【ansible-playbook】命令进行解析的,ansbile-playbook命令会根据自上而下的顺序依次执行playbook文件中的内容。同时,playbook开创了很多特性,它可以允许传输某个命令的状态到后面的指令,它也可以从一台机器的文件中抓取内容并附为变量,然后在另一台机器中使用,这使得playbook可以实现一些复杂的部署机制,这是ansible命令无法实现的。

bash 复制代码
---- #文档开始
- 前言
- 目录

# 客户订单
date: 2026-04-06
customer:
  - name: ck
items:
  - no: 20260406CP6534
  - desc: cpu
bash 复制代码
# Playbook文件格式
- apple
- banana
- Orange
      service: name=httpd state=restarted

# 等价于如下的json格式
[
 "apple",
 "banana",
 "orange"
]

二、playbook的构成

​ **playbook是由一个或多个"play"组成的列表。**play的主要功能在于,将事先合并为一组的主机装扮成事先通过ansible定义好的角色。将多个play组织在一个playbook中就可以让它们联同起来按事先编排的机制完成一系列复杂的任务。

playbook的构成部分 说明
target部分 定义将要执行 playbook 的远程主机组
variable部分 定义playbook运行时需要使用的变量
task部分 定义将要在远程主机上执行的任务列表
handler部分 定义task 执行完成以后需要调用的任务

2.1、Hosts和Users

playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。

playbook选项 说明
hosts 用于指定要执行指定任务的主机,每个playbook都必须指定hosts,hosts也可以使用通配符格式。主机或主机组在inventory清单中指定,可以使用系统默认的【/etc/ansible/hosts】,也可以自己编辑,在运行的时候加上-i选项,可指定自定义主机清单的位置。在运行清单文件的时候,--list-hosts选项会显示那些主机将会参与执行任务的过程中。
remote_user 用于指定在远程主机上执行任务的用户。可以指定任意用户,也可以使用sudo,但是用户必须要有执行相应任务的权限。

2.2、任务列表(tasks list)

play的主体部分是task list。

内容 说明
任务执行 task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。在运行自上而下某playbook时,如果中途发生错误,则所有已执行任务都将回滚,因此在更正playbook后需要重新执行一次。
执行幂等性 task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的(幂等性; 即一个命令,即使执行一次或多次, 其结果也一样),这意味着多次执行是安全的,因为其结果均一致。tasks包含name和要执行的模块,name是可选的,只是为了便于用户阅读,建议加上去,模块是必须的,同时也要给予模块相应的参数。 bash #定义tasks推荐使用module: options"的格式 service: name=httpd state=running

2.3、handlers

用于当关注的资源发生变化时采取一定的操作。handlers是和"notify"配合使用的。

【notify】这个动作可用于在每个play的最后被触发,这样可以避免多次有改变发生时,每次都执行指定的操作,通过"notify",仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也就是说notify用来调用handler中定义的操作。

注意:在 notify中定义的内容一定要和handlers中定义的" - name"内容一样,这样才能达到触发的效果,否则会不生效。

2.4、tags

tags用于让用户选择运行或略过playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分;但是当一个playbook任务比较多时,一个一个的判断每个部分是否发生了变化,也需要很长时间。因此,如果确定某些部分没有发生变化,就可以通过tags跳过这些代码片断。

2.5、playbook执行结果解析

使用ansible-playbook运行playbook文件,输出的内容为JSON格式。并且由不同颜色组成,便于识别。一般而言,输出内容中:

执行结果颜色
绿色 代表执行成功,但系统保持原样
黄色 代表系统状态发生改变,也就是执行的操作生效
红色 代表执行失败,会显示错误信息。

三、ansible-playbook各模块及应用示例

3.1、shell模块

bash 复制代码
#在远程主机(192.168.1.30)上执行命令,用法与【command】模块一样,不过shell模块执行命令时使用的是【/bin/sh】可执行任何命令
vi shell.yml

#【shell.yml】文件的完整内容
- hosts: 192.168.1.30
  remote_user: root
  vars:
    ansible_ssh_port: 22222
    ansible_ssh_pass: admin123456
  tasks:
    - name: ansible shell
      shell: ps -ef | grep sshd>/tmp/sshd1.log; mkdir -p /data/cktest
    - name: ansible command
      command: touch /data/cktest/ck.log
  
    
 #执行命令     
 ansible-playbook shell.yml

3.2、raw模块

raw模块功能类似与前面说的command、shell能够完成的操作,raw也都能完成。不同的是,raw模块不需要远程主机上的python环境。

ansible要执行自动化操作,需要管理机上装ansible,客户机上也需要安装python,如果客户机上没有安装python模块,那么command、shell模块将无法工作,而raw却可以正常工作,因此,如果有的机器是没有装python,或者说安装的python版本在python2.4以下,就可以使用raw模块来装python、python-simplejson等。

bash 复制代码
#raw模块示例
vi raw.yml

#【raw.yml】完整内容
- hosts: 192.168.1.30
  remote_user: root
  vars:
    ansible_ssh_port: 22222
    ansible_ssh_pass: admin123456
  tasks:
    - name: ansible raw test1
      raw: ps -ef | grep sshd | awk '{print $2}'>/tmp/sshd2.log
    - name: ansible raw test2
      raw: dnf -y install python36-devel
  
    
 #执行命令     
 ansible-playbook raw.yml

3.3、file模块

file模块主要用于远程主机上的文件操作。file模块包含如下选项:

file模块选项 说明
force 需要在两种情况下强制创建软链接: 《1》是源文件不存在但之后会建立的情况下; 《2》是目标软链接已存在,需要先取消之前的软链,然后创建新的软链。 有两个选项:yes|no
group 定义文件/目录的属组
mode 定义文件/目录的权限
owner 定义文件/目录的属主
path 必选项,定义文件/目录的路径
recurse 递归的设置文件的属性,只对目录有效
src 要被链接的源文件的路径,只应用于state=link的情况
dest 被链接到的目标路径,只应用于state=link的情况
state 有如下几个选项: **directory:**表示目录,如果目录不存在,则创建目录。 **link:**创建软链接 **hard:**创建硬链接 **touch:**如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间 **absent:**删除目录、文件或者取消链接文件。
bash 复制代码
#file模块示例
vi file.yml

#【file.yml】文件的完整内容
- hosts: 192.168.1.30
  remote_user: root
  vars:
    ansible_ssh_port: 22222
    ansible_ssh_pass: admin123456
  tasks:
    - name: mkdir ckdir directory
      file: path=/data/ckdir state=directory mode=0755
    - name: chmod siege
      file: dest=/data/siege mode=0755 recurse=yes
    - name: link files
      file: src=/etc/ssh/sshd_config dest=/mnt/sshd_config owner=sshd state=link
    - name: delete files
      file: path=/mnt/Python-3.12.13.tgz state=absent
    - name: chown files
      file: path=/data/text1.txt owner=nobody group=nobody mode=0644
   
    
 #执行命令     
 ansible-playbook file.yml

3.4、Copy模块

Copy模块用于复制文件到远程主机,copy模块包含如下选项:

Copy模块选项 说明
backup 在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no
dest 必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录
directory_mode 递归的设定目录的权限,默认为系统默认权限
force 如果目标主机包含该文件,但内容不同: 《1》如果设置为yes,则强制覆盖; 《2》如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。 默认为yes
src 要复制到远程主机的文件在本地的地址,可以是绝对路径,也可以是相对路径。 如果路径是一个目录,它将递归复制;在这种情况下: 《1》如果路径使用"/"来结尾,则只复制目录里的内容; 《2》如果没有使用"/"来结尾,则包含目录在内的整个内容全部复制,类似于rsync。
bash 复制代码
#copy模块示例
vi copy.yml

#【copy.yml】完整内容:
- hosts: 192.168.1.30
  remote_user: root
  gather_facts: false
  vars:
    ansible_ssh_port: 22222
    ansible_ssh_pass: admin123456
  tasks:
    - name: copy and chown
      copy: src=/etc/sudoers dest=/mnt/sudoers owner=root group=root mode=440 backup=yes
    - name: checking files
      copy: src=/etc/sudoers dest=/mnt/sudoers validate='visudo -cf %s'
    - name: copy directory
      copy: src=/etc/yum/ dest=/mnt/bak owner=coffeemilk group=coffeemilk directory_mode=644
    
    
 #执行命令     
 ansible-playbook copy.yml

3.5、synchronize模块

synchronize模块常用的选项有如下几个:

synchronize模块选项 说明
compress 是否开启压缩(默认开启)
copy_links 复制链接文件(默认为no)
delete 表示删除管理机中没有但远程主机存在的文件,使两边内容一样,以管理机为主(默认为no)
src 要复制到远程主机的文件在管理机上的路径 如果路径是一个目录,它将递归复制;在这种情况下: 《1》如果路径使用"/"来结尾,则只复制目录里的内容; 《2》如果没有使用"/"来结尾,则包含目录在内的整个内容全部复制,类似于rsync。
dest 要将文件复制到的远程主机的绝对路径
dest_port 默认为22端口,走ssh协议,表示远程主机端口
mode 可选push和pull模块: 《1》push模块的话,一般用于从管理机向远程主机上传文件; 《2》pull模式用于从远程主机上取文件到管理机。

注意:使用这个模块的时候,必须保证远程主机上有rsync这个命令,不然会报错。

bash 复制代码
#synchronize模块示例
#查看ansible所在主机是否已经安装了sync
rpm -qa | grep rsync

#创建synchronize示例文件
vi synchronize.yml

#【synchronize.yml】文件的完整内容:
- hosts: 192.168.1.30
  remote_user: root
  vars:
    ansible_ssh_port: 22222
    ansible_ssh_pass: admin123456
  tasks:
    - name: synchronize rsync diretory
      synchronize: src=/data/openclaw-main dest=/mnt/sync delete=yes
    - name: synchronize rsync direcoty files
      synchronize: src=/data/openclaw-main/ dest=/mnt/sync2 delete=yes
 
 
#执行命令
ansible-playbook synchronize.yml

3.6、unarchive模块

unarchive模块用来实现解压缩,也就是将压缩文件解压分发到远程不同节点上。只需记住如下几个参数即可:

unarchive模块选项 说明
src 源文件路径,这个源文件在管理机上
dest 指定远程主机的文件路径
mode 设置远程主机上文件权限
bash 复制代码
#unarchive模块示例
vi unarchive.yml

#【unarchive.yml】文件完整内容:
- hosts: 192.168.1.30
  remote_user: root
  gather_facts: false
  vars:
    ansible_ssh_port: 22222
    ansible_ssh_pass: admin123456
  tasks:
    - name: unarchive files
      unarchive: src=/data/HashTool_v1.4.0.zip dest=/data
    - name: create directory
      file: path=/data/HashTool666 state=directory mode=755
    - name: unarchive files to speical directory
      unarchive: src=/data/HashTool_v1.4.0.zip dest=/data/HashTool666


#执行命令
ansible-playbook unarchive.yml

3.7、service模块

用于管理远程主机上的服务:

service模块选项 说明
enabled 是否开机启动 yes|no
name 必选项,服务名称
pattern 定义一个模式,如果通过status指令来查看服务的状态时,没有响应,就会通过ps指令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然在运行
sleep 如果执行了restarted,在则stop和start之间沉睡几秒钟
state 对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)
bash 复制代码
#service模块示例
vi service.yml

#【service.yml】文件的完整内容:
- hosts: 192.168.1.30
  remote_user: root
  gather_facts: false
  vars:
    ansible_ssh_port: 22222
    ansible_ssh_pass: admin123456
  tasks:
    - name: nginx restart
      service: name=nginx state=restarted enabled=yes
      

#执行命令
ansible-playbook service.yml

3.8、cron模块

用于管理计划任务:

cron模块的选项 说明
backup 对远程主机上的原任务计划内容修改之前做备份
cron_file 用来指定一个计划任务文件,也就是将计划任务写到远程主机上/etc/cron.d目录下,创建一个文件对应的计划任务。
minute 分钟(0-59,*,*/2,......)
hour 小时(0-23,*,*/2,......)
day 日(1-31,*,*/2,......)
month 月(1-12,*,*/2,......)
weekday 周(0-7,*,......)
job 要执行的任务,依赖于state=present
name 定义定时任务的描述信息
special_time 特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时)
state 确认该任务计划是创建还是删除,分别是present和absent;present表示创建定时任务,absent表示删除定时任务,默认为present。
user 以哪个用户的身份执行job指定的任务。
bash 复制代码
#cron模块示例
vi cron.yml

#【cron.yml】文件的完整内容:
- hosts: 192.168.1.30
  remote_user: root
  gather_facts: false
  vars:
    ansible_ssh_port: 22222
    ansible_ssh_pass: admin123456
  tasks:
    - name: cron demo
      cron: backup=true name=autobackup day=*/1 hour=3 minute=16 user=root job='/home/coffeemilk/backup.sh'
    - name: delete cron
      cron: name=autobackup state=absent
      

#执行命令
ansible-playbook cron.yml

3.9、yum模块

使用yum包管理器来管理软件包:

yum模块选项 说明
config_file yum的配置文件
disable_gpg_check 关闭gpg_check
disablerepo 禁用某个源
enablerepo 启用某个源
name 要进行操作的软件包的名字
state 表示要安装还是删除软件包,要安装软件包,可选择present(安装)、installed(安装)、 latest(安装最新版本),删除软件包可选择absent、removed。
bash 复制代码
#yum模块示例
vi yum.yml

#【yum.yml】文件的完整内容:
- hosts: 192.168.1.30
  remote_user: root
  gather_facts: false
  vars:
    ansible_ssh_port: 22222
    ansible_ssh_pass: admin123456
  tasks:
    - name: yum install epel
      yum: name=epel-release state=latest
    - name: yum install redis
      yum: name=redis state=latest enablerepo=epel
    - name: redis restart
      service: name=redis state=restarted enabled=yes

4.0、user模块与group模块

user模块是请求的是【useradd】【userdel】【usermod】三个指令,goup模块请求的是【groupadd】【groupdel】【groupmod】三个指令。

user模块与group模块选项 说明
name 指定用户名
group 指定用户的主组
groups 指定附加组,如果指定为('groups=')表示删除所有组
shell 指定默认shell
state 设置帐号状态,不指定为默认为present,表示创建,指定值为absent表示删除
remove 当使用状态为state=absent时使用,类似于userdel --remove选项
bash 复制代码
#user模块与group模块示例
vi user-group.yml

#【user-group.yml】文件的完整内容:
- hosts: 192.168.1.30
  remote_user: root
  gather_facts: false
  vars:
    ansible_ssh_port: 22222
    ansible_ssh_pass: admin123456
  tasks:
    - name: create group
      group: name=cktest state=present
    - name: batch create user
      user: name={{item}} groups=coffeemilk,wheel
      with_items:
        - ck01
        - ck02
        - ck03
        
        
#执行命令
ansible-playbook user-group.yml

4.1、lineinfile模块

lineinfile模块实现对文件进行内容替换:

lineinfile模块选项 说明
path 操作的远程主机上的文件路径
regexp 正则表达式,要替换的内容规则
line 指定替换后的文本内容
state 当设置为absent代表删除匹配的行
insertafter 可以将文本插入到"指定的行"之后
insertbefore 可以将文本插入到"指定的行"之前
backup 进行替换操作前是否进行备份
bash 复制代码
#lineinfile模块示例
vi lineinfile.yml

#【lineinfile.yml】文件的完整内容:
- hosts: 192.168.1.30
  remote_user: root
  gather_facts: false
  vars:
    ansible_ssh_port: 22222
    ansible_ssh_pass: admin123456
  tasks:
    - name: 在ulimit开头的行后插入数据
      lineinfile: path=/data/testfile/profile insertafter='ulimit(.*)' line="ulimit -c ulimited"
    - name: 将内容插入到文件末尾
      lineinfile: path=/data/testfile/profile line="export JAVA_HOME=/usr/jdk"
    - name: 匹配文件中的内容,然后将该行内容替换为指定内容
      lineinfile: path=/data/testfile/config regexp='SELINUX=(.*)' line="SELINUX=disabled"
    - name: 匹配文件中的内容,然后将该行内容删除
      lineinfile: path=/data/testfile/resolv.conf regexp='search(.*)' state=absent
      
      
#执行命令
ansible-playbook lineinfile.yml

4.2、setup模块获取Ansible facts信息

Ansible facts是远程主机上的系统信息(主要包含IP地址、操作系统版本、网络设备、mac地址、内存、磁盘、硬件等信息)。这些信息对于需要根据远程主机的信息作为执行条件操作的场景非常有用。Ansible提供了一个setup模块来收集远程主机的系统信息,这些facts信息可以直接以变量的形式使用。

playbooks中,经常会用到的一个参数【gather_facts】就与该模块相关(gather_facts默认值为yes);也就是说,在使用Ansible对远程主机执行任何一个playbook之前,总会先通过setup模块获取facts,并将信息暂存在内存中,直到该playbook执行结束。

bash 复制代码
#获取远程主机的所有系统信息
ansible 192.168.1.30 -e ansible_port=22222 -m setup -k

#获取的所有系统信息数据格式都是JSON格式,facts还支持查看指定信息,使用关键字【filter】过滤(如查看ipv4的信息)
ansible 192.168.1.30 -e ansible_port=22222 -m setup -k -a 'filter=ansible_all_ipv4_addresses'
相关推荐
yy_xzz2 小时前
【Linux开发】01多线程编程:线程的创建与运行
linux·运维·服务器
蜕变的土豆2 小时前
ABB1200系列机器人配置
运维·服务器·机器人
闻哥2 小时前
Docker Swarm 负载均衡深度解析:VIP vs DNSRR 模式详解
java·运维·jvm·docker·容器·负载均衡
我爱学习好爱好爱2 小时前
Ansible include任务复用 tags ignore_errors
linux·运维·ansible
@土豆2 小时前
混合云组网-基于公有云产品实现(非开源方法)
运维·网络·开源
wd5i8kA8i10 小时前
自研多线程 SSH 极速文件传输助手(附 GitHub 源码)
运维·ssh·github
Boop_wu10 小时前
[Java 算法] 字符串
linux·运维·服务器·数据结构·算法·leetcode
菱玖12 小时前
SRC常见漏洞情况分类
运维·安全·安全威胁分析
SkyXZ~12 小时前
Jetson有Jtop,Linux有Htop,RDK也有Dtop!
linux·运维·服务器·rdkx5·rdks100·dtop