Ansible

ansible是个什么东西呢?官方的title是“Ansible is Simple IT Automation”——简单的自动化IT工具。这个工具的目标有这么几项:

  • 自动化部署APP;
  • 自动化管理配置项;
  • 自动化的持续交互;
  • 自动化的(AWS)云服务管理;

官方:https://docs.ansible.com/ansible/latest/index.html

所有的这几个目标从本质上来说都是在一个台或者几台服务器上,执行一系列的命令而已。通俗的说就是批量的在远程服务器上执行命令。当然,最主要的是它是基于 paramiko 开发的。这个paramiko是什么呢?它是一个纯Python实现的ssh协议库。不需要在远程主机上安装client/agents,因为它们是基于ssh来和远程主机通讯的。

简单归纳一下:基于 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用 YMAL 及 Jinja2模板语言,更强的远程命令执行操作。

ansible的特点

部署简单, 只需要在控制主机上部署ansible环境,被控制端上只要求安装ssh和python 2.5以上版本,这个对于类unix系统来说相当与无需配置.

  • no angents: 被管控节点无需安装agent;
  • no server: 无服务端,使用是直接调用命名;
  • modules in any languages: 基于模块工作, 可以使用任意语言开发模块;
  • 易读的语法: 基于yaml语法编写playbook;
  • 基于推送模式: 不同于puppet的拉取模式,直接由调用者控制变更在服务器上发生的时间;
  • 模块是幂等性的:定义的任务已存在则不会做任何事情,意味着在同一台服务器上多次执行同一个playbook是安全的;

ansible基本架构图:

1. Ansible基础 - 图1

从上图可以了解到其由以下部分组成:

  • 核心:ansible
  • 核心模块(Core Modules):这些都是ansible自带的模块
  • 扩展模块(Custom Modules):如果核心模块不足以完成某种功能,可以添加扩展模块
  • 插件(Plugins):完成模块功能的补充
  • 剧本(Playbooks):ansible的任务配置文件,将多个任务定义在剧本中,由ansible自动执行
  • 连接插件(Connectior Plugins):ansible基于连接插件连接到各个主机上,虽然ansible是使用ssh连接到各个主机的,但是它还支持其他的连接方法,所以需要有连接插件
  • 主机群(Host Inventory):定义ansible管理的主机

一. 安装Ansible及配置文件

Ansible是一种无代理程序自动化工具,默认情况下会通过SSH协议管理计算机。安装后,Ansible不会添加数据库,并且没有启动或运行的守护程序。您只需要将其安装在一台计算机上(可以很容易地是一台笔记本电脑),它就可以从该中心管理整个远程计算机。当Ansible管理远程计算机时,它不会在其上安装或运行软件,因此,在移至新版本时如何升级Ansible并没有真正的问题。

  • 控制节点:Ansible可以在装有Python 2(2.7版)或Python 3(3.5版及更高版本)的任何计算机上运行。包括Red Hat,Debian,CentOS,macOS,任何BSD等。需要SSH支持;
  • 控制节点不支持Windows;
  • 被管理节点上需要有SSH支持,且需要Python 2(2.6版或更高版本)或Python 3(3.5版或更高版本);
  • 如果被管理节点上启用了SELinux,则安装libselinux-python;

安装方式:

  • 通过包管理工具YUM进行安装
  • 通过pip进行安装
  • 源码包进行安装

官方:https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html
建议使用YUM进行安装,需要epel源支持

  1. # yum install ansible

