Ansible笔记

1、Ansible

Ansible是一个自动化的管理IT资源的工具。

1)Ansible基本介绍

Ansible功能 Ansbile优点 Ansible缺点
批量执行远程命令,可以对N多台主机同时进行命令的执行 无客户的 效率低、易挂起
批量配置软件服务,可以进行自动化的方式配置和管理服务 推送式
实现软开发功能,jumpserver堡垒机底层就是使用ansible来实现的自动化批量管理 丰富的module
编排高级的IT任务,ansible的playbookd是一门编程语言,可以用来描绘一套IT剧本架构,完成复杂的任务,类似shell脚本 基于YAML的Playbook
通过roles角色定义,可以自定义部署某一个角色任务或某一些角色任务

2)Ansible与其他软件的对比

对比项目 Puppet Chef Salt Ansible
客户端
通讯方式 socket ssh Rabbitmq ssh
Web页面
效率 一般 一般
易用
实现语言 ruby python python python
API
开源社区 4219 4479 6998 19504

3)Ansible安装

环境准备:python+setuptools+pip(可选)

(1)快速安装
安装pip:easy_install pip
安装Ansible:pip install ansible
(2)源码安装
github获取源码。。。
(3)系统源安装

  • centos(推荐)
yum install epel-release -y
yum install ansible
  • ubuntu
apt-get install software-properties-common
apt-add-repository ppa:ansible/ansible
apt-get update
apt-get install ansible

安装完成使用ansible --version查看版本

[root@localhost ~]# ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Oct 14 2020, 14:45:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]

安装完成查看/etc/ansible目录

[root@localhost etc]# tree ansible/
ansible/
├── ansible.cfg
├── hosts
└── roles

1 directory, 2 files

4)Ansible架构&运行

  • 架构
    image
  • 运行
    image

5)Ansible配置文件路径搜索策略

搜索策略:

  • 检查环境变量export ANSIBLE_CONFIG指向的路径文件
  • ./ansible.cfg检查当前目录下的ansible.cfg配置文件
  • ~/.ansible.cfg检查当前用户目录下的ansible.cfg配置文件
  • /etc/ansible/ansible.cfg检查etc目录的配置文件

6)Ansible两种认证方式

关于指纹(known_hosts):

可以手动确认指纹(ssh登录后确认),或者直接忽略指纹确认(修改ansible配置文件,修改如下参数host_key_checking = False打开忽略指纹确认的参数即可)

  • 指纹提示实例
[root@localhost .ssh]# ssh root@192.168.44.134
The authenticity of host '192.168.44.134 (192.168.44.134)' can't be established.
ECDSA key fingerprint is SHA256:xMmum9QKAwyNpUaSnUpIN8vgGehttG6522tcJUdoTmA.
ECDSA key fingerprint is MD5:7b:3c:09:08:b0:6a:80:86:3e:bf:6a:b1:98:3c:8a:bb.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.44.134' (ECDSA) to the list of known hosts.
root@192.168.44.134's password:
Last login: Tue Jun 18 14:59:36 2024 from 192.168.44.1

⚠️指纹(known_hosts)在ansible服务端
(1)密码认证
需要在/etc/ansible/hosts中进行配置:

[centos]
192.168.44.135 ansible_user=root ansible_password=xroot

(2)公钥认证
请见:SSH无密码(密钥验证)登录的配置

8)Ansible执行命令结果(状态颜色)

绿色:命令以用户期望的执行了,但是状态没有发生改变;
黄色:命令以用户期望的执行了,并且状态发生了改变;
紫色:警告信息,说明ansible提示你有更合适的用法;
红色:命令错误,执行失败;
蓝色: 详细的执行过程;

9)调试-忽略错误

在 playbook 执行的过程中,难免会遇到一些错误。由于 playbook 遇到错误后,不会执行之后的任务,不便于调试,此时,可以使用 ignore_errors 来暂时忽略错误,使得 playbook 继续执行。

- hosts: all
  remote_user: root
  tasks:
    - name: Ignore False
      command: /bin/false
      ignore_errors: no
    - name: touch test.txt
      file: path=/tmp/test.txt state=touch

2、Ansible配置文件-ansible.cfg

1)Ansible配置文件

  ansible 的配置文件为/etc/ansible/ansible.cfg,ansible 有许多参数,下面我们列出一些常见的参数:

inventory = /etc/ansible/hosts		#这个参数表示资源清单inventory文件的位置
library = /usr/share/ansible		#指向存放Ansible模块的目录,支持多个目录方式,只要用冒号(:)隔开就可以
forks = 5		#并发连接数,默认为5
sudo_user = root		#设置默认执行命令的用户
remote_port = 22		#指定连接被管节点的管理端口,默认为22端口,建议修改,能够更加安全
host_key_checking = False		#设置是否检查SSH主机的密钥,值为True/False。关闭后第一次连接不会提示配置实例
timeout = 60		#设置SSH连接的超时时间,单位为秒
log_path = /var/log/ansible.log		#指定一个存储ansible日志的文件(默认不记录日志)

2)Ansible配置项说明

(1)defaults默认配置项

点击查看代码
- ask_pass & ask_sudo_pass
>ask_pass:可以控制Ansible剧本playbook是否会自动默认弹出密码
ask_subo_pass:用户使用的系统平台开启了sudo密码的话,应该开绿这一参数
- gather_subset
>设置收集的内容:包括all、network、hardware、virtual、facter、ohai
- remote_port & remote_tmp & remote_user
>客户机的设置,分别对登录的用户和端口,以及临时目录
- sudo_exe & sudo_flags & sudo_user
>sudo命令相关设置,分别是sudo命令路径、sudo参数、能够使用sudo的user

