ansible 是什么?
ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
ansible是基于 paramiko 开发的,并且基于模块化工作,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。ansible不需要在远程主机上安装client/agents,因为它们是基于ssh来和远
程主机通讯的。ansible目前已经已经被红帽官方收购,是自动化运维工具中大家认可度最高的,并且上手容易,学习简单。是每位运维工程师必须掌握的技能之一。
ansible 特点
- 部署简单,只需在主控端部署Ansible环境,被控端无需做任何操作;
- 默认使用SSH协议对设备进行管理;
- 有大量常规运维操作模块,可实现日常绝大部分操作;
- 配置简单、功能强大、扩展性强;
- 支持API及自定义模块,可通过Python轻松扩展;
- 通过Playbooks来定制强大的配置、状态管理;
- 轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
- 提供一个功能强大、操作性强的Web管理界面和REST API接口------AWX平台。
上图为ansible的基本架构,从上图可以了解到其由以下部分组成:
- 核心:ansible
- 核心模块(Core Modules):这些都是ansible自带的模块
- 扩展模块(Custom Modules):如果核心模块不足以完成某种功能,可以添加扩展模块
- 插件(Plugins):完成模块功能的补充
- 剧本(Playbooks):ansible的任务配置文件,将多个任务定义在剧本中,由ansible自动执行
- 连接插件(Connectior Plugins):ansible基于连接插件连接到各个主机上,虽然ansible是使用ssh连接到各个主机的,但是它还支持其他的连接方法,所以需要有连接插件
- 主机群(Host Inventory):定义ansible管理的主机
安装
1、强烈建议使用yum 进行安装,或者装所有服务器配置为同一版本的python以避免因为python版本而导致的错误。
2、使用pip3 进行安装。最好将所有服务器安装同一版本的python,以避免版本问题。
#yum install sshpass 有时交互输入密码时自动交互使用。
#pip3 install ansible paramiko PyYAML Jinja2
ansible 程序结构
安装目录如下(yum安装):
配置文件目录:/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检查etc目录的配置文件。
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日志的文件(默认不记录日志)
使用yum进行安装时,产生的配置文件
ansible.cfg
ansible命令
Ad-Hot 模式(这其实是一个概念性的名字,是相对于写 Ansible playbook 来说的.类似于在命令行敲入shell命令和 写shell scripts两者之间的关系)
ansible -m -a
ansible 匹配的资产主机 -m 使用的模块 -a 模块的参数
例子:
(ansible as -m shell -a "ls /")
as:组名 使用shell模块 -a "做什么"
参数: -a 'Arguments', --args='Arguments' 命令行参数
-m NAME, --module-name=NAME 执行模块的名字,默认使用 command 模块,所以如果是只执行单一命令可以不用 -m参数
-i PATH, --inventory=PATH 指定库存主机文件的路径,默认为/etc/ansible/hosts.
-u Username, --user=Username 执行用户,使用这个远程用户名而不是当前用户
-U --sudo-user=SUDO_User sudo到哪个用户,默认为 root
-k --ask-pass 登录密码,提示输入SSH密码而不是假设基于密钥的验证
-K --ask-sudo-pass 提示密码使用sudo
-s --sudo sudo运行
-S --su 用 su 命令
-f --forks=NUM 并行任务数。NUM被指定为一个整数,默认是5。 #ansible testhosts -a "/sbin/reboot" -f 10 重启testhosts组的所有机器,每次重启10台
--private-key=PRIVATE_KEY_FILE 私钥路径,使用这个文件来验证连接
-v --verbose 详细信息
all 针对hosts 定义的所有主机执行
-M MODULE_PATH, --module-path=MODULE_PATH 要执行的模块的路径,默认为/usr/share/ansible/
-o --one-line 压缩输出,摘要输出.尝试一切都在一行上输出。
-B 后台运行超时时间
-P 调查后台程序时间
-T Seconds, --timeout=Seconds 时间,单位秒s
-P NUM, --poll=NUM 调查背景工作每隔数秒。需要- b
-c Connection, --connection=Connection 连接类型使用。可能的选项是paramiko(SSH),SSH和地方。当地主要是用于crontab或启动。
--tags=TAGS 只执行指定标签的任务 例子:ansible-playbook test.yml --tags=copy 只执行标签为copy的那个任务
--list-hosts 只打印有哪些主机会执行这个 playbook 文件,不是实际执行该 playbook 文件 --list-tasks 列出所有将被执行的任务
-C, --check 只是测试一下会改变什么内容,不会真正去执行;相反,试图预测一些可能发生的变化
--syntax-check 执行语法检查的剧本,但不执行它
-l SUBSET, --limit=SUBSET 进一步限制所选主机/组模式 --limit=192.168.0.15 只对这个ip执行
--skip-tags=SKIP_TAGS 只运行戏剧和任务不匹配这些值的标签 --skip-tags=copy_start
-e EXTRA_VARS, --extra-vars=EXTRA_VARS 额外的变量设置为键=值或YAML / JSON
#cat update.yml
- hosts: {{ hosts }}
remote_user: {{ user }}
..............
#ansible-playbook update.yml --extra-vars "hosts=vipers user=admin" 传递{{hosts}}、{{user}}变量,hosts可以是 ip或组名
-l,--limit 对指定的 主机/组 执行任务 --limit=192.168.0.10,192.168.0.11 或
-l 192.168.0.10,192.168.0.11 只对这个2个ip执行任务
ansible命令解释
通过ansible命令执行的任务称为ad-hoc命令(任务),其实它是相对playbook而言的。通常,命令行用来实现ansible的批量管理功能,playbook用来实现批量自动化功能。
【以下为普通选项:】
-a MODULE_ARGS
--args=MODULE_ARGS
传递参数给模块
--ask-vault-pass
询问vault的密码
-B SECONDS
--background=SECONDS
异步后台方式执行任务,并在指定的秒数后超时,超时会杀掉任务的进程。默认是同步,即保持长连接,它会等待所有执行完毕(即阻塞模式)。但有时候是没必要这样的,比如某些命令的执行时间比ssh的超时时间还长。如果不指定超时秒数,将以同步方式运行任务
-P POLL_INTERVAL
--poll=POLL_INTERVAL
异步模式下轮训任务的时间间隔,默认10秒
-C
--check
不对远程主机做出一些改变,而是预测某些可能发生的改变
-D
--diff
当文件或模板发生了改变,显示出不同之处,和-C选项配合使用更佳
-e EXTRA_VARS
--extra-vars=EXTRA_VARS
配置额外的配置变量(key=value或者YAML/JSON格式)
-f FORKS
--forks=FORKS
指定并行处理的进程数量,默认为5个
-h
--help
显示帮助信息
-i INVENTORY
--inventory-file=INVENTORY
指定inventory文件,多个文件使用逗号分隔。默认为/etc/ansible/hosts
-l SUBSET
--limit=SUBSET
使用额外的匹配模式来筛选目标主机列表。此处的匹配模式是在已有匹配模式下进行的,所以是更严格的筛选。例如指定了主机组的情况下,使用-l选项从中只选一台主机进行控制
--list-hosts
不会执行任何操作,而是列出匹配到的主机列表
-m MODULE_NAME
--module-name=MODULE_NAME
指定要执行的模块名,默认的模块为"command"
-M MODULE_PATH
--module-path=MODULE_PATH
指定模块目录,默认未设置
--new-vault-password-file=NEW_VAULT_PASSWORD_FILE
new vault password file for rekey
-o
--one-line
简化输出(一行输出模式)
--output=OUTPUT_FILE
output file name for encrypt or decrypt; use - for stdout
--syntax-check
检查playbook的语法,不会执行
-t TREE
--tree=TREE
记录输出到此目录中(测试时以每个host名如IP地址为文件名记录,结果记录到对应的文件中)。
此选项在ansible巨慢的时候(如瞬间应该返回的命令还需要10多秒才完成)有奇用,或者将ansible的结果重定向到某个文件中也能解决,为什么如此,我也不明白(表面看来和输出方式有关系),多次亲测有效。
--vault-password-file=VAULT_PASSWORD_FILE
指定vault密码文件
-v
--verbose
输出详细信息,-vvv和-vvvv会输出更多新
--version
显示ansible的版本
【以下是连接选项,用于控制谁以及如何连接主机:】
-k
--ask-pass
询问连接时的密码
--private-key=KEY_FILE
--key-file=KEY_FILE
使用文件来认证SSH连接过程。
-u REMOTE_USER
--user=REMOTE_USER
使用指定的用户名进行连接
-c CONNECTION
--connection=CONNECTION
连接类型,默认为ssh。paramiko (SSH), ssh, winrm and local. local is mostly useful for crontab or kickstarts.
-T TIMEOUT, --timeout=TIMEOUT
连接的超时时间,单位为秒,默认为10
--ssh-common-args=SSH_COMMON_ARGS
指定传递给sftp/scp/ssh等工具的通用额外参数
--sftp-extra-args=SFTP_EXTRA_ARGS
指定只传递给sftp的额外参数,如-f
--scp-extra-args=SCP_EXTRA_ARGS
指定只传递给scp的额外参数,如-l
--ssh-extra-args=SSH_EXTRA_ARGS
指定只传递给ssh的额外参数,如-R
【以下是权限控制选项:控制在目标主机上以什么身份和权限运行任务:】
-s
--sudo
为运行ansible命令的用户提升权限为sudo_user的权限,此命令已废弃,使用become代替
-U SUDO_USER
--sudo-user=SUDO_USER
期望的sudo_user,默认为root,已废弃,使用become替代
-S
--su
使用su的方式执行操作,已废弃,使用become替代
-R SU_USER
--su-user=SU_USER
使用此user的su执行操作,默认为root,已废弃,使用become替代
-b
--become
使用become的方式升级权限
--become-method=BECOME_METHOD
指定提升权限的方式,可选以下几种:sudo/su/pbrun/pfexec/doas/dzdo/ksu/runas值
--become-user=BECOME_USER
要提升为哪个user的权限,默认为root
--ask-sudo-pass
询问sudo密码,已废弃,使用become替代
--ask-su-pass
询问su的密码,已废弃,使用become替代
-K
--ask-become-pass
询问become提升权限时的密码
ansible-doc
ansible-doc -h Usage: ansible-doc [options] [module...]
该指令用于查看模块信息,常用参数有两个-l 和 -s ,具体如下:
//列出所有已安装的模块 # ansible-doc -l
//查看具体某模块的用法,这里如查看command模块 # ansible-doc -s command
ansible-galaxy
ansible-galaxy -h
Usage: ansible-galaxy [init|info|install|list|remove] [--help] [options] ...
ansible-galaxy 指令用于方便的从Ansible Galaxy 站点下载第三方扩展模块,我们可以形象的理解其类似于centos下的yum、python下的pip
ansible-playbook
通过读取playbook 文件后,执行相应的动作,
ansible-pull
该指令使用需要谈到ansible的另一种模式---pull 模式,这和我们平常经常用的push模式刚好相反,其适用于以下场景:你有数量巨大的机器需要配置,即使使用非常高的线程还是要花费很多时间;
ansible-vault
ansible-vault主要应用于配置文件中含有敏感信息,又不希望他能被人看到,vault可以帮你加密/解密这个配置文件,属高级用法。主要对于playbooks里比如涉及到配置密码或其他变量时,可以通过该指令加密,这样我们通过cat看到的会是一个密码串类的文件,编辑的时候需要输入事先设定的密码才能打开。这种playbook文件在执行时,需要加上 --ask-vault-pass参数,同样需要输入密码后才能正常执行。具体该部分可以参看官网
=============================================================
Inventory 资产清单
默认保存在/etc/ansible/hosts 。 您可以使用命令行上的-i 选项指定其他inventory文件。
inventory文件可以是许多格式之一,具体取决于您拥有的inventory插件。 对于这个例子, /etc/ansible/hosts的格式是一个INI(类似于Ansible的默认设置,使用 ; 进行注释),如下所示:
|---------------------------------------------------------------------------------------------------------------------------------|
| mail.example.com [webservers] foo.example.com bar.example.com [dbservers] one.example.com two.example.com three.example.com |
|------------------------------------------------------------------------------------------------------------------------|
| # cat hosts 192.168.184.102 mini1 ansible_ssh_host="192.168.184.101" ansible_ssh_user="root" ansible_ssh_pass="123456" |
单个域名或ip表示 单台设备。[ ] 表示分组,一般按照服务器不同的功用进行分类,同一台设备可以属于多个分组。
如果您拥有运行在非标准SSH端口上的主机
如果你有很多主机遵循类似的模式,你可以这样做,而不是列出每个主机名:
[webservers] www[01:50].example.com
对于数字模式,可以根据需要包括或删除前导零。 范围是包容性的 您还可以定义字母范围:
[databases] db-[a:f].example.com
主机变量
很容易将变量分配给稍后将在playbook中使用的主机:
[atlanta] host1 http_port=80 maxRequestsPerChild=808 host2 http_port=443 maxRequestsPerChild=909
组变量
变量也可以一次性应用于整个组:
[atlanta] host1 host2
注意:组变量必须一行一个 [atlanta:vars] ntp_server=ntp.atlanta.example.com proxy=proxy.atlanta.example.com
组和子组,即可以将多个组放入同一个组中进行统一管理
也可以使用:children后缀来创建组组。 如上所述,您可以使用:vars应用:vars
默认组
有两个默认组: all和ungrouped 。
all 包含每个主机。
ungrouped 包含没有进行分组的所有主机。
分割主机变量,组变量
Ansible中的首选实践实际上不是在主Inventory文件中存储变量。
除了将变量直接存储在INI文件中,主机和组变量可以存储在相对于Inventory文件的单个文件中。
这些变量文件采用YAML格式。 有效的文件扩展名包括'.yml','.yaml',无后缀。
假主机资产文件路径是:
/etc/ansible/hosts
如果主机被命名为"foosball",并且在"raleigh"和"webservers"组中,以下位置的YAML文件中的变量将提供给主机:
/etc/ansible/group_vars/raleigh /etc/ansible/group_vars/webservers /etc/ansible/host_vars/foosball
例如,假设您拥有按数据中心分组的主机,并且每个数据中心使用一些不同的服务器。 "raleigh"组的组文件"/ etc / ansible / group_vars / raleigh"中的数据可能如下所示:
--- ntp_server: acme.example.org database_server: storage.example.org
常用资产内置变量:
除了内置变量还可以自定义变量,变量可以在模板等地方进行使用。
ansible_ssh_host
将要连接的远程主机名.与你想要设定的主机的别名不同的话,可通过此变量设置.
ansible_ssh_port ssh
端口号.如果不是默认的端口号,通过此变量设置.
ansible_ssh_user
默认的 ssh 用户名
ansible_ssh_pass ssh
密码(这种方式并不安全,我们强烈建议使用 --ask-pass 或 SSH 密钥)
ansible_sudo_pass sudo
密码(这种方式并不安全,我们强烈建议使用 --ask-sudo-pass)
ansible_sudo_exe (new in version 1.8)
sudo 命令路径(适用于1.8及以上版本)
ansible_connection
与主机的连接类型.比如:local, ssh 或者 paramiko. Ansible 1.2 以前默认使用 paramiko.1.2 以后默认使用 'smart','smart' 方式会根据是否支持 ControlPersist, 来判断'ssh' 方式是否可行. ansible_ssh_private_key_file ssh
使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的情况.
ansible_shell_type
目标系统的shell类型.默认情况下,命令的执行使用 'sh' 语法,可设置为 'csh' 或 'fish'. ansible_python_interpreter
目标主机的 python 路径.适用于的情况: 系统中有多个 Python, 或者命令路径不是"/usr/bin/python",比如 \*BSD, 或者 /usr/bin/python
不是 2.X 版本的 Python.我们不使用 "/usr/bin/env" 机制,因为这要求远程用户的路径设置正确,且要求 "python" 可执行程序名不可为 python以外的名字(实际有可能名为python26). 与 ansible_python_interpreter 的工作方式相同,可设定如 ruby 或 perl 的路径....
Ansible-INI,一个主机文件的示例:
Ansible会像SSH那样试图用你的当前用户名来连接你的远程机器.要覆写远程用户名,只需使用'-u'参数. 如果你想访问 sudo模式,这里也有标识(flags)来实现:
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| # as bruce $ ansible all -m ping -u bruce # as bruce, sudoing to root $ ansible all -m ping -u bruce --sudo # as bruce, sudoing to batman $ ansible all -m ping -u bruce --sudo --sudo-user batman |
Ad-Hot 模式
ansible -m -a
ansible 匹配的资产主机 -m 使用的模块 -a 模块的参数
其中匹配主机的方法有如下几种:
1、直接写资产中的主机名或ip 192.168.184.101
2、使用通配 192.168.184.* *.example.com
3、多个组 中的主机 : 表示 或 webservers:dbservers
4、从组中排除某一组 webservers:!phoenix
5、取两个组中的交集 webservers:&dbservers
例:webservers:dbservers:&staging:!phoenix
表示"'webservers' 和 'dbservers' 两个组中隶属于 'staging' 组并且不属于 'phoenix' 组
6、取某一组中的某一断主机 webservers[0] webservers[0-25]
7、使用正则匹配 使用 ~ ~(web|db).*\.example\.com