查看版本

  1. [root@localhost ~]# ansible --version
  2. ansible 2.9.7
  3. config file = /etc/ansible/ansible.cfg
  4. configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  5. ansible python module location = /usr/lib/python2.7/site-packages/ansible
  6. executable location = /usr/bin/ansible
  7. python version = 2.7.5 (default, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

1.1 ansible 相关概念

Ansible与节点有关的重要术语包括控制节点,受管节点,清单和主机文件:

  • 控制节点(Control node):指安装了Ansible的主机,也叫Ansible服务器端,管理机。 Ansible控制节点主要用于发布运行任务,执行控制命令。Ansible的程序都安装在控制节点上,控制节点需要安装Python和Ansible所需的各种依赖库。注意:目前Ansible还不能安装在Windows下。
  • 受控节点(Managed nodes):也叫客户机,就是想用Ansible执行任务的客户服务器。
  • 清单(Inventory):受控节点的列表,就是所有要管理的主机列表。
  • host文件:清单列表通常保存在一个名为hosts文件中。在hosts文件中,可以使用IP地址或者主机名来表示具体的管理主机和认证信息,并可以根据主机的用户进行分组。缺省文件:/etc/ansible/hosts,可以通过-i指定自定义的host文件。
  • 模块(Modules):模块是Ansible执行特定任务的代码块。比如:添加用户,上传文件和对客户机执行ping操作等。Ansible现在默认自带450多个模块,,Ansible Galaxy公共存储库则包含大约1600个模块。
  • 任务(Task):是Ansible客户机上执行的操作。可以使用ad-hoc单行命令执行一个任务。
  • 剧本(Playbook):是利用YAML标记语言编写的可重复执行的任务的列表,playbook实现任务的更便捷的读写和贡献。比如,在Github上有大量的Ansible playbooks共享。
  • 角色(roles):角色是Ansible 1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。

1.2 ansible配置文件

ansible 程序结构

  • 配置文件目录:/etc/ansible/
  • 执行文件目录:/usr/bin/
  • Lib库依赖目录:/usr/lib/pythonX.X/site-packages/ansible/
  • Help文档目录:/usr/share/doc/ansible-X.X.X/
  • Man文档目录:/usr/share/man/man1/

ansible配置文件查找顺序

ansible与我们其他的服务在这一点上有很大不同,这里的配置文件查找是从多个地方找的,顺序如下:

  • 检查环境变量ANSIBLE_CONFIG指向的路径文件(export ANSIBLE_CONFIG=/etc/ansible.cfg);
  • ~/.ansible.cfg,检查当前目录下的ansible.cfg配置文件;
  • /etc/ansible/ansible.cfg配置文件。

ansible配置文件

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

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

ansible主机清单

在配置文件中,我们提到了资源清单,这个清单就是我们的主机清单,里面保存的是一些 ansible 需要连接管理的主机列表。我们可以来看看他的定义方式:

官方参照:https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html

##直接指明主机或主机名,没有分组,在分组前面进行定义
green.example.com
blue.example.com
192.168.100.1
192.168.100.10
##定义一个主机组[组名]把地址或主机名加进去
[webservers]
alpha.example.org
beta.example.org
192.168.1.100
192.168.1.110
## 也可以这样来写多个主机
www[001:006].example.com
##也可以定义字母范围
[databases]
db-[a:f].example.com

##一个主机也可以在多个组中

默认有两个组:
  • all:代表所有的主机
  • ungrouped:包含没有在其它组中的所有主机

添加变量到清单中
##分配变量到一个单一的主机:host variables
[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909

##如果是非标准的SSH端口,可以这样写
badwolf.example.com:5309

##连接变量也可以与主机变量一起工作
[targets]

localhost              ansible_connection=local
other1.example.com     ansible_connection=ssh        ansible_user=myuser
other2.example.com     ansible_connection=ssh        ansible_user=myotheruser

##还可以定义别名
jumper ansible_port=5555 ansible_host=192.0.2.50

##分配变量到多个主机:group variables
[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com

继承变量值,为组中组设置组变量。
  • 可以使用:children后缀进行组嵌套组;
  • 可以使用:vars后缀应用变量到组中组;
[atlanta]
host1
host2

[raleigh]
host2
host3

##组中包含其他的组
[southeast:children] 
atlanta
raleigh

[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2

[usa:children]
southeast
northeast
southwest
northwest

组织组和主机变量

Ansible中的首选实践实际上不是在主Inventory文件中存储变量。除了将变量直接存储在INI文件中,主机和组变量可以存储在相对于Inventory文件的单个文件中。这些变量文件必须采用YAML格式。有效的文件扩展名包括’.yml’,’.yaml’,’.json’或者没有文件扩展名。

假设主机资产文件路径是/etc/ansible/hosts,如果主机被命名为“foosball”,并且在“raleigh”和“webservers”组中,以下位置的YAML文件中的变量将提供给主机:

/etc/ansible/group_vars/raleigh
/etc/ansible/group_vars/webservers
/etc/ansible/host_vars/foosball

例如,如果按数据中心对清单中的主机进行分组,并且每个数据中心使用其自己的NTP服务器和数据库服务器,则可以创建一个名为/etc/ansible/group_vars/raleigh文件来存储raleigh组的变量:

---
ntp_server: acme.example.org
database_server: storage.example.org

常用资产内置变量
ansible_ssh_host # 远程主机
ansible_ssh_port # 指定远程主机ssh端口
ansible_ssh_user # ssh连接远程主机的用户,默认root
ansible_ssh_pass # 连接远程主机使用的密码,在文件中明文,建议使用--ask-pass或者使用SSH keys
ansible_sudo_pass # sudo密码, 建议使用--ask-sudo-pass
ansible_connection # 指定连接类型: local, ssh, paramiko
ansible_ssh_private_key_file # ssh 连接使用的私钥
ansible_shell_type # 指定连接对端的shell类型, 默认sh,支持csh,fish
ansible_python_interpreter # 指定对端使用的python编译器的路径

二. 使用ansible命令

2.1 ansible 任务执行模式

Ansible 系统由控制主机对被管节点的操作方式可分为两类,即ad-hoc和playbook:

  • ad-hoc模式(点对点模式):
    使用单个模块,支持批量执行单条命令。ad-hoc 命令是一种可以快速输入的命令,而且不需要保存起来的命令。类似于shell命令的执行。
  • playbook模式(剧本模式):是Ansible主要管理方式,也是Ansible功能强大的关键所在。playbook通过多个task集合完成一类功能,如Web服务的安装部署、数据库服务器的批量备份等。可以简单地把playbook理解为通过组合多条ad-hoc操作的配置文件。类似于shell脚本方式。

2.2 ansible执行流程

1. Ansible基础 - 图2

简单理解就是Ansible在运行时, 首先读取ansible.cfg中的配置, 根据规则获取Inventory中的管理主机列表, 并行的在这些主机中执行配置的任务, 最后等待执行返回的结果。

  1. 加载自己的配置文件,默认/etc/ansible/ansible.cfg;
  2. 查找对应的主机配置文件,找到要执行的主机或者组;
  3. 加载自己对应的模块文件,如 command;
  4. 通过ansible将模块或命令生成对应的临时py文件(python脚本), 并将该文件传输至远程服务器;
  5. 对应执行用户的家目录的.ansible/tmp/XXX/XXX.PY文件;
  6. 给文件 +x 执行权限;
  7. 执行并返回结果;
  8. 删除临时py文件,sleep 0退出;

2.3 ansible常用命令

常用命令集

/usr/bin/ansible  ##Ansibe 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界面可与用户交互的命令执行工具

##其中,比较常用的是/usr/bin/ansible和/usr/bin/ansible-playbook

ansible-doc 命令

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

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

例如:

##查看和copy有关的模块
[root@localhost ~]# ansible-doc -l | grep copy
vsphere_copy                                                  Copy a file to a VMware datastore                               
win_copy                                                      Copies files to remote locations on windows hosts               
bigip_file_copy                                               Manage files in datastores on a BIG-IP                          
ec2_ami_copy                                                  copies AMI between AWS regions, return new image id             
win_robocopy                                                  Synchronizes the contents of two directories using Robocopy     
copy                                                          Copy files to remote locations                                  
na_ontap_lun_copy                                             NetApp ONTAP copy LUNs                                          
icx_copy                                                      Transfer files from or to remote Ruckus ICX 7000 series switches
unarchive                                                     Unpacks an archive after (optionally) copying it from the local ...
ce_file_copy                                                  Copy a file to a remote cloudengine device over SCP on HUAWEI Cl...
postgresql_copy                                               Copy data between a file/program and a PostgreSQL table         
ec2_snapshot_copy                                             copies an EC2 snapshot and returns the new Snapshot ID          
nxos_file_copy                                                Copy a file to a remote NXOS device                             
netapp_e_volume_copy                                          NetApp E-Series create volume copy pairs

## 查看copy模块的用法
[root@localhost ~]# ansible-doc -s copy
- name: Copy files to remote locations
  copy:
      attributes:            # The attributes the resulting file or directory should have. To get supported flags look at the man
                               page for `chattr' on the target system. This string should contain
                               the attributes in the same order as the one displayed by `lsattr'.
                               The `=' operator is assumed as default, otherwise `+' or `-'
                               operators need to be included in the string.
      backup:                # Create a backup file including the timestamp information so you can get the original file back if
                               you somehow clobbered it incorrectly.
....省略

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可查看更详细信息

例如:

##在所有远程主机上执行uname -r命令
[root@localhost ~]# ansible all -m command -a 'uname -r' -k
SSH password: 
10.0.0.129 | CHANGED | rc=0 >>
3.10.0-1062.el7.x86_64
10.0.0.11 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: ssh: connect to host 10.0.0.11 port 22: No route to host", 
    "unreachable": true
}
10.0.0.31 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: ssh: connect to host 10.0.0.31 port 22: No route to host", 
    "unreachable": true
}

##使用ping 模块
[root@localhost ~]# ansible all -m ping -k
SSH password: 
10.0.0.129 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
10.0.0.31 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: ssh: connect to host 10.0.0.31 port 22: No route to host", 
    "unreachable": true
}
10.0.0.11 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: ssh: connect to host 10.0.0.11 port 22: No route to host", 
    "unreachable": true
}