- action_plugins & callback_plugins & connection_plugins & filter_plugins & lookup_plugins & vars_plugins
>开发者中心的插件相关功能,开发者可以开发相应的插件,来完成自己的功能。分别对应的功能为:激活事件、回调、连接、过滤器、加载路径、任何地方加载

- forks
>最大开辟的进程数,这个数不易过大,过大性能耗费高,不易过小,过小的话,并发性能低,一般的设置方法是cpu核数*2

- module_name
>这个是/usr/bin/ansible的默认模块名(-m)。默认是‘command’模块,command模块不支持shell变量、管道、配额,所以也许你希望把这个参数改为‘shell’

- vault_password_file
>这个文件也可以称为一个脚本的形式,如果你使用脚本而不是单纯文件的话,请确保它可以执行并且密码可以在标准输出上打印出来。如果你的脚本需要提示请求数据,请求将会发到标准错误输出中。

- pattern
>如果没有提供“hosts”节点,这是playbook要通信的默认主机组。默认值是对所有主机通信,如果不想被惊吓到,最好还是设置个选项。

- inventory & library
>分别为存放可以通信主机的目录和Ansible默认搜寻模块路径。

(2)privilege_escalation执行命令的用户权限设置
(3)paramiko_connection paramika插件设置
(4)ssh_connection ssh连接设置
(5)accelerate
(6)selinux & colors
(7)gathering 打开或者关闭fact变量

gathering = explict

3、Ansible主机清单文件-hosts

如何添加一台机器:

编辑Ansible服务端的主机清单文件(Inventory):/etc/ansible/hosts
确认指纹即添加目标机器指纹到Ansible服务端的known_hosts
添加Ansible服务端的公钥到目标机器的authorized_keys
运行ansible all -m ping测试是否添加成功

HostInventory:记录由Ansible管理的主机信息,包括端口、密码、ip等

1)Inventory分组

通过Ansible Inventory文件(作用是分组)可同时操作属于一个组的多台主机,多台主机之间的通过inventory文件配置,默认的文件路径为/etc/ansible/hosts,方括号[]中是组名,一个主机可以属于不同的组。

one.example.com
[webservers]
two.example.com
three.example.com

(1)自定义连接端口
在编写hosts文件时,在域名或者ip后,加上冒号端口号。

192.168.1.1:5000
one.example.com:7999

(2)别名

jumper ansible_port=5555 ansible_host=192.168.1.50

查看所有主机:ansible all --list-hosts
(3)指定登录用户

jumper ansible_port=5555 ansible_host=192.168.1.1 ansible_user=papa

(4)ip连续

[vim]
vim[1:50].example.com
vim[a-f].example.com

2)Inventory参数选项

点击查看代码
ansible_host
ansible_port
ansible_user
ansible_password
ansible_sudo_pass
ansible_sudo_exe
ansible_connection 与主机的连接类型,比如:local、ssh或者paramiko
ansible_ssh_private_key_file
ansible_shell_type 目标系统的shell类型
ansible_python_interpreter

3)通过inventory在主机组或单个主机中设置变量

(1)主机变量

[centos]
192.168.44.135 myid=1

(2)主机组变量

[centos:vars]
port=80
[centos]
192.168.44.135

⚠️host_vars、group_vars详见第7章

4)inventory的升级用法:

/etc/ansible/hosts是ansible中默认的被管理节点的IP存放的文件路径,如果想自己定义,或者想把不同类型的主机存在不同的文件中,可以在/etc/ansible/ansible.cfg中更改配置文件即可。

[root@localhost ~]# vim /etc/ansible/ansible.cfg
inventory      = /root/myhosts/
[root@localhost ~]# tree /root/myhosts/
/root/myhosts/
├── dbserver
└── httpd

4、Ansible命令

1)Ansible命令集

/usr/bin/ansible  Ansible AD-Hoc 临时命令执行工具,常用于临时命令的执行
/usr/bin/ansible-doc   Ansible 模块功能查看工具
/usr/bin/ansible-galaxy  下载/上传优秀代码或Roles模块 的官网平台,基于网络的
/usr/bin/ansible-playbook  Ansible 定制自动化的任务集编排工具
/usr/bin/ansible-pull  Ansible远程执行命令的工具,拉取配置而非推送配置(使用较少,海量机器时使用,对运维的架构能力要求较高)
/usr/bin/ansible-vault  Ansible 文件加密工具
/usr/bin/ansible-console  Ansible基于Linux Consoble界面可与用户交互的命令执行工具

2)Ansible命令详解

ansible <host-pattern> [-f forks] [-m module_name] [-a args]

点击查看代码
-a MODULE_ARGS   #模块的参数,如果执行默认COMMAND的模块,即是命令参数,如: “date”,“pwd”等等
-k,--ask-pass #ask for SSH password。登录密码,提示输入SSH密码而不是假设基于密钥的验证
--ask-su-pass #ask for su password。su切换密码
-K,--ask-sudo-pass #ask for sudo password。提示密码使用sudo,sudo表示提权操作
--ask-vault-pass #ask for vault password。假设我们设定了加密的密码,则用该选项进行访问
-B SECONDS #后台运行超时时间
-C #模拟运行环境并进行预运行,可以进行查错测试
-c CONNECTION #连接类型使用
-f FORKS #并行任务数,默认为5
-i INVENTORY #指定主机清单的路径,默认为/etc/ansible/hosts
--list-hosts #查看有哪些主机组
-m MODULE_NAME #执行模块的名字,默认使用 command 模块,所以如果是只执行单一命令可以不用 -m参数
-o #压缩输出,尝试将所有结果在一行输出,一般针对收集工具使用
-S #用 su 命令
-R SU_USER #指定 su 的用户,默认为 root 用户
-s #用 sudo 命令
-U SUDO_USER #指定 sudo 到哪个用户,默认为 root 用户
-T TIMEOUT #指定 ssh 默认超时时间,默认为10s,也可在配置文件中修改
-u REMOTE_USER #远程用户,默认为 root 用户
-v #查看详细信息,同时支持-vvv,-vvvv可查看更详细信息

  • ansible all -a 'ls' -v
    ansible all -m command -a 'ls' -v

