一、ansible详解
ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能力。 ansible是基于 paramiko 开发的,并且基于模块化工作,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。ansible不需要在远程主机上安装client/agents,因为它们是基于ssh来和远程主机通讯的。且真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。主要包括:如下:
- 连接插件connection plugins:负责和被监控端实现通信;
- host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
- 各种模块核心模块、command模块、自定义模块;
- 借助于插件完成记录日志邮件等功能;
- playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。
- ansible目前已经已经被红帽官方收购,是自动化运维工具中大家认可度最高的,并且上手容易,学习简单。是每位运维工程师必须掌握的技能之一。
- 部署简单,只需在主控端部署Ansible环境,被控端无需做任何操作;
- 默认使用SSH协议对设备进行管理;(ansible和远程主机有连接是因为ssh协议 ansible要对远程主机进行免密登录 ssh–22)
- 有大量常规运维操作模块,可实现日常绝大部分操作;
- 配置简单、功能强大、扩展性强;
- 支持API及自定义模块,可通过Python轻松扩展;
- 通过Playbooks来定制强大的配置、状态管理;
- 轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
- 提供一个功能强大、操作性强的Web管理界面和REST API接口——AWX平台。
- 如上图所见 ansible常用模块如下列所示:
- ansible core : ansible 自身核心模块
- host inventory: 主机库,定义可管控的主机列表
- connection plugins: 连接插件,一般默认基于 ssh 协议连接
- modules:core modules (自带模块 核心) custom modules (自定义模块)
playbooks :剧本,按照所设定编排的顺序执行完成安排任务
ansible任务执行模式:
Ansible 系统由控制主机对被管节点的操作方式可分为两类,即adhoc和playbook:
- ad-hoc模式(点对点模式): 使用单个模块,支持批量执行单条命令。ad-hoc 命令是一种可以快速输入的命令,而且不需要保存起来的命令。就相当于bash中的一句话shell。
- playbook模式(剧本模式): 是Ansible主要管理方式,也是Ansible功能强大的关键所在。playbook通过多个task集合完成一类功能,如Web服务的安装部署、数据库服务器的批量备份等。可以简单地把playbook理解为通过组合多条ad-hoc操作的配置文件。
ansible执行流程:
是Ansible主要管理方式,也是Ansible功能强大的关键所在。playbook通过多个task集合完成一类功能,如Web服务的安装部署、数据库服务器的批量备份等。可以简单地把playbook理解为通过组合多条ad-hoc操作的配置文件。
- ansible hosts(主机清单) -m module_name(模块名) -a job(对后端主机进行的操作)
- -M 指定模块路径
- -m 使用模块,默认 command 模块
- -a or –args 模块参数
- -i inventory 文件路径,或可执行脚本
- -k 使用交互式登录密码
- -e 定义变量
- -v 详细信息,-vvvv 开启 debug 模式
- ansible的执行结果:
- ansible的执行结果
- 绿色 执行成功
- 红色 执行失败
- 黄色 执行成功 并且对后端的主机进行了修改
- 紫色 警告
二、环境部署及实操
所需安装包从这里获取:
链接:https://pan.baidu.com/s/122DrPPev90Q3cVEN6uCEbw
提取码:ozal
服务 | IP |
---|---|
ansible | 192.168.20.10 |
客户端01 | 192.168.20.20 |
客户端02 | 192.168.20.30 |
先展示脱网安装在做联网安装
-
- 把所需的安装包拖进ansible服务器新建的文件夹ansibleapp内
[root@lpj1 ~]# createrepo /root/app
Directory /root/app must exist
[root@lpj1 ~]# createrepo /root/ansibleapp
Spawning worker 0 with 11 pkgs
Workers Finished
Saving Primary metadata
Saving file lists metadata
Saving other metadata
Generating sqlite DBs
Sqlite DBs complete
[root@lpj1 ~]# ls /root/ansibleapp/
ansible-2.4.2.0-2.el7.noarch.rpm
libyaml-0.1.4-11.el7_0.x86_64.rpm
python2-jmespath-0.9.0-3.el7.noarch.rpm
python-babel-0.9.6-8.el7.noarch.rpm
python-httplib2-0.9.2-1.el7.noarch.rpm
python-jinja2-2.7.2-2.el7.noarch.rpm
python-markupsafe-0.11-10.el7.x86_64.rpm
python-paramiko-2.1.1-2.el7.noarch.rpm
python-passlib-1.6.5-2.el7.noarch.rpm
PyYAML-3.10-11.el7.x86_64.rpm
repodata
sshpass-1.06-2.el7.x86_64.rpm
- 新做一个yum源
[root@lpj1 ~]# cd /etc/yum.repos.d/
[root@lpj1 yum.repos.d]# vim ansible.repo
[root@lpj1 yum.repos.d]# cat ansible.repo
[ansible]
name=ansible
baseurl=file:///root/ansibleapp
enabled=1
gpgcheck=0
- 进行安装及查看版本
[root@lpj1 yum.repos.d]# yum -y install ansible
[root@lpj1 yum.repos.d]# ansible --version
ansible 2.4.2.0
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, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
联网安装如下:(能够ping通baidu)
[root@lpj2 ~]# cd /etc/yum.repos.d/
[root@lpj2 yum.repos.d]# wget http://mirrors.aliyun.com/repo/Centos-7.repo
--2020-06-10 16:17:47-- http://mirrors.aliyun.com/repo/Centos-7.repo
正在解析主机 mirrors.aliyun.com (mirrors.aliyun.com)... 60.221.72.241, 60.221.72.243, 124.165.216.248, ...
正在连接 mirrors.aliyun.com (mirrors.aliyun.com)|60.221.72.241|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:2523 (2.5K) [application/octet-stream]
正在保存至: “Centos-7.repo.1”
100%[==================================>] 2,523 --.-K/s 用时 0s
2020-06-10 16:17:47 (311 MB/s) - 已保存 “Centos-7.repo.1” [2523/2523])
[root@lpj2 yum.repos.d]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
--2020-06-10 16:15:29-- http://mirrors.aliyun.com/repo/epel-7.repo
正在解析主机 mirrors.aliyun.com (mirrors.aliyun.com)... 124.165.216.238, 139.170.154.152, 116.177.243.231, ...
正在连接 mirrors.aliyun.com (mirrors.aliyun.com)|124.165.216.238|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:664 [application/octet-stream]
正在保存至: “/etc/yum.repos.d/epel.repo”
100%[==================================>] 664 --.-K/s 用时 0s
2020-06-10 16:15:29 (152 MB/s) - 已保存 “/etc/yum.repos.d/epel.repo” [664/664])
2020-06-10 16:11:41 (352 MB/s) - 已保存 “Centos-7.repo” [2523/2523])
[root@lpj2 yum.repos.d]# yum -y install ansible
查看版本
[root@lpj2 yum.repos.d]# ansible --version
ansible 2.9.9
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, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
主控端生成秘钥
[root@lpj1 ~]# ssh-keygen ## 4次回车
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
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:wed2LJ4toiiTfH49BaIzfkoZqedj7lH5J7Fil3OdziY root@lpj1
The key's randomart image is:
+---[RSA 2048]----+
| |
| . |
| o . |
| ....+ . |
| o.o.S.+ o |
| .++ . *.* . |
| ..o=oo.O.* + |
| =+=+o+o*E+. |
| OB=. . oo |
+----[SHA256]-----+
[root@lpj1 ~]# cd /root/.ssh/
[root@lpj1 .ssh]# ls
id_rsa id_rsa.pub
id_rsa私钥 id_rsa.pub公钥
公钥传递到远程主机上
[root@lpj1 .ssh]# ssh-copy-id root@192.168.20.20
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.20.20 (192.168.20.20)' can't be established.
ECDSA key fingerprint is SHA256:toHBDUUac+V6dbIrzsgiZfD38kR35IwY6NsDfkEwyXE.
ECDSA key fingerprint is MD5:4c:9f:c4:1b:d8:1e:bf:97:80:e6:55:f6:68:f1:56:1e.
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.20.20's password: 输入所远程连接主机的用户密码
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@192.168.20.20'"
and check to make sure that only the key(s) you wanted were added.
远程连接第二台
[root@lpj1 .ssh]# ssh-copy-id root@192.168.20.30
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.20.30 (192.168.20.30)' can't be established.
ECDSA key fingerprint is SHA256:bEN7HssU4h/61Fs5KCK9FM4iZCBIa76702eEBpGHHPU.
ECDSA key fingerprint is MD5:05:0d:46:30:8d:1b:4d:aa:6f:28:b2:64:2b:94:e6:23.
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.20.30's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@192.168.20.30'"
and check to make sure that only the key(s) you wanted were added.
查看远程主机上的公钥
第一台
[root@lpj2 ~]# cd /root/.ssh/
[root@lpj2 .ssh]# ls
authorized_keys
第二台
[root@lpj3 ~]# cd /root/.ssh/
[root@lpj3 .ssh]# ls
authorized_keys
[root@lpj3 .ssh]#
回到ansible服务器上 远程连接客户端 看是否连接成功
[root@lpj1 .ssh]# ssh root@192.168.20.20
Last login: Wed Jun 10 16:25:33 2020 from 192.168.20.1
[root@lpj2 ~]# exit
logout
Connection to 192.168.20.20 closed.
[root@lpj1 .ssh]# ssh root@192.168.20.30
Last login: Wed Jun 10 15:57:21 2020 from 192.168.20.1
[root@lpj3 ~]# exit
logout
Connection to 192.168.20.30 closed.
[root@lpj1 .ssh]#
-- 列出ansible所有的模块 ## -l 列出
[root@lpj1 ansible]# ansible-doc -l
a10_server Manage A10 Networks AX/SoftAX/Thu.
a10_server_axapi3 Manage A10 Networks AX/SoftAX/Thu.
a10_service_group Manage A10 Networks AX/SoftAX/Thu.
a10_virtual_server Manage A10 Networks AX/SoftAX/Thu.
accelerate Enable accelerated mode on remote.
aci_aep Manage attachable Access Entity P.
aci_ap Manage top level Application Prof.
aci_bd Manage Bridge Domains (BD) on Cis.
aci_bd_subnet Manage Subnets on Cisco ACI fabri.
aci_bd_to_l3out Bind Bridge Domain to L3 Out on C.
aci_config_rollback Provides rollback and rollback pr.
aci_config_snapshot Manage Config Snapshots on Cisco .
aci_contract Manage contract resources on Cisc.
aci_contract_subject Manage initial Contract Subjects .
aci_contract_subject_to_filter Bind Contract Subjects to Filters.
aci_epg Manage End Point Groups (EPG) on .
aci_epg_monitoring_policy Manage monitoring policies on Cis.
aci_epg_to_contract Bind EPGs to Contracts on Cisco A.
aci_epg_to_domain Bind EPGs to Domains on Cisco ACI.
: ##使用q退出 如果死机 终端关掉就可以了
-- 查看模块的帮助信息 ##-s 加载模块名
[root@lpj1 ansible]# ansible-doc -s ping
- name: Try to connect to host, verify a usable python and return `pong' on
ping:
data: # Data to return for the `ping' return value. I
this parameter is
set to `crash',
the module will
cause an
exception.
ansible常用模块之 ping 测试主控端和远程主机是否能够连通 ssh
[root@lpj1 .ssh]# cd /etc/ansible/
[root@lpj1 ansible]# vim hosts ## 主机清单
[peng] ##清单名称
192.168.20.20 ##远程主机的IP
192.168.20.30
[jie]
192.168.20.20
[root@lpj1 ansible]# ansible peng -m ping
192.168.20.20 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.20.30 | SUCCESS => {
"changed": false,
"ping": "pong"
}
[root@lpj1 ansible]# ansible jie -m ping
192.168.20.20 | SUCCESS => {
"changed": false,
"ping": "pong"
}
[root@lpj1 ansible]# ansible all -m ping ##all所有主机清单中的所有主机
192.168.20.30 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.20.20 | SUCCESS => {
"changed": false,
"ping": "pong"
}
[root@lpj1 ansible]# ansible 192.168.20.30 -m ping ## 通过IP测试
192.168.20.30 | SUCCESS => {
"changed": false,
"ping": "pong"
}
ansible常用模块之 command : command 模块用于在远程主机上执行命令,
ansible默认就是使用 command 模块。
command 模块有一个缺点的缺陷是不能用特殊符号 例如| > >>
[root@lpj1 ansible]# ansible all -m command -a "ls /home"
192.168.20.30 | SUCCESS | rc=0 >>
peng
192.168.20.20 | SUCCESS | rc=0 >>
peng
## 参数 chdir 切换目录
## creates 当指定文件存在时,命令不执行 当指定文件不存在时,命令执行
##removes 当指定的文件存在时,命令执行 当指定文件不存在时 命令不执行
chdir演示如下 :
[root@lpj1 ansible]# ansible all -m command -a "chdir=/home ls"
192.168.20.20 | SUCCESS | rc=0 >>
peng
zs
192.168.20.30 | SUCCESS | rc=0 >>
ls
peng
creates演示如下 :
[root@lpj1 ansible]# ansible all -m command -a "creates=/etc/fstab ls /home" ##存在时
192.168.20.30 | SUCCESS | rc=0 >>
skipped, since /etc/fstab exists
192.168.20.20 | SUCCESS | rc=0 >>
skipped, since /etc/fstab exists
[root@lpj1 ansible]# ansible all -m command -a "creates=/etc/fstabbbbbb ls /home" ##不存在时候
192.168.20.30 | SUCCESS | rc=0 >>
ls
peng
192.168.20.20 | SUCCESS | rc=0 >>
peng
zs
removes演示如下 :
[root@lpj1 ansible]# ansible all -m command -a "removes=/etc/fstab ls /home" ##存在时
192.168.20.30 | SUCCESS | rc=0 >>
ls
peng
192.168.20.20 | SUCCESS | rc=0 >>
peng
zs
[root@lpj1 ansible]# ansible all -m command -a "removes=/etc/fstabdfsfsdf ls /home" ## 不存在时
192.168.20.30 | SUCCESS | rc=0 >>
skipped, since /etc/fstabdfsfsdf does not exist
192.168.20.20 | SUCCESS | rc=0 >>
skipped, since /etc/fstabdfsfsdf does not exist
ansible常用的模块之 : shell:shell模块用于在受控主机上执行受控主机上的脚本,也可以直接在受控主机上执行命令,是万能模块
[root@lpj1 ansible]# ansible all -m shell -a "touch /home/aa"
[WARNING]: Consider using file module with state=touch rather than running touch
192.168.20.20 | SUCCESS | rc=0 >>
192.168.20.30 | SUCCESS | rc=0 >>
[root@lpj1 ansible]# ansible all -m shell -a "ls /home | grep aa"
192.168.20.30 | SUCCESS | rc=0 >>
aa
192.168.20.20 | SUCCESS | rc=0 >>
aa
[root@lpj1 ansible]# ansible all -m shell -a "echo '123' > /home/aa "
192.168.20.20 | SUCCESS | rc=0 >>
192.168.20.30 | SUCCESS | rc=0 >>
[root@lpj1 ansible]# ansible all -m shell -a "cat /home/aa "
192.168.20.30 | SUCCESS | rc=0 >>
123
192.168.20.20 | SUCCESS | rc=0 >>
123
ansible常用模块之 user : 管理或者创建远程主机上的用户
参数 :参数: name 指定用户名 如果用户不存在 则创建该用户
[root@lpj1 ansible]# ansible all -m user -a "name=aa"
192.168.20.20 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 1002,
"home": "/home/aa",
"name": "aa",
"shell": "/bin/bash",
"state": "present",
"stderr": "useradd: warning: the home directory already exists.\nNot copying any file from skel directory into it.\n",
"stderr_lines": [
"useradd: warning: the home directory already exists.",
"Not copying any file from skel directory into it."
],
"system": false,
"uid": 1002
}
192.168.20.30 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 1002,
"home": "/home/aa",
"name": "aa",
"shell": "/bin/bash",
"state": "present",
"stderr": "useradd: warning: the home directory already exists.\nNot copying any file from skel directory into it.\n",
"stderr_lines": [
"useradd: warning: the home directory already exists.",
"Not copying any file from skel directory into it."
],
"system": false,
"uid": 1002
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -1 /etc/passwd" ##password 给用户添加密码 修改密码 添加密码的时候只能识别加密后的字符
192.168.20.30 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash
192.168.20.20 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash
[root@lpj1 ansible]# yum -y install openssl-devel
[root@lpj1 ansible]# openssl passwd -1 123.com
$1$xNp3AQv9$UnFy1fpdc0m4/TuUJsqmj/
[root@lpj1 ansible]# ansible all -m user -a 'name=aa password=$1$xNp3AQv9$UnFy1fpdc0m4/TuUJsqmj/ '
192.168.20.20 | SUCCESS => {
"append": false,
"changed": true,
"comment": "",
"group": 1002,
"home": "/home/aa",
"move_home": false,
"name": "aa",
"password": "NOT_LOGGING_PASSWORD",
"shell": "/bin/bash",
"state": "present",
"uid": 1002
}
192.168.20.30 | SUCCESS => {
"append": false,
"changed": true,
"comment": "",
"group": 1002,
"home": "/home/aa",
"move_home": false,
"name": "aa",
"password": "NOT_LOGGING_PASSWORD",
"shell": "/bin/bash",
"state": "present",
"uid": 1002
} ## 这里要单引号 双引号不行
远程主机上进行验证
[peng@lpj2 ~]$ su aa
密码:123.com
bash: /home/aa/.bashrc: 不是目录
bash-4.2$
参数:
exit 返回到root用户
uid 指定用户的uid
group 指定用户的基本组
groups 指定用户的附加组
append=yes 增量增加附加组 相当于把用户添加到另一个附加组中
append=no 全量添加附加组 相当于只设置一个附加组
指定uid
[root@lpj1 ansible]# ansible all -m user -a "uid=1030 name=test"
192.168.20.30 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 1030,
"home": "/home/test",
"name": "test",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1030
}
192.168.20.20 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 1030,
"home": "/home/test",
"name": "test",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1030
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -2 /etc/passwd"
192.168.20.30 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash
test:x:1030:1030::/home/test:/bin/bash
192.168.20.20 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash
test:x:1030:1030::/home/test:/bin/bash
指定用户的基本组
[root@lpj1 ansible]# ansible all -m user -a"name=test group=aa"
192.168.20.30 | SUCCESS => {
"append": false,
"changed": true,
"comment": "",
"group": 1002,
"home": "/home/test",
"move_home": false,
"name": "test",
"shell": "/bin/bash",
"state": "present",
"uid": 1030
}
192.168.20.20 | SUCCESS => {
"append": false,
"changed": true,
"comment": "",
"group": 1002,
"home": "/home/test",
"move_home": false,
"name": "test",
"shell": "/bin/bash",
"state": "present",
"uid": 1030
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -2 /etc/passwd"
192.168.20.30 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash
test:x:1030:1002::/home/test:/bin/bash
192.168.20.20 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash
test:x:1030:1002::/home/test:/bin/bash
附加组
[root@lpj1 ansible]# ansible all -m user -a "name=test groups=test"
192.168.20.20 | SUCCESS => {
"append": false,
"changed": true,
"comment": "",
"group": 1002,
"groups": "test",
"home": "/home/test",
"move_home": false,
"name": "test",
"shell": "/bin/bash",
"state": "present",
"uid": 1030
}
192.168.20.30 | SUCCESS => {
"append": false,
"changed": true,
"comment": "",
"group": 1002,
"groups": "test",
"home": "/home/test",
"move_home": false,
"name": "test",
"shell": "/bin/bash",
"state": "present",
"uid": 1030
}
[root@lpj1 ansible]# ansible all -m user -a "name=test groups=test"
192.168.20.20 | SUCCESS => {
"append": false,
"changed": true,
"comment": "",
"group": 1002,
"groups": "test",
"home": "/home/test",
"move_home": false,
"name": "test",
"shell": "/bin/bash",
"state": "present",
"uid": 1030
}
192.168.20.30 | SUCCESS => {
"append": false,
"changed": true,
"comment": "",
"group": 1002,
"groups": "test",
"home": "/home/test",
"move_home": false,
"name": "test",
"shell": "/bin/bash",
"state": "present",
"uid": 1030
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -2 /etc/group"
192.168.20.20 | SUCCESS | rc=0 >>
aa:x:1002:
test:x:1030:test
增量添加
[root@lpj1 ansible]# ansible all -m shell -a "groupadd one"
192.168.20.20 | SUCCESS | rc=0 >>
192.168.20.30 | SUCCESS | rc=0 >>
[root@lpj1 ansible]# ansible all -m user -a "name=test groups=one append=yes"
192.168.20.20 | SUCCESS => {
"append": true,
"changed": true,
"comment": "",
"group": 1002,
"groups": "one",
"home": "/home/test",
"move_home": false,
"name": "test",
"shell": "/bin/bash",
"state": "present",
"uid": 1030
}
192.168.20.30 | SUCCESS => {
"append": true,
"changed": true,
"comment": "",
"group": 1002,
"groups": "one",
"home": "/home/test",
"move_home": false,
"name": "test",
"shell": "/bin/bash",
"state": "present",
"uid": 1030
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -3 /etc/group"
192.168.20.20 | SUCCESS | rc=0 >>
aa:x:1002:
test:x:1030:test
one:x:1031:test
192.168.20.30 | SUCCESS | rc=0 >>
aa:x:1002:
test:x:1030:test
one:x:1031:test
全量添加
[root@lpj1 ansible]# ansible all -m user -a "name=test groups=one append=no"
192.168.20.20 | SUCCESS => {
"append": false,
"changed": true,
"comment": "",
"group": 1002,
"groups": "one",
"home": "/home/test",
"move_home": false,
"name": "test",
"shell": "/bin/bash",
"state": "present",
"uid": 1030
}
192.168.20.30 | SUCCESS => {
"append": false,
"changed": true,
"comment": "",
"group": 1002,
"groups": "one",
"home": "/home/test",
"move_home": false,
"name": "test",
"shell": "/bin/bash",
"state": "present",
"uid": 1030
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -3 /etc/group"
192.168.20.20 | SUCCESS | rc=0 >>
aa:x:1002:
test:x:1030:
one:x:1031:test
192.168.20.30 | SUCCESS | rc=0 >>
aa:x:1002:
test:x:1030:
one:x:1031:test
state=absent 删除用户 默认不删除家目录
remove=yes 删除用户的同时删除掉家目录
state=absent 演示如下
[root@lpj1 ansible]# ansible all -m user -a "name=test state=absent remove=yes"
192.168.20.20 | SUCCESS => {
"changed": true,
"force": false,
"name": "test",
"remove": true,
"state": "absent",
"stderr": "userdel: group test not removed because it is not the primary group of user test.\n",
"stderr_lines": [
"userdel: group test not removed because it is not the primary group of user test."
]
}
192.168.20.30 | SUCCESS => {
"changed": true,
"force": false,
"name": "test",
"remove": true,
"state": "absent",
"stderr": "userdel: group test not removed because it is not the primary group of user test.\n",
"stderr_lines": [
"userdel: group test not removed because it is not the primary group of user test."
]
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -1 /etc/passwd"
192.168.20.20 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash
192.168.20.30 | SUCCESS | rc=0 >>
aa:x:1002:1002::/home/aa:/bin/bash
[root@lpj1 ansible]# ansible all -m shell -a "ls /home"
192.168.20.30 | SUCCESS | rc=0 >>
aa
ls
peng
192.168.20.20 | SUCCESS | rc=0 >>
aa
peng
zs
-- ansible常用模块之group: 创建和管理远程主机上的组
参数:
name 指定组 如果不存在则创建
gid 修改或者指定组的gid
state=absent 删除指定的组
name:
[root@lpj1 ansible]# ansible all -m group -a "name=two"
192.168.20.30 | SUCCESS => {
"changed": false,
"gid": 1032,
"name": "two",
"state": "present",
"system": false
}
192.168.20.20 | SUCCESS => {
"changed": false,
"gid": 1032,
"name": "two",
"state": "present",
"system": false
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -1 /etc/group"
192.168.20.30 | SUCCESS | rc=0 >>
two:x:1032:
192.168.20.20 | SUCCESS | rc=0 >>
two:x:1032:
gid
[root@lpj1 ansible]# ansible all -m group -a "name=two gid=1050"
192.168.20.20 | SUCCESS => {
"changed": true,
"gid": 1050,
"name": "two",
"state": "present",
"system": false
}
192.168.20.30 | SUCCESS => {
"changed": true,
"gid": 1050,
"name": "two",
"state": "present",
"system": false
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -1 /etc/group"
192.168.20.20 | SUCCESS | rc=0 >>
two:x:1050:
192.168.20.30 | SUCCESS | rc=0 >>
two:x:1050:
state=absent
[root@lpj1 ansible]# ansible all -m group -a "name=two state=absent"
192.168.20.30 | SUCCESS => {
"changed": true,
"name": "two",
"state": "absent"
}
192.168.20.20 | SUCCESS => {
"changed": true,
"name": "two",
"state": "absent"
}
[root@lpj1 ansible]# ansible all -m shell -a "tail -1 /etc/group"
192.168.20.20 | SUCCESS | rc=0 >>
apache:x:48:
192.168.20.30 | SUCCESS | rc=0 >>
apache:x:48:
--ansible常用模块之.script : 在远程主机上执行主控端的脚本
参数 chdir 切换目录 远程主机上的目录
creates 文件存在 脚本不执行
removes 文件存在 脚本执行
[root@lpj1 ansible]# vim test.sh
[root@lpj1 ansible]# cat test.sh
#!/bin/bash
cd /usr
ls | grep src
creates:存在
[root@lpj1 ansible]# ansible all -m script -a "creates=/etc/fstab chdir=/root test.sh"
192.168.20.20 | SKIPPED
192.168.20.30 | SKIPPED
不存在:
[root@lpj1 ansible]# ansible all -m script -a "creates=/etc/fstabbbbb chdir=/root test.sh"
192.168.20.30 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.20.30 closed.\r\n",
"stdout": "src\r\n",
"stdout_lines": [
"src"
]
}
192.168.20.20 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.20.20 closed.\r\n",
"stdout": "src\r\n",
"stdout_lines": [
"src"
]
}
removes:存在
[root@lpj1 ansible]# ansible all -m script -a "removes=/etc/fstab chdir=/root test.sh"
192.168.20.20 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.20.20 closed.\r\n",
"stdout": "src\r\n",
"stdout_lines": [
"src"
]
}
192.168.20.30 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.20.30 closed.\r\n",
"stdout": "src\r\n",
"stdout_lines": [
"src"
]
}
不存在
[root@lpj1 ansible]# ansible all -m script -a "removes=/etc/fstabbbb chdir=/root test.sh"
192.168.20.20 | SKIPPED
192.168.20.30 | SKIPPED
--ansible常用模块之setup:查看远程主机上的信息 查看自带的变量
参数 filter 过滤
[root@lpj1 ansible]# ansible all -m setup (粘贴了其中一点)
"rx_software",
"software"
],
"type": "ether"
},
"ansible_virtualization_role": "guest",
"ansible_virtualization_type": "VMware",
"gather_subset": [
"all"
],
"module_setup": true
},
"changed": false
}
进行过滤
[root@lpj1 ansible]# ansible all -m setup -a "filter=ansible_all_ipv4_addresses"
192.168.20.20 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.122.1",
"192.168.20.20"
]
},
"changed": false
}
192.168.20.30 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.122.1",
"192.168.20.30"
]
},
"changed": false
}
--ansible常用模块之 copy模块:将主控端的文件复制到远程主机上,可以复制目录,但是目录当中必须有文件
参数 src 要复制文件的路径 (源文件)
dest 将文件复制到目标主机的位置
[root@lpj1 ansible]# touch hehehe
[root@lpj1 ansible]# ansible all -m copy -a "src=/root/hehehe dest=/home"
[root@lpj1 ansible]# ansible all -m shell -a "ls /mnt"
192.168.20.20 | SUCCESS | rc=0 >>
192.168.20.30 | SUCCESS | rc=0 >>
content 将指定的内容写入到远程主机的文件中 会将原来的内容进行覆盖
[root@lpj1 ansible]# ansible all -m copy -a "content='11111\n22222' dest=/home/hehehe"
192.168.20.20 | SUCCESS => {
"changed": true,
"checksum": "7b6b1fce37f21601911579bd732fad05501edb46",
"dest": "/home/hehehe",
"gid": 0,
"group": "root",
"md5sum": "97a3ddd80988315f10613a8dec79ec34",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:user_home_dir_t:s0",
"size": 11,
"src": "/root/.ansible/tmp/ansible-tmp-1591862346.87-85101333503247/source",
"state": "file",
"uid": 0
}
192.168.20.30 | SUCCESS => {
"changed": true,
"checksum": "7b6b1fce37f21601911579bd732fad05501edb46",
"dest": "/home/hehehe",
"gid": 0,
"group": "root",
"md5sum": "97a3ddd80988315f10613a8dec79ec34",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:user_home_dir_t:s0",
"size": 11,
"src": "/root/.ansible/tmp/ansible-tmp-1591862346.88-75036136590050/source",
"state": "file",
"uid": 0
}
[root@lpj1 ansible]# ansible all -m shell -a "cat /home/hehehe"
192.168.20.30 | SUCCESS | rc=0 >>
11111
22222
192.168.20.20 | SUCCESS | rc=0 >>
11111
22222
[root@lpj1 ansible]# ansible all -m copy -a "content='55555\n66666' dest=/home/hehehe"192.168.20.30 | SUCCESS => {
"changed": true,
"checksum": "e66591a2bac048a079c0c0db1a65718cf2c2c226",
"dest": "/home/hehehe",
"gid": 0,
"group": "root",
"md5sum": "d0ce73b19a9bdf7d94fbe1605e74339a",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:user_home_dir_t:s0",
"size": 11,
"src": "/root/.ansible/tmp/ansible-tmp-1591862384.91-157847546279054/source",
"state": "file",
"uid": 0
}
192.168.20.20 | SUCCESS => {
"changed": true,
"checksum": "e66591a2bac048a079c0c0db1a65718cf2c2c226",
"dest": "/home/hehehe",
"gid": 0,
"group": "root",
"md5sum": "d0ce73b19a9bdf7d94fbe1605e74339a",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:user_home_dir_t:s0",
"size": 11,
"src": "/root/.ansible/tmp/ansible-tmp-1591862384.9-201026476411221/source",
"state": "file",
"uid": 0
}
[root@lpj1 ansible]# ansible all -m shell -a "cat /home/hehehe"
192.168.20.20 | SUCCESS | rc=0 >>
55555
66666
192.168.20.30 | SUCCESS | rc=0 >>
55555
66666
copy 当没有任何参数的时候 当主控端拷贝的文件和远程主机上的文件名一致时 ,但是内容不一致,则会强制覆盖
force=no 当主控端拷贝的文件和远程主机上的文件名一致时 ,但是内容不一致,则不会覆盖 会放弃拷贝
backup=yes 当主控端拷贝的文件和远程主机上的文件名一致时 ,但是内容不一致,会覆盖 但是会对远程主机的文件进行备份
[root@lpj1 ansible]# echo 111111 > hehehe
[root@lpj1 ansible]# ansible all -m copy -a "src=/root/hehehe dest=/home"
[root@lpj1 ansible]# ansible all -m shell -a "cat /home/hehehe"
192.168.20.20 | SUCCESS | rc=0 >>
55555
66666
192.168.20.30 | SUCCESS | rc=0 >>
55555
66666
[root@lpj1 ansible]# ansible all -m copy -a "src=/root/hehehe dest=/home backup=yes"
[root@lpj1 ansible]# ansible all -m shell -a "cat /home/hehehe"
192.168.20.30 | SUCCESS | rc=0 >>
55555
66666
192.168.20.20 | SUCCESS | rc=0 >>
55555
66666
[root@lpj1 ansible]# ansible all -m shell -a "ls /home"
192.168.20.30 | SUCCESS | rc=0 >>
aa
hehe
hehehe
ls
peng
rr
192.168.20.20 | SUCCESS | rc=0 >>
aa
hehe
hehehe
peng
rr
zs
[root@lpj1 ansible]# mkdir /aaa
[root@lpj1 ansible]# ansible all -m copy -a "src=/aaa dest=/home/"
192.168.20.20 | SUCCESS => {
"changed": false,
"dest": "/home/",
"src": "/aaa"
}
192.168.20.30 | SUCCESS => {
"changed": false,
"dest": "/home/",
"src": "/aaa"
}
[root@lpj1 ansible]# ansible all -m shell -a "ls /home"
192.168.20.30 | SUCCESS | rc=0 >>
aa
hehe
hehehe
ls
peng
rr
192.168.20.20 | SUCCESS | rc=0 >>
aa
hehe
hehehe
peng
rr
zs
[root@lpj1 ansible]# ansible all -m copy -a "src=/aaa dest=/home/"
192.168.20.30 | SUCCESS => {
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/home/aaa/rrr",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1591862653.72-171925879046613/source",
"state": "file",
"uid": 0
}
192.168.20.20 | SUCCESS => {
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/home/aaa/rrr",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:user_home_t:s0",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1591862653.71-71362448129619/source",
"state": "file",
"uid": 0
}
[root@lpj1 ansible]# ansible all -m shell -a "ls /home"
192.168.20.20 | SUCCESS | rc=0 >>
aa
aaa
hehe
hehehe
peng
rr
zs
192.168.20.30 | SUCCESS | rc=0 >>
aa
aaa
hehe
hehehe
ls
peng
rr
owner: 指定文件的属主
group :指定文件的属组
mode:指定文件的权限
[root@lpj1 ansible]# ansible all -m user -a "name=rr"
192.168.20.20 | SUCCESS => {
"append": false,
"changed": false,
"comment": "",
"group": 1003,
"home": "/home/rr",
"move_home": false,
"name": "rr",
"shell": "/bin/bash",
"state": "present",
"uid": 1003
}
192.168.20.30 | SUCCESS => {
"append": false,
"changed": false,
"comment": "",
"group": 1003,
"home": "/home/rr",
"move_home": false,
"name": "rr",
"shell": "/bin/bash",
"state": "present",
"uid": 1003
}
[root@lpj1 ansible]# touch cc
[root@lpj1 ansible]# ansible all -m copy -a "src=/root/cc dest=/"
[root@lpj1 ansible]# ansible all -m shell -a "ls -l /cc"
192.168.20.20 | SUCCESS | rc=0 >>
-rw-r--r--. 1 root root 0 Jun 11 17:44 /cc
192.168.20.30 | SUCCESS | rc=0 >>
-rw-r--r--. 1 root root 0 Jun 11 09:44 /cc
[root@lpj1 ansible]# ansible all -m shell -a "ls -l /cc"
[root@lpj1 ansible]# ansible all -m copy -a "src=/root/cc dest=/ group=rr"
[root@lpj1 ansible]# ansible all -m shell -a "ls -l /cc"
[root@lpj1 ansible]# ansible all -m copy -a "src=/root/cc dest=/ mode=777"
[root@lpj1 ansible]# ansible all -m shell -a "ls -l /cc"
[root@lpj1 ansible]# ansible all -m copy -a "src=/root/cc dest=/ mode=7777"
[root@lpj1 ansible]# ansible all -m shell -a "ls -l /cc"
--ansible常用模块之yum:模块 在远程主机上使用yum安装软件 远程主机上要提前配置好yum
参数 name:软件名
state : installed 安装软件包
removed 卸载软件包
卸载:
[root@lpj1 ansible]# ansible all -m yum -a "name=httpd state=removed"
192.168.20.30 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror, langpacks\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-90.el7.centos will be erased\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nRemoving:\n httpd x86_64 2.4.6-90.el7.centos @a 9.4 M\n\nTransaction Summary\n================================================================================\nRemove 1 Package\n\nInstalled size: 9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Erasing : httpd-2.4.6-90.el7.centos.x86_64 1/1 \n Verifying : httpd-2.4.6-90.el7.centos.x86_64 1/1 \n\nRemoved:\n httpd.x86_64 0:2.4.6-90.el7.centos \n\nComplete!\n"
]
}
安装
[root@lpj1 ansible]# ansible all -m yum -a "name=httpd state=installed"
192.168.20.30 | 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 httpd.x86_64 0:2.4.6-90.el7.centos will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n httpd x86_64 2.4.6-90.el7.centos a 2.7 M\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 2.7 M\nInstalled size: 9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : httpd-2.4.6-90.el7.centos.x86_64 1/1 \n Verifying : httpd-2.4.6-90.el7.centos.x86_64 1/1 \n\nInstalled:\n httpd.x86_64 0:2.4.6-90.el7.centos \n\nComplete!\n"
]
}
192.168.20.20 | 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 httpd.x86_64 0:2.4.6-90.el7.centos will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n httpd x86_64 2.4.6-90.el7.centos a 2.7 M\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 2.7 M\nInstalled size: 9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : httpd-2.4.6-90.el7.centos.x86_64 1/1 \n Verifying : httpd-2.4.6-90.el7.centos.x86_64 1/1 \n\nInstalled:\n httpd.x86_64 0:2.4.6-90.el7.centos \n\nComplete!\n"
]
}
--ansbile常用模块service模块 管理远程主机上的服务
参数 name 服务名
state started 开启 stopped 关闭 restarted 重启 reloaded重新加载(开启服务的时候才能加载) enabled=yes 加入到开机自启当中
[root@lpj1 ansible]# ansible all -m service -a "name=httpd state=started"
[root@lpj1 ansible]# ansible all -m shell -a "netstat -anput | grep httpd"
192.168.20.20 | SUCCESS | rc=0 >>
tcp6 0 0 :::80 :::* LISTEN 13769/httpd
192.168.20.30 | SUCCESS | rc=0 >>
tcp6 0 0 :::80 :::* LISTEN 13662/httpd
[root@lpj1 ansible]# ansible all -m service -a "name=httpd state=stopped"
[root@lpj1 ansible]# ansible all -m shell -a "netstat -anput | grep httpd"
192.168.20.20 | FAILED | rc=1 >>
non-zero return code
192.168.20.30 | FAILED | rc=1 >>
non-zero return code
[root@lpj1 ansible]# ansible all -m service -a "name=httpd state=restarted"
[root@lpj1 ansible]# ansible all -m service -a "name=httpd state=reloaded"
[root@lpj1 ansible]# ansible all -m service -a "name=httpd enabled=yes"
[root@lpj1 ansible]# ansible all -m shell -a "systemctl is-enabled httpd"
192.168.20.20 | SUCCESS | rc=0 >>
enabled
192.168.20.30 | SUCCESS | rc=0 >>
enabled
ansible常用模块之 file 管理远程主机上的文件或者目录
参数 path指定路径 如果远程主机上没有该文件名 则创建
state 创建的类型 touch文件 directory 目录 link软链接 hard硬链接
创建软硬链接 必须写绝对路径 src 远程主机上的源文件 path(dest)远程主机上的链接文件
[root@lpj1 ansible]# ansible all -m file -a "state=touch path=/usr/src/heihei"
192.168.20.30 | SUCCESS => {
"changed": true,
"dest": "/usr/src/heihei",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 0,
"state": "hard",
"uid": 0
}
192.168.20.20 | SUCCESS => {
"changed": true,
"dest": "/usr/src/heihei",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 0,
"state": "hard",
"uid": 0
}
[root@lpj1 ansible]# ansible all -m file -a "state=directory path=/usr/src/qq"
192.168.20.30 | SUCCESS => {
"changed": false,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/usr/src/qq",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 6,
"state": "directory",
"uid": 0
}
192.168.20.20 | SUCCESS => {
"changed": false,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/usr/src/qq",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 6,
"state": "directory",
"uid": 0
}
[root@lpj1 ansible]# ansible all -m file -a "state=link src=/usr/src/qq path=/usr/src/ee"
192.168.20.30 | SUCCESS => {
"changed": false,
"dest": "/usr/src/ee",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 11,
"src": "/usr/src/qq",
"state": "link",
"uid": 0
}
192.168.20.20 | SUCCESS => {
"changed": false,
"dest": "/usr/src/ee",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 11,
"src": "/usr/src/qq",
"state": "link",
"uid": 0
}
[root@lpj1 ansible]# ansible all -m file -a "state=hard src=/usr/src/heihei path=/usr/src/ttt"
192.168.20.20 | SUCCESS => {
"changed": false,
"dest": "/usr/src/ttt",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 0,
"src": "/usr/src/heihei",
"state": "hard",
"uid": 0
}
192.168.20.30 | SUCCESS => {
"changed": false,
"dest": "/usr/src/ttt",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 0,
"src": "/usr/src/heihei",
"state": "hard",
"uid": 0
}
owner 修改或指定属主
group 修改或指定属组
mode 修改或指定权限
[root@lpj1 ansible]# ansible all -m file -a "path=/yyy state=touch mode=777 owner=rr group=rr"
192.168.20.20 | SUCCESS => {
"changed": true,
"dest": "/yyy",
"gid": 1003,
"group": "rr",
"mode": "0777",
"owner": "rr",
"secontext": "unconfined_u:object_r:etc_runtime_t:s0",
"size": 0,
"state": "file",
"uid": 1003
}
192.168.20.30 | SUCCESS => {
"changed": true,
"dest": "/yyy",
"gid": 1003,
"group": "rr",
"mode": "0777",
"owner": "rr",
"secontext": "unconfined_u:object_r:etc_runtime_t:s0",
"size": 0,
"state": "file",
"uid": 1003
}
[root@lpj1 ansible]# ansible all -m shell -a "ls -l /yyy"
192.168.20.20 | SUCCESS | rc=0 >>
-rwxrwxrwx. 1 rr rr 0 Jun 11 21:32 /yyy
192.168.20.30 | SUCCESS | rc=0 >>
-rwxrwxrwx. 1 rr rr 0 Jun 11 16:18 /yyy
[root@lpj1 ansible]# ansible all -m file -a "path=/yyy mode=755"
192.168.20.20 | SUCCESS => {
"changed": true,
"gid": 1003,
"group": "rr",
"mode": "0755",
"owner": "rr",
"path": "/yyy",
"secontext": "unconfined_u:object_r:etc_runtime_t:s0",
"size": 0,
"state": "file",
"uid": 1003
}
192.168.20.30 | SUCCESS => {
"changed": true,
"gid": 1003,
"group": "rr",
"mode": "0755",
"owner": "rr",
"path": "/yyy",
"secontext": "unconfined_u:object_r:etc_runtime_t:s0",
"size": 0,
"state": "file",
"uid": 1003
}
[root@lpj1 ansible]# ansible all -m shell -a "ls -l /yyy"
192.168.20.30 | SUCCESS | rc=0 >>
-rwxr-xr-x. 1 rr rr 0 Jun 11 16:18 /yyy
192.168.20.20 | SUCCESS | rc=0 >>
-rwxr-xr-x. 1 rr rr 0 Jun 11 21:32 /yyy
[root@lpj1 ansible]# ansible all -m file -a "path=/yyy owner=root"
192.168.20.30 | SUCCESS => {
"changed": true,
"gid": 1003,
"group": "rr",
"mode": "0755",
"owner": "root",
"path": "/yyy",
"secontext": "unconfined_u:object_r:etc_runtime_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
192.168.20.20 | SUCCESS => {
"changed": true,
"gid": 1003,
"group": "rr",
"mode": "0755",
"owner": "root",
"path": "/yyy",
"secontext": "unconfined_u:object_r:etc_runtime_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
[root@lpj1 ansible]# ansible all -m shell -a "ls -l /yyy"
192.168.20.30 | SUCCESS | rc=0 >>
-rwxr-xr-x. 1 root rr 0 Jun 11 16:18 /yyy
192.168.20.20 | SUCCESS | rc=0 >>
-rwxr-xr-x. 1 root rr 0 Jun 11 21:32 /yyy
[root@lpj1 ansible]# ansible all -m file -a "path=/yyy mode=7777"
192.168.20.20 | SUCCESS => {
"changed": true,
"gid": 1003,
"group": "rr",
"mode": "07777",
"owner": "root",
"path": "/yyy",
"secontext": "unconfined_u:object_r:etc_runtime_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
192.168.20.30 | SUCCESS => {
"changed": true,
"gid": 1003,
"group": "rr",
"mode": "07777",
"owner": "root",
"path": "/yyy",
"secontext": "unconfined_u:object_r:etc_runtime_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
[root@lpj1 ansible]# ansible all -m shell -a "ls -l /yyy"
192.168.20.30 | SUCCESS | rc=0 >>
-rwsrwsrwt. 1 root rr 0 Jun 11 16:18 /yyy
192.168.20.20 | SUCCESS | rc=0 >>
-rwsrwsrwt. 1 root rr 0 Jun 11 21:32 /yyy
删除文件或目录
state=absent
[root@lpj1 ansible]# ansible all -m file -a "path=/yyy state=absent"
192.168.20.20 | SUCCESS => {
"changed": true,
"path": "/yyy",
"state": "absent"
}
192.168.20.30 | SUCCESS => {
"changed": true,
"path": "/yyy",
"state": "absent"
}
-- ansible常用模块之cron 在远程主机上添加计划任务
参数
minute 分钟
hour 小时
day 天
mouth 月
weekday 周
job 执行的命令
name 对计划任务的命名
special_time=hourly 每小时
10 8 * * * echo xixi
[root@lpj1 ansible]# ansible all -m cron -a "name=one hour=8 minute=10 job='echo xixi'"
192.168.20.30 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"one"
]
}
192.168.20.20 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"one"
]
}
[root@lpj1 ansible]# ansible all -m cron -a "name=one hour=8 minute=10 job='echo xixi'"
192.168.20.30 | SUCCESS => {
"changed": false,
"envs": [],
"jobs": [
"one"
]
}
192.168.20.20 | SUCCESS => {
"changed": false,
"envs": [],
"jobs": [
"one"
]
}
root@lpj1 ansible]# ansible all -m shell -a "crontab -l"
192.168.20.20 | SUCCESS | rc=0 >>
#Ansible: one
10 8 * * * echo xixi
192.168.20.30 | SUCCESS | rc=0 >>
#Ansible: one
10 8 * * * echo xixi
[root@lpj1 ansible]# ansible all -m shell -a "crontab -r"
192.168.20.20 | SUCCESS | rc=0 >>
192.168.20.30 | SUCCESS | rc=0 >>
ansible常用模块之lineinfile 用来给文件中添加内容 或者修改文件中的内容
参数:regexp 正则匹配 ^…… ……$
line 将匹配的内容进行替换
line 单独使用 是在文件的最后添加内容
[root@lpj1 ansible]# ansible all -m file -a "name=/oo state=touch"
192.168.20.20 | SUCCESS => {
"changed": true,
"dest": "/oo",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:etc_runtime_t:s0",
"size": 18,
"state": "file",
"uid": 0
}
192.168.20.30 | SUCCESS => {
"changed": true,
"dest": "/oo",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:etc_runtime_t:s0",
"size": 18,
"state": "file",
"uid": 0
}
[root@lpj1 ansible]# ansible all -m shell -a "echo -e '111111\n222222\n33333' > /oo"
192.168.20.20 | SUCCESS | rc=0 >>
192.168.20.30 | SUCCESS | rc=0 >>
[root@lpj1 ansible]# ansible all -m shell -a "cat /oo"
192.168.20.30 | SUCCESS | rc=0 >>
111111
222222
33333
192.168.20.20 | SUCCESS | rc=0 >>
111111
222222
33333
[root@lpj1 ansible]# ansible all -m lineinfile -a "line='44444' path=/oo"
192.168.20.20 | SUCCESS => {
"backup": "",
"changed": true,
"msg": "line added"
}
192.168.20.30 | SUCCESS => {
"backup": "",
"changed": true,
"msg": "line added"
}
[root@lpj1 ansible]# ansible all -m shell -a "cat /oo"
192.168.20.20 | SUCCESS | rc=0 >>
111111
222222
33333
44444
192.168.20.30 | SUCCESS | rc=0 >>
111111
222222
33333
44444
[root@lpj1 ansible]# ansible all -m lineinfile -a "regexp="^2" line='5555' path=/oo"
192.168.20.30 | SUCCESS => {
"backup": "",
"changed": true,
"msg": "line replaced"
}
192.168.20.20 | SUCCESS => {
"backup": "",
"changed": true,
"msg": "line replaced"
}
[root@lpj1 ansible]# ansible all -m shell -a "cat /oo"
192.168.20.20 | SUCCESS | rc=0 >>
111111
5555
33333
44444
192.168.20.30 | SUCCESS | rc=0 >>
111111
5555
33333
44444
insertbefore 在匹配行的前面添加内容
insertafter 在匹配行的之后添加
[root@lpj1 ansible]# ansible all -m lineinfile -a "insertbefore='^4' line='22222' path=/oo"
192.168.20.30 | SUCCESS => {
"backup": "",
"changed": true,
"msg": "line added"
}
192.168.20.20 | SUCCESS => {
"backup": "",
"changed": true,
"msg": "line added"
}
[root@lpj1 ansible]# ansible all -m shell -a "cat /oo"
192.168.20.30 | SUCCESS | rc=0 >>
111111
5555
33333
22222
44444
192.168.20.20 | SUCCESS | rc=0 >>
111111
5555
33333
22222
44444
[root@lpj1 ansible]# ansible all -m lineinfile -a "insertafter='^5' line='33333' path=/oo"
192.168.20.20 | SUCCESS => {
"backup": "",
"changed": false,
"msg": ""
}
192.168.20.30 | SUCCESS => {
"backup": "",
"changed": false,
"msg": ""
}
[root@lpj1 ansible]# ansible all -m shell -a "cat /oo"
192.168.20.20 | SUCCESS | rc=0 >>
111111
5555
33333
22222
44444
192.168.20.30 | SUCCESS | rc=0 >>
111111
5555
33333
22222
44444
playbook 剧本
playbook 是由多个模块组成的
yaml语言编写的 集合性语言 c语言 python ruby perl
后缀 .yaml .yml
语法格式
--- 代表yaml文件
区分大小写
层级是通过缩进 使用空格
#注释
数据类型
集合
列表
字符串
数据
对象
yaml语言编写的playbook剧本中 特殊字符的含义
tasks 任务
handlers 触发器
variables 变量
ansible的变量
1.本身就有很多的变量 这些变量是可以直接使用的
setup 查看远程主机上的信息 查看自带的变量
参数 filter 过滤
[root@localhost ~]# ansible all -m setup
[root@localhost ~]# ansible all -m setup -a "filter=ansible_all_ipv4_addresses"
2.可以通过命令来设置变量 -e
--- #代表yaml文件
- hosts: peng #主机清单
remote_user: root #用户
tasks: #任务
- name: touch file #命名
shell: echo {{ var }} > haha #创建文件
[root@lpj1 ansible]# ansible-playbook -e "var=haha" test.yaml
PLAY [peng] **************************************************************************
TASK [Gathering Facts] ***************************************************************
ok: [192.168.20.20]
ok: [192.168.20.30]
TASK [touch file] ********************************************************************
changed: [192.168.20.20]
changed: [192.168.20.30]
PLAY RECAP ***************************************************************************
192.168.20.20 : ok=2 changed=1 unreachable=0 failed=0
192.168.20.30 : ok=2 changed=1 unreachable=0 failed=0
[root@lpj1 ansible]# ansible all -m shell -a "cat haha"
192.168.20.30 | SUCCESS | rc=0 >>
haha
192.168.20.20 | SUCCESS | rc=0 >>
haha
3.可以直接将变量写到剧本当中
[root@lpj1 ansible]# vim test.yaml
---
- hosts:peng
remote_user: root
vars:
var: hehe
tasks:
- name: touch file
shell: echo {{ var }} > haha
[root@lpj1 ansible]# ansible-playbook test.yaml
PLAY [peng] **************************************************************************
TASK [Gathering Facts] ***************************************************************
ok: [192.168.20.30]
ok: [192.168.20.20]
TASK [touch file] ********************************************************************
changed: [192.168.20.20]
changed: [192.168.20.30]
PLAY RECAP ***************************************************************************
192.168.20.20 : ok=2 changed=1 unreachable=0 failed=0
192.168.20.30 : ok=2 changed=1 unreachable=0 failed=0
[root@lpj1 ansible]# ansible all -m shell -a "cat haha"
192.168.20.20 | SUCCESS | rc=0 >>
hehe
192.168.20.30 | SUCCESS | rc=0 >>
hehe
[root@lpj1 ansible]#