常见的 patterns

Description Pattern(s) Targets
所有主机 all (or *)
一个主机 host1
多个主机 host1:host2 (or host1,host2)
一个组 webservers
多个组 webservers:dbservers all hosts in webservers plus all hosts in dbservers
排除组 webservers:!atlanta all hosts in webservers except those in atlanta
组的交集 webservers:&staging any hosts in webservers that are also in staging

例如:

webservers:dbservers:&staging:!phoenix
##webservers和dbservers组中的且在staging组中的主机,且不包含在phoenix组中的主机。

还可以使用通配符

192.0.\*
\*.example.com
\*.com

##可以同时混合通配符模式和组
one*.com:dbservers

2.4 常用模块

Ansible 提供了非常丰富的功能模块,包括:

  • Cloud modules:云计算模块
  • Clustering modules:集群模块
  • Commands modules:命令行模块
  • Crypto modules:密码模块
  • Database modules:数据库模块
  • Files modules:文件模块
  • Identity modules:身份验证模块
  • Inventory modules:资产管理
  • Messaging modules:消息队列
  • Monitoring modules:监控管理
  • Net Tools modules:网络工具
  • Network modules:网络模块
  • Notification modules:通知管理
  • Packaging modules:包管理
  • Remote Management modules:远程管理
  • Source Control modules:版本控制
  • Storage modules:存储模块
  • System modules:系统管理
  • Utilities modules:公共服务
  • Web Infrastructure modules:web基础服务
  • Windows modules:Windows模块