3)Ansible-doc 命令

ansible-doc 命令常用于获取模块信息及其使用帮助,一般用法如下:

ansible-doc -l				#获取全部模块的信息
ansible-doc -s MOD_NAME		#获取指定模块的使用帮助

4)Ansible两种命令执行方式

Ansible实现批量管理主机的模式主要有:

利用ansible命令实现批量管理(ad-hoc)模式:ansible
利用ansible剧本实现批量管理(playbook)模式:ansible-playbook

ad-hoc和playbook的关系就好比shell命令与shell scripts的关系

5、Ansible常用模块(module)

1)调试-ping 模块

主机连通性测试:

ansible命令主体:ansible/ansible-playbook
被操作的目标机器的正则表达式:all
指定要使用的模块:-m ping

ansible all -m ping

2)命令脚本-command 模块

这个模块可以直接在远程主机上执行命令,并将结果返回本主机。
ansible centos -m command -a 'ss -ntl'

命令模块接受命令名称,后面是空格分隔的列表参数。给定的命令将在所有选定的节点上执行。它不会通过shell进行处理,比如$HOME和操作如"<",">","|",";","&" 工作(需要使用(shell)模块实现这些功能)。注意,该命令不支持|管道命令。

下面来看一看该模块下常用的几个命令:

参数 说明
chdir 在执行命令之前,先切换到该目录
executable 切换shell来执行命令,需要使用命令的绝对路径
free_form 要执行的Linux指令,一般使用Ansible的-a参数代替
creates 一个文件名,当这个文件存在,则该命令不执行,可以用来做判断
removes 一个文件名,这个文件不存在,则该命令不执行
#先切换到/data/ 目录,再执行“ls”命令
ansible centos -m command -a 'chdir=/data/ ls'
#如果/data/aaa.jpg存在,则不执行“ls”命令`
ansible centos -m command -a 'creates=/data/aaa.jpg ls'
#如果/data/aaa.jpg存在,则执行“cat /data/a”命令
ansible centos -m command -a 'removes=/data/aaa.jpg cat /data/a'

free_form参数 :必须参数,指定需要远程执行的命令,需要说明一点,free_form参数与其他参数并不相同,free_form并不是一个”实际存在”的参数名,比如,当我们想要在远程主机上执行ls命令时,我们并不需要写成free_form=ls ,这样写反而是错误的,因为并没有任何参数的名字是free_form,当我们想要在远程主机中执行ls命令时,直接写成ls即可,这就是free_form参数的含义,因为command模块的作用是执行命令,所以,任何一个可以在远程主机上执行的命令都可以被称为free_form。

但command 模块更安全,因为他不受用户环境的影响, 也很大的避免了潜在的 shell 注入风险

3)命令脚本-shell 模块

shell模块可以在远程主机上调用shell解释器运行命令,支持shell的各种功能,例如管道等。

ansible centos -m shell -a 'cat /etc/passwd |grep "keer"'

⚠️也可以运行远程主机上的脚本

ansible centos -m shell -a 'sh /applications/df2.sh'

和command相同,但是支持解析特殊 shell 符号,但这样有潜在的 shell 注入风险

4)命令脚本-script 模块

该模块用于将本机的脚本在被管理端的机器上运行。该模块直接指定脚本的路径即可,我们通过例子来看一看到底如何使用的:

点击查看代码
# 先生成一个本地的script脚本:df.sh,并给其加上执行权限(chmod +x df.sh)
#!/bin/bash

date >> /applications/disk_total.log
df -lh >> /applications/disk_total.log

# ansible运行
ansible centos -m script -a '/applications/df.sh'
# 查看运行结果
ansible centos -m shell -a 'cat /applications/disk_total.log'

在远程主机上执行脚本文件 ,和 raw 模块一样,不要求目标主机上已经装好 python

5)命令脚本-raw 模块

执行底层 shell 命令。command 和 shell 模块都是通过目标主机上的 python 代码启动 /bin/bash 来执行命令的,但目标主机上可能没有安装 python,这时只能使用 raw 模块在远程主机上直接启动

6)文件管理-copy 模块

这个模块用于将文件复制到远程主机,同时支持给定内容生成文件和修改权限等。
  其相关选项如下:

参数 说明
src 被复制到远程主机的本地文件。可以是绝对路径,也可以是相对路径。如果路径是一个目录,则会递归复制,用法类似于"rsync"
content 用于替换"src",可以直接指定文件的值
dest 必选项,将源文件复制到的远程主机的绝对路径
backup 当文件内容发生改变后,=yes在覆盖之前把源文件备份,备份文件包含时间信息
directory_mode 递归设定目录的权限,默认为系统默认权限
mode 设置文件权限,如755
force 当目标主机包含该文件,但内容不同时,设为"yes",表示强制覆盖;设为"no",表示目标主机的目标位置不存在该文件才复制。默认为"yes"
others 所有的 file 模块中的选项可以在这里使用
# 复制文件
ansible centos -m copy -a 'src=/applications/test dest=/applications'
# 给定内容生成文件,并制定权限
ansible centos -m copy -a 'content="test from content\n" dest=/applications/test/test.txt mode=777'
# 给定内容生成文件,并制定权限+如果目标文件存在,则备份
ansible centos -m copy -a 'content="test from content2\n" dest=/applications/test/test.txt mode=777 backup=yes'

7)文件管理-file 模块

该模块主要用于设置文件的属性,比如创建文件、创建链接文件、删除文件等。
  下面是一些常见的命令:

参数 说明
path 被管理文件的路径
force 需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes/no
group 定义文件/目录的属组。后面可以加上mode:定义文件/目录的权限
owner 定义文件/目录的属主。后面必须跟上path:定义文件/目录的路径
recurse 递归设置文件的属性,只对目录有效,后面跟上src
src 指定链接文件的路径,只应用于state=link的情况
dest 被链接到的路径,只应用于state=link的情况
mode 设置文件的权限
state 状态,有以下选项

状态 选项
directory 如果目录不存在,就创建目录
file 即使文件不存在,也不会被创建
link 创建软链接
hard 创建硬链接
touch 如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent 删除目录、文件或者取消链接文件
# 创建目录
ansible centos -m file -a 'path=/applications/testfile state=directory'
# 创建链接文件-软(删除源文件有影响)
ansible centos -m file -a 'path=/applications/testfile/testb.txt src=/applications/test/test.txt state=link'
ansible centos -m file -a 'dest=/applications/testfile/testbb.txt src=/applications/test/test.txt state=link'
# 创建链接文件-硬链(删除源文件无影响)
ansible centos -m file -a 'path=/applications/testfile/testc.txt src=/applications/test/test.txt state=hard'
# 删除文件
ansible centos -m file -a 'path=/applications/test/test.txt state=absent'

8)文件管理-fetch 模块

该模块用于从远程某主机获取(复制)文件到本地。
  有两个选项:

参数 说明
dest 用来存放文件的目录
src 在远程拉取的文件,并且必须是一个file,不能是目录
ansible centos -m fetch -a 'src=/applications/testfile/testc.txt dest=/applications/test'

要注意,文件保存的路径是我们设置的接收目录下的被管制主机ip(192.168.44.135)目录下

[root@localhost test]# tree
.
├── 192.168.44.135
│   └── applications
│       └── testfile
│           └── testc.txt

9)系统管理-cron 模块

该模块适用于管理cron计划任务的。
  其使用的语法跟我们的crontab文件中的语法一致,同时,可以指定以下选项:

参数 说明
day= 日应该运行的工作( 1-31, *, */2, )
hour= 小时 ( 0-23, *, */2, )
minute= 分钟( 0-59, *, */2, )
month= 月( 1-12, *, /2, )
weekday= 周 ( 0-6 for Sunday-Saturday,, )
job= 指明运行的命令是什么
name= 定时任务描述
reboot 任务在重启时运行,不建议使用,建议使用special_time
special_time 特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时)
state 指定状态,present表示添加定时任务,也是默认设置,absent表示删除定时任务
user 以哪个用户的身份执行
# 添加计划任务
ansible centos -m cron -a 'name="ntp update every 5 hour" hour=*/5 job="/sbin/ntpdate ntpdate ntp.aliyun.com &> /dev/null"'
# 删除计划任务 (根据name进行删除,删除之前可以先查看看定时任务)
ansible centos -m cron -a 'name="ntp update every 5 hour" state=absent'

10)软件包管理-yum 模块

顾名思义,该模块主要用于软件的安装。
  其选项如下:

参数 说明
name 所安装的包的名称或路径(一个或多个)
state installed、present:安装(不更新), latest:安装最新的(更新), removed、absent:卸载软件
update_cache 强制更新yum的缓存
conf_file 指定远程yum安装时所依赖的配置文件(安装本地已有的包)
disable_pgp_check 是否禁止GPG checking,只用于presentor latest
disablerepo 临时禁止使用yum库。 只用于安装或更新时
enablerepo 临时使用的yum库。只用于安装或更新时
validate_certs 如果下载地址是https,需要设置为no
ansible centos -m yum -a 'name=boxes state=present'

11)用户管理-user 模块

该模块主要是用来管理用户账号。
  其主要选项如下:

参数 说明
comment 用户的描述信息
createhome 是否创建家目录
force 在使用state=absent时, 行为与userdel –force一致
group 指定基本组
groups 指定附加组,如果指定为(groups=)表示删除所有组
home 指定用户家目录
move_home 如果设置为home=时, 试图将用户主目录移动到指定的目录
name 指定用户名
non_unique 该选项允许改变非唯一的用户ID值
password 指定用户密码
remove 在使用state=absent时, 行为是与userdel –remove一致
shell 指定默认shell
state 设置帐号状态,不指定为创建,指定值为absent表示删除
system 当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
uid 指定用户的uid
ansible centos -m user -a 'name=hacker home=/home/hacker'

12)service 模块

该模块用于服务程序的管理。
  其主要选项如下:

参数 说明
arguments 命令行提供额外的参数
enabled 设置开机启动
name= 服务名称
runlevel 开机启动的级别,一般不用指定
sleep 在重启服务的过程中,是否等待。如在服务关闭以后等待2秒再启动。(定义在剧本中。)
state 有四种状态,分别为:started:启动服务, stopped:停止服务, restarted:重启服务, reloaded:重载配置
ansible centos -m service  -a 'name=nginx state=started enabled=true'
ansible centos -m service -a 'name=nginx state=stopped'

13)用户管理-group 模块

该模块主要用于添加或删除组。
  常用的选项如下:

命令 说明
gid 设置组的GID号
name 指定组的名称
state 指定组的状态,默认为创建,设置值为absent为删除
system 设置值为yes,表示创建为系统组
ansible centos -m group -a 'name=centos'

14)setup 模块

该模块主要用于收集信息,是通过调用facts组件来实现的。

facts组件是Ansible用于采集被管机器设备信息的一个功能,我们可以使用setup模块查机器的所有facts信息,可以使用filter来查看指定信息。整个facts信息被包装在一个JSON格式的数据结构中,ansible_facts是最上层的值。
facts就是变量,内建变量 。每个主机的各种信息,cpu颗数、内存大小等。会存在facts中的某个变量中。调用后返回很多对应主机的信息,在后面的操作中可以根据不同的信息来做不同的操作。如redhat系列用yum安装,而debian系列用apt来安装软件。

