Linux常用命令--Ansible
摘要
-
本文介绍Ansible的安装和使用。
-
本文基于CentOS8。
Ansible简介
-
Ansible 是一个开源的自动化运维工具,它基于 Python 语言开发,支持跨平台,可以运行在 Linux、Unix、Mac OS X、Windows 等多种系统环境。
-
Ansible简单易用,只需要在控制主机上安装 Ansible 并在被管理主机上安装 Python 2.6 或更高版本即可(现有的开源Linux系统基本都自带了Python ,所以相当于远程主机什么都不需要安装),就可以管理远程主机对其进行自动化配置、编排高级工作流程以支持应用程序部署、系统更新等。
-
Ansible可以用来管理Linux、Unix、Windows、OpenStack、AWS、GCP、OpenShift、Kubernetes等系统环境。
-
Ansible官网文档:https://docs.ansible.com/ansible/latest/
-
Ansible中文权威指南:https://ansible-tran.readthedocs.io/en/latest/index.html
Ansible安装
-
Ansible安装方式有多种,这里介绍通过pip安装,当前系统中的python版本为python3.9。
1 | python3 -m pip install ansible |
-
如果尚未安装pip,可以通过下面的方法进行安装
1 | wget https://bootstrap.pypa.io/get-pip.py |
-
安装完成后,可以查看一下版本
1 | ansible --version |
-
Ansible常用参数:
参数 | 说明 |
---|---|
-u | 指定连接到主机的用户名 |
-i | 指定连接hosts文件的路径 |
-k | 指定连接到主机的密码 |
-m | 指定模块名称,可以指定模块的参数,比如指定shell模块的参数:-m shell -a ‘ls -l’ |
-a | 指定模块的参数,比如指定shell模块的参数:-m shell -a ‘ls -l’ |
-e | 指定附加参数,比如指定shell端口: -e ‘ansible_port=22’ |
-b | 切换到root权限 |
-f | 指定并发连接数,默认为5,即可以同时管理5台主机 |
Ansible的配置文件
-
ansible的相关配置都是通过一个名为
ansible.cfg
的配置文件进行配置的,但我们通过pip安装是不会默认创建它的,实际上不创建这个配置文件也不影响ansible的执行,因为其会使用一些默认的配置,并且在大多数场景下默认的配置就能满足需求。 -
ansible查找配置文件的顺序,优先级由上到下逐渐降低
1 | * ANSIBLE_CONFIG (一个环境变量) |
-
如果需要修改默认配置,我们可以通过如下命令创建一份配置文件
1 | # 此时会创建一份所有配置项都以 ; 开头的配置文件,我们要修改那个配置,就删除其前面的 ; ,然后修改其值即可 |
-
常用配置详解
1 | # 通用默认配置段; |
Ansible的hosts配置
-
需要创建hosts文件,使用ansible时,ansible会到hosts文件中查找对应的远程主机配置,默认的查找路径为
/etc/ansible/hosts
,也可以通过ansible.cfg
修改默认配置
hosts文件格式1
-
hosts文件格式如下:
1 | # 可以配置ip或主机名 |
-
命令行里加上连接参数
1 | # 执行命令,多个ip逗号分隔 |
hosts文件格式2
-
hosts文件里也可以配置连接参数
1 | [webservers] |
-
此时命令行连接时就不需要指定连接参数了
1 | ansible -i hosts -u username -m ping 10.10.2.45,10.10.2.46 |
hosts文件格式3
-
ansible是基于ssh建立连接的,所以只要ssh能连上远程主机,ansible就可以管理远程主机,如果我们为ssh配置config文件,那么ansible就可以直接将config里的Host名称配置到hosts文件里,这样就不需要配置连接参数了,同时此时也可以支持跳板机。关于ssh的config详细说明可以参考Linux常用命令--ssh、scp与免密登录
- 配置~/.ssh/config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21# 跳板机
Host forward
User ec2-user
HostName 53.22.227.200
Port 22
IdentityFile ~/.ssh/id_rsa
# 远程主机
Host remote-host
User ec2-user
HostName 10.9.5.123
Port 22
IdentityFile ~/.ssh/key.pem
ProxyCommand ssh forward -W %h:%p
# 远程主机 ,10.9网段的所有主机
Host 10.9.*
User ec2-user
Port 22
IdentityFile ~/.ssh/key.pem
ProxyCommand ssh forward -W %h:%p- hosts文件
1
2
3
4
5[webservers]
forward # 与config中配置的Host名称一致
remote-host # 与config中配置的Host名称一致
10.9.5.123 # 匹配config中的网段
10.9.5.124 # 匹配config中的网段- 命令行
1
2
3
4
5
6
7
8
9
10
11
12
13# 通过指定主机名或ip
ansible -m ping remote-host
ansible -m ping 10.9.5.123
# 通配符匹配,此时在匹配hosts中123和124
ansible -m ping "10.9.5.*"
# 通过分组名
ansible -m ping webservers
# 通过all指定hosts里的全部主机
ansible -m ping all
查看hosts配置相关命令
-
列出所有组的配置ip信息
1 | ansible all --list-hosts |
-
查看当前hosts中配置所有组名称
1 | ansible localhost -m debug -a 'var=groups.keys()' |
-
列出指定组的配置ip信息
1 | ansible dbservers --list-hosts |
Ansible模块
-
列出所有模块
1 | ansible-doc -l |
-
查看指定模块的参数信息,如下查看shell模块的参数说明
1 | ansible-doc -s shell |
-
查看模块的帮助信息,如下查看shell模块的帮助信息,这与官方文档一致:shell模块
1 | ansible-doc shell |
-
Ansible管理工具常用的模块:
command、shell、file、user、copy、service、yum、synchronze、cron、setup、ping
等。可以在命令行里指定各个模块的参数(ansible
命令),也可以将参数配置到yml文件里,然后在命令行里指定yml文件(ansible-playbook
命令),下面会结合两种方式一块介绍。网上有大把的关于ansible命令的使用说明,这里只简单介绍几个模块的使用方法,其他模块的使用方法可以参考ansible模块 -
下面介绍的都是ansible核心模块:ansible-core
debug模块
-
debug模块此模块在执行期间打印语句,可用于调试变量或表达式
-
通过命令行执行命令
1 | ansible webservers -m debug -a 'msg="System HostName: {{ inventory_hostname }}"' |
-
通过yml文件执行命令
1 | # debug.yml |
-
常用参数说明:
ansible-doc -s debug
参数 | 描述 |
---|---|
msg | 打印消息,支持变量 |
var | 打印消息,支持变量,注册变量 , 与msg互斥 |
ping模块
-
ping模块用于测试主机的连通性,它会尝试连接到主机,验证可用的python,并在成功时返回“pong”,可以指定主机名或ip,也可以指定分组名,也可以指定all
-
通过命令行执行命令
1 | ansible webservers -m ping |
-
通过yml文件执行命令
1 | # ping.yml |
ansible-playbook
- 通过ansible-playbook命令,可以指定yml文件
- ansible-playbook相关命令
1 | # 检查yml文件语法格式 |
setup模块
-
该模块用于采集被管理设备信息并返回给服务端,后面跟
--tree <目录>
,可以将采集信息以ip为文件名保存至指定目录下
1 | # 查看全部信息 |
-
常用参数说明:
ansible-doc -s setup
参数 | 描述 |
---|---|
gather_subset | 指定要收集的系统信息的子集。可以是 all(所有信息)、network(网络信息)、hardware(硬件信息)等。默认为 all。 |
gather_timeout | 设置信息收集的超时时间,单位为秒。默认为 10 秒。 |
filter | 指定要收集的系统信息的过滤条件。可以是一个或多个标签,只收集匹配的信息。 |
fact_path | 指定自定义 facts 文件的路径。 |
这里重点介绍一下gather_subset
1 | all: 收集所有可用的系统信息。 |
command模块
-
command模块为ansible默认模块,主要用于执行Linux基础命令,可以执行远程服务器命令执行、任务执行等操作。
-
command模块不支持管道符号、变量,只能运行简单命令,复杂命令需要使用shell模块
-
示例1
1 | ansible webservers -m command -a "df -hT" |
1 | # command.yml |
-
示例2:参数chdir:切换到指定目录后再运行命令
可以通过
ansible-doc -s command
查看其支持的参数
1 | ansible webservers -m command -a "chdir=/tmp ls -l" |
1 | # command2.yml |
-
常用参数说明:
ansible-doc -s command
参数 | 描述 |
---|---|
argv | 要执行的命令,可以是字符串形式或列表形式。 |
chdir | 在执行命令之前切换到的目录。 |
cmd | 要执行的命令。 |
creates | 指定一个文件名或模式,如果匹配的文件已经存在,则不执行命令。 |
expand_argument_vars | 是否展开作为变量的参数。默认为 true,表示展开变量。 |
free_form | 以字符串形式指定要执行的命令。这个参数并不存在,但是 command 模块接受自由形式的字符串作为命令。 |
removes | 指定一个文件名或模式,如果匹配的文件存在,则执行命令。 |
stdin | 将命令的标准输入设置为指定的值。 |
stdin_add_newline | 是否在标准输入数据后添加换行符。 |
strip_empty_ends | 是否从标准输出的末尾剥离空行。 |
shell模块
-
shell模块与command模块类似,可以执行远程服务器命令执行、任务执行等操作,但是shell模块支持管道符号、变量,可以执行复杂命令
-
示例:
1 | # 查看进程 |
1 | # shell.yml |
-
常用参数说明:
ansible-doc -s shell
参数 | 描述 |
---|---|
argv | 要执行的命令,可以是字符串形式或列表形式。 |
chdir | 在执行命令之前切换到的目录。 |
cmd | 要执行的命令。 |
creates | 指定一个文件名或模式,如果匹配的文件已经存在,则不执行命令。 |
executable | 用于执行命令的可执行程序,默认情况下为 /bin/sh。 |
free_form | 以字符串形式指定要执行的命令。这个参数并不存在,但是 shell 模块接受自由形式的字符串作为命令。 |
removes | 指定一个文件名或模式,如果匹配的文件存在,则执行命令。 |
stdin | 将命令的标准输入设置为指定的值。 |
stdin_add_newline | 是否在标准输入数据后添加换行符。 |
strip_empty_ends | 是否从标准输出的末尾剥离空行。 |
file模块
-
file模块主要用于文件和目录的管理,可以创建、删除、修改文件和目录,可以指定文件或目录的属性,可以指定文件或目录的权限,可以指定文件或目录的owner、group、mode等信息,等等
-
示例:创建目录
1 | ansible webservers -m file -a "path=/tmp/`date +%F` state=directory mode=755" |
1 | # file.yml |
-
常用参数说明:
ansible-doc -s file
参数 | 描述 |
---|---|
path | 文件或目录的路径。 |
state | 文件或目录的状态。可选值包括 file(文件)、directory(目录)、link(符号链接)。默认为 file。 |
owner | 文件或目录的所有者。 |
group | 文件或目录的所属组。 |
mode | 文件或目录的权限。 |
src | 源文件路径,用于复制文件或创建链接。 |
dest | 目标文件路径,用于复制文件或创建链接。 |
follow | 是否遵循符号链接。如果为 yes,则会遵循符号链接进行操作。默认为 yes。 |
selevel | 文件或目录的 SELinux 安全上下文。 |
serole | 文件或目录的 SELinux 角色。 |
setype | 文件或目录的 SELinux 类型。 |
seuser | 文件或目录的 SELinux 用户。 |
unsafe_writes | 是否启用不安全的写入模式。如果为 yes,则在写入文件之前不会创建备份。默认为 no。 |
这里重点说一下
state
1 | file:表示要求目标主机上存在指定的文件。如果文件已经存在,则不执行任何操作;如果文件不存在,则会创建它。 |
copy模块
-
copy模块主要用于将文件复制到远程服务器,可以指定文件的源路径、目标路径、owner、group、mode等信息,等等
-
示例:复制文件到指定目录
1 | # -b 切换到root用户下执行 |
1 | # copy.yml |
-
常用参数说明:
ansible-doc -s copy
参数 | 描述 |
---|---|
src | 源文件的路径。 |
dest | 目标文件的路径。 |
backup | 是否备份目标文件。如果为 yes,则在复制目标文件之前会创建一个备份文件。默认为 yes。 |
content | 要写入目标文件的内容。 |
directory_mode | 目标目录的权限。只有当目标是一个目录时才会生效。 |
follow | 是否跟随符号链接。如果为 yes,则会跟随符号链接进行操作。默认为 yes。 |
force | 是否强制覆盖目标文件。如果为 yes,则强制复制源文件,即使目标文件已经存在。默认为 no。 |
group | 目标文件的所属组。 |
mode | 目标文件的权限。 |
owner | 目标文件的所有者。 |
remote_src | 指定源文件是否在远程主机上。如果为 yes,表示源文件在远程主机上。默认为 no。 |
fetch模块
-
fetch模块主要用于将文件从远程服务器复制到本地,可以指定文件的源路径、目标路径、owner、group、mode等信息,等等
-
示例:将文件从远程服务器复制到本地
1 | ansible webservers -m fetch -a "src=/tmp/a.txt dest=/tmp/ flat=yes" |
1 | # fetch.yml |
-
常用参数说明:
ansible-doc -s fetch
参数 | 描述 |
---|---|
src | 远程主机上要拉取的文件的路径。 |
dest | 本地主机上文件的目标路径。 |
flat | 是否将文件放置在顶层目录中。如果为 yes,则所有文件都将放置在一个目录中。默认为 no。 |
fail_on_missing | 如果为 yes,则在源文件不存在时失败。默认为 yes。 |
validate_checksum | 是否验证远程文件的校验和。默认为 no。 |
cron模块
-
cron模块主要用于在远程服务器上创建、修改、删除定时任务
-
示例:创建定时任务
1 | ansible webservers -m cron -a 'name="restart httpd" hour=*/5 job="systemctl restart httpd"' |
1 | # cron.yml |
-
常用参数说明:
ansible-doc -s cron
参数 | 描述 |
---|---|
name | cron 任务的名称。 |
minute | cron 任务执行的分钟。 |
hour | cron 任务执行的小时。 |
day | cron 任务执行的日期。 |
month | cron 任务执行的月份。 |
weekday | cron 任务执行的星期几。 |
job | 要执行的命令或脚本。 |
cron_file | 要操作的 cron 文件的路径。默认为 /etc/crontab。 |
state | cron 任务的状态。可选值包括 present(默认)和 absent。表示要求任务存在或不存在。 |
user | cron 任务的执行用户。默认为 root。 |
backup | 是否备份 cron 文件。可选值包括 true 和 false。 |
state
1 | present:表示要求指定的 cron 任务存在。如果指定的 cron 任务不存在,则 Ansible 将会创建它。如果已经存在,则不执行任何操作。 |
yum模块
-
yum模块主要用于在远程服务器上安装、卸载、更新软件包,可以指定软件包的名称、版本、repo等信息,等等
-
示例:安装软件包
1 | # 安装软件包,相当于 yum install httpd |
1 | # yum.yml |
-
常用参数说明:
ansible-doc -s yum
参数 | 解释 |
---|---|
name | 指定要操作的包的名称。 |
update_cache | 指定是否在执行操作之前更新 yum 缓存。可选值为 yes 或 no 。默认为 yes 。 |
disable_gpg_check | 指定是否禁用 GPG 检查。如果为 yes ,则禁用 GPG 检查。默认为 no 。 |
disable_plugin | 指定是否禁用指定的 yum 插件。可以是一个插件名称的列表。 |
enablerepo | 指定要启用的仓库。可以是一个仓库名称的列表。 |
disablerepo | 指定要禁用的仓库。可以是一个仓库名称的列表。 |
installroot | 指定要安装软件包的根目录。 |
security | 指定是否只安装安全更新。如果为 yes ,则只安装安全更新。默认为 no 。 |
list | 指定是否列出所有已安装的包。如果为 yes ,则列出已安装的包。默认为 no 。 |
state | 指定软件包的状态。可选值为 present 、latest 、absent 、installed 、removed 。默认为 present 。 |
这里重点说一下
state
1 | present: 表示要求目标主机上存在指定的软件包。如果软件包已经安装,则不执行任何操作;如果软件包未安装,则会安装它。 |
service模块:调用的是service
命令
-
service模块主要用于在远程服务器上启动、停止、重启、重新加载、启用、禁用、检查服务,可以指定服务的名称、状态、启动方式等信息,等等
-
示例:启动服务
1 | ansible webservers -m service -a "name=httpd state=started" |
1 | # service.yml |
-
常用参数说明:
ansible-doc -s service
参数 | 描述 |
---|---|
name | 服务的名称。 |
state | 服务的状态。可选值包括 started(已启动)、stopped(已停止)、restarted(已重启)。 |
enabled | 是否在启动时自动启用服务。如果为 yes,则在系统启动时自动启动服务。默认为 yes。 |
pattern | 匹配服务的模式。默认情况下为服务名称。 |
sleep | 在重新启动服务之前等待的秒数。 |
arguments | 启动或停止服务时要传递的参数。 |
state
1 | started:表示要求服务处于已启动状态。如果指定的服务未启动,则 Ansible 将尝试启动该服务。如果服务已经处于运行状态,则不执行任何操作。 |
systemd模块:支持centos7+
,调用的是systemctl
-
systemd模块用于控制 systemd 后台服务,允许你启动、重新启动、停止或者重新加载 systemd 服务。此外,你也可以使用它来使服务在系统启动时自动启动或禁止自动启动。除此之外,systemd 模块还允许你检查服务的状态。
-
示例
1 | ansible webservers -m systemd -a "name=httpd state=restarted" |
1 | # systemd.yml |
-
主要参数说明:
ansible-doc -s systemd
参数 | 描述 |
---|---|
enabled | 指定服务是否应该在启动时自动启用。可选值为 yes 或 no。默认为 yes。 |
masked | 指定服务是否应该被置为 masked 状态,禁止手动启动。可选值为 yes 或 no。默认为 no。 |
name | 服务的名称。 |
state | 指定服务的状态。可选值为 started(启动)、stopped(停止)、restarted(重新启动)、reloaded(重新加载) |
script模块
-
script模块主要用于在远程服务器上执行本地的脚本
-
示例:执行脚本
1 | ansible webservers -m script -a "chdir=/tmp /tmp/a.sh" |
1 | # script.yml |
-
常用参数说明:
ansible-doc -s script
参数 | 描述 |
---|---|
chdir | 在远程主机上执行脚本之前切换到的目录。 |
free_form | 要在远程主机上执行的脚本内容。 |
creates | 如果指定的文件已经存在,则不执行脚本。 |
executable | 指定要使用的脚本解释器。 |
removes | 在执行脚本之后,如果指定的文件存在,则删除该文件。 |
cmd | 指定要执行的命令。 |
decrypt | 指定要解密的源文件。 |
user模块
-
user模块主要用于在远程服务器上创建、修改、删除用户,可以指定用户的名称、密码、uid、gid、home、shell等信息,等等
-
示例:创建用户
1 | ansible webservers -m user -a "name=nginx group=nginx shell=/sbin/nologin create_home=no" |
1 | # user.yml |
-
常用参数说明:
ansible-doc -s user
参数 | 描述 |
---|---|
append | 是否将用户添加到现有组,而不是替换组。 |
comment | 对用户的注释信息。 |
createhome | 是否创建用户的家目录。 |
expires | 用户帐户过期日期。 |
force | 是否强制创建或更改用户帐户。 |
generate_ssh_key | 是否生成用户的 SSH 密钥对。 |
group | 用户所属组的名称或 ID。 |
groups | 用户所属的其他组。 |
home | 用户的家目录路径。 |
login_class | 用户登录类。 |
move_home | 是否在更改用户家目录路径时移动其内容。 |
name | 用户的名称。 |
non_unique | 允许用户具有非唯一的数字 ID。 |
password | 用户的密码哈希值或加密后的密码。 |
remove | 是否删除用户。 |
shell | 用户的 shell。 |
state | 用户帐户的状态。 |
system | 是否为系统用户。 |
uid | 用户的数字 ID。 |
state
1 | present:表示要求指定的用户账户存在。如果指定的用户账户不存在,则 Ansible 将会创建该账户。如果用户账户已经存在,则不执行任何操作。 |
get_url模块
-
get_url模块负责下载文件到目标主机。
-
示例
1 | ansible webservers -m get_url -a "url=https://www.example.com dest=/tmp" |
1 | # get_url.yml |
-
主要参数说明:
ansible-doc -s get_url
参数 | 描述 |
---|---|
url | 要下载的文件的 URL 地址。 |
dest | 下载文件保存的目标路径。 |
force | 是否强制覆盖目标路径中的文件。可选值为 yes 或 no。默认为 yes。 |
timeout | 下载超时时间,单位为秒。默认为 10 秒。 |
validate_certs | 是否验证 SSL 证书。可选值为 yes 或 no。默认为 yes。 |
owner | 下载后文件的所有者。 |
group | 下载后文件的所属组。 |
mode | 下载后文件的权限模式。 |
backup | 是否创建备份文件。可选值为 yes 或 no。默认为 no。 |
headers | 附加的 HTTP 请求头。 |
force_basic_auth | 是否强制使用 HTTP 基本身份验证。可选值为 yes 或 no。默认为 yes。 |
http_agent | 用于 HTTP 请求的代理。 |
lineinfile模块
-
lineinfile模块主要用于在远程主机上查找和替换文件中的行,可以指定要查找的行、要替换的行、要添加的行等信息,等等
-
示例:设置环境变量,需要注意的是此时环境变量在剧本的上下文中是不生效的,如果需要在剧本上下文生效的环境变量,可以使用
shell
模块
1 | ansible webservers -m lineinfile -a "path=/etc/profile line='PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin' state=present backup=yes" |
1 | # lineinfile.yml |
-
主要参数说明:
ansible-doc -s lineinfile
参数 | 描述 |
---|---|
path | 要修改的文件的路径。 |
line | 要添加、修改或删除的行内容。 |
state | 指定要执行的操作。 |
regexp | 用于匹配行的正则表达式。 |
search_string | 用于匹配行的字符串。 |
backup | 是否创建备份文件。可选值为 yes 或 no。默认为 no。 |
backrefs | 是否允许在 regexp 中使用反向引用。 |
insertbefore | 指定一个行,将新行插入到它之前。 |
insertafter | 指定一个行,将新行插入到它之后。 |
firstmatch | 是否只匹配第一个匹配项。 |
state说明
1 | present:确保指定的行存在于文件中。如果文件中不存在指定的行,则会添加该行。如果文件中已经存在该行,则不做任何改变。 |
ansible-playbook:剧本
-
ansible-playbook是Ansible的核心命令,用于执行playbook文件,playbook文件是Ansible执行任务的最小单元,一个playbook文件可以包含多个play,每个play可以包含多个task,每个task可以包含多个module,每个module可以执行一个操作,比如创建目录、安装软件包、启动服务、执行脚本等
-
上面在介绍ansible模块时,我们已经编写了一些playbook文件,就是那些yml文件,运行时也是通过ansible-playbook命令执行的,但是基本上都是单个任务单个模块,下面我们来看一个复杂一些的示例
-
示例:安装nginx并配置
1 | # playbook.yml |
-
优化1
问题: 上面的剧本有个问题,就是如果系统已经安装了nginx,则运行这个剧本还是会重新安装
解决方法: 先判断nginx是否已经安装,如果已经安装,直接跳过安装步骤,直接执行启动命令,否则执行安装步骤,然后再执行启动命令
1 |
|
register :用于将命令执行的结果保存到变量中,我们可以调用变量的属性,比如rc表示命令返回的状态码($?),stdout表示命令的输出,stderr表示命令的错误输出
ignore_errors :用于忽略错误
loop :用于循环列表
when :用于判断条件,只有条件满足时才执行
-
优化2
问题: 上面的步骤有点多,比如下载、解压、编译nginx,这些都是在没有安装nginx的情况下要运行的任务
解决方法: 使用shell模块可以将这些步骤封装成一个任务
1 |
|
-
优化3
问题: 上面的剧本虽然已经满足了我的需求,但是不够简练,因为很多任务并不是主要任务,我需要在每个任务中进行条件判断来决定是否执行该任务,能否只保留主要任务,其它任务只有当这些主要任务成功运行了才会被运行呢?比如这里的主要任务就是两个:1-判断是否安装了nginx,没安装就去安装,2-判断是否启动了nginx,没启动就去启动
解决方法: 使用基于handlers的notify语句,这样可以减少重复执行任务的次数
何为handlers
Handler 本身是一种非同步的 callback function ,在这里则是指关连于特定 tasks 的事件 (event) 触发机制。当关联 handler 的 tasks 状态为被改变 (changed) 且都已被执行时,才会触发一次
何为 tasks 状态为被改变 (changed)
在Ansible中,task的状态会根据任务执行的结果而改变。当一个任务成功完成并且使得系统的状态与预期不同(即执行了一些更改),那么这个任务的状态就会被标记为"changed"。
具体来说,task状态为"changed"的条件包括但不限于以下情况:
1 | 文件变更:例如复制、创建、删除文件等操作导致了文件系统的变更。 |
1 |
|
-
优化4
问题: 上面的剧本中nginx的安装版本和安装路径都是写死的,能否动态配置呢?
解决方法: 提取变量,使用vars
1 |
|
1 | # 默认 |
小贴士
- 除了我们自己定义的变量,我们也可以使用Ansible内置的变量,Ansible内置的变量可以参考官方文档。
- 我们用的最多的就是
ansible_facts
变量获取主机信息,如IP地址、MAC地址、操作系统版本等。也就是通过setup
模块获取的信息。 - 在使用
ansible_facts
变量时需要开启gather_facts
选项,默认是开启的。 - 常用的
ansible_facts
变量如下,注意这里属性名称前是不加ansible_
前缀的:
1 | ansible_facts['distribution']: 远程主机的操作系统分发名称。 |
ansible-playbook:Template
-
Ansible Playbook Template是一种Ansible的特性,它允许您在Playbook中使用
Jinja2
模板语言来动态生成配置文件或其他文本文件。通过使用模板,您可以根据变量、条件、循环等动态信息来生成目标文件,从而使配置文件更具可扩展性和灵活性。 -
下面是使用Ansible Playbook Template的一些常见用法和特性:
1 | Jinja2模板语言: Ansible Playbook Template使用Jinja2模板语言,这是一种功能强大的模板引擎,支持变量替换、条件语句、循环语句等功能。 |
-
Jinja2模板文件后缀为
.j2
,常用语法如下:
1 | # 打印变量 |
-
结合上面部署nginx的示例,我这里增加一个任务,就是替换nginx发布目录下的index.html,然后重启nginx,这里给出
index.html.j2
1 |
|
-
接着我们修改剧本yml
1 |
|
-
替换之后的效果
1 |
|
-
template模块
的常用参数说明ansible-doc -s template
参数 | 必需 | 默认值 | 描述 |
---|---|---|---|
src | 是 | 无 | 模板文件的路径。 |
dest | 是 | 无 | 目标文件的路径。 |
force | 否 | false | 如果目标文件已经存在,是否强制覆盖。 |
backup | 否 | false | 如果设置为true,则在覆盖目标文件之前创建备份。 |
unsafe_writes | 否 | false | 如果设置为true,则会跳过文件的暂时性写入保护(如确保在写入文件之前不会更改其内容)。 |
newline_sequence | 否 | \n | 用于生成文件时的换行符序列。 |
validate | 否 | 无 | 要应用于生成文件的验证器脚本的路径。 |
mode | 否 | 无 | 目标文件的权限模式。 |
owner | 否 | 无 | 目标文件的所有者。 |
group | 否 | 无 | 目标文件的所属组。 |
-
这里要注意
template模块
与copy
模块的区别,前者在上传时会进行变量替换。
ansible-playbook:Role
-
Ansible中的Role是一种组织和管理剧本的方法,它允许您将相关的任务、变量、文件和处理程序组合到一个可重用的单元中。Role使得您可以更轻松地管理和组织大型的Ansible项目,并促进了可维护性和复用性。
-
Role的特性
1 | 组织性:Role允许您将相关的任务和文件组织在一起,使得代码更易于理解和维护。每个Role通常都有一个特定的目的,例如安装特定的软件、配置服务或执行特定的系统管理任务。 |
-
创建role
1 | # 在当前目录下创建一个名称为nginx-install的role,实际上就是创建一个名称为nginx-install的目录结构 |
1 | files:存放由copy或script模块等调用的文件 |
-
ansible查找role的路径,推荐放到
/etc/ansible/roles
1 | $(pwd)/roles |
我们将上面安装nginx那个剧本修改为role的方式
-
nginx-install/tasks/main.yml
1 |
|
-
nginx-install/handlers/main.yml
1 |
|
-
nginx-install/vars/main.yml
1 |
|
小贴士
- 上面介绍的
tasks
、handlers
,其目录中都含有一个main.yml文件,这个文件是必须存在的 - 但是如果配置的内容比较多,都写在main.yml文件中,那么这个文件就显得有点臃肿,所以可以将这些内容拆分成多个文件,然后在main.yml文件中通过
include
进行包含
1 |
|
tasks
或者handlers中
还可以使用include_tasks
进行包含
1 |
|
-
vars
里也可以定义多个yml文件存储变量,然后在tasks中通过include_vars
进行包含,注意,必须放在task的yml文件中
1 | # 此时不需要加上vars路径,会自动从vars目录下查找 |
-
将模板文件和图片文本保存到对应的路径
nginx-install/templates/index.html.j2
nginx-install/files/me.png
-
执行
假设我们将创建的角色安装到了/etc/ansible/roles
下
创建启动剧本
nginx-install-start.yml
,我们也可以修改tests/test.yml
1 | - name: 安装nginx并配置 |
执行role
1 | ansible-playbook nginx-install-start.yml |
ansible-galaxy
什么是ansible-galaxy
-
用于从ansible-galaxy官网上查找,下载
role
和collection
的工具,如何下载和使用网站上都有说明。 -
我们也可以将自己创建好的
role
发布到ansible-galaxy
上,可以参考 Ansible Role Publish To Galaxy
role
1 | # 搜索role |
collection
-
ansible-galaxy同时支持下载 collection
1 | # 查看已经安装的collection |
-
Ansible Collection 是 Ansible 社区为了更好地管理和组织 Ansible 角色、模块、插件等内容而引入的概念。它可以被视为一种打包机制,用于将相关的 Ansible 内容打包成单独的单元,使得其更易于分享、安装和维护。
-
具体来说,Ansible Collection 具有以下作用:
1 | 组织和管理角色、模块和插件:通过 Collection,可以将相关的角色、模块和插件打包在一起,形成逻辑上的单元,提高了内容的组织性和可管理性。 |
-
总的来说,Ansible Collection 提供了一种更高级别的组织和管理方式,使得 Ansible 内容更易于分享、使用和维护,从而提高了 Ansible 的整体生态系统的健壮性和可用性。
小贴士
- 前面的剧本中我们多次使用到了
become
切换用户到root用户,其实在ansible.cfg
中我们可以配置become_user
,这样我们就可以不用每次都切换用户了 - 但这里有个需要注意的点,就是因为
become
会以一个全新的环境执行任务,所以其不会包含原用户的环境变量。可以理解为其是通过sudo su
切换到root,而非sudo -i
。
后记
关于ansible的知识点还有很多没有研究到,后面会慢慢补吧……
-
关于将Ansible Role发布到Galaxy的详细介绍可以参看 Ansible Role Publish To Galaxy
-
关于将Ansible Collection发布到Galaxy的详细介绍可以参看 Ansible Collection Publish To Galaxy