官方:https://docs.ansible.com/ansible/latest/modules/modules_by_category.html

ping 模块

尝试连接到主机,如果成功返回pong

  • 这不是ICMP ping,这只是一个简单的测试模块,需要在远程节点上使用Python。
  • 对于Windows目标,请改用win_ping模块。
  • 对于网络目标,请改用net_ping模块。
[root@localhost ~]# ansible test -m ping -k
SSH password: 
10.0.0.132 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

command 模块

这个模块可以直接在远程主机上执行命令,并将结果返回本主机。是默认的模块,即’-m command’可以省略掉。

[root@localhost ~]# ansible test -m command -a 'ls -l /boot' -k
SSH password: 
10.0.0.132 | CHANGED | rc=0 >>
总用量 125088
-rw-r--r--. 1 root root   152976 8月   8 2019 config-3.10.0-1062.el7.x86_64
drwx------. 3 root root       17 11月  9 2018 efi
drwxr-xr-x. 2 root root       27 11月  4 2019 grub
drwx------. 5 root root       97 11月  4 2019 grub2
-rw-------. 1 root root 78626163 11月  4 2019 initramfs-0-rescue-cbb88e9dbaf54b458691a39a30543fa7.img
-rw-------. 1 root root 31915921 11月  4 2019 initramfs-3.10.0-1062.el7.x86_64.img
-rw-r--r--. 1 root root   318717 8月   8 2019 symvers-3.10.0-1062.el7.x86_64.gz
-rw-------. 1 root root  3594971 8月   8 2019 System.map-3.10.0-1062.el7.x86_64
-rwxr-xr-x. 1 root root  6734016 11月  4 2019 vmlinuz-0-rescue-cbb88e9dbaf54b458691a39a30543fa7
-rwxr-xr-x. 1 root root  6734016 8月   8 2019 vmlinuz-3.10.0-1062.el7.x86_64
  • 命令模块接受命令名称,后面是空格分隔的列表参数。
  • 给定的命令将在所有选定的节点上执行。它不会通过shell进行处理,比如$HOME和操作如”<”,”>”,”|”,”;”,”&” 工作(需要使用(shell)模块实现这些功能)。
  • 该命令不支持管道命令”|”。

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

  • chdir:在执行命令之前,先切换到该目录
  • executable:切换shell来执行命令,需要使用命令的绝对路径
  • free_form:要执行的Linux指令,一般使用Ansible的-a参数代替。
  • creates:一个文件名,当这个文件存在,则该命令不执行,可以用来做判断
  • removes:一个文件名,这个文件不存在,则该命令不执行