(1)查看信息
我们可以直接用命令获取到变量的值

# 查看内存
ansible centos -m setup -a 'filter="*mem*"'
# 通过命令查看
ansible centos -m shell -a 'free -m'

(2)保存信息
  我们的setup模块还有一个很好用的功能就是可以保存我们所筛选的信息至我们的主机上,同时,文件名为我们被管制的主机的IP,这样方便我们知道是哪台机器出的问题。

ansible centos -m setup -a 'filter="*mem*"' --tree /applications

15)网络请求模块-get_url模块

用于将文件或软件从http、https或ftp下载到本地节点上或被管理机节点上。

参数 说明
url 指定下载地址:HTTP,HTTPS或FTP URL(http、https、ftp)
dest 下载到(目录已存在)
force 如果yes,dest不是目录,将每次下载文件,如果内容改变,替换文件。如果no,则只有在目标不存在时才会下载该文件。
mode 指定权限
sha256sum 如果将SHA-256校验和传递给此参数,目标文件的摘要将在下载后计算,以确保其完整性
url_username 用于HTTP基本认证的用户名。 对于允许空密码的站点,此参数可以不使用
url_password 用于HTTP基本认证的密码。 如果未指定url_username参数,则不会使用url_password参数

16)网络请求模块-uri

替代curl

ansible centos -m uri -a 'url=https://www.baidu.com timeout=10 return_content=no'

  常用的选项如下:

命令 说明
hosts localhost 在本机执行此次任务,也可以指定其他机器
serial 10: 明确定义 Ansible 如何批量执行当前剧本的目标
uri 使用了 URI 插件,参考链接:https://docs.ansible.com/ansible/2.9/modules/uri_module.html
url 具体的 要巡检的站点的 URL 地址
vars 定义该 Playbook 中用到的变量
until 直到后面的条件满足才为真
retries 重试次数
delay 每隔几秒检测一次
item 和 with_items 通过这 2 个参数实现循环批量执行

⚠️url地址必须以http或者https开头

Ansible中的with_items功能非常强大,它允许用户循环遍历列表或字典中的项目,并对每个项目执行相同的任务或操作。在迭代过程中,可以使用固定的变量名“item”来引用迭代项。

点击查看代码
---
- hosts: localhost
  gather_facts: no
  serial: 10
  tasks:
    - name: check url status
      uri:
        url: "{{ item }}"
        timeout: 10
        return_content: no
        follow_redirects: safe
        validate_certs: yes
      with_items: "{{ url_list }}"
      register: result
      until: result.status == 200
      retries: 20 #(最长检测20*5s)
      delay: 5
      vars:
        url_list:
        - https://www.baidu.com
        - https://www.taobao.com
        - https://www.qq.com

17)睡眠-wait_for

wait_for 只是用来在规定时间内检测,状态是否为所期望的状态是才,才执行后续的操作

---
- hosts: localhost
  gather_facts: no
- name: Sleep for 10 seconds
  wait_for:
    host: {{ inventory_hostname}}
	port: 6088
	state: stopped
    delay: 10
    state: present
  when:
    - inventory_hostname in groups.controller

TODO

18)解压缩模块- unarchive

  • 将本地主机上的存档文件,发送到远程主机指定的目录下解存档。
  • 直接解压目标主机上的存档文件。

  常用的选项如下:

命令 说明
copy 如果参数copy=yes,则把本地的存档文件拷贝到目标主机。如果参数copy=no,则在目标主机上查找存档文件。
src 如果copy=yes,是指定本地主机存档文件的源路径。如果copy=no,则是指定远端主机存档文件的源路径。
dest 远程主机上的一个路径,即存档文件解压的绝对路径。

6、Ansible ad-hoc模式

Ansible的ad-hoc模式也就是ansible的命令行模式,该模式通常用来临时处理一些任务。例如

临时批量查看所有被管控机器的内存、负载、磁盘
临时批量分发某个特定文件

7、Ansible playbook模式

1)Ansible playbook 简介

  playbook 是 ansible 用于配置,部署,和管理被控节点的剧本。
  通过 playbook 的详细描述,执行其中的一系列 tasks ,可以让远端主机达到预期的状态。playbook 就像 Ansible 控制器给被控节点列出的的一系列 to-do-list ,而被控节点必须要完成。
  也可以这么理解,playbook 字面意思,即剧本,现实中由演员按照剧本表演,在Ansible中,这次由计算机进行表演,由计算机安装,部署应用,提供对外服务,以及组织计算机处理各种各样的事情。

2)Ansible playbook使用场景

  执行一些简单的任务,使用ad-hoc命令可以方便的解决问题,但是有时一个设施过于复杂,需要大量的操作时候,执行的ad-hoc命令是不适合的,这时最好使用playbook。
  就像执行shell命令与写shell脚本一样,也可以理解为批处理任务,不过playbook有自己的语法格式。
  使用playbook你可以方便的重用这些代码,可以移植到不同的机器上面,像函数一样,最大化的利用代码。在你使用Ansible的过程中,你也会发现,你所处理的大部分操作都是编写playbook。可以把常见的应用都编写成playbook,之后管理服务器会变得十分简单。

3)Ansible playbook格式

playbook由YMAL语言编写。
以下为playbook常用到的YMAL格式:
  ①文件的第一行应该以 "---" (三个连字符)开始,表明YMAL文件的开始。
  ②在同一行中,#之后的内容表示注释,类似于shell,python和ruby。
  ③YMAL中的列表元素以”-”开头然后紧跟着一个空格,后面为元素内容。
  ④同一个列表中的元素应该保持相同的缩进(2个空格,不要用tab键)。否则会被当做错误处理。
  ⑤play中hosts,variables,roles,tasks等对象的表示方法都是键值中间以":"分隔表示,":"后面还要增加一个空格。

