1. Ansible 基础和常用模块
1 Ansible 安装和入门
1.1 Ansible安装
- 官方EPEL源提供Ansible
[12:02:55 root@ansible ~]#yum -y install ansible
[12:03:01 root@ansible ~]#ansible --version
ansible 2.9.16
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Apr 2 2020, 13:16:51) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
1.2 Ansible 配置文件
1.2.1 配置文件
- /etc/ansible/ansible.cfg # 主配置文件, 用来配置Ansible功能
- /etc/ansible/hosts # 定义主机清单文件
- /etc/ansible/roles # 定义角色目录
1.2.2 Ansible 主配置文件
- /etc/ansible/ansible.cfg: 大部分内容都无需修改
[defaults]
# some basic default values...
#inventory = /etc/ansible/hosts # 定义主机清单
#library = /usr/share/my_modules/ # 库文件
#module_utils = /usr/share/my_module_utils/
#remote_tmp = ~/.ansible/tmp # 用来存放Python临时文件的目录, ansible推送时的临时文件会存放在被管理节点的这个目录里
#local_tmp = ~/.ansible/tmp # Python临时文件在ansible主机的存放目录
#plugin_filters_cfg = /etc/ansible/plugin_filters.yml
#forks = 5 # ansbile并发处理的数量, 默认为5, 也就是每次处理5个主机
#poll_interval = 15
#sudo_user = root # 默认的sudo用户, 该账户需要在目标主机存在, 并且有相应的管理权限.
#ask_sudo_pass = True # 当ansible使用sudo账号连接到被管理节点时, 是否需要被管理节点的账户密码
#ask_pass = True # 远程连接时是否需要ssh密码
#transport = smart
#remote_port = 22 # 被管理节点ssh端口号
#module_lang = C
#module_set_locale = False
#host_key_checking = False # 第一次连接某个主机时, 是否需要同意下载对端主机公钥, 直接下载无需手动同意, 或者修改ansible的/etc/ssh/ssh_config文件, 或者执行时使用`ssh -o`
#log_path=/var/log/ansible.log # ansible日志, 建议开启
#module_name= command # ansible执行命令时, 默认使用的模块, 改成shell比较好
1.2.3 主机清单
eg: 本文案例
CentOS-8
10.0.0.85
10.0.0.86
CentOS-7
10.0.0.187
[websrvs]
10.0.0.85
10.0.0.86
[appsrvs]
10.0.0.187
10.0.0.85
[dbsrvs]
10.0.0.187
10.0.0.86
1.3 Ansible 工具
[18:06:08 root@ansible ~]#ansible
ansible ansible-connection ansible-doc ansible-inventory ansible-pull ansible-vault
ansible-config ansible-console ansible-galaxy ansible-playbook ansible-test
- /usr/bin/ansible # 主程序, 临时命令执行工具
- /usr/bin/ansible-doc # 查看配置文档, 模块功能查看工具
- /usr/bin/ansible-playbook # 定制自动化任务, 编排剧本工具, 相当于脚本
- /usr/bin/ansible-pull # 远程执行命令的工具
- /usr/bin/ansible-vault # 文件加密工具
- /usr/bin/ansible-console # 基于Console界面与用于交互的执行工具
- /usr/bin/ansible-galaxy # 下载/上传优秀代码或Roles模块的官网平台
利用ansible实现管理的主要方式
- Ad-Hoc: 利用ansible命令, 临时执行任务
- Ansible-playbook: 主要用于长期规划好的, 大型项目的场景, 需要前期规划好
1.3.1 ansible-doc
- 查看可用模块
ansible-doc -l
- 查看某个模块的使用方法
ansible-doc -s MODULES_NAME, 简要描述
ansible-doc MODULES_NAME, 详细使用方法
ping模块只是检测某个主机是否可以被ansible管理, 并不是执行icmp协议的ping命令
[12:15:56 root@ansible ~]#ansible-doc -s ping
- name: Try to connect to host, verify a usable python and return `pong' on success
ping:
data: # Data to return for the `ping' return value. If this parameter is set to `crash', the module will cause an exception.
1.3.2 配置基于key的ssh认证
IPLIST="
10.0.0.85
10.0.0.86
10.0.0.187
"
rpm -q sshpass &> /dev/null || yum -y install sshpass
[ -f /root/.ssh/id_rsa ] || ssh-keygen -f /root/.ssh/id_rsa -P ''
export SSHPASS=000000
for IP in $IPLIST;do
sshpass -e ssh-copy-id -o StrictHostkeyChecking=no $IP
done
[12:21:54 root@ansible ~]#ansible all -m ping
10.0.0.187 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.86 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
10.0.0.85 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
1.3.3 列出主机清单
[12:22:00 root@ansible ~]#ansible websrvs --list-hosts
hosts (2):
10.0.0.85
10.0.0.86
[12:24:09 root@ansible ~]#ansible all --list-hosts
hosts (3):
10.0.0.187
10.0.0.85
10.0.0.86
- 格式要求
不支持的格式:
ansible 10.0.0.8[5:6] -m ping
ansible "10.0.0.8[5:6]" -m ping
[12:24:14 root@ansible ~]#ansible 10.0.0.8[5:6] -m ping
[WARNING]: Could not match supplied host pattern, ignoring: 10.0.0.8
[WARNING]: No hosts matched, nothing to do
10.0.0.8[1:3] = 10.0.0.81 和 10.0.0.83
- 通配符
ansible '*' -m ping
ansible 192.168.1.* -m ping
ansible "srvs" -m ping
ansible "10.0.0.236 10.0.0.237" -m ping
- 或关系
在websrvs组或在appsrvs组里的主机
[12:25:29 root@ansible ~]#ansible websrvs:appsrvs --list-hosts
hosts (3):
10.0.0.85
10.0.0.86
10.0.0.187
- 逻辑与
在websrvs组并且也在dbsrvs组里的主机
[12:29:30 root@ansible ~]#ansible 'websrvs:&appsrvs' --list-hosts
hosts (1):
10.0.0.85
- 逻辑非
在websrvs组, 但不在dbsrvs组中的主机
注意: 此处必须用单引号
[12:29:37 root@ansible ~]#ansible 'websrvs:!dbsrvs' --list-hosts
hosts (1):
10.0.0.85
- 综合逻辑
ansible 'websrvs:dbsegs:&appsrvs:!ftpsrvs' -m ping
- 正则表达式
ansible 'websrvs:dbsrvs' -m ping
ansible "~(web|db).*\.linux\.com" -m ping
eg: 在k8s环境中, 如果ansible本机也被加入到了host清单里, 那么k8s配置完主机需要批量重启远程主机时,需要把本机先刨除在ansible命令执行清单外. 避免如果本机先重启了那么这条ansible命令也就不会执行后续重启其他主机的操作了.
ansible 'kube*:etcd:!10.0.0.101' -a reboot; reboot
ansible命令执行过程
- 加载自己的配置文件, 默认/etc/ansible/ansible.cfg
- 加载自己对应的模块文件, 如: command
- 通过ansible将模块或命令生成对应的临时py文件, 并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件
- 给文件添加执行权限
- 执行并返回结果
- 删除临时py文件, 退出
ansible执行状态
绿色: 执行成功并且不需要做改变的操作
黄色: 执行成功并且对目标主机做变更
红色: 执行失败
2 Ansible 常用模块
2.1 command 模块
- ansible的默认模块, 执行命令时不指定-m,那么就是使用command模块
- command模块只支持基本的linux命令
- 不支持特殊符号,如($VARNAME < > | ; & ...), 需要用shell模块
- 命令需要写在''或者""里,
ansible all -m command -a 'cat /etc/issue'
[13:55:48 root@ansible ~]#ansible-doc -s command
- name: Execute commands on targets
command:
argv: # Passes the command as a list rather than a string. Use `argv'
to avoid quoting values that
would otherwise be interpreted
incorrectly (for example "user
name"). Only the string or the
list form can be provided, not
both. One or the other must be
provided.
chdir: # Change into this directory before running the command.
cmd: # The command to run.
creates: # A filename or (since 2.0) glob pattern. If it already exists,
this step *won't* be run.
free_form: # The command module takes a free form command to run. There is
no actual parameter named 'free
form'.
removes: # A filename or (since 2.0) glob pattern. If it already exists,
this step *will* be run.
stdin: # Set the stdin of the command directly to the specified value.
stdin_add_newline: # If set to `yes', append a newline to stdin data.
strip_empty_ends: # Strip empty lines from the end of stdout/stderr in result.
warn: # Enable or disable task warnings.
eg: cat /os/centos-release
[12:37:10 root@ansible ~]#ansible all -m command -a 'cat /etc/centos-release '
10.0.0.187 | CHANGED | rc=0 >>
CentOS Linux release 7.8.2003 (Core)
10.0.0.86 | CHANGED | rc=0 >>
CentOS Linux release 8.2.2004 (Core)
10.0.0.85 | CHANGED | rc=0 >>
CentOS Linux release 8.2.2004 (Core)
eg: ls /data/* # command 模块不支持特殊符号
[12:37:27 root@ansible ~]#ansible all -m command -a 'ls /data/*'
10.0.0.187 | FAILED | rc=2 >>
ls: cannot access /data/*: No such file or directorynon-zero return code
10.0.0.85 | FAILED | rc=2 >>
ls: cannot access '/data/*': No such file or directorynon-zero return code
10.0.0.86 | FAILED | rc=2 >>
ls: cannot access '/data/*': No such file or directorynon-zero return code
[12:39:01 root@ansible ~]#ansible all -m command -a 'echo $HOSTNAME' # ansible的变量需要用单引号, 不过command模块不支持
10.0.0.187 | CHANGED | rc=0 >>
$HOSTNAME
10.0.0.86 | CHANGED | rc=0 >>
$HOSTNAME
10.0.0.85 | CHANGED | rc=0 >>
$HOSTNAME
[12:39:34 root@ansible ~]#ansible all -m command -a "echo $HOSTNAME" # ansible的变量需要使用单引号, 双引号会显示本机信息
10.0.0.187 | CHANGED | rc=0 >>
ansible
10.0.0.85 | CHANGED | rc=0 >>
ansible
10.0.0.86 | CHANGED | rc=0 >>
ansible
[14:08:01 root@ansible ~]#ansible all -a "ls /boot > /data/ls.log"
#不支持重定向
2.2 shell 模块
- 类似command模块, 但是支持特殊符合, 通配符, $VAR, <, >,...
- 对于变量, 需要用在单引号
- shell模块无法支持复杂的命令, 复杂命令需要使用script模块
eg:
[12:44:54 root@ansible ~]#ansible all -m shell -a "echo $HOSTNAME"
10.0.0.187 | CHANGED | rc=0 >>
ansible
10.0.0.85 | CHANGED | rc=0 >>
ansible
10.0.0.86 | CHANGED | rc=0 >>
ansible
[12:45:10 root@ansible ~]#ansible all -m shell -a 'echo $HOSTNAME'
10.0.0.187 | CHANGED | rc=0 >>
centos-7-6.prac
10.0.0.86 | CHANGED | rc=0 >>
CentOS-8-6
10.0.0.85 | CHANGED | rc=0 >>
CentOS-8-5
[12:45:27 root@ansible ~]#ansible all -m shell -a "ls /boot > /data/ls.log"
10.0.0.187 | CHANGED | rc=0 >>
10.0.0.85 | CHANGED | rc=0 >>
10.0.0.86 | CHANGED | rc=0 >>
[12:00:07 root@CentOS-8-5 ~]#ls /data
ls.log
Ansible log: /var/log/ansible.log, 需要在配置文件中取消注释才能生效
chdir: 执行命令前, 先切换到某个目录, 相当于 cd /dir; CMD
[12:47:43 root@ansible ~]#ansible all -m shell -a 'chdir=/data ls'
10.0.0.187 | CHANGED | rc=0 >>
ls.log
pkgs
prac
scripts
10.0.0.86 | CHANGED | rc=0 >>
ls.log
pkgs
prac
scripts
10.0.0.85 | CHANGED | rc=0 >>
ls.log
pkgs
prac
scripts
creates: 如果指定的文件或者目录存在, 则不会执行后续命令
[12:49:22 root@ansible ~]#ansible all -a 'creates=/etc ls -l /etc/issue'
10.0.0.187 | SUCCESS | rc=0 >>
skipped, since /etc exists
10.0.0.86 | SUCCESS | rc=0 >>
skipped, since /etc exists
10.0.0.85 | SUCCESS | rc=0 >>
skipped, since /etc exists
[12:50:09 root@ansible ~]#ansible all -a 'creates=/etc/issue ls -l /etc/issue'
10.0.0.187 | SUCCESS | rc=0 >>
skipped, since /etc/issue exists
10.0.0.85 | SUCCESS | rc=0 >>
skipped, since /etc/issue exists
10.0.0.86 | SUCCESS | rc=0 >>
skipped, since /etc/issue exists
removes: 如果文件或目录存在, 则执行后续命令
[12:52:22 root@ansible ~]#ansible all -a 'removes=/etc/issue ls -l /etc/issue'
10.0.0.187 | CHANGED | rc=0 >>
-rw-r--r--. 1 root root 23 Apr 8 2020 /etc/issue
10.0.0.85 | CHANGED | rc=0 >>
-rw-r--r--. 1 root root 23 Jun 3 2020 /etc/issue
10.0.0.86 | CHANGED | rc=0 >>
-rw-r--r--. 1 root root 23 Jun 3 2020 /etc/issue
2.3 script 模块
- 在被管理节点执行脚本, 脚本只需要在管理节点存在即可
- 脚本在Ansible本机或者远程主机都无需执行权限
- 脚本在管理节点的路径必须指定, 可以是绝对路径或者相对路径
eg: 执行test.sh脚本
test.sh
#!/bin/bash
echo $HOSTNAME
[12:56:15 root@ansible ~]#ansible all -m script -a '/root/test.sh' # 直接把脚本路径写到-a后的参数即可
10.0.0.187 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 10.0.0.187 closed.\r\n",
"stderr_lines": [
"Shared connection to 10.0.0.187 closed."
],
"stdout": "centos-7-6.prac\r\n",
"stdout_lines": [
"centos-7-6.prac"
]
}
10.0.0.85 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 10.0.0.85 closed.\r\n",
"stderr_lines": [
"Shared connection to 10.0.0.85 closed."
],
"stdout": "CentOS-8-5\r\n",
"stdout_lines": [
"CentOS-8-5"
]
}
10.0.0.86 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 10.0.0.86 closed.\r\n",
"stderr_lines": [
"Shared connection to 10.0.0.86 closed."
],
"stdout": "CentOS-8-6\r\n",
"stdout_lines": [
"CentOS-8-6"
]
}
2.4 copy 模块
- 将本地文件拷贝到远程节点
- 如果没有指定mode='权限', 那么拷贝过去的文件的权限是644, 目录是755权限
- 由于ansible的幂等性, 除非文件内容做了修改, 否则无论执行了几次命令, ansible都不会再拷贝文件
src: 如果复制的是一个目录, 那么目录如果没有加/补全, 那么复制的是整个目录, 如果加了/补全, 那么复制的是目录里的内容, 而不是目录本身
# Local path to a file to copy to the remote server. This can be
absolute or relative. If path is
a directory, it is copied
recursively. In this case, if
path ends with "/", only inside
contents of that directory are
copied to destination.
Otherwise, if it does not end
with "/", the directory itself
with all contents is copied.
This behavior is similar to the
`rsync' command line tool.
dest: 远程目标路径必须是绝对路径, 并且如果源是目录那么目标也必须是目录; 此外, 如果目标主机已经有了相同的文件, 默认会覆盖, 可以加 backup=yes 来先备份目标文件
# (required) Remote absolute path where the file should be copied
to. If `src' is a directory,
this must be a directory too. If
`dest' is a non-existent path
and if either `dest' ends with
"/" or `src' is a directory,
`dest' is created. If `dest' is
a relative path, the starting
directory is determined by the
remote host. If `src' and `dest'
are files, the parent directory
of `dest' is not created and the
task fails if it does not
already exist.
eg: copy /data/scripts/test.sh to remote hosts
[15:03:06 root@ansible ~]#ansible all -m copy -a 'src=/data/scripts/test.sh dest=/data/scripts/test1.sh'
[15:03:13 root@ansible ~]#ansible all -m shell -a 'ls /data/scripts'
10.0.0.187 | CHANGED | rc=0 >>
test1.sh
10.0.0.85 | CHANGED | rc=0 >>
test1.sh
10.0.0.86 | CHANGED | rc=0 >>
test1.sh
owner: 可以指定owner参数, 但是用户必须在被管理节点事先存在, 否则文件或目录拷贝过去后owner是不会变的.
backup: 如果远程节点有相同的文件, 那么copy时可以指定'backup=yes', 这会创建一个备份文件. 当某个文件需要被经常修改时, 要加backup=yes参数, 否则新的文件copy过去后会把旧的文件覆盖了
eg:
- 先在被管理节点/opt目录下创建test.sh脚本
[15:18:42 root@ansible ~]#ansible all -m shell -a 'touch /opt/test.sh'
- 将管理节点的test.sh文件copy到被管理节点/opt下, 指定ower,mode和backup=yes
[15:20:38 root@ansible ~]#ansible all -m copy -a 'src=/root/test.sh dest=/opt mode=600 owner=daemon backup=yes'
[12:46:24 root@CentOS-8-5 ~]#ls -l /opt
total 4
-rw------- 1 daemon root 19 Jan 31 15:21 test.sh # copy过来的文件, 权限, owner都修改了
-rw-r--r-- 1 root root 0 Jan 31 15:19 test.sh.28220.2021-01-31@15:21:45~ # 原先的文件会被打上timestamp
content: 将命令行的内容, 写入到被管理节点目标文件, 目标文件如果不存在, 会自动创建
eg:
[15:25:44 root@ansible ~]#ansible all -m copy -a 'content="line1\nline2\nline3" dest=/opt/test.txt'
[15:21:25 root@centos-7-6 ~]#ll /opt
total 8
drwxr-xr-x 5 root root 45 Jan 31 15:05 data
-rw------- 1 daemon root 19 Jan 31 15:21 test.sh
-rw-r--r-- 1 root root 0 Jan 31 15:19 test.sh.29262.2021-01-31@15:21:46~
-rw-r--r-- 1 root root 17 Jan 31 15:25 test.txt
[15:25:54 root@centos-7-6 ~]#cat /opt/test.txt
line1
line2
line3
copy 目录:
[15:28:36 root@ansible ~]#ansible all -m copy -a 'src=/tmp/ dest=/tmp'
[15:29:22 root@centos-7-6 ~]#ls /tmp
file.txt
[15:28:36 root@ansible ~]#ansible all -m copy -a 'src=/tmp dest=/tmp'
[15:29:22 root@centos-7-6 ~]#ls /tmp
file.txt tmp
2.5 fetch 模块
- 从被管理节点抓取文件到ansible主机的目录, 目前不支持抓取整个目录, 只能抓文件
- fetch的源只能是文件, 目前不支持抓目录, 也就是说fetch的源是管理节点的文件, 而目的是ansible主机的一个目录, 如果是从多台主机抓文件, 那么会在ansible目标目录按照抓取主机的ip地址生成各自的文件夹防止抓取同名文件覆盖
eg: 从被管理节点抓取/etc/issue文件到/opt目录下
[15:41:57 root@ansible ~]#ansible all -m fetch -a 'src=/etc/issue dest=/opt'
源文件存放的上级目录也会被抓取和创建, 相当于抓的整个路径
[15:42:22 root@ansible ~]#tree /opt
/opt
├── 10.0.0.187
│ └── etc
│ └── issue
├── 10.0.0.85
│ └── etc
│ └── issue
└── 10.0.0.86
└── etc
└── issue
6 directories, 3 files
2.6 file 模块
- 配置被管理节点上的文件属性和目录属性
state支持: absent, directory, file, hard, link, touch
eg: state=file, 只会显示文件的状态
[15:45:57 root@ansible ~]#ansible all -m file -a 'path=/etc/issue state=file'
10.0.0.187 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/etc/issue",
"size": 23,
"state": "file",
"uid": 0
}
10.0.0.85 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/etc/issue",
"size": 23,
"state": "file",
"uid": 0
}
10.0.0.86 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/etc/issue",
"size": 23,
"state": "file",
"uid": 0
}
state=touch, - 创建文件, 但是需要所在路径存在, 否则命令执行会失败
state=absent, - 删除文件
eg: 修改被管理节点的/data/test/yum.conf文件属性
- 先将ansible节点的yum.conf文件copy到被管理节点
[15:52:15 root@ansible ~]#ansible all -m copy -a 'src=/etc/yum.conf dest=/data/test'
[15:52:38 root@ansible ~]#ansible all -m shell -a 'ls -l /data/test'
10.0.0.187 | CHANGED | rc=0 >>
total 4
-rw-r--r-- 1 root root 970 Jan 31 15:52 yum.conf
10.0.0.85 | CHANGED | rc=0 >>
total 4
-rw-r--r-- 1 root root 970 Jan 31 15:52 yum.conf
10.0.0.86 | CHANGED | rc=0 >>
total 4
-rw-r--r-- 1 root root 970 Jan 31 15:52 yum.conf
- 修改文件属性
[15:54:48 root@ansible ~]#ansible all -m file -a 'path=/data/test/yum.conf mode=600 owner=daemon'
[15:54:48 root@ansible ~]#ansible all -m shell -a 'ls -l /data/test'
10.0.0.187 | CHANGED | rc=0 >>
total 4
-rw------- 1 daemon root 970 Jan 31 15:52 yum.conf
10.0.0.86 | CHANGED | rc=0 >>
total 4
-rw------- 1 daemon root 970 Jan 31 15:52 yum.conf
10.0.0.85 | CHANGED | rc=0 >>
total 4
-rw------- 1 daemon root 970 Jan 31 15:52 yum.conf
如果不涉及从ansible复制文件到目标主机, 只是修改目标主机的文件或者目录, 那么只需要path即可, 后面加state=MODE
案例:
#创建空文件
ansible all -m file -a 'path=/data/test.txt state=touch' #state=touch不会递归创建目录, 因此要求路径必须已经存在
ansible all -m file -a 'path=/data/test.txt state=absent' #absent,如果文件存在则删除, present,如果文件不存在则创建, 如果所在目录不存在, 则递归创建
ansible all -m file -a 'path=/root/test.sh owner=wang mode=755'
#创建目录
ansible all -m file -a 'path=/data/mysql state=directory owner=mysql' group=mysql'
#创建软连接
ansible all -m file -a 'src=/data/testfile path|dest|name=/data/testfile-link state=link' # src是被管理节点本地的文件, 因为file就是管理远程节点的文件或目录
#创建目录
ansible all -m file -a 'path=/data/testdir state=directory'
2.7 unarchive 模块
- 解包解压文件
实现有两种用法:
- 1 将ansible主机上的压缩包传到远程主机后解压缩至指定目录, 设置copy=yes
- 2 将远程主机上的某个压缩包解压缩到指定的路径下, 设置copy=no
常见参数:
copy: 默认为yes, 当copy=yes, 拷贝的文件是从ansible主机复制到远程主机上, 如果设置为copy=no, 那么会在远程主机上寻找src源文件
remote_src: 和copy功能一样且互斥, yes表示在远程主机, 不在ansible主机, no表示文件在ansible主机上
src: 源文件, 可以是ansible主机上的路径, 也可以是远程主机上的路径, 如果是远程主机上的路径则需要设置copy=no
dest: 远程主机上的目标路径
mode: 设置解压缩后的文件权限
ansible all -m unarchive -a 'src=/data/foo.tgz dest=/var/lib/foo owner=daemon group=bin'
ansible all -m unarchive -a 'src=/tmp/foo.zip dest=/data copy=no mode=0777'
ansible all -m unarchive -a 'src=https://www.baidu.com/image.jpg dest=/data copy=no'
2.8 archive 模块
-
将远程主机上的文件打包压缩到指定的路径
-
可以配合fetch模块, 先将远程主机上的文件打包, 然后抓取到ansible管理节点
eg:
#archive
[16:04:17 root@ansible ~]#ansible all -m archive -a 'path=/var/log dest=/tmp/log.tar.bz2 format=bz2 mode=600' # archive可以指定权限
#fetch
[16:04:51 root@ansible ~]#ansible all -m fetch -a 'src=/tmp/log.tar.bz2 dest=/data/prac'
[16:05:53 root@ansible ~]#ll /data/prac
total 0
drwxr-xr-x 3 root root 17 Jan 31 16:05 10.0.0.187
drwxr-xr-x 3 root root 17 Jan 31 16:05 10.0.0.85
drwxr-xr-x 3 root root 17 Jan 31 16:05 10.0.0.86
[16:05:55 root@ansible ~]#tree /data/prac
/data/prac
├── 10.0.0.187
│ └── tmp
│ └── log.tar.bz2
├── 10.0.0.85
│ └── tmp
│ └── log.tar.bz2
├── 10.0.0.86
│ └── tmp
│ └── log.tar.bz2
2.9 hostname 模块
- 无法批量修改主机名, 每次只能修改一个
- 支持多版本, 会自动识别, 并且立即永久生效, 会修改hostname文件
eg:
[16:28:56 root@ansible ~]#ansible 10.0.0.100 -m hostname -a 'name=node1.com'
2.10 cron 模块
功能: 定义远程管理主机上执行计划任务
支持时间: minute, hour, day, month, weekday
如果计划任务是执行脚本, 那么要求远程主机上有该脚本, 或者先在ansible上编写脚本, 在通过copy拷贝到远程主机
案例:
#创建任务
ansible 10.0.0.238 -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh'
#hour=2 表示2点
#minute=30 表示2点半
#weekday=1-5 表示周一到周五
#name 给计划任务起名
#job 实际执行的脚本
执行命令后, 会在管理节点的/etc/crontab里面创建计划任务
禁用计划任务
ansible websrvs -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh disabled=yes'
启用计划任务
ansible websrvs -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh disabled=no'
删除计划任务
ansible websrvs -m cron -a 'name="backup mysql" state=absent'
ansible websrvs -m crom -a 'state=absent name=backup mysql'
2.11 yum和apt 模块
eg: websrvs组安装httpd
[14:39:31 root@ansible ~]#ansible websrvs -m yum -a 'name=httpd state=present' # present是安装,默认就是present安装, absent是卸载
eg: websrvs组卸载httpd
[14:39:31 root@ansible ~]#ansible websrvs -m yum -a 'name=httpd state=absent'
2.12 service 模块
- 管理远程主机上的service 服务
管理目标主机上的服务, 设置为开机启动, 停止, 重启等
ansible all -m service -a 'name=httpd state=started enabled=yes'
ansible all -m service -a 'name=httpd state=stopped'
ansible all -m service -a 'name=httpd state=reloaded'
ansible all -m shell -a "sed -i 's/^Listen 80/Listen 8080/ /etc/httpd/conf/httpd.conf'"
2.13 user 模块
管理用户: 批量创建, 删除同一个用户
#创建用户
ansible all -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1 group=root'
ansible all -m user -a 'name=nginx comment=nginx uid=88 group=nginx groups="root, daemon" shell=/sbin/nologin system=yes create_home=no home=/data/nginx non_unique=yes'
2.14 group 模块
管理组
#创建组
ansible websrvs -m group -a 'name=nginx gid=88 system=yes'
#删除组
ansible websrvs -m group -a 'name=nginx state=absent'
2.15 lineinfile 模块
ansible在使用sed时经常会遇到需要转义的问题, 而且ansible在遇到特殊符号进行替换时存在问题, 无法正常进行替换, 其实在ansible自身还提供了两个模块, lineinfile模块和replace模块
一般在ansible中当去修改某个文件的单行进行替换的时候需要使用lineinfile
regexp参数: 使用正则表达式匹配对应的行, 当替换文本时, 如果有多行文本都能被匹配, 则只有最后面被匹配到的那行才会被替换, 当删除文本时, 如果有多行文本都能被匹配, 这些行都会被删除, 如果想多行匹配替换, 建议replace
ansible websrvs -m lineinfile -a "path=/etc/httpd/conf/httpd.conf regexp='^Listen' line='Listen 80' "
2.16 replace 模块
类似于sed命令, 基于正则匹配和替换, 会对匹配到的所有行进行操作
ansible all -m replace -a "path=/etc/fstab regexp='^(UUID.*)' replace='#\1' "
2.17 setup 模块
该模块用来收集主机的系统信息, 这些facts信息可以直接以变量的形式使用, 但是如果主机较多, 会影响执行速度, 可以使用gather_facts:no
来禁止Ansible收集facts信息
范例:
ansible all -m setup #获取所有setup信息, 可以当做变量使用
ansible all -m setup -a 'filter=ansible_hostname' #获取指定的setup信息