##先切换到/boot目录,然后再执行ls命令
[root@localhost ~]# ansible test  -a 'chdir=/boot ls' -k
SSH password: 
10.0.0.132 | CHANGED | rc=0 >>
config-3.10.0-1062.el7.x86_64
efi
grub
grub2
initramfs-0-rescue-cbb88e9dbaf54b458691a39a30543fa7.img
initramfs-3.10.0-1062.el7.x86_64.img
symvers-3.10.0-1062.el7.x86_64.gz
System.map-3.10.0-1062.el7.x86_64
vmlinuz-0-rescue-cbb88e9dbaf54b458691a39a30543fa7
vmlinuz-3.10.0-1062.el7.x86_64

##如果/root/aaa.jpg存在,则不执行“ls”命令
[root@localhost ~]# ansible test  -a 'creates=/root/aaa.jpg ls' -k
SSH password: 
10.0.0.132 | SUCCESS | rc=0 >>
skipped, since /root/aaa.jpg exists

##如果/root/aaa.jpg不存在,则不执行“ls”命令
[root@localhost ~]# ansible test  -a 'removes=/root/aaa.jpg ls' -k
SSH password: 
10.0.0.132 | SUCCESS | rc=0 >>
skipped, since /root/aaa.jpg does not exist

shell模块

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

[root@localhost ~]# ansible test  -m shell -a 'cat /etc/passwd | grep root' -k
SSH password: 
10.0.0.132 | CHANGED | rc=0 >>
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

script

在远程主机执行主控端的shell/python脚本,该模块直接指定脚本的路径即可。

# ansible webservers -m script -a '/etc/ansible/test.sh'

copy模块

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

  • src:被复制到远程主机的本地文件。可以是绝对路径,也可以是相对路径。如果路径是一个目录,则会递归复制,用法类似于”rsync”
  • content:用于替换”src”,可以直接指定文件的值
  • dest:必选项,将源文件复制到的远程主机的绝对路径
  • backup:当文件内容发生改变后,在覆盖之前把源文件备份,备份文件包含时间信息
  • directory_mode:递归设定目录的权限,默认为系统默认权限
  • force:当目标主机包含该文件,但内容不同时,设为”yes”,表示强制覆盖;设为”no”,表示目标主机的目标位置不存在该文件才复制。默认为”yes”
  • file模块使用的选项也都可以使用
##复制文件,并设置权限及属主属组
[root@ansible-manager ~]# ansible test -m copy -a 'src=/root/img.jpg dest=/tmp owner=root group=root mode=0700' -k
SSH password: 
10.0.0.136 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "aa07377aa33813e17cd6868109a890e9f914e543", 
    "dest": "/tmp/img.jpg", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "34969438a7ee5838e61c1154c768b304", 
    "mode": "0700", 
    "owner": "root", 
    "size": 83437, 
    "src": "/root/.ansible/tmp/ansible-tmp-1589945168.8-9178-218360001328627/source", 
    "state": "file", 
    "uid": 0
}
10.0.0.135 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "aa07377aa33813e17cd6868109a890e9f914e543", 
    "dest": "/tmp/img.jpg", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "34969438a7ee5838e61c1154c768b304", 
    "mode": "0700", 
    "owner": "root", 
    "size": 83437, 
    "src": "/root/.ansible/tmp/ansible-tmp-1589945168.79-9176-39679609169241/source", 
    "state": "file", 
    "uid": 0
}

