ansible基本了解和常用模块
ansible用前了解:
Ansible命令执行来源
USER,普通用户;
CMDB(配置管理数据库)API调用;
PUBLIC/PRIVATE CLOUD API调用;
USER->Ansible Playbook-> Ansible;
利用ansible实现管理的方式:
一:Ad-Hoc即ansible命令,主要用于临时命令使用场景;
二:Ansible-playbook主要用于长期规划好的,大型项目的场景,需要有前提的规划;
Ansible主要组成部分
`Ansible-playbook(剧本)执行过程:`
将已有编排好的任务集写入Ansible-Playbook
通过ansible-playbook命令分拆任务集至逐条ansible命令,按预定规则逐条执行
`Ansible主要操作对象:`
Hosts主机
NetWorking网络设备
注意事项:
- 执行ansible的主机一般称为主控端,master或者堡垒机;
- 主控端Python版本需要2.6以上;
- 被控端Python版本小于2.4需要安装pyton-simplejson;
- 被控端如开启SELinux需要安装libselinux-python;
- windows不能做为主控端;
ansible的相关文件
配置文件:
/etc/ansible/ansible.cfg:主配置文件,配置ansibleg工作特性。
/etc/ansible/hosts:主机清单。
/etc/ansible/roles/:存放角色的目录。
ansibel主配置文件:
程序:
/usr/bin/ansible:主程序,临时命令执行工具。
/usr/bin/ansible-doc:查看配置 文档,模块功能查看工具。
/usr/bin/ansible-galaxy:下载/上传优秀代码或roles模块的官网平台。
/usr/bin/ansible-playbook:定制自动化任务,编排剧本工具;
/usr/bin/ansible-pull:远程执行命令的工具。
/usr/bin/ansible-vault:文件加密工具。
/usr/bin/ansible-console:基于Console界面与用户交互的执行工具。
主机清单inventory:
ansible的主要功能在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名。
默认的inventory file为/etc/ansible/hosts
inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成。
主机清单是实现配置ansible的最首要任务,如果没有主机清单,它不能管理任何主机被控端的主机必须要放到主机清单中,才能受到管理。
/etc/ansible/hosts文件格式:
inventory文件遵循INI文件风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中;此外,SSH默认端口是22,若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口来标明,同时若主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机:
[webserver]
www.baidu.com
www.lookwa.com:22
db[1:3].apple.com
[web]
192.168.1.1
192.168.1.1[1:5] //表示1.11到1.15的主机IP。
192.168.20.1:20022
db-[a-f].example.com
ansib le的实现是基于ssh服务(访问方式:密码验证/秘钥免密登陆),不需要专业代理软件,但是也就有了弊端,因为ssh不是专门用来为ansible服务的协议,因此也就只能管理百台机器,数量多执行效率就会下降。上千台的机器就需要专门的自动化管理软件,目前国内比较流行的是Saltstack,有专门的agent代理服务,也是基于python实现的。
幂等性:ansible任务执行1遍和执行n遍效果是一样的。其中已经正常执行完命令的主机不会再次执行该命令,不因重复带来意外情况。
ansible统一管理前提:
方式一:.基于SSH服务的key验证实现主机的配置管理,应用部署,任务执行等功能。
###主控端
#ssh-keygen(回车确认,最好是对key加一下密码) //设置key
#ssh-copy-id 远程主机IP //将key传送到被控端
方式二:在host主机清单中,在主机IP的后面添加远程用户名称及其密码,若为登录用户后sudo切换root或其他用户,则需添加远程sudo切换为相应用户时的用户名称和密码。
#[root@localhost ansible]# cat hosts-1
#192.168.10.132 ansible_ssh_user="root" ansible_ssh_pass="roottoor"
192.168.10.132 ansible_ssh_user="app" ansible_ssh_pass="app" ansible_become_user="root" ansible_become_pass="roottoor"
`Inventory清单参数列表: ansible 与远程主机的交互的一些参数,可在hosts文件中使用:`
1.主机连接:
ansible_connection:连接主机的类型,这里可以是ansible连接插件的名称中的一个,如ssh 协议中的 smart,ssh或者paramiko。默认值是smart。
2.ssh 连接
ansible_ssh_host:使用主机的名称去连接,可以使用别名
ansible_ssh_port:如果默认不是22的话,要定义ssh的端口号
ansible_ssh_user:默认ssh连接用户
ansible_ssh_pass:默认ssh 连接的passwd(不要在这里出现明文密码,而是要使用vault)
ansible_ssh_private_key_file:连接时使用私钥文件。如果不想使用ssh代理的话,可以有多个密钥
ansible_ssh_common_args:该设置将总是为sftp,scp,ssh附加到命令行,可用于为某个主机或组配置ProxyCommand
ansible_sftp_extra_args:该设置将sftp附加到命令行
ansible_scp_extra_args:该设置将scp附加到命令行
ansible_ssh_extra_args:该设置将ssh附件到命令行
ansible_ssh_pipelining:决定是否使用ssh 管道,它将覆盖ansible.cfg中的pipelining设置
2.2版本后的特性.
ansible_ssh_executable:这个设置将覆盖使用系统ssh的默认行为。它将覆盖ansible.cfg中的ssh_executable设置
使用特权命令(如sudo)
ansible_become:允许升级权限,相当于 ansible_sudo 或者 ansible_su
ansible_become_method:允许设置特殊权限的方法
ansible_become_user:允许设置特殊权限的用户,相当于 ansible_sudo_user 或者 ansible_su_user
ansible_become_pass:允许设置特殊权限的密码(不要在这里直接输入明文),相当于 ansible_sudo_pass 或者 ansible_su_pass
远程主机环境参数
ansible_shell_type:目标系统的shell 类型,你不应该设置这个参数,除非你设置的 ansible_shell_executable 与默认的sh 不兼容。默认情况下,命令是在sh shell 环境风格下运行的。此处可以设置为csh或fish shell。
ansible_python_interpreter:目标系统的python 程序路径。这对于有多个python 版本运行环境的系统很有帮助,或者是默认python 程序不在/usr/bin/python 下,如 *BSD。
ansible_*_interpreter:适用于任何工作,*处可以替换成其它语言,如ruby或者perl,就像ansible_python_interpreter.这将替换在该主机上运行模块时的shebang。
如下所示的示例文件:
非SSH 的连接类型
如上面所说,ansible 执行剧本时通过ssh连接,但是它又不仅仅只局限于ssh这种连接类型。连接的类型是可以变的。如下面的几种
local:该连接类型将在控制机本身上执行剧本。
docker:该连接类型将使用本地docker直接将 剧本部署到 docker 容器中。以下是有连接器处理的参数:
ansible_host :要连接的docker 容器名称
ansible_user :在容器中操作的用户名,必须是容器内存在的用户
ansible_become :如果设置为 true,这个用户将被用于在容器内进行操作
ansible_docker_extra_args :可以是Docker 程序 启动时支持的额外参数,不是特定的命令,此参数主要用于配置远程Docker 守护进程使用。
ansibl系列命令:
#ansible
#ansible-doc
#ansible-playbook
#ansible-vault
#ansible-console
#asible-galaxy
#ansible-pul …等
命令讲解:
ansible-doc命令
#ansible-doc :显示模块帮助
ansible-doc -l 列出所有模块
ansible-doc ping 查看指定模块帮助用法
ansible-doc -s ping 查看指定模块的playbook片段
ansible命令:
#ansible IP/组/all -m 模块 -a '模块中的参数(相应命令)'
--version
--list-hosts 显示主机列表,可简写-list
-k/--ask-pass:提示输入ssh连接密码
-K:提示输入sudo时的口令
-u:以什么用户登录
-b:-u参数指定的用户登录后切换为sudo用户,ansible配置文件默认为root用户。视情况,可能需要到远程主机上visudo确认。
-C 或 --check:使用ansible时只是单纯测试脚本或命令,但不真正执行的参数。
--syntax-check:使用ansible测试脚本或命令语法是否正确的参数。
图例:
实例:
1.将192.168.30.101主机加入hosts主机清单,-k通过密码验证,默认与主控端用户一致,为root。注:-k密码验证只能访问一台或者是对应用户的密码全部一致才能通过。如果密码不一致,命令也会执行,只不过密码正确的显示success正确输出,错误的报FAILED。对于控制多台主机,则极为不便,因此建议基于key验证。
know_hosts文件一般在家目录.ssh/know_hosts,这里记录着ssh通过ssh协议连接的主机密码。通过ssh命令初次连接主机后,会将其加入到该文件中,信任该主机。
ansible的各模块详解:
不明白的模块,可以使用一下命令来查看模块具体解释:
[root@localhost ~]#ansible-doc -s 模块
使用各模块的前提:最好配置好基于SSH的key验证/在hosts文件中添加相应参数,否则会因为密码问题导致失败。
注意:以下练习都是基于SSH的key验证的基础上进行的实验,被控端执行命令的用户时root;
基于SSH的KEY验证
[root@localhost ansible]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:MgzOGSvdtTaEGRWn7LlTYGa0RzM/5lx3vElvK6i9KEs root@localhost.localdomain
The key's randomart image is:
+---[RSA 2048]----+
| ..+.= |
| * = + . |
| o o @ . + ..+|
| + B B = + o..=|
| . * = S . o oo|
| . + + . ..|
| Eo . . . |
| .. .+ . |
| .oo o. |
+----[SHA256]-----+
[root@localhost ansible]# ssh-copy-id 192.168.10.134
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.10.134 (192.168.10.134)' can't be established.
ECDSA key fingerprint is SHA256:nu/ygM1+oeg9lJ8hO6hqSLmxCiXj+f+VMgdATMA/KNM.
ECDSA key fingerprint is MD5:dd:30:2e:b1:92:6b:d4:1f:fa:4c:ac:66:b8:2d:e6:3e.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.10.134's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '192.168.10.134'"
and check to make sure that only the key(s) you wanted were added.
[root@localhost ansible]# ssh root@192.168.10.134
Last login: Wed May 27 10:24:54 2020 from 192.168.10.135
[root@localhost ~]# ifconfig
1:主机连通性测试:
我们使用"#ansible web -m ping"命令来进行主机连通性测试,效果如下:
[root@localhost ansible]# ansible 192.168.10.134 -m ping
192.168.10.134 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
2:Command模块:
在远程主机执行命令,默认模块,可忽略-m选项。
“command”模块采用命令名,后跟空格列表-带分隔符的参数。给定的命令将对所有选定的节点。它不会通过shell进行处理,因此类似于“$HOME”的变量。而像如"<",">","|",";","&" 之类的操作将不起作用(使用如果您需要这些功能,[shell]模块)。对于Windows目标,请使用[win_command]模块。
**该模块常用的命令**:
chdir:在命令运行之前,先切换到此目录
creates:文件名或全局模式。如果这个文件名存在,则此步骤不会运行
removes:文件名或全局模式。如果这个文件名存在,则此步骤运行。
argv:运行用户以列表和字符串的形式提供命令。只有可以提供字符串或列表表单,但不能同时提 供两者。
stdin:将命令的stdin直接设定为指定值
warn:如果ansible.cfg中的命令_warning处于打开状态,则不要对此特定项发出警告。
executable:切换shell来执行命令,需要使用命令的决定路径。
free_form:要执行的Linux指令,一般使用ansible的-a参数代替。
练习:
//先切换到/data/ 目录,再执行pwd命令
[root@localhost ansible]# ansible slave -m command -a 'chdir=/data/ pwd'
192.168.10.134 | CHANGED | rc=0 >>
/data
//先切换到/data/ 目录,再执行“ls”命令
[root@localhost ansible]# ansible slave -m command -a 'chdir=/data/ ls'
192.168.10.134 | CHANGED | rc=0 >>
a.txt
dest
slaved
//如果/data/a.txt存在,则不执行“cat /data/a.txt”命令
[root@localhost ansible]# ansible slave -m command -a 'creates=/data/a.txt cat /data/a.txt'
192.168.10.134 | SUCCESS | rc=0 >>
skipped, since /data/a.txt exists
/果/data/a.txt存在,则不执行“cat /data/a.txt”命令
[root@localhost ansible]# ansible slave -m command -a 'removes=/data/a.txt cat /data/a.txt' /
192.168.10.134 | CHANGED | rc=0 >>
this is slave
注意:若cat后的文件名不是绝对路径,则默认为被控端的/root/目录下的相应文件;
[root@localhost ansible]# ansible slave -m command -a 'mkdir /data/M_s'
[WARNING]: Consider using the file module with state=directory rather than running 'mkdir'.
If you need to use command because file is insufficient you can add 'warn: false' to this
command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.
192.168.10.134 | CHANGED | rc=0 >>
[root@localhost ansible]# ansible slave -m command -a 'ls /data/'
192.168.10.134 | CHANGED | rc=0 >>
a.txt
dest
M_s
slaved
[root@localhost ansible]# ansible slave -m command -a 'mkdir /data/M_s;ls /data/' //删除被控端的M_s目录后,测试";"。
[WARNING]: Consider using the file module with state=directory rather than running 'mkdir'.
If you need to use command because file is insufficient you can add 'warn: false' to this
command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.
`192.168.10.134 | FAILED | rc=1 >>
mkdir: cannot create directory ‘/data/’: File existsnon-zero return code`
[root@localhost ansible]# ansible slave -m command -a 'echo "example" >/data/a.txt;cat /data/a.txt' //失败,command模块中,echo的后续内容全部被输出
192.168.10.134 | CHANGED | rc=0 >>
example >/data/a.txt;cat /data/a.txt
[root@localhost ansible]# ansible slave -m command -a 'echo "example" | passwd --stdin app' //修改密码,虽然显示CHANGED,但这结果其实是echo " magedu | passwd --stdin app"
192.168.10.134 | CHANGED | rc=0 >>
example | passwd --stdin app
[root@localhost ansible]# ansible slave -m command -a 'echo example|passwd'
192.168.10.134 | CHANGED | rc=0 >>
example|passwd
注意:修改用户密码,需要用shell模块,该模块功能比command更全。
3:shell模块:
和command相似,用shell执行命令;"shell"模块采用命令名,后跟空格列表-带分隔符的参数。它几乎与[command]模块完全相同,但运行通过远程节点上的shell(/bin/sh
)执行命令。对于windows目标,使用[win_shell]模块代替。
shell模块可以在远程主机上调用shell解释器运行命令,支持shell的各种功能,例如管道等。
只要是shell命令,都可以通过这个模块在远程主机上运行,这里就不一一举例了。
//修改app用户密码
[root@localhost ansible]# ansible slave -m shell -a 'echo "example" | passwd --stdin app'
192.168.10.134 | CHANGED | rc=0 >>
Changing password for user app.
passwd: all authentication tokens updated successfully.
// ">>"和";"应用
[root@localhost ansible]# ansible slave -m shell -a 'echo "example shell" >>/data/a.txt;cat /data/a.txt'
192.168.10.134 | CHANGED | rc=0 >>
this is slave
this is slave
example shell
//创建/data/M_S目录,并查看/data/目录
[root@localhost ansible]# ansible slave -m shell -a 'mkdir /data/M_S ; ls /data/'
[WARNING]: Consider using the file module with state=directory rather than running 'mkdir'. If you need to use command
because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.
192.168.10.134 | CHANGED | rc=0 >>
a.txt
dest
M_S
4:script模块:
'script’模块采用脚本名称,后跟空格列表-带分隔符的参数。路径处的本地脚本将传送到远程节点,然后在远程节点上执行。
给定的脚本将通过远程节点上的shell环境在被控端执行脚本的内容。
本模块不需要远程系统上的python,很像[raw]模块。这个模块也使支持windows目标。
[root@localhost data]# ansible slave -m script -a '/data/a.sh'
The authenticity of host '192.168.10.137 (192.168.10.137)' can't be established.
ECDSA key fingerprint is SHA256:nu/ygM1+oeg9lJ8hO6hqSLmxCiXj+f+VMgdATMA/KNM.
ECDSA key fingerprint is MD5:dd:30:2e:b1:92:6b:d4:1f:fa:4c:ac:66:b8:2d:e6:3e.
Are you sure you want to continue connecting (yes/no)? yes
192.168.10.137 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.10.137 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.10.137 closed."
],
"stdout": "",
"stdout_lines": []
}
5:copy模块:
‘复制’模块将文件从本地复制到远程计算机上的位置,同时支持给定内容生成文件和修改权限等。
src :被复制到远程主机的本地文件。可以是绝对路径,也可以是相对路径。如果路径是一个目录,则会递归复制,用法类似于"rsync"
content :用于替换"src",可以直接指定文件的值
dest :必选项,将源文件复制到的远程主机的绝对路径
owner :文件复制过去后的所有者
group:文件复制过去后的所属组
mode:文件的权限设定,执行a+x这种方式
backup=yes:表示先备份,防止误删除原始文件。当文件内容发生改变后,在覆盖之前把源文件备份,备份文件包含时间信息。
directory_mode:递归设定目录的权限,默认为系统默认权限
force:当目标主机包含该文件,但内容不同时,设为"yes",表示强制覆盖;设为"no",表示目标主机的目标位置不存在该文件才复制。默认为"yes"
others :所有的 file 模块中的选项可以在这里使用
练习:
//将文件从本地复制到远程主机并指定权限和用户
[root@localhost_master data]# ansible slave -m copy -a 'src=/data/a.sh dest=/data/ owner=app group=app mode=0755'
192.168.10.137 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "7ed5f3482012f825a11161dbd833d90fda02249b",
"dest": "/data/a.sh",
"gid": 1001,
"group": "app",
"md5sum": "00d7249c8ef7b559ce01cff104573e4e",
"mode": "0755",
"owner": "app",
"size": 32,
"src": "/root/.ansible/tmp/ansible-tmp-1590562505.04-80498096495448/source",
"state": "file",
"uid": 1001
}
[root@localhost_slave data]# ll
total 8
-rwxr-xr-x 1 app app 32 May 27 14:55 a.sh
//用content代替src,给定生成内容的文件,并指定权限。
[root@localhost data]# ansible slave -m copy -a 'content="I am master file\n" dest=/data/a.txt owner=app mode=0755'
192.168.10.137 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "59b127cef1d09aefd013fd57e0a606a297e020ea",
"dest": "/data/a.txt",
"gid": 0,
"group": "root",
"md5sum": "dc03fa3cefa908bcff46b8ee32e6f0b0",
"mode": "0755",
"owner": "app",
"size": 16,
"src": "/root/.ansible/tmp/ansible-tmp-1590562780.52-47887868778870/source",
"state": "file",
"uid": 1001
}
[root@localhost data]# ansible slave -m shell -a 'ls -l /data/a.txt;cat /data/a.txt' //查看
192.168.10.137 | CHANGED | rc=0 >>
-rwxr-xr-x 1 app root 16 May 27 14:59 /data/a.txt
I am master file
//修改原文件内容,并备份
[root@localhost data]# ansible slave -m copy -a 'content="I am master filessssssssss\n" dest=/data/a.txt backup=yes owner=app mode=0755'
192.168.10.137 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"backup_file": "/data/a.txt.5296.2020-05-27@15:04:12~",
"changed": true,
"checksum": "05f20d03a1e552e1b5f74c23195d8fb808fe977d",
"dest": "/data/a.txt",
"gid": 0,
"group": "root",
"md5sum": "8d1f612d84a45feba7fa326a15637cfd",
"mode": "0755",
"owner": "app",
"size": 27,
"src": "/root/.ansible/tmp/ansible-tmp-1590563039.5-195554648605789/source",
"state": "file",
"uid": 1001
}
[root@localhost data]# ansible slave -m shell -a 'ls -l /data/;cat /data/a.txt' //查看
192.168.10.137 | CHANGED | rc=0 >>
total 8
-rwxr-xr-x 1 app root 27 May 27 15:04 a.txt
-rwxr-xr-x 1 app root 16 May 27 14:59 a.txt.5296.2020-05-27@15:04:12~
I am master filessssssssss
6:fetch模块:
该模块用于从远程某主机获取(复制)文件到本地。
有两个选项:
dest:用来存放文件的目录
src:在远程拉取的文件,并且必须是一个file,不能是目录
练习:
[root@localhost data]# ansible slave -m fetch -a 'src=/data/a.txt dest=/data' //将远程主机的a.txt文件复制到本地的/data目录下
192.168.10.137 | CHANGED => {
"changed": true,
"checksum": "05f20d03a1e552e1b5f74c23195d8fb808fe977d",
"dest": "/data/192.168.10.137/data/a.txt",
"md5sum": "8d1f612d84a45feba7fa326a15637cfd",
"remote_checksum": "05f20d03a1e552e1b5f74c23195d8fb808fe977d",
"remote_md5sum": null
}
[root@localhost data]# ls /data/192.168.10.137/data/a.txt
//由此可以,从远程复制到本地时,会先创建一个父目录(名称为远程主机IP)。
7:file模块:
用于远程主机上的文件操作,设置文件的属性,比如创建文件、创建链接文件、删除文件等。
path :必选项,定义文件的路径及文件名称
state :状态,有以下6个选项:
directory:如果目录不存在,就创建目录
file:即使文件不存在,也不会被创建
link:创建软链接
hard:创建硬链接
touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent:删除目录、文件或者取消链接文件
force :需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创
建新的软链,有两个选项:yes|no
group :定义文件/目录的属组。后面可以加上mode:定义文件/目录的权限
owner :定义文件/目录的属主。后面必须跟上path:定义文件/目录的路径。
mode :指定文件权限,比如数字644;
recurse :递归设置文件的属性,只对目录有效(暂时不明白如何使用)。
src:被链接的源文件路径,只应用于state=link的情况
dest :被链接到的路径,只应用于state=link的情况
练习:
[root@localhost data]# ansible slave -m file -a 'path=/data/M_s/file state=directory owner=app group=app '
//在远程创建file目录,设置属性
192.168.10.137 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 1001,
"group": "app",
"mode": "0755",
"owner": "app",
"path": "/data/M_s/file",
"size": 6,
"state": "directory",
"uid": 1001
}
//在远程创建文件("目录和文件好像不能递归创建")
[root@localhost data]# ansible slave -m file -a 'path=/data/file2 state=touch owner=app group=app '
192.168.10.137 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/data/file2",
"gid": 1001,
"group": "app",
"mode": "0644",
"owner": "app",
"size": 0,
"state": "file",
"uid": 1001
}
//创建链接文件
[root@server ~]# ansible slave -m file -a 'path=/data/bbb.jpg src=aaa.jpg state=link'
192.168.10.137 | SUCCESS => {
"changed": true,
"dest": "/data/bbb.jpg",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 7,
"src": "aaa.jpg",
"state": "link",
"uid": 0
}
[root@server ~]# ansible web -m shell -a 'ls -l /data'
192.168.37.122 | SUCCESS | rc=0 >>
total 28
-rw-r--r-- 1 root root 5649 Dec 5 13:49 aaa.jpg
lrwxrwxrwx 1 root root 7 Dec 6 10:25 bbb.jpg -> aaa.jpg
//创建软链接文件
[root@localhost data]# ansible all -m file -a 'src=/etc/fstab dest=/data/fstab.link state=link'
192.168.10.137 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/data/fstab.link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 10,
"src": "/etc/fstab",
"state": "link",
"uid": 0
}
[root@localhost data]# ansible all -m shell -a 'ls -l /data'
192.168.10.137 | CHANGED | rc=0 >>
total 0
-rw-r--r-- 1 app app 0 May 27 16:10 file2
lrwxrwxrwx 1 root root 10 May 27 16:13 fstab.link -> /etc/fstab
[root@server ~]# ansible slave -m file -a 'path=/data/a state=absent'
//删除文件
192.168.10.137 | SUCCESS => {
"changed": true,
"path": "/data/a",
"state": "absent"
}
8:cron模块
该模块适用于管理cron计划任务的。
其使用的语法跟我们的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= #定时任务描述
special_time # 定时任务的别称,用于定义何时运行job条目。有效值有参数:参数:reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时)。
state #指定状态,present表示添加定时任务,也是默认设置,absent表示删除定时任务
user # 以哪个用户的身份执行
backup # (yes/no)如果设置了,则会在修改远程cron_file前备份这些文件。
disabled # 禁用crontab中的某个job,要求state=present
练习:
//添加计划任务
[root@server ~]# ansible web -m cron -a 'name="ntp update every 5 min" minute=*/5 job="/sbin/ntpdate 172.17.0.1 &> /dev/null"'
192.168.37.122 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"ntp update every 5 min"
]
}
[root@server ~]# ansible web -m shell -a 'crontab -l'
192.168.37.122 | SUCCESS | rc=0 >>
#Ansible: ntp update every 5 min
*/5 * * * * /sbin/ntpdate 172.17.0.1 &> /dev/null
//删除计划任务
[root@server ~]# ansible web -m shell -a 'crontab -l' //查看已有计划任务
192.168.37.122 | SUCCESS | rc=0 >>
#Ansible: ntp update every 5 min
*/5 * * * * /sbin/ntpdate 172.17.0.1 &> /dev/null
#Ansible: df everyday
* 15 * * * df -lh >> /tmp/disk_total &> /dev/null
[root@server ~]# ansible web -m cron -a 'name="df everyday" hour=15 job="df -lh >> /tmp/disk_total &> /dev/null" state=absent' //删除指定计划任务
192.168.37.122 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"ntp update every 5 min"
]
}
[root@server ~]# ansible web -m shell -a 'crontab -l' //查看现在的计划任务
192.168.37.122 | SUCCESS | rc=0 >>
#Ansible: ntp update every 5 min
*/5 * * * * /sbin/ntpdate 172.17.0.1 &> /dev/null
9.yum模块
该模块主要用于软件的yum安装。
其选项如下:
name= #所安装的包的名称
state=
#present--->安装;
#latest--->安装最新的;#
#absent---> 卸载软件。
update_cache #强制更新yum的缓存
conf_file #指定远程yum安装时所依赖的配置文件(安装本地已有的包)。
disable_pgp_check #是否禁止GPG checking,只用于presentor latest。
disablerepo #临时禁止使用yum库。 只用于安装或更新时。
enablerepo #临时使用的yum库。只用于安装或更新时。
练习:
[root@server ~]# ansible web -m yum -a 'name=htop state=present'
192.168.37.122 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package htop.x86_64 0:2.0.2-1.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n htop x86_64 2.0.2-1.el7 epel 98 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 98 k\nInstalled size: 207 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : htop-2.0.2-1.el7.x86_64 1/1 \n Verifying : htop-2.0.2-1.el7.x86_64 1/1 \n\nInstalled:\n htop.x86_64 0:2.0.2-1.el7 \n\nComplete!\n"
]
}
10.service模块
该模块用于服务程序的管理。
其主要选项如下:
arguments #命令行提供额外的参数
enabled #设置开机启动。
name= #服务名称
runlevel #开机启动的级别,一般不用指定。
sleep 在重启服务的过程中,是否等待。如在服务关闭以后等待2秒再启动。(定义在剧本中。)
state #有四种状态,分别为:
#started--->启动服务;
#stopped--->停止服务;
#restarted--->重启服务;
#reloaded--->重载配置;
练习:
[root@server ~]# ansible web -m service -a 'name=nginx state=started enabled=true' //开启服务
192.168.37.122 | SUCCESS => {
"changed": true,
"enabled": true,
"name": "nginx",
"state": "started",
……
}
[root@server ~]# ansible web -m shell -a 'ss -ntl'
192.168.37.122 | SUCCESS | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:80 *:*
//关闭服务
[root@server ~]# ansible web -m service -a 'name=nginx state=stopped'
192.168.37.122 | SUCCESS => {
"changed": true,
"name": "nginx",
"state": "stopped",
……
}
[root@server ~]# ansible web -m shell -a 'ss -ntl | grep 80'
192.168.37.122 | FAILED | rc=1 >>
已经没有80端口了,说明nginx服务已经关闭了。
11:user模块
该模块主要是用来管理用户账号。
其主要选项如下:
name :指定用户名。
password :输入的密码信息,一般用于修改/新建用户时使用。该密码为明文,需要该为加密密码;需要用到python
python交互界面:
import crypt;
crypt.crypt('666666')
获取666666的加密密码
uid :指定用户uid信息;
group :指定用户主要属于哪个组;
groups :指定用户属于哪个附加组信息;
append :=yes/no-->如果用户原本就存在多个附加组,那么当使用 groups 参数设置附加组时,当前设置会覆盖原来的附加组设置,如果不想覆盖
原来的附加组设置,需要结合 append 参数,将 append 设置为 yes,表示追加附加组到现有的附加组设置,append 默认值为 no。
shell :=/bin/bash或/sbin/nologin--》指定是否能够登陆。
create_home:=yes/no,是否创建用户家目录;
home :指定家目录创建在什么路径,默认为/home。
remove :=yes/no,当 state 的值设置为 absent 时,表示要删除远程主机中的用户。但是在删除用户时,不会删除用户的家目录等信息,这是因为
remove 参数的默认值为 no,如果设置为yes,在删除用户的同时,会删除用户的家目录。当 state=absent 并且 remove=yes 时,相当
于执行 “userdel --remove” 命令。
state: =present/absent--->present为创建;ansent为删除。此参数用于指定用户是否存在于远程主机中;present,表示用户需要存在,当设置为
absent 时表示删除用户。
update_passwd :=always/on_create--》
@ always 时表示:如果 password 参数设置的值与用户当前的加密过的密码字符串不一致,则直接更新用户的密码,默认值即为 always;
@ on_create 时:如果 password参数设置的值与用户当前的加密过的密码字符串不一致,则不会更新用户的密码字符串,保持之前的密码设定。如果是
新创建的用户,即使此参数设置为 on_create,也会将用户的密码设置为 password 参数对应的值。
expores :"date -d 2018-12-31 +%s用此命令获取指定时间的时间戳"
此参数用于指定用户的过期时间,相当于设置 /etc/shadow 文件中的的第8列,比如,你想要设置用户的过期日期为2018年12月31日,那么你首
先要获取到2018年12月31日的 unix 时间戳,使用命令 “date -d 2018-12-31 +%s” 获取到的时间戳为1546185600,
所以,当设置expires=1546185600 时,表示用户的过期时间为2018年12月31日0点0分,设置成功后,查看远程主机的 /etc/shadow 文件,
对应用户的第8八列的值将变成17895(表示1970年1月1日到2018年12月31日的天数,unix时间戳的值会自动转换为天数,我们不用手动的进行换算),
目前此参数只支持在 Linux 和 FreeBSD 系统中使用。
注意:
指定password参数时,不能使用明文密码,因为后面这一串密码会被直接传送到被管理主机的/etc/shadow文件中,所以需要
先将密码字符串进行加密处理。然后将得到的字符串放到password中即可。
# ansible centos -m shell -a 'echo "slave1" |passwd --stdin slave'
//与user模块的password直接指定密码不同,[echo "slave1" |passwd --stdin slave]该命令得到的密码在被控端的shadow文件中显示是加密密码(在centos6和centos7上以测试过);
练习:
[root@server ~]# ansible web -m user -a 'name=keer uid=11111'
//添加用户
192.168.37.122 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 11111,
"home": "/home/keer",
"name": "keer",
"shell": "/bin/bash",
"state": "present",
"stderr": "useradd: warning: the home directory already exists.\nNot copying any file from skel directory into it.\nCreating mailbox file: File exists\n",
"system": false,
"uid": 11111
}
[root@server ~]# ansible web -m shell -a 'cat /etc/passwd |grep keer'
192.168.37.122 | SUCCESS | rc=0 >>
keer:x:11111:11111::/home/keer:/bin/bash
删除用户:
[root@server ~]# ansible web -m user -a 'name=keer state=absent'
192.168.37.122 | SUCCESS => {
"changed": true,
"force": false,
"name": "keer",
"remove": false,
"state": "absent"
}
[root@server ~]# ansible web -m shell -a 'cat /etc/passwd |grep keer'
192.168.37.122 | FAILED | rc=1 >>
12:group模块
该模块主要用于添加或删除组。
常用的选项如下:
gid= @设置组的GID号
name= @指定组的名称
state= @指定组的状态,默认为创建,设置值为absent为删除
system= @设置值为yes,表示创建为系统组
练习:
//创建组
[root@server ~]# ansible web -m group -a 'name=sanguo gid=12222'
192.168.37.122 | SUCCESS => {
"changed": true,
"gid": 12222,
"name": "sanguo",
"state": "present",
"system": false
}
[root@server ~]# ansible web -m shell -a 'cat /etc/group | grep 12222'
192.168.37.122 | SUCCESS | rc=0 >>
sanguo:x:12222:
13:template模块:
基于模板方式生成一个文件复制到远程主机。
注:template使用Jinjia2格式作为文件模版,进行文档内变量的替换的模块。它的每次使用都会被ansible标记为”changed”状态。
backup: @如果原目标文件存在,则先备份目标文件
src: @在ansible控制器上的Jinja2格式化模板的路径。 这可以是相对或绝对的路径。
dest: @将模板渲染到远程机器上的位置。
force: @是否强制覆盖,默认为yes
owner: @目标文件属主
group: @目标文件属组
mode: @目标文件的权限模式,模式可以被指定为符号模式(例如,u + rwx或u = rw,g = r,o = r)。
#vim template.yml
14:get_url模块:
该模块主要用于从http、ftp、https服务器上下载文件。
类似wegt
sha256sum:@下载完成后进行sha256 check;
timeout: @下载超时时间,默认10s
url: @下载的URL
url_password、url_username:@主要用于需要用户名密码进行验证的情况
dest: @将文件下载到哪里的绝对路径。如果dest是目录,则使用服务器提供的文件名,或者如果没有提供,将使用远程服务器上的URL的基本名称。
headers: @以格式“key:value,key:value”为请求添加自定义HTTP标头。
#vim get_url.yml
15:unarchive模块:
用于解压文件;
模块包含如下选项:
copy: @在解压文件之前,是否先将文件复制到远程主机,默认为yes。若为no,则要求目标主机上压缩包必须存在。
creates: @指定一个文件名,当该文件存在时,则解压指令不执行
dest: @远程主机上的一个路径,即文件解压的绝对路径。
group: @解压后的目录或文件的属组
list_files: @如果为yes,则会列出压缩包里的文件,默认为no,2.0版本新增的选项
mode: @解压后文件的权限
src: @如果copy为yes,则需要指定压缩文件的源路径
owner: @解压后文件或目录的属主
#vim unarchive.yml
16:setup模块:
该模块主要用于收集信息,是通过调用facts组件来实现的。
facts组件是Ansible用于采集被管机器设备信息的一个功能,我们可以使用setup模块查机器的所有facts信息,可以使用filter来查看指定信息。整个facts信息被包装在一个JSON格式的数据结构中,ansible_facts是最上层的值。
facts就是变量,内建变量 。每个主机的各种信息,cpu颗数、内存大小等。会存在facts中的某个变量中。调用后返回很多对应主机的信息,在后面的操作中可以根据不同的信息来做不同的操作。如redhat系列用yum安装,而debian系列用apt来安装软件。
我们的setup模块还有一个很好用的功能就是可以保存我们所筛选的信息至我们的主机上,同时,文件名为我们被管制的主机的IP,这样方便我们知道是哪台机器出的问题。
练习:
[root@server ~]# ansible web -m setup -a 'filter="*mem*"' #查看内存
192.168.37.122 | SUCCESS => {
"ansible_facts": {
"ansible_memfree_mb": 1116,
"ansible_memory_mb": {
"nocache": {
"free": 1397,
"used": 587
},
"real": {
"free": 1116,
"total": 1984,
"used": 868
},
"swap": {
"cached": 0,
"free": 3813,
"total": 3813,
"used": 0
}
},
"ansible_memtotal_mb": 1984
},
"changed": false
}
[root@server ~]# ansible web -m shell -a 'free -m'
192.168.37.122 | SUCCESS | rc=0 >>
total used free shared buff/cache available
Mem: 1984 404 1122 9 457 1346
Swap: 3813 0 3813
//保存信息
[root@server tmp]# ansible web -m setup -a 'filter="*mem*"' --tree /tmp/facts
192.168.37.122 | SUCCESS => {
"ansible_facts": {
"ansible_memfree_mb": 1115,
"ansible_memory_mb": {
"nocache": {
"free": 1396,
"used": 588
},
"real": {
"free": 1115,
"total": 1984,
"used": 869
},
"swap": {
"cached": 0,
"free": 3813,
"total": 3813,
"used": 0
}
},
"ansible_memtotal_mb": 1984
},
"changed": false
}
[root@server ~]# cd /tmp/facts/
[root@server facts]# ls
192.168.37.122
[root@server facts]# cat 192.168.37.122
{"ansible_facts": {"ansible_memfree_mb": 1115, "ansible_memory_mb": {"nocache": {"free": 1396, "used": 588}, "real": {"free": 1115, "total": 1984, "used": 869}, "swap": {"cached": 0, "free": 3813, "total": 3813, "used": 0}}, "ansible_memtotal_mb": 1984}, "changed": false}
总练习:
`1. 编辑/etc/ansible/hosts文件,添加3个组,组名为[websrvs]、[tmtsrvs]、[ngxsrvs],每个组下有1个服务器ip(自定义)`
[root@server ansible]#vim /etc/ansible/hosts
[websrvs]
IP地址
[tmtsrvs]
IP地址
[ngxsrvs]
IP地址
`2. 使用ansible时只是单纯测试脚本或命令,但不真正执行的参数是?`
-C 或 --check
`3. 使用ansible测试脚本或命令语法是否正确的参数是?`
--syntax-check
`4. 在websrvs组下的创建用户web,密码为123456,用户过期时间是2020-06-01`
[root@server ansible]# python
Python 2.7.5 (default, Apr 11 2018, 07:36:10)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import crypt;crypt.crypt('123456')
'$6$DbGCRsgXdVf54KtM$gbu77IptU7zJaiu0j6e/9ei/3Dy.4936r0WkHW6fbeiPQ2iqTPOn559fTm6TUhaBEc.QPl3RDh650PiVXo4qz0'
[root@server ansible]#date -d 2020-06-01 +%s
1590940800
[root@server ansible]#ansible websrvs –m user –a ‘name=web expires=1590940800 password="python经过加密的密码"’
`5.在tmtsrvs组下添加一条计划任务,任务名称“bak cron“,任务于每周六、周日的凌晨1:10分执行,任务内容将/tmp/test.tar.xz解压到/opt目录下`
[root@server ansible]#ansible tmtsrvs –m cron –a ‘name=”bak cron”minute=10 hour=1 weekday=6,7 job=”tar –Jxf /tmp/test.tar.xz –C /opt”’
`6.在ngxsrvs组下添加一条计划任务,任务名称start ngx,任务将在重启时执行,任务内容是重启nginx(路径:/opt/nginx/sbin/nginx)`
[root@server ansible]#ansible ngxsrvs –m cron –a ’name=“start ngx”special_time=reboot job=”/opt/nginx/sbin/nginx”‘
`7.将ngxsrvs组下计划任务start ngx删除.`
[root@server ansible]#ansible ngxsrvs –m cron –a ‘name=”start ngx”state=absent’
`8.将tmtsrvs组下的计划任务“bak cron”注释掉,同时将原任务执行时间修改为每周一的03:00,原任务内容修改为echo test,并对计划任务备份`
[root@server ansible]#ansible tmtsrvs –m cron –a ‘name=”bak cron”minute=0 hour=3 job=”echo test”disabled=yes backup=yes’
`9.在tmtsrvs组服务器/opt/test目录下,创建test01文件,属主属组为test,权限为644`
[root@server ansible]#ansible tmtsrvs –m file –a ‘path=/opt/test/test01 state=present owner=test group=test mode=644’
`10.为tmtsrvs组服务器/opt/test/test01文件创建软链接,软链接名为ltest01`
[root@server ansible]#ansible tmtsrvs –m file –a ‘path=/opt/test/ltest01 state=link src=/opt/test/test01’
`11.将本机/opt/test文件拷贝到tmtsrvs组服务器下/opt/test目录下,若有同名文件则先备份,属主test,权限644`
[root@server ansible]#ansible tmtsrvs –m copy –a ‘src=/opt/test dest=/opt/test backup=yes owner=test mode=644’
`12.将tmtsrvs组服务器下/opt/test/test文件拉取到本地/opt/目录下`
[root@server ansible]#ansible tmtsrvs –m fetch –a ‘src=/opt/test/test dest=/opt’
`13.进入到tmtsrvs组服务器/opt目录下,执行ls命令,使用command模块`
[root@server ansible]#ansible tmtsrvs –m command –a ‘chdir=/opt ls’
`14.使用shell模块,将tmtsrvs组服务器中test用户密码修改为123456`
[root@server ansible]#ansible tmtsrvs –m shell –a ‘echo “123456”|passwd –stdin test’
`15.为ngxsrvs组服务器安装nginx,通过yum模块`
[root@server ansible]#ansible ngxsrvs –m yum –a ‘name=nginx state=latest’
`16.为ngxsrvs组服务器卸载nginx服务,通过yum模块`
[root@server ansible]#ansible ngxsrvs –m yum –a ‘name=nginx state=absent’
`17.为ngxsrvs组服务器启动nginx服务,通过service模块`
[root@server ansible]#ansible ngxsrvs –m service –a ‘name=nginx state=started’
`18.使用ansible-playbook编写一个脚本create_test.yaml,内容是新建用户test,在/opt目录下创建test目录,并在/opt/test目录下创建test01文件,文件属主属组为test`
[root@server ansible]#vim /etc/ansible/create_test.yaml
---
- hosts: ip
remote_user: root
tasks:
- name: create user test
user:name=test
- name: create dir test
file:path=/opt/test state=directory
- name: create file test
file:path=/opt/test/test01 state=touch owner=test group=test
[root@server ansible]#ansible-playbook create_test.yaml