点击查看代码
---
#安装与运行nginx服务
- hosts: centos
  remote_user: root
  tasks:
    - name: install nginx package
      yum: name=nginx state=present
    - name: starting nginx service
      service: name=nginx state=started

我们的文件名称应该以.yml结尾,其中,有三个部分组成:

hosts:使用 hosts 指示使用哪个主机或主机组来运行下面的 tasks ,每个 playbook 都必须指定 hosts ,hosts也可以使用通配符格式。主机或主机组在 inventory 清单中指定,可以使用系统默认的/etc/ansible/hosts,也可以自己编辑,在运行的时候加上-i选项,指定清单的位置即可。在运行清单文件的时候,–list-hosts选项会显示那些主机将会参与执行 task 的过程中。
remote_user:指定远端主机中的哪个用户来登录远端系统,在远端系统执行 task 的用户,可以任意指定,也可以使用 sudo,但是用户必须要有执行相应 task 的权限。
tasks:指定远端主机将要执行的一系列动作。tasks 的核心为 ansible 的模块,前面已经提到模块的用法。tasks 包含 name 和要执行的模块,name 是可选的,只是为了便于用户阅读,不过还是建议加上去,模块是必须的,同时也要给予模块相应的参数。

4)Ansible playbook命令:ansible-playbook

ansible-playbook命令参数
-i 指定主机清单文件
-C 模拟运行剧本,检查是否有问题
--syntax-check 仅仅检查剧本格式是否有误

ansible-playbook -C createuser.yml

5)Playbook的核心元素

Hosts:主机组;
Tasks:任务列表;
Variables:变量,设置方式有四种;
Templates:包含了模板语法的文本文件;
Handlers:由特定条件触发的任务;

6)Paybooks配置文件的基础组件

Hosts:运行指定任务的目标主机
remoute_user:在远程主机上执行任务的用户;
sudo_user
tasks:任务列表

image

注意:shell和command模块后面直接跟命令(使用:),而非key=value类的参数列表;

tasks:
     - name: install httpd package
       yum: name=httpd state=present
# or
tasks:
    - name: install httpd package
      yum:
        name: httpd
        state: present

7)Ansible-playbook触发器-handlers和notify

handlers:Handlers是Ansible Playbook中的一种特殊任务,无法直接运行。它需要被其他任务通知后才会运行。它的主要作用是处理Playbook中各个任务之间的通知和协调。当某个任务完成后,如果满足特定条件,就会触发相应的Handler任务。
notify:Notify是Ansible Playbook中的一个触发器,它用于通知Handlers任务。当某个任务完成后,如果满足特定条件,就会触发相应的Notify任务。Notify任务本身并不执行任何操作,它的作用是通知其他任务(如Handlers任务)执行相应的操作。
格式:

tasks:
  – name: TASK_NAME
   module: arguments
   notify: HANDLER_NAME
handlers:
  – name: HANDLER_NAME
   module: arguments

  • ansible-playbook安装了httpd,当修改了 httpd 的配置文件后我们需要重启httpd服务才会使得配置文件生效;ansible-playbook可以通过触发器来实现一旦发现配置文件有修改就重启服务的操作。
点击查看代码
---
- hosts: centos
  remote_user: root
  tasks:
    - name: install httpd package
      yum:
        name: httpd
        state: present
    - name: copy config file
      copy: src=/applications/httpd.conf dest=/etc/httpd/conf/
      notify: restart httpd service
    - name: httpd service
      service:
        name: httpd
        state: started
        enabled: yes
  handlers:
    - name: restart httpd service
      service: name=httpd state=restarted

8)Ansible-playbook调试器-debug

debug模块在执行期间打印语句,并且可用于调试变量或表达式,而不必停止playbook

---
- hosts: centos
  # gather_facts: no
  tasks:
    - name: 'facts 定义变量'
      set_fact:
        fact_hostname: '{{ ansible_facts.hostname }}'
    - name: 'facts 变量示例'
      debug:
        msg:
        - '{{ ansible_hostname }}'
        - '{{ fact_hostname }}'

9)playbook中的when条件判断

在Ansible中,提供的唯一一个通用的条件判断是when指令,
当when指令的值为true时,则该任务执行,否则不执行该任务。


  • when一个比较常见的应用场景是实现跳过某个主机不执行任务或者只有满足条件的主机执行任务
---
- name: this is when test playbook
  hosts: all
  remote_user: root
  tasks:
   - name: test when
     debug: msg="判断位置"
     when: ansible_default_ipv4.address == "192.168.140.111"

8、Ansible-variables变量详解

1)命令行变量

ansible-playbook命令的命令行中的-e VARS, --extra-vars=VARS,这样就可以直接把自定义的变量传入。
命令行使用"-e '变量名=值' "设置的变量优先级最高,使用以下playbook,调用形式:

  • 一个变量
    ansible-playbook -e "task_type='xxxxxxxxxxxx'" 01_centos_ping.yml
    ansible-playbook --extra-vars='task_type="my_type"' 01_centos_ping.yml
点击查看代码
---
- hosts: centos
  vars:
    task_type: ansible ping
  tasks:
    - name: ' {{ task_type }} '
      ping:
  • 多个变量
    ansible-playbook -e "task_type='xxxxxxxxxxxx' task_msg='hello world'" 03_centos_ping.yml
    ansible-playbook --extra-vars='task_type="my_type" task_msg="hello world"' 03_centos_ping.yml
点击查看代码
---
- hosts: centos
  tasks:
    - name: ' {{ task_type }} '
      debug:
        msg: " {{ task_msg }} "

2)主机和主机组变量

请见第3章第三节