##给定内容生成文件,并制定权限
[root@ansible-manager ~]# ansible test -m copy -a 'content="Hello World!\n" dest=/tmp/testfile mode=666' -k
SSH password: 
10.0.0.135 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "a0b65939670bc2c010f4d5d6a0b3e4e4590fb92b", 
    "dest": "/tmp/testfile", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "8ddd8be4b179a529afa5f2ffae4b9858", 
    "mode": "0666", 
    "owner": "root", 
    "size": 13, 
    "src": "/root/.ansible/tmp/ansible-tmp-1589945341.35-9289-203290782277786/source", 
    "state": "file", 
    "uid": 0
}
10.0.0.136 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "a0b65939670bc2c010f4d5d6a0b3e4e4590fb92b", 
    "dest": "/tmp/testfile", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "8ddd8be4b179a529afa5f2ffae4b9858", 
    "mode": "0666", 
    "owner": "root", 
    "size": 13, 
    "src": "/root/.ansible/tmp/ansible-tmp-1589945341.36-9291-161259367368874/source", 
    "state": "file", 
    "uid": 0
}

##备份文件,然后覆盖新内容
[root@ansible-manager ~]# ansible test -m copy -a 'content="Hello John!\n" dest=/tmp/testfile mode=666 backup=yes' -k
SSH password: 
10.0.0.135 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "backup_file": "/tmp/testfile.2284.2020-05-20@11:35:58~", 
    "changed": true, 
    "checksum": "6dd74b2791ad4eabe0be6c5020b358009957b80e", 
    "dest": "/tmp/testfile", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "5ea04c7e09659cd99acbed92d875d646", 
    "mode": "0666", 
    "owner": "root", 
    "size": 12, 
    "src": "/root/.ansible/tmp/ansible-tmp-1589945757.74-9434-5447632282428/source", 
    "state": "file", 
    "uid": 0
}
10.0.0.136 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "backup_file": "/tmp/testfile.2854.2020-05-20@11:35:58~", 
    "changed": true, 
    "checksum": "6dd74b2791ad4eabe0be6c5020b358009957b80e", 
    "dest": "/tmp/testfile", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "5ea04c7e09659cd99acbed92d875d646", 
    "mode": "0666", 
    "owner": "root", 
    "size": 12, 
    "src": "/root/.ansible/tmp/ansible-tmp-1589945757.74-9436-146865133877038/source", 
    "state": "file", 
    "uid": 0
}

##到目的主机查看
[root@ansible01 ~]# ls -l /tmp/testfile*
-rw-rw-rw- 1 root root 12 5月  20 11:35 /tmp/testfile
-rw-rw-rw- 1 root root 13 5月  20 11:29 /tmp/testfile.2284.2020-05-20@11:35:58~

file文件

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

##模块可以做到修改文件的属主和权限,(在这里可替换为 copy 模块,是等效的):
$ ansible webservers -m file -a "dest=/srv/foo/a.txt mode=600"
$ ansible webservers -m file -a "dest=/srv/foo/b.txt mode=600 owner=root group=root"

##使用 file 模块也可以创建目录,与执行 mkdir -p 效果类似:
$ ansible webservers -m file -a "dest=/path/to/c mode=755 owner=root group=root state=directory"

##删除目录(递归的删除)和删除文件:
$ ansible webservers -m file -a "dest=/path/to/c state=absent"

fetch模块

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

  • dest:用来存放文件的目录
  • src:在远程拉取的文件,并且必须是一个file,不能是目录
[root@ansible-manager ~]# ansible test -m fetch -a 'src=/etc/ssh/sshd_config dest=/data' -k
SSH password: 
10.0.0.135 | CHANGED => {
    "changed": true, 
    "checksum": "f2b054756f78acb1169cbc8b8f347a69630cb8bc", 
    "dest": "/data/10.0.0.135/etc/ssh/sshd_config", 
    "md5sum": "40d961cd3154f0439fcac1a50bd77b96", 
    "remote_checksum": "f2b054756f78acb1169cbc8b8f347a69630cb8bc", 
    "remote_md5sum": null
}
10.0.0.136 | CHANGED => {
    "changed": true, 
    "checksum": "f2b054756f78acb1169cbc8b8f347a69630cb8bc", 
    "dest": "/data/10.0.0.136/etc/ssh/sshd_config", 
    "md5sum": "40d961cd3154f0439fcac1a50bd77b96", 
    "remote_checksum": "f2b054756f78acb1169cbc8b8f347a69630cb8bc", 
    "remote_md5sum": null
}
[root@ansible-manager ~]# tree /data/
/data/
├── 10.0.0.135
│   └── etc
│       └── ssh
│           └── sshd_config
└── 10.0.0.136
    └── etc
        └── ssh
            └── sshd_config

6 directories, 2 files

cron模块

