文章目录
- 02-Ansible 基本使用
- Ansible 清单
- Ansible 软件包中文件
- 主机清单
- 静态主机清单
- 最简单的静态清单
- 主机组
- 主机组嵌套
- 范围简写
- 动态主机清单
- ansible-inventory 命令
- 管理 ANSIBLE 配置文件
- 配置文件位置和优先级
- 配置文件解析
- 配置文件示例
- ansible-config 命令
- ansible-config view
- ansible-config dump
- ansible-config list
- localhost 连接
- 运行 AD HOC 命令
- 实验环境
- ansible AD HOC 命令
- Ansible 部分模块
- 基础执行(command/shell 模块)
- ansible-doc 命令
- command模块
- shell 模块
- raw 模块
- ansible AD HOC 命令选项
02-Ansible 基本使用
Ansible 清单
Ansible 软件包中文件
[dyx@controller ~]# rpm -ql ansible配置文件目录 /etc/ansible
执行文件目录 /usr/bin
lib依赖库目录 /usr/lib/python2.7/site-packages/ansible
插件 /usr/share/ansible/plugins
Help文档目录 /usr/share/doc/ansible
Man文档目录/usr/share/man/man1/
主机清单
Inventory 定义Ansible将要管理的一批主机。这些主机也可以分配到组中,以进行集中管理 组可以包含
子组,主机也可以是多个组的成员。清单还可以设置应用到它所定义的主机和组的变量。
通过以下方式定义主机清单:
**静态主机清单:**以文本文件的方式来定义。
**动态主机清单:**使用外部信息提供程序通过脚本或其他程序来自动生成。目的是从启动环境中获取主机清单,例如openstack、kubernetes、zabbix等。
静态主机清单
主机清单支持多种格式,例如ini、yaml、脚本等。
本次课程使用 ini 格式。
最简单的静态清单
受管节点的主机名或IP地址的列表,每行一个。
示例:
[dyx@controller ~]# vim inventory[dyx@controller ~]# cat inventoryweb1.example.com web2.example.com db1.example.com db2.example.com192.168.0.42验证主机是否在inventory中
[dyx@controller ~]# ansible --list-hosts -i inventory web1.example.comhosts(1): web1.example.com[dyx@controller ~]# ansible --list-hosts -i inventory 192.168.0.42hosts(1):192.168.0.42ansible命令通过–inventory PATHNAME或-i PATHNAME选项在命令行中指定清单文件的位置,其中PATHNAME是所需清单文件的路径。
主机组
还可以将受管节点组织为主机组。通过主机组,更加有效地对一系列系统运行Ansible。
格式:
[groupname]hostnamehostip示例:
[dyx@controller ~]# vim inventory[dyx@controller ~]# cat inventoryapp1.examlpe.com[webservers]web1.example.com web2[dbservers]db1.example.com db2.example.com192.0.2.42192.0.2.3验证:
[dyx@controller ~]# ansible --list-hosts -i inventory webservershosts(2): web1.example.com web2# 注意:192.0.2.43属于dbservers组[dyx@controller ~]# ansible --list-hosts -i inventory dbservershosts(4): db1.example.com db2.example.com192.0.2.42192.0.2.3有两个组总是存在的:
all:包含inventory中所有主机。
ungrouped:inventory中列出的,但不属于任何组的主机。
验证:
[dyx@controller ~]# ansible --list-hosts -i inventory allhosts(7): app1.examlpe.com web1.example.com web2 db1.example.com db2.example.com192.0.2.42192.0.2.3[dyx@controller ~]# ansible --list-hosts -i inventory ungroupedhosts(1): app1.examlpe.com根据需要,将主机分配在多个组中,例如根据主机的角色、其物理位置以及是否在生产环境中等因素。
[dyx@controller ~]# vim inventory[dyx@controller ~]# cat inventory[webservers]web1.example.com web2192.168.3.7[dbservers]db1.example.com db2.example.com192.0.2.42[eastdc]web1.example.com db1.example.com[westdc]web2 db2验证:
[dyx@controller ~]# ansible --list-hosts -i inventory webservershosts(3): web1.example.com web2192.168.3.7[dyx@controller ~]# ansible --list-hosts -i inventory eastdchosts(2): web1.example.com db1.example.com主机组嵌套
一个主机组还可以属于另外一个主机组。
示例:
[dyx@controller ~]# vim inventory[dyx@controller ~]# cat inventory[webservers]web1.example.com web2192.168.3.7[dbservers]db1.example.com db2.example.com192.0.2.42[eastdc]web1.example.com db1.example.com[westdc]web2 db2[dc:children]eastdc westdc验证:
[dyx@controller ~]# ansible --list-hosts -i inventory dchosts(4): web1.example.com db1.example.com web2 db2子组中的主机组必须定义,否则会出现语法上的报错。
示例:
[dyx@controller ~]# vim inventory[dyx@controller ~]# cat inventory[webservers]web1.example.com web2192.168.3.7[dbservers]db1.example.com db2.example.com192.0.2.42[eastdc]web1.example.com db1.example.com[westdc]web2 db2[dc:children]eastdc westdc`node1`验证:
torydc[WARNING]: * Failed to parse /dyx/inventory with yaml plugin: We were unable toreadeither as JSON nor YAML, these are the errors we got from each: JSON: No JSON object could be decoded Syntax Errorwhileloading YAML. did notfindexpected<document start>The error appears to bein'/root/inventory':line2,column1, but may be elsewhereinthefiledepending on the exact syntax problem. The offending line appears to be:[webservers]web1.example.com ^ here[WARNING]: * Failed to parse /root/inventory with ini plugin: /root/inventory:22: Section[dc:children]includes undefined group: node[WARNING]: Unable to parse /root/inventory as an inventorysource[WARNING]: No inventory was parsed, only implicit localhost is available[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match'all'hosts(4): web1.example.com db1.example.com web2 db2范围简写
通过指定主机名称或IP地址的范围来简化Ansible主机清单。您可以指定数字或字母范围。
语法:[start:end]
示例:
[dyx@controller ~]# vim inventory# 代表192.168.4.0-192.168.7.255[priv]192.168.[4:7].[0:255]#代表01,02...10[hosts]host[01:10].example.com# 代表a b c[servers]server[a:c].example.com验证:
[dyx@controller ~]# ansible --list-hosts -i inventory hostshosts(10): host01.example.com host02.example.com host03.example.com host04.example.com host05.example.com host06.example.com host07.example.com host08.example.com host09.example.com host10.example.com[dyx@controller ~]# ansible --list-hosts -i inventory servershosts(3): servera.example.com serverb.example.com serverc.example.com以下是错误的范围示例:
[dyx@controller ~]# vim inventory[servers]server[0a:2c].example.com验证:
[dyx@controller ~]# ansible --list-hosts -i inventory all[WARNING]: * Failed to parse /root/inventory with yaml plugin: We were unable toreadeither as JSON nor YAML, these are the errors we got from each: JSON: No JSON object could be decoded Syntax Errorwhileloading YAML. did notfindexpected<document start>The error appears to bein'/root/inventory':line2,column1, but may be elsewhereinthefiledepending on the exact syntax problem. The offending line appears to be:[serevers]server[0a:2c].example.com ^ here[WARNING]: * Failed to parse /root/inventory with ini plugin: invalid literalforint()with base10:`'0a'`[WARNING]: Unable to parse /root/inventory as an inventorysource[WARNING]: No inventory was parsed, only implicit localhost is available[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match'all'hosts(0):动态主机清单
使用外部数据提供的信息动态生成Ansible清单信息。
本课程内容不做进一步讨论。
ansible-inventory 命令
通过不同的格式查看清单文件。
[dyx@controller ~]# ansible-inventory --helpusage: ansible-inventory[-h][--version][-v][-i INVENTORY][--vault-id VAULT_IDS][--ask-vault-pass|--vault-password-file VAULT_PASSWORD_FILES][--playbook-dir BASEDIR][--list][--host HOST][--graph][-y][--toml][--vars][--export][--output OUTPUT_FILE][host|group]positional arguments:host|group optional arguments: --ask-vault-pass askforvault password --export When doing an --list, representina way that is optimizedforexport,not as an accurate representation of how Ansible has processed it --output OUTPUT_FILE When doing --list, send the inventory to afileinstead of to thescreen--playbook-dir BASEDIR Since this tool does not use playbooks, use this as a substitute playbook directory.This sets the relative pathformany features including roles/ group_vars/ etc. --toml Use TOMLformatinstead of default JSON, ignoredfor--graph --vars Add vars to graph display, ignored unless used with --graph --vault-id VAULT_IDS the vault identity to use --vault-password-file VAULT_PASSWORD_FILES vault passwordfile--version show program's version number, configfilelocation, configured module search path, module location, executable location andexit-h, --help show thishelpmessage andexit-i INVENTORY, --inventory INVENTORY, --inventory-file INVENTORY specify inventoryhostpath or comma separatedhostlist. --inventory-file is deprecated -v, --verbose verbose mode(-vvvformore, -vvvv toenableconnection debugging)-y, --yaml Use YAMLformatinstead of default JSON, ignoredfor--graph Actions: One of following must be used on invocation, ONLY ONE!--graph create inventory graph,ifsupplying pattern it must be a valid group name --host HOST Output specifichostinfo, works as inventory script --list Output all hosts info, works as inventory script Show Ansible inventory information, by default it uses the inventory script JSONformat示例清单:
[dyx@controller ~]# vim inventoryapp1.example.com[webservers]web1.example.com web2.example.com192.168.3.7[dbservers]db1.example.com db2.example.com192.0.2.42[eastdc]web1.example.com db1.example.com[westdc]web2.example.com db2.example.com[dc:children]eastdc westdc验证:
# 树形结构显示[dyx@controller ~]# ansible-inventory -i inventory --graph@all:|--@dbservers:||--192.0.2.42||--db1.example.com||--db2.example.com|--@dc:||--@eastdc:|||--db1.example.com|||--web1.example.com||--@westdc:|||--db2.example.com|||--web2.example.com|--@ungrouped:||--app1.example.com|--@webservers:||--192.168.3.7||--web1.example.com||--web2.example.com# yaml格式显示[dyx@controller ~]# ansible-inventory -i inventory --list -yall: children: dbservers: hosts:192.0.2.42:{}db1.example.com:{}db2.example.com:{}dc: children: eastdc: hosts: db1.example.com:{}web1.example.com:{}westdc: hosts: db2.example.com:{}web2.example.com:{}ungrouped: hosts: app1.example.com:{}webservers: hosts:192.168.3.7:{}web1.example.com:{}web2.example.com:{}管理 ANSIBLE 配置文件
配置文件位置和优先级
- 环境变量 ANSIBLE_CONFIG
- ./ansible.cfg,当前位置中的 ansible.cfg,当前位置一般是项目目录。
- ~/.ansible.cfg
- /etc/ansible/ansible.cfg
从上到下,优先级越来越低。
建议:在当前目录下定义ansible.cfg文件。
验证优先级:
# 环境准备[dyx@controller ~]$mkdirweb&&cdweb# 查看ansible命令当前使用的配置文件[dyx@controller web]$ ansible --version ansible2.9.27 configfile=`/etc/ansible/ansible.cfg`configured module search path=[u'/home/dyx/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']ansible python module location=/usr/lib/python2.7/site-packages/ansible executable location=/bin/ansible python version=2.7.5(default, Oct142020,14:45:30)[GCC4.8.520150623(Red Hat4.8.5-44)]# 或者[dyx@controller web]$ ansible --version|grep'config file'configfile=/etc/ansible/ansible.cfg[dyx@controller web]$touch~/.ansible.cfg[dyx@controller web]$ ansible --version|grep'config file'configfile=/home/dyx/.ansible.cfg[dyx@controller web]$touchansible.cfg[dyx@controller web]$ ansible --version|grep'config file'configfile=/home/dyx/web/ansible.cfg[dyx@controller web]$exportANSIBLE_CONFIG=/opt/ansible.cfg[dyx@controller web]$sudotouch/opt/ansible.cfg[dyx@controller web]$ ansible --version|grep'config file'configfile=/opt/ansible.cfg[dyx@controller web]$unsetANSIBLE_CONFIG[dyx@controller web]$ ansible --version|grep'config file'configfile=/home/dyx/web/ansible.cfg配置文件解析
ansible 默认配置文件 /etc/ansible/ansible.cfg。
Ansible 配置文件包括以下部分:
[dyx@controller web]$grep"^\["/etc/ansible/ansible.cfg[defaults][inventory][privilege_escalation][paramiko_connection][ssh_connection][persistent_connection][accelerate][selinux][colors][diff]常用参数解析如下:
[defaults]# inventory 指定清单文件路径inventory=/etc/ansible/hosts# 并发执行同一个任务的主机数量forks=5# ansible检查任务是否执行完成的时间间隔poll_interval=15# 连接登录到受管主机时是否提示输入密码ask_pass=True# 控制facts如何收集# smart - 如果facts已经收集过了,就不收集了。# implicit - facts收集,剧本中使用gather_facts: False关闭facts收集。# explicit - facts不收集,剧本中使用gather_facts: True关闭facts收集。gathering=implicit# 收集facts范围# all - gather all subsets# network - gather min and network facts# hardware - gather hardware facts (longest facts to retrieve)# virtual - gather min and virtual facts# facter - import facts from facter# ohai - import facts from ohai# You can combine them using comma (ex: network,virtual)# You can negate them using ! (ex: !hardware,!facter,!ohai)# A minimal set of facts is always gathered.gather_subset=all# 收集facts超时时间gather_timeout=10# 变量注入,通过ansible_facts引用inject_facts_as_vars=True# 定义角色路径,以冒号分隔roles_path=/etc/ansible/roles# SSH是否检验 host keyhost_key_checking=False# 连接登录到受管主机时使用的用户身份remote_user=root# ansible 命令和ansible-playbook 命令输出内容存放位置log_path=/var/log/ansible.log# ansible 命令默认模块module_name=command# ssh 私钥文件位置private_key_file=/path/to/file# 默认ansible-vault命令的密码文件vault_password_file=/path/to/vault_password_file# 定义ansible_managed变量值ansible_managed=Ansible managed# 剧本执行过程中,遇到未定义的变量不报错error_on_undefined_vars=False# 系统告警启用system_warnings=True# 下架告警启用deprecation_warnings=True# 使用command和shell模块时,是否提示告警command_warnings=False# facts保存在哪里,例如redisfact_caching=memory[inventory]# 启用的清单插件, 默认为: 'host_list', 'script', 'auto', 'yaml', 'ini', 'toml'#enable_plugins = host_list, virtualbox, yaml, constructed# 当清单源是一个目录的时候,忽略这些后缀的清单文件#ignore_extensions = .pyc, .pyo, .swp, .bak, ~, .rpm, .md, .txt, ~, .orig, .ini,.cfg, .retry[privilege_escalation]# 连接到受管主机后是否需要进行权限提升或切换用户become=True# 使用何种方式进行用户切换或提权become_method=sudo# 用户切换或提权后的对应用户become_user=root# 进行用户切换或提权时是否提示输入密码become_ask_pass=False说明:“#” 和 ";"开头的行,作为注释
配置文件示例
对于基本操作, 使用[defaults]和[privilege_escalation]即可。
配置文件示例
[dyx@controller web]$vimansible.cfg[dyx@controller web]$catansible.cfg[defaults]remote_user=dyxinventory=./inventory[privilege_escalation]become=truebecome_user=rootbecome_method=sudobecome_ask_pass=false编辑inventory
[dyx@controller web]$viminventory[dyx@controller web]$catinventory node[1:4]最终效果:
[dyx@controller web]$ ansible all -ahostnamenode4|CHANGED|rc=0>>node4.dyx.cloud node2|CHANGED|rc=0>>node2.dyx.cloud node3|CHANGED|rc=0>>node3.dyx.cloud node1|CHANGED|rc=0>>node1.dyx.cloudansible-config 命令
用于分析ansible命令的配置。
[dyx@controller web]$ ansible-config -h usage: ansible-config[-h][--version][-v]{list,dump,view}... View ansible configuration. positional arguments:{list,dump,view}`list Print all config options``dump Dump configuration``view View configurationfile`optional arguments: --version show program's version number, configfilelocation, configured module search path, module location, executable location andexit-h, --help show thishelpmessage andexit-v, --verbose verbose mode(-vvvformore, -vvvv toenableconnection debugging)ansible-config view
查看当前ansible配合文件内容。
[dyx@controller web]$ ansible --version|grepfileconfigfile=/home/dyx/web/ansible.cfg[dyx@controller web]$ ansible-config view[defaults]remote_user=dyxinventory=./inventory[privilege_escalation]become=truebecome_user=rootbecome_method=sudobecome_ask_pass=falseansible-config dump
当前ansible生效的所有配置,包括所有默认值
[dyx@controller web]$ ansible-config dump ACTION_WARNINGS(default)=True AGNOSTIC_BECOME_PROMPT(default)=True ALLOW_WORLD_READABLE_TMPFILES(default)=False ANSIBLE_CONNECTION_PATH(default)=None ANSIBLE_COW_PATH(default)=None ANSIBLE_COW_SELECTION(default)=default ANSIBLE_COW_WHITELIST(default)=['bud-frogs','bunny','cheese','daemon','default','d ANSIBLE_FORCE_COLOR(default) = False ANSIBLE_NOCOLOR(default) = False ANSIBLE_NOCOWS(default) = False ANSIBLE_PIPELINING(default) = False ANSIBLE_SSH_ARGS(default) = -C -o ControlMaster=auto -o ControlPersist=60s ANSIBLE_SSH_CONTROL_PATH(default) = None ANSIBLE_SSH_CONTROL_PATH_DIR(default) = ~/.ansible/cp ANSIBLE_SSH_EXECUTABLE(default) = ssh ANSIBLE_SSH_RETRIES(default) = 0 ANY_ERRORS_FATAL(default) = False BECOME_ALLOW_SAME_USER(default) = False BECOME_PLUGIN_PATH(default) = [u'/home/dyx/.ansible/plugins/become', u'/usr/share/ansible CACHE_PLUGIN(default)=memory CACHE_PLUGIN_CONNECTION(default)=None CACHE_PLUGIN_PREFIX(default)=ansible_facts CACHE_PLUGIN_TIMEOUT(default)=86400COLLECTIONS_PATHS(default)=[u'/home/dyx/.ansible/collections', u'/usr/share/ansible/col COLOR_CHANGED(default) = yellow COLOR_CONSOLE_PROMPT(default) = white COLOR_DEBUG(default) = dark gray COLOR_DEPRECATE(default) = purple COLOR_DIFF_ADD(default) = green COLOR_DIFF_LINES(default) = cyan COLOR_DIFF_REMOVE(default) = red COLOR_ERROR(default) = red COLOR_HIGHLIGHT(default) = white COLOR_OK(default) = green COLOR_SKIP(default) = cyan COLOR_UNREACHABLE(default) = bright red COLOR_VERBOSE(default) = blue COLOR_WARN(default) = bright purple COMMAND_WARNINGS(default) = True CONDITIONAL_BARE_VARS(default) = True CONNECTION_FACTS_MODULES(default) = {'iosxr': 'iosxr_facts', 'voss': 'voss_facts', 'cisco COVERAGE_REMOTE_OUTPUT(default)=None COVERAGE_REMOTE_WHITELIST(default)=* DEFAULT_ACTION_PLUGIN_PATH(default)=[u'/home/dyx/.ansible/plugins/action', u'/usr/share DEFAULT_ALLOW_UNSAFE_LOOKUPS(default) = False DEFAULT_ASK_PASS(default) = False DEFAULT_ASK_VAULT_PASS(default) = False DEFAULT_BECOME(/home/dyx/web/ansible.cfg) = True DEFAULT_BECOME_ASK_PASS(/home/dyx/web/ansible.cfg) = False DEFAULT_BECOME_EXE(default) = None DEFAULT_BECOME_FLAGS(default) = DEFAULT_BECOME_METHOD(/home/dyx/web/ansible.cfg) = sudo DEFAULT_BECOME_USER(/home/dyx/web/ansible.cfg) = root DEFAULT_CACHE_PLUGIN_PATH(default) = [u'/home/dyx/.ansible/plugins/cache', u'/usr/share/a DEFAULT_CALLABLE_WHITELIST(default)=[]DEFAULT_CALLBACK_PLUGIN_PATH(default)=[u'/home/dyx/.ansible/plugins/callback', u'/usr/s DEFAULT_CALLBACK_WHITELIST(default) = [] DEFAULT_CLICONF_PLUGIN_PATH(default) = [u'/home/dyx/.ansible/plugins/cliconf', u'/usr/sha DEFAULT_CONNECTION_PLUGIN_PATH(default)=[u'/home/dyx/.ansible/plugins/connection', u'/u DEFAULT_DEBUG(default) = False DEFAULT_EXECUTABLE(default) = /bin/sh DEFAULT_FACT_PATH(default) = None DEFAULT_FILTER_PLUGIN_PATH(default) = [u'/home/dyx/.ansible/plugins/filter', u'/usr/shareansible-config list
查看所有配置参数用途,配置位置等。
[dyx@controller web]$ ansible-config list ACTION_WARNINGS: default:truedescription:[By default Ansible will issue a warning when received from a task action(module or action plugin), These warnings can be silenced by adjusting this setting to False.]env: -{name: ANSIBLE_ACTION_WARNINGS}ini: -{key: action_warnings, section: defaults}name: Toggle action warnings type: boolean version_added:'2.5'AGNOSTIC_BECOME_PROMPT: default:truedescription: Display an agnostic become prompt instead of displaying a prompt containin thecommandline supplied become method env: -{name: ANSIBLE_AGNOSTIC_BECOME_PROMPT}ini: -{key: agnostic_become_prompt, section: privilege_escalation}name: Display an agnostic become prompt type: boolean version_added:'2.5'yaml:{key: privilege_escalation.agnostic_become_prompt}ALLOW_WORLD_READABLE_TMPFILES:localhost 连接
默认Ansible连接到受管主机的协议为 smart (通常采用最有效的方式 - SSH)。如本地清单中并未指定localhost,Ansible会隐式设置
localhost,并使用local连接类型连接localhost。
local连接类型会忽略remote_user的设置,并且直接在本地系统上运行命令。
如果使用了特权提升,此时ansible将会在运行sudo时使用运行Ansible命令的账户的身份进行提权,而非remote_user所指定的账户。
更改localhost连接方式:清单中包涵 localhost。
运行 AD HOC 命令
实验环境
[laogao@controller ~]$mkdirweb&&cdweb[laogao@controller web]$cat>ansible.cfg<<'EOF' [defaults] remote_user = laogao inventory = ./inventory [privilege_escalation] become = True become_user = root become_method = sudo become_ask_pass = False EOF[laogao@controller web]$cat>inventory<<'EOF' node1 node2 node3 node4 EOFansible AD HOC 命令
命令作用:
快速执行单个Ansible任务,而不需要将它保存下来供以后再次运行。它们是简单的在线操作,无需编写playbook即可运行。
**快速测试和更改很有用。**例如,您可以使用临时命令确保一组服务器上的/ etc/hosts文件中存在某一特定的行。您可以使用另一个临时
命令在许多不同的计算机上高效重启一项服务,或者确保特定的软件包为最新版本。
命令语法:
ansible host-pattern -m module[-a'module arguments'][-i inventory]host-pattern,是inventory中定义的主机或主机组,可以为ip、hostname、inventory中的group组名、具有“,”或“*”或“:”等特殊字符的匹配型字符串,是必选项。
-m module,module是一个小程序,用于实现具体任务。
-a ‘module arguments’,是模块的参数。
-i inventory,指定inventory文件。
命令执行结果颜色说明:
Ansible的返回结果都非常友好,用3种颜色来表示执行结果:
红色:表示执行过程有异常,一般会中止剩余所有的任务。
绿色:表示目标主机已经是预期状态,不需要更改 。
黄色:表示命令执行结束后目标有状态变化,并设置为预期状态,所有任务均正常执行。
Ansible 部分模块
Ansible 模块存放位置:/usr/lib/python*/site-packages/ansible
官网:https://docs.ansible.com/projects/ansible/latest/collections/index_module.html。
文件模块
- copy: 将控制主机上的文件复制到受管节点,类似于scp
- file: 设置文件的权限和其他属性
- lineinfile: 确保特定行是否在文件中
- synchronize: 使用rsync将控制主机上的文件同步到受管节点
软件包模块
- package: 自动检测操作系统软件包管理器
- yum: 使用 YUM 软件包管理器管理软件包
- apt: 使用 APT 软件包管理器管理软件包
- gem: 管理 Rubygem
- pip: 从 PyPI 管理 Python 软件包
系统模块
- ansible.posix.firewalld: 使用firewalld管理任意端口和服务
- reboot: 重新启动计算机
- service: 管理服务
- user、group: 管理用户和组帐户
NetTools模块
- get_url: 通过HTTP、HTTPS或FTP下载文件
- nmcli: 管理网络
- uri: 与 Web 服务交互
ansible AD HCO命令案例:
基础执行(command/shell 模块)
command是默认模块(无需显式指定 -m ),适用于执行无shell特性(管道、重定向、环境变量)的简单命令
示例 1:查看远程主机主机名
[dyx@controller web]$ ansible all -mcommand-a"hostname"node2|CHANGED|rc=0>>node2.dyx.cloud node4|CHANGED|rc=0>>node4.dyx.cloud node3|CHANGED|rc=0>>node3.dyx.cloud node1|CHANGED|rc=0>>node1.dyx.cloud[dyx@controller web]$ ansible all -a"hostname"node2|CHANGED|rc=0>>node2.dyx.cloud node4|CHANGED|rc=0>>node4.dyx.cloud node3|CHANGED|rc=0>>node3.dyx.cloud node1|CHANGED|rc=0>>node1.dyx.cloud示例 2:检查远程主机操作系统版本
[dyx@controller web]$ ansible all -mcommand-a"cat /etc/os-release"[dyx@controller web]$ ansible all -a"cat /etc/os-release"示例 3:查看远程主机内存使用情况
[dyx@controller web]$ ansible all -a"free -h"node2|CHANGED|rc=0>>total usedfreeshared buff/cache available Mem:1.9G 472M1.2G 12M 312M1.3G Swap:3.9G 0B3.9G node3|CHANGED|rc=0>>total usedfreeshared buff/cache available Mem:1.9G 475M1.2G 12M 311M1.3G Swap:3.9G 0B3.9G node4|CHANGED|rc=0>>total usedfreeshared buff/cache available Mem:1.9G 479M1.2G 12M 312M1.3G Swap:3.9G 0B3.9G node1|CHANGED|rc=0>>total usedfreeshared buff/cache available Mem:1.9G 474M1.2G 12M 311M1.3G Swap:3.9G 0B3.9G示例 4:统计远程主机指定目录文件数量
# 注:这里ls+wc是两个命令,但未用管道符(command不支持管道),实际是执行`ls -l /var/log/nginx`后通过wc统计,若需管道需用shell模块[dyx@controller web]$ ansible all -a"ls -l /etc |wc -l"[dyx@controller web]$ ansible all -m shell -a"ls -l /etc |wc -l"node2|CHANGED|rc=0>>276node4|CHANGED|rc=0>>276node3|CHANGED|rc=0>>276node1|CHANGED|rc=0>>276示例 5:创建空文件
[dyx@controller web]$ ansible all -a"touch /tmp/ansible_test.txt"[WARNING]: Consider using thefilemodule withstate=touch rather than running'touch'.If you need to usecommandbecausefileis insufficient you canadd'warn: false'to thiscommandtask orset'command_warnings=False'inansible.cfg to get rid of this message. node3|CHANGED|rc=0>>node2|CHANGED|rc=0>>node4|CHANGED|rc=0>>node1|CHANGED|rc=0>>示例 6:检查远程服务进程
[dyx@controller web]$ ansible all -a"ps aux"# ✅ 正确:仅执行ps aux,后续过滤可在本地处理ansible all -a"ps aux | grep sshd"# ❌ 错误:command不支持管道,需改用shell[dyx@controller web]$ ansible all -m shell -a"ps aux |grep sshd"node2|CHANGED|rc=0>>root12180.00.21129004316? Ss12:240:00 /usr/sbin/sshd -D root19030.00.31679486784? Ss12:250:00 sshd: root@pts/0 root40570.00.21567765584? Ss15:360:00 sshd: dyx[priv]dyx40600.00.11570882824? S15:360:00 sshd: dyx@pts/1 root53060.00.01132801192pts/1 S+15:390:00 /bin/sh -cpsaux|grepsshd root53080.00.0112812940pts/1 S+15:390:00grepsshd node4|CHANGED|rc=0>>root12180.00.21129004316? Ss12:240:00 /usr/sbin/sshd -D root19060.00.31679486780? Ss12:250:00 sshd: root@pts/0 root40500.00.21567765588? Ss15:360:00 sshd: dyx[priv]dyx40540.00.11570882816? S15:360:00 sshd: dyx@pts/1 root52980.00.01132801192pts/1 S+15:400:00 /bin/sh -cpsaux|grepsshd root53000.00.0112812940pts/1 S+15:400:00grepsshd node3|CHANGED|rc=0>>root12180.00.21129004312? Ss12:240:00 /usr/sbin/sshd -D root19080.00.31679486780? Ss12:250:00 sshd: root@pts/0 root40020.00.21567765584? Ss15:360:00 sshd: dyx[priv]dyx40060.00.11570882820? S15:360:00 sshd: dyx@pts/1 root52500.00.01132801192pts/1 S+15:400:00 /bin/sh -cpsaux|grepsshd root52520.00.0112812940pts/1 S+15:400:00grepsshd node1|CHANGED|rc=0>>root12090.00.21129004316? Ss12:240:00 /usr/sbin/sshd -D root19040.00.31679486776? Ss12:250:00 sshd: root@pts/0 root39810.00.21567765592? Ss15:360:00 sshd: dyx[priv]dyx39840.00.11570882820? S15:360:00 sshd: dyx@pts/1 root52320.00.01132801192pts/1 S+15:400:00 /bin/sh -cpsaux|grepsshd root52340.00.0112812944pts/1 S+15:400:00grepsshd示例 7:查看远程主机磁盘挂载信息
ansible all -a"mount | grep /sys"# ❌ 错误:含管道,改用shell[dyx@controller web]$ ansible all -a"mount"# ✅ 正确:查看所有挂载,本地筛选/sys示例 8:验证远程主机端口连通性(基础版)
# 检查80端口是否监听(需安装nc)[dyx@controller web]$ ansible all -a"nc -zv 127.0.0.1 22"node3|CHANGED|rc=0>>Ncat: Version7.50(https://nmap.org/ncat)Ncat: Connected to127.0.0.1:22. Ncat:0bytes sent,0bytes receivedin0.01seconds. node1|CHANGED|rc=0>>Ncat: Version7.50(https://nmap.org/ncat)Ncat: Connected to127.0.0.1:22. Ncat:0bytes sent,0bytes receivedin0.01seconds. node2|CHANGED|rc=0>>Ncat: Version7.50(https://nmap.org/ncat)Ncat: Connected to127.0.0.1:22. Ncat:0bytes sent,0bytes receivedin0.01seconds. node4|CHANGED|rc=0>>Ncat: Version7.50(https://nmap.org/ncat)Ncat: Connected to127.0.0.1:22. Ncat:0bytes sent,0bytes receivedin0.01seconds.示例 9:查看远程主机指定文件的最后 10 行
ansible all -a"tail -10 /var/log/messages"示例 10:查看IP地址
[dyx@controller web]$ ansible all -a"ip -br a"node1|CHANGED|rc=0>>lo UNKNOWN127.0.0.1/8 ::1/128 ens33 UP192.168.108.11/24 fe80::9f3f:8d41:73d1:d531/64 fe80::af36:4fe7:4616:f9d6/64 virbr0 DOWN192.168.122.1/24 virbr0-nic DOWN node3|CHANGED|rc=0>>lo UNKNOWN127.0.0.1/8 ::1/128 ens33 UP192.168.108.13/24 fe80::af36:4fe7:4616:f9d6/64 fe80::9f3f:8d41:73d1:d531/64 fe80::8c56:cea:5e7a:8aa5/64 virbr0 DOWN192.168.122.1/24 virbr0-nic DOWN node2|CHANGED|rc=0>>lo UNKNOWN127.0.0.1/8 ::1/128 ens33 UP192.168.108.12/24 fe80::af36:4fe7:4616:f9d6/64 fe80::9f3f:8d41:73d1:d531/64 fe80::8c56:cea:5e7a:8aa5/64 virbr0 DOWN192.168.122.1/24 virbr0-nic DOWN node4|CHANGED|rc=0>>lo UNKNOWN127.0.0.1/8 ::1/128 ens33 UP192.168.108.14/24 fe80::af36:4fe7:4616:f9d6/64 fe80::9f3f:8d41:73d1:d531/64 fe80::8c56:cea:5e7a:8aa5/64 virbr0 DOWN192.168.122.1/24 virbr0-nic DOWNansible-doc 命令
[dyx@controller web]$ ansible-doc -h usage: ansible-doc[-h][--version][-v][-M MODULE_PATH][--playbook-dir BASEDIR][-t{become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars}][-j][-F|-l|-s|--metadata-dump][plugin[plugin...]]plugin documentation tool positional arguments: plugin Plugin optional arguments: --metadata-dump **For internal testing only** Dump json metadataforall plugins. --playbook-dir BASEDIR Since this tool does not use playbooks, use this as a substitute playbook directory.This sets the relative pathformany features including roles/ group_vars/ etc. --version show program's version number, config file location, configured module search path, module location, executable location and exit -F, --list_files Show plugin names and their source files without summaries (implies --list) -M MODULE_PATH, --module-path MODULE_PATH prepend colon-separated path(s) to module library (def ault=~/.ansible/plugins/modules:/usr/share/ansible/plu gins/modules) -h, --help show this help message and exit -j, --json Change output into json format. -l, --list List available plugins -s, --snippet Show playbook snippet for specified plugin(s) -t {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars}, --type {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars} Choose which plugin type (defaults to "module"). Available plugin types are : ('become', 'cache', 'callback', 'cliconf', 'connection', 'httpapi', 'inventory', 'lookup', 'netconf', 'shell', 'module', 'strategy', 'vars')-v, --verbose verbose mode(-vvvformore, -vvvv toenableconnection debugging)SeemanpagesforAnsible CLI options or websitefortutorials https://docs.ansible.com示例:
# 查看模块清单及说明[dyx@controller web]$ ansible-doc -l fortios_router_community_list Configure community li... azure_rm_devtestlab_info Get Azure DevTest Lab... ecs_taskdefinition register a task defini... avi_alertscriptconfig Moduleforsetup of Al... tower_receive Receive assets from An.........# 查看模块清单及位置[dyx@controller web]$ ansible-doc -F fortios_router_community_list /usr/lib/python2.7/site-pac azure_rm_devtestlab_info /usr/lib/python2.7/site-pac ecs_taskdefinition /usr/lib/python2.7/site-pac avi_alertscriptconfig /usr/lib/python2.7/site-pac tower_receive /usr/lib/python2.7/site-pac netapp_e_iscsi_target /usr/lib/python2.7/site-pac azure_rm_acs /usr/lib/python2.7/site-pac......# 查看特定模块说明文档[dyx@controller web]$ ansible-doc user>USER(/usr/lib/python2.7/site-packages/ansible/modules/system/user.py)Manage user accounts and user attributes. For Windows targets, use the[win_user]module instead. * This module is maintained by The Ansible Core Team * This module is maintained by The Ansible Core Team OPTIONS(=is mandatory): - append If`yes',addthe user to thegroupsspecifiedin`groups'. If`no', user will only be added to thegroupsspecifiedin`groups', removing them from all other groups. Mutually exclusive with`local'[Default: False]type: bool# 提示信息NOTES: * There are specific requirements per platform on user management utilities. However they generally come pre- installed with the system and Ansible will require they are present at runtime. If they are not, a descriptive error message will be shown. * On SunOS platforms, the shadowfileis backed up automatically since this module edits it directly. On other platforms, the shadowfileis backed up by the underlying tools used by this module. * On macOS, this module uses`dscl' to create, modify, and delete accounts.`dseditgroup' is used to modify group membership. Accounts are hidden from the login window by modifying`/Library/Preferences/com.apple.loginwindow.plist'.# 作者AUTHOR: Stephen Fromm(@sfromm)# METADATA描述了谁在维护该模块。# status记录了模块开发状态。# stableinterface: 模块的关键字稳定,将尽力确保不删除关键字或更改其含义。# preview: 模块处于技术预览阶段,可能不稳定,其关键字可能会更改,或者它可能需要本身会受到不兼容更改的库或Web服务。# deprecated: 未来某一发行版中将不再提供。# removed: 模块已从发行版中移除,但因文档需要存在存根,以帮助之前的用户迁移到新的模块。METADATA: status: - stableinterface# supported_by记录了哪些社区在维护该模块:# core:Ansible核心开发人员维护,始终随Ansible提供。# curated:模块由社区中的合作伙伴或公司提交并维护。这些模块的维护者必须留意报告的任何问题,或者调取针对该模块提出的请求。在社区维护人员批准了更改后,上游 “core” 开发人员审核对策划模块提出的更改。核心提交者也确保因为Ansible引擎中的变化而对这些模块造成的任何问题得到修正。这些模块目前随Ansible提供,但是可能会在未来某个时候另外打包。# community:模块不受到core上游开发人员、合作伙伴或公司的支持,完全由一般开源社区维护。此类别中的模块仍然完全可用,但对问题的响应速度完全取决于社区。这些模块目前也随Ansible提供,但是可能会在未来某个时候另外打包。supported_by: core# 模块使用示例EXAMPLES: - name: Add the user'johnd'with a specific uid and a primary group of'admin'user: name: johnd comment: John Doe uid:1040group: admin......# 模块返回值说明RETURN VALUES: append: description: Whether or not to append the user togroupsreturned: When state is'present'and the user exists type: bool sample: True comment: description: Comment section frompasswdfile, usually the user name returned: When user exists......如果现有的模块无法实现现有需求,用户也可以自行编写模块:
Ansible会从变量ANSIBLE_LIBRARY中查找模块
如果该变量未设置,将会从ansible.cfg配置文件library设置的位置查找模块
copy模块(文件/目录拷贝)
核心作用:从控制端拷贝文件 / 目录到远程主机,支持权限、属主、内容直接写入等。
案例 1:基础文件拷贝(指定源和目标)
[dyx@controller web]$touch/tmp/local_file.txt[dyx@controller web]$ ansible all -m copy -a"src=/tmp/local_file.txt dest=/opt/remote_file.txt"#验证[root@node1 ~]# ls /opt |grep remoteremote_file.txt说明:将控制端 /tmp/local_file.txt 拷贝到远程主机 /opt/remote_file.txt ;
备注:目标文件已存在时会覆盖(默认行为)。
案例 2:拷贝并设置权限 + 属主属组
[dyx@controller web]$sudoyuminstall-y httpd[dyx@controller web]$ ansible all -m copy -a"src=/etc/httpd/conf/httpd.conf dest=/tmp/feiyy owner=dyx group=root mode=0644 backup=yes"#验证[root@node1 ~]# ls /tmp|grep feiyyfeiyy- 说明:
- 拷贝 nginx 配置文件到远程 web 服务器;
- 设置属主 nginx 、属组 nginx ,权限 0644 ;
- backup=yes :覆盖前自动备份原文件(后缀为时间戳)。
在此拷贝
[root@controller ~]# echo hhh >/etc/httpd/conf/httpd.conf[dyx@controller web]$ ansible all -m copy -a"src=/etc/httpd/conf/httpd.conf dest=/tmp/feiyy owner=dyx group=root mode=0644 backup=yes"#验证[root@node1 ~]# ls /tmp|grep feiyyfeiyy feiyy.6832.2025-12-15@16:42:21~command模块
command 模块允许管理员在受管节点的命令行中运行任意命令。要运行的命令通过-a选项指定为该模块的参数。
[dyx@controller web]$ ansible node1 -mcommand-a'hostname'node1|CHANGED|rc=0>>node1.dyx.cloud[dyx@controller web]$ ansible node1 -mcommand-a'hostname'-o node1|CHANGED|rc=0|(stdout)node1.dyx.cloud说明:
command 模块执行的远程命令不受受管节点上的shell处理,无法访问shell环境变量,也不能执行重定向和传送等shell操作。
如果临时命令没有指定模块,Ansible默认使用command模块。
shell 模块
shell模块允许您将要执行的命令作为参数传递给该模块。 Ansible随后对受管节点远程执行该命令。与command模块不同的是, 这些命令
将通过受管节点上的shell进行处理。因此,可以访问shell环境变量,也可使用重定向和管道等shell操作。
[dyx@controller web]$ ansible node1 -mcommand-asetnode1|FAILED|rc=2>>[Errno2]No suchfileor directory[dyx@controller web]$ ansible node1 -m shell -asetnode1|CHANGED|rc=0>>BASH=/bin/shBASHOPTS=cmdhist:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepathBASH_ALIASES=()BASH_ARGC=()BASH_ARGV=()BASH_CMDS=()BASH_EXECUTION_STRING=setBASH_LINENO=()BASH_SOURCE=()BASH_VERSINFO=([0]="4"[1]="2"[2]="46"[3]="2"[4]="release"[5]="x86_64-redhat-linux-gnu")BASH_VERSION='4.2.46(2)-release'DIRSTACK=()EUID=0GROUPS=()HOME=/rootHOSTNAME=node1.dyx.cloudHOSTTYPE=x86_64IFS=' 'LANG=en_US.UTF-8LOGNAME=rootLS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:'MACHTYPE=x86_64-redhat-linux-gnuMAIL=/var/mail/dyxOPTERR=1OPTIND=1OSTYPE=linux-gnuPATH=/sbin:/bin:/usr/sbin:/usr/binPOSIXLY_CORRECT=yPPID=2405PS4='+ 'PWD=/home/dyxSHELL=/bin/bashSHELLOPTS=braceexpand:hashall:interactive-comments:posixSHLVL=2SUDO_COMMAND='/bin/sh -c echo BECOME-SUCCESS-msrwdmrluwtjkhtfvqdhffcuglwtfjqc ; /usr/bin/python /home/dyx/.ansible/tmp/ansible-tmp-1765848154.46-2146-236870616870838/AnsiballZ_command.py'SUDO_GID=1001SUDO_UID=1001SUDO_USER=dyxTERM=xtermUID=0USER=rootUSERNAME=rootXDG_SESSION_ID=3_=/usr/bin/python**注意:**command和shell模块要求被管理主机安装Python。
raw 模块
raw 模块,可以直接在远端主机shell中执行命令,远端主机不需要安装Python(特别是针对网络设备)。在大部分场景中,不推荐使用command、shell、raw模块执行命令,因为这些模块不具有幂等性。
[dyx@controller web]$ ansible node1 -m raw -a'echo "hello world" > /tmp/hello.txt'node1|CHANGED|rc=0>>Shared connection to node1 closed.# 此处多了一个现实:断开连接,相当于通过ssh连接到受管节点执行命令。[dyx@controller web]$ ansible node1 -a'cat /tmp/hello.txt'node1|CHANGED|rc=0>>hello world# 对比shell模块[dyx@controller web]$ ansible node1 -m shell -a'echo "hello ansible " > /tmp/hello.txt'node1|CHANGED|rc=0>>ansible AD HOC 命令选项
临时命令选项优先级高于配置文件中配置
| 配置文件指令 | 命令行选项 |
|---|---|
| inventory | -i |
| remote_user | -u |
| ask_pass | -k,–ask_pass |
| become | –become,-b |
| become_method | –become_method |
| become_user | –become_user |
| become_ask_pass | –ask-become-pass,-K |