3)playbook中vars定义变量

当前剧本生效,涉及多个剧本不方便,写在剧本开头:

---
- hosts: centos
  vars:
    task_type: ansible ping
  tasks:
    - name: '{{ task_type }} '
      ping:

4)playbook中变量文件

⚠️自身内部的优先级:
host_vars/主机名【或别名】 定义变量 > group_vars/清单组名 定义变量 > group_vars/all 定义变量> inventory 文件中直接定义变量

全局范围内命令行-e设置的变量>清单中的ssh变连接变量等>playbook及其相关配置vars和vars_file>清单中短的其他变量>facts变量>角色role定义的变量
(1)单个文件
所有变量写入到文件中,在剧本中通过vars_files:变量路径导入。

---
- hosts: centos
  vars_files: './vars_files.yml'
  tasks:
    - name: '{{ task_type }} '
      ping:
[root@localhost ansible_variables]# cat vars_files.yml
task_type: ansible ping

(2)独立文件-group_vars
主机组共用的变量文件group_vars:根据主机清单里面的分组创建目录,存放vars.yml,根据主机所属的主机组,自动读取group_vars/组件名/vars.yml文件。

group_vars是一个目录,这个名称固定,必须是和你的inventory文件和ansible.cfg文件位于同一级目录(放在playbook脚本同一目录也行,优先级高些),其下创建的文件需要和你主机清单中的组名称一致,在这个文件中写入变量和值,或者文件名为 all「特殊组」,表示对所有机器主机生效。

---
- hosts: centos
  tasks:
    - name: '{{ task_type }} '
      ping:

[root@localhost group_vars]# tree
.
└── centos
    └── vars.yml

1 directory, 1 file
[root@localhost group_vars]#

(3)独立文件-host_vars

要创建的 host_vars 目录要与 inventory 清单文件在同一目录,或者与要执行的 playbook 的 yml 文件在同一个目录。
host_vars 目录下的文件名是 inventory 清单文件中的主机名或别名。如果有别名那么文件名为别名。

5)ansible内置变量(facts变量)

收集主机的基本信息,如果想提示ansible执行速度可以在playbook脚本中进行关闭gather_facts: no(也可以在ansible.cfg配置文件中关闭)。

我们可以使用setup模块(ansible centos -m setup -a 'filter=ansible_hostname')获取被管理机器的所有facts信息,可以使用filter来过滤指定的信息。setup模块获取的整个facts信息被包装在一个json格式的数据结构中,ansible_facts是最外层的值。

常用facts变量:ansible_hostname等。
通过playbook调用变量,运行一个收集事实并使用debug模块显示ansible_facts变量值的简短playbook:
(1)直接使用:

---
- hosts: centos
  # gather_facts: no
  tasks:
    - name: 'facts 变量示例'
      debug:
        msg:
        - '{{ ansible_hostname }}'

(2)set_fact跨task使用
在前面的task中定义的set_fact变量,可以在后面的task变量中直接调用。

---
- hosts: centos
  # gather_facts: no
  tasks:
    - name: 'facts set_fact变量'
      set_fact:
        fact_hostname: '{{ ansible_facts.hostname }}'
    - name: 'facts 变量示例'
      debug:
        msg:
        - '{{ fact_hostname }}'

6)注册变量-register

注册变量主要是使用register来捕获命令的输出,将其保存在一个临时变量中,便于进行特定操作。

---
- hosts: centos
  tasks:
    - name: "get host port info"
      shell: netstat -lntp
      register: host_port
    - name: "print host port"
      debug:
        # msg: "{{ host_port }}" #输出全部信息
        # msg: "{{ host_port.cmd }}" #引用1
        msg: "{{ host_port['cmd'] }}"

第一个 task 中,使用了 register 注册变量,名为 host_port ;当 shell 模块执行完毕后,会将数据放到该变量中。
第二给 task 中,使用了 debug 模块,并从 host_port 中获取数据。

7)vars_prompt交互变量

参数 解析
prompt 表示对用户的提示信息
private 表示用户在输入时是否隐藏输入的信息
default 表示如果用户没有输入,则此项的默认值

(1)简单交互

---
- hosts: centos
  vars_prompt:
    - name: "one"
      prompt: "请输入第一个值"
      privte: no
    - name: "two"
      prompt: "请输入第二个值"
      default: 'hello'
      private: yes
  tasks:
    - name: dis one value
      debug:
        msg: "{{ one }}"
    - name: dis two value
      debug:
        msg: "{{ two }}"

(2)创建主机清单中机器的用户和密码示例

  • encrypt
    可以指定在密码处可以指定使用sha512对密码进行哈希加密
  • confirm
    可以设置重复确认密码,两次密码不符合会报“VALUES ENTERED DO NOT MATCH ”
---
- hosts: centos
  vars_prompt:
    - name: "name"
      prompt: "请输入用户名"
      privte: no
    - name: "passwd"
      prompt: "请输入密码"
      private: yes
      encrypt: "sha512_crypt"
      confirm: yes
  tasks:
    - name: user & password collent
      user:
        name: "{{ name }}"
        password: "{{ passwd }}"

8)ansible 迭代with_item、with_list、with_dict、with_togther

执行一些重复性操作,比如指安装软件包,批量创建用户,操作某个目录下的所有文件等;
(1)列表字符串等的循环

点击查看代码
---
- hosts: centos
  tasks:
    - name: 列表字符串等的循环
      shell: "echo {{ item }}"
      with_items:
        - nginx
        - vim
        - ifconfig
    - name: 列表字符串等的循环2
      shell: echo {{ item }}
      with_items:
        [nginx2,vim2,ifconfig2]
    - name: 列表字符串等的循环3
      shell: echo {{ item }}
      with_items:
        {nginx3,vim3,ifconfig3}

(2)字典的循环