该模块适用于管理cron计划任务的。其使用的语法跟Linux中的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 # 以哪个用户的身份执行
##添加一个计划任务
[root@ansible-manager ~]# ansible test -m cron -a 'name="check time every 5 min" minute=*/5 job="/usr/bin/date >> /tmp/datetime"' -k
SSH password: 
10.0.0.135 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": [
        "check time every 5 min"
    ]
}
10.0.0.136 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": [
        "check time every 5 min"
    ]
}

##在目的被控制主机上查看一下
[root@ansible01 ~]# crontab -l
#Ansible: check time every 5 min
*/5 * * * * /usr/bin/date >> /tmp/datetime

##删除任务
[root@ansible-manager ~]# ansible test -m cron -a 'name="check time every 5 min" minute=*/5 job="/usr/bin/date >> /tmp/datetime" state=absent' -k
SSH password: 
10.0.0.135 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": []
}
10.0.0.136 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": []
}
##删除的时候name和job是必须要写的参数

yum模块

该模块主要用于软件的安装。其选项如下:

  • name  #所安装的包的名称
  • state  #present—>安装, latest—>安装最新的, absent—> 卸载软件。
  • update_cache  #强制更新yum的缓存
  • conf_file  #指定远程yum安装时所依赖的配置文件(安装本地已有的包)。
  • disable_pgp_check  #是否禁止GPG checking,只用于presentor latest。
  • disablerepo  #临时禁止使用的yum库。 只用于安装或更新时。
  • enablerepo  #临时使用的yum库。只用于安装或更新时。
##安装软件包lftp
[root@ansible-manager ~]# ansible test -m yum -a 'name=lftp state=present' 

##卸载软件包lftp
[root@ansible-manager ~]# ansible test -m yum -a 'name=lftp state=absent'

service 模块

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

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

##停止服务并设置开机不自启动
[root@ansible-manager ~]# ansible test -m service -a 'name=httpd state=stopped enabled=false'

user 模块

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

  • comment:用户的描述信息
  • createhome:是否创建家目录
  • force:在使用state=absent时, 行为与userdel –force一致.
  • group:指定基本组
  • groups:指定附加组,如果指定为(groups=)表示删除所有组
  • home:指定用户家目录
  • name:指定用户名
  • password:指定用户密码
  • remove:在使用state=absent时, 行为是与userdel –remove一致
  • shell:指定默认shell
  • state:设置帐号状态,不指定为创建,指定值为absent表示删除
  • system:当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
  • uid:指定用户的uid
## 查询远程主机是否有lisi用户
[root@ansible-manager ~]# ansible test -a 'getent passwd lisi'
192.168.154.136 | FAILED | rc=2 >>
non-zero return code
192.168.154.138 | FAILED | rc=2 >>
non-zero return code

## 创建lisi用户
[root@ansible-manager ~]# ansible test -m user -a 'name=lisi uid=3000 shell=/sbin/nologin'
192.168.154.138 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "comment": "", 
    "create_home": true, 
    "group": 3000, 
    "home": "/home/lisi", 
    "name": "lisi", 
    "shell": "/sbin/nologin", 
    "state": "present", 
    "system": false, 
    "uid": 3000
}
192.168.154.136 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "comment": "", 
    "create_home": true, 
    "group": 3000, 
    "home": "/home/lisi", 
    "name": "lisi", 
    "shell": "/sbin/nologin", 
    "state": "present", 
    "system": false, 
    "uid": 3000
}

##再次查看lisi用户
[root@ansible-manager ~]# ansible test -a 'getent passwd lisi'
192.168.154.138 | CHANGED | rc=0 >>
lisi:x:3000:3000::/home/lisi:/sbin/nologin
192.168.154.136 | CHANGED | rc=0 >>
lisi:x:3000:3000::/home/lisi:/sbin/nologin

##删除lisi用户
[root@ansible-manager ~]# ansible test -m user -a 'name=lisi state=absent'
192.168.154.138 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "force": false, 
    "name": "lisi", 
    "remove": false, 
    "state": "absent"
}
192.168.154.136 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "force": false, 
    "name": "lisi", 
    "remove": false, 
    "state": "absent"
}

group 模块

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

  • gid=:设置组的GID号
  • name=:指定组的名称
  • state=:指定组的状态,默认为创建,设置值为absent为删除
  • system=:设置值为yes,表示创建为系统组