点击查看代码
---
- hosts: centos
  tasks:
    - name: 字典的循环
      debug:
        msg: "{{ item.name }}:{{ item.age }}"
      with_items:
        - { name: zhangsan,age: 10 }
        - { name: lisi,age: 20 }

(3)外部yml文件中定义的变量引入循环

[root@localhost iteration]# cat define_var.yml
---
apache:
  protocol: http
  port: [80,8080]
  timeout: 20
点击查看代码
---
- hosts: centos
  vars_files: ./define_var.yml
  tasks:
    - name: 外部yml文件中定义的变量引入循环
      debug:
        msg: "{{ item }} \n,{{ item.port }}\n,{{ item.port[0] }}"
      with_items:
        - "{{ apache }}"
点击查看代码
---
- hosts: centos
  tasks:
    - name: with items
      debug:
        msg: "{{ item  }}"
      with_items:
        - test1
        - test2
    - name: with items2
      debug:
        msg: "{{ item }}"
      with_items: "{{ url_list }}"
      vars:
        url_list:
          - https://www.baidu.com
          - https://www.taobao.com

9、tags标签-调试

给一些模块加上标签,运行剧本的时候可以运行指定标签的内容,排除指定标签。

1)执行指定tag的task

ansible-playbook --tags="install_nginx" 07_nginx_present.yml
ansible-playbook --tags="install_nginx,start_nginx" 07_nginx_present.yml

2)排除指定tag的task

ansible-playbook --skip-tags="install_nginx,conf_nginx" 07_nginx_present.yml

3)查看playbook中的所有tag

可以通过--list-tags参数列出指定的playbook中所有的tag
ansible-playbook --list-tags 07_nginx_present.yml

点击查看代码
---
- hosts: centos
  remote_user: root
  tasks:
    - name: install nginx
      yum: name=nginx state=present
      tags: install_nginx
    - name: copy nginx conf
      copy: src=/applications/nginx.conf dest=/etc/nginx/nginx.conf backup=yes
      tags: conf_nginx
      notify: reload
    - name: start nginx service
      service: name=nginx state=started
      tags: start_nginx
  handlers:
    - name: reload
      service: name=nginx state=restarted

4)打tag的几种方式

(1)为一个任务指定一个标签

tags: conf_nginx

(2)为一个任务指定多个标签

tags:
  - install_nginx
  - nginx_web

tags: ['install_nginx','nginx_web']

tags: install_nginx,nginx_web

(3)为一个play指定一组标签
当为一个play指定一组标签后,该play下的所有task都会自动继承该标签,各task也可以自定义自己的标签。

- name: configure web servers 
  hosts: centos
  remote_user: root
  tags: 
    - tag_nginx
  tasks:
    ...

5)ansible内置tag

除了用户自定义tag,ansible也内置了几个tag,这些tag都包含特殊含义:
  常用的选项如下:

内置tag 说明
always 一旦某个task被打上了always的tag,则无论是playbook的完整执行,还是指定tag执行,不管你指定的tag是啥,该任务总是会被执行。除非明确指定"--skip-tags=always"选项,才不会执行该task。
never 该标签与always正好相反,总是不会执行,除非明确指定"--tags=never"选项
tagged 在调用时使用--tags tagged所有打了tag的任务都会被执行,包含never tag的除外,没有标签的不会被执行;在调用时使用--skip-tags tagged所有打了tag的任务都不会被执行,包括always tag也不会被执行
untagged 在调用时使用--tags untagged所有未打tag的任务都会被执行,打了always tag的也会被执行;在调用时使用--skip-tags untagged所有未打tag的任务都不会被执行
all 表示所有任务都会被执行,在默认情况下,不指定任何标签,则使用的就是该标签

10、Ansible-Templates

Jinja是基于Python的模板引擎。Template类是Jinja的一个重要组件,可以看作是一个编译过的模板文件,用来产生目标文本,传递Python的变量给模板去替换模板中的标记。
一定要以.j2 为后缀的 template 模板文件

1)templates实例

本次我们以改变nginx的配置文件为例,来展现Templates模块的运用:
(1)准备Jinjia模板
先从nginx.conf复制一份配置文件命名为nginx.conf.j2,然后将nginx.conf.j2中需要替换的部分使用模板进行标记,{{ 变量名 }},其他部分不变

[root@localhost playbook]# cat /applications/nginx.conf.j2
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes {{ ansible_processor_vcpus }};
listen {{ nginxport }};
#其他部分略

(2)编写剧本,定义变量

点击查看代码
---
- hosts: centos
  vars:
    - nginxname: nginx
      nginxport: 80
  tasks:
    - name: install {{ nginxname }}
      yum: name={{ nginxname }} state=present
    - name: template {{ nginxname }}.conf
      template: src=/applications/{{ nginxname }}.conf.j2 dest=/etc/{{ nginxname }}/{{ nginxname }}.conf backup=yes
      notify: nginxreload
      tags: nginxreload
    - name: start {{ nginxname }} service
      service: name={{ nginxname }} state=started
      tags: nginxstart
  handlers:
    - name: nginxreload
      service: name={{ nginxname }} state=restarted

⚠️如果修改nginx端口失败,可以查看tcp的容许端口:
semanage port -l|grep http_port_t

# add
semanage port -a -t http_port_t -p tcp 8081
# del
semanage port -d -t http_port_t -p tcp 8081

(3)运行指定tag
ansible-playbook 08_template_nginx.yml -t nginxreload

11、Ansible-Roles

参考:
https://www.cnblogs.com/breezey/p/10996658.html
https://www.cnblogs.com/keerya/p/7987886.html
https://www.cnblogs.com/juzib/p/17269588.html

posted @ 2024-06-19 19:11  权杖攻城狮  阅读(20)  评论(0编辑  收藏  举报