##创建caiwubu组
[root@ansible-manager ~]# ansible test -m group -a 'name=caiwubu gid=1500'
192.168.154.136 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "gid": 1500, 
    "name": "caiwubu", 
    "state": "present", 
    "system": false
}
192.168.154.138 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "gid": 1500, 
    "name": "caiwubu", 
    "state": "present", 
    "system": false
}

##查看是否成功创建
[root@ansible-manager ~]# ansible test -a 'getent group caiwubu'
192.168.154.138 | CHANGED | rc=0 >>
caiwubu:x:1500:
192.168.154.136 | CHANGED | rc=0 >>
caiwubu:x:1500:

##删除组
[root@ansible-manager ~]# ansible test -m group -a 'name=caiwubu state=absent'
192.168.154.136 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "name": "caiwubu", 
    "state": "absent"
}
192.168.154.138 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "name": "caiwubu", 
    "state": "absent"
}

setup 模块

  • 该模块主要用于收集信息,是通过调用facts组件来实现的。
  • facts组件是Ansible用于采集被管机器设备信息的一个功能,我们可以使用setup模块查机器的所有facts信息,可以使用filter来查看指定信息。整个facts信息被包装在一个JSON格式的数据结构中,ansible_facts是最上层的值。
  • facts就是变量,内建变量。每个主机的各种信息,cpu颗数、内存大小等,会存在facts中的某个变量中,调用后返回很多对应主机的信息,在后面的操作中可以根据不同的信息来做不同的操作。
  • 可以使用其变量,直接在playbook中应用
## 直接拿到被控主机所有的变量值
[root@ansible-manager ~]# ansible test -m setup

##通过filter来过滤需要的值
[root@ansible-manager ~]# ansible test -m setup -a 'filter="*mem*"'

##setup模块还有一个很好用的功能就是可以保存我们所筛选的信息至我们的主机上,同时,文件名为被管控主机的IP
[root@ansible-manager ~]# ansible test -m setup -a 'filter="*mem*"' --tree  /tmp/facts
192.168.154.138 | SUCCESS => {
    "ansible_facts": {
        "ansible_memfree_mb": 1666, 
        "ansible_memory_mb": {
            "nocache": {
                "free": 1774, 
                "used": 206
            }, 
            "real": {
                "free": 1666, 
                "total": 1980, 
                "used": 314
            }, 
            "swap": {
                "cached": 0, 
                "free": 2047, 
                "total": 2047, 
                "used": 0
            }
        }, 
        "ansible_memtotal_mb": 1980, 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
192.168.154.136 | SUCCESS => {
    "ansible_facts": {
        "ansible_memfree_mb": 6819, 
        "ansible_memory_mb": {
            "nocache": {
                "free": 7192, 
                "used": 771
            }, 
            "real": {
                "free": 6819, 
                "total": 7963, 
                "used": 1144
            }, 
            "swap": {
                "cached": 0, 
                "free": 2047, 
                "total": 2047, 
                "used": 0
            }
        }, 
        "ansible_memtotal_mb": 7963, 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
[root@ansible-manager ~]# cd /tmp/facts/
[root@ansible-manager facts]# ls
192.168.154.136  192.168.154.138
[root@ansible-manager facts]# cat 192.168.154.136
{"ansible_facts": {"ansible_memfree_mb": 6819, "ansible_memory_mb": {"nocache": {"free": 7192, "used": 771}, "real": {"free": 6819, "total": 7963, "used": 1144}, "swap": {"cached": 0, "free": 2047, "total": 2047, "used": 0}}, "ansible_memtotal_mb": 7963, "discovered_interpreter_python": "/usr/bin/python"}, "changed": false}

常用的过滤选项

ansible_all_ipv4_addresses         所有的ipv4地址
ansible_all_ipv6_addresses         所有的ipv6地址
ansible_architecture               系统的架构
ansible_date_time                  系统时间
ansible_default_ipv4               系统的默认ipv4地址
ansible_distribution               系统名称
ansible_distribution_file_variety  系统的家族
ansible_distribution_major_version 系统的版本
ansible_domain                     系统所在的域
ansible_fqdn                       系统的主机名
ansible_hostname                   系统的主机名,简写
ansible_os_family                  系统的家族
ansible_processor_cores            cpu的核数
ansible_processor_count            cpu的颗数
ansible_processor_vcpus            cpu的个数