一、ansible详解

  • 1.1、什么是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目前已经已经被红帽官方收购,是自动化运维工具中大家认可度最高的,并且上手容易,学习简单。是每位运维工程师必须掌握的技能之一。
  • 1.2、ansible的特点

  • 部署简单,只需在主控端部署Ansible环境,被控端无需做任何操作;
  • 默认使用SSH协议对设备进行管理;(ansible和远程主机有连接是因为ssh协议 ansible要对远程主机进行免密登录 ssh–22)
  • 有大量常规运维操作模块,可实现日常绝大部分操作;
  • 配置简单、功能强大、扩展性强;
  • 支持API及自定义模块,可通过Python轻松扩展;
  • 通过Playbooks来定制强大的配置、状态管理;
  • 轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
  • 提供一个功能强大、操作性强的Web管理界面和REST API接口——AWX平台。
  • 1.3、ansible常用模块

  • 如上图所见 ansible常用模块如下列所示:
  • ansible core : ansible 自身核心模块
  • host inventory: 主机库,定义可管控的主机列表
  • connection plugins: 连接插件,一般默认基于 ssh 协议连接
  • modules:core modules (自带模块 核心) custom modules (自定义模块)
    playbooks :剧本,按照所设定编排的顺序执行完成安排任务
  • 1.4、ansible任务执行

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操作的配置文件。

  • 1.5、ansible基础命令

  • 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
  • 虚拟环境实操如下

  • 2.1、安装ansible (联网安装和脱网安装)
先展示脱网安装在做联网安装
-
- 把所需的安装包拖进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.0config file = /etc/ansible/ansible.cfgconfigured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']ansible python module location = /usr/lib/python2.7/site-packages/ansibleexecutable location = /usr/bin/ansiblepython 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.9config file = /etc/ansible/ansible.cfgconfigured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']ansible python module location = /usr/lib/python2.7/site-packages/ansibleexecutable location = /usr/bin/ansiblepython version = 2.7.5 (default, Aug  7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
  • 2.2、ansible 配置公私钥

  • 上面我们已经提到过 ansible 是基于 ssh 协议实现的,所以其配置公私钥的方式与 ssh 协议的方式相同,下面说明免密登录的原理和具体操作:
  • 免密登录的原理:免密登录的原理
    主控端生成一对密钥,将公钥传递到远程主机上,当主控端想要连接远程主机时,远程主机会随机发送一串字符给主控端,主控端将这串字符用私钥加密,返回给远程主机,远程主机使用公钥将加密的字符解密,如果和自己生成的字符一致,则验证通过,可以进行登录
主控端生成秘钥
[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: 1Now 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: 1Now 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]#
  • 2.3、ansible常用模块如下:

-- 列出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. Ithis parameter isset to `crash',the module willcause anexception.
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 >>
peng192.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
zs192.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 exists192.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
peng192.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
peng192.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 exist192.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 touch192.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 >>
aa192.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 >>
123192.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/bash192.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/bash192.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/bash192.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:test192.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:test192.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/bash192.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
peng192.168.20.20 | SUCCESS | rc=0 >>
aa
peng
zs
-- ansible常用模块之group: 创建和管理远程主机上的组参数:name  指定组   如果不存在则创建gid    修改或者指定组的gidstate=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
22222192.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
66666192.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
66666192.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
66666192.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
rr192.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
rr192.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
zs192.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 /cc192.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 code192.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 >>
enabled192.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 /yyy192.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 /yyy192.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 /yyy192.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 /yyy192.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 xixi192.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
33333192.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
44444192.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
44444192.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
44444192.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
44444192.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 >>
haha192.168.20.20 | SUCCESS | rc=0 >>
haha
3.可以直接将变量写到剧本当中
[root@lpj1 ansible]# vim test.yaml
---- hosts:pengremote_user: rootvars:var: hehetasks:- name: touch fileshell: 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 >>
hehe192.168.20.30 | SUCCESS | rc=0 >>
hehe[root@lpj1 ansible]# 

自动化运维工具——【ansible】——从菜鸟到菜鸟相关推荐

  1. 自动化运维工具----ansible

    自动化运维工具----ansible ansible是新出现的运维工具是基于Python研发的糅合了众多老牌运维工具的优点实现了批量操作系统配置.批量程序的部署.批量运行命令等功能. 主要模块以及功能 ...

  2. 自动化运维工具ansible(安装与模块介绍)

    自动化运维工具ansible(安装与模块介绍) 一.ansible运维工具概述 (一).ansible的特点 (二).ansible的原理 (三)ansible的优点 二.安装ansible 三.an ...

  3. 自动化运维工具Ansible详细部署 - 人生理想在于坚持不懈 - 51CTO技术博客

    自动化运维工具Ansible详细部署 - 人生理想在于坚持不懈 - 51CTO技术博客 自动化运维工具Ansible详细部署 - 人生理想在于坚持不懈 - 51CTO技术博客 自动化运维工具Ansib ...

  4. 自动化运维工具Ansible实战---常用模块

    Ansible默认提供了很多模块来供我们使用.在Linux中,我们可以通过 ansible-doc -l 命令查看到当前Ansible支持哪些模块,通过 ansible-doc -s [模块名] 又可 ...

  5. 自动化运维工具ansible的安装管理以及模块介绍

    自动化运维工具ansible的安装管理以及模块介绍 目录 自动化运维工具ansible的安装管理以及模块介绍 一.ansible概述 1.几种常用运维工具比较 2.Ansible简介 3.Ansibl ...

  6. 自动化运维工具-Ansible的Playbook的使用

    Playbook的使用 前言 一.Playbook是什么? 二.playbook使用场景 三.Playbook格式说明 四.Play book变量的使用 1 在主机列表定义变量 2 在playbook ...

  7. 自动化运维工具-Ansible实战指南

    Ansible实战 前言 一.Ansible简介 1.ansible是什么? 2.ansible特点 3.ansible架构 主要模块 工作流程 命令执行过程 二.Ansible 配置 1 安装ans ...

  8. 自动化运维工具——Ansible(三)——分组管理

    自动化运维工具--Ansible(三)--分组管理 1. 通过ip地址分组 1.1 写法一 1.2 写法二 2. 通过主机名分组 2.1 写法一 2.2 写法二 3. 子组 1. 通过ip地址分组 1 ...

  9. 自动化运维工具Ansible

    ansible简介: ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)的优点,实现了批量系统配置.批 ...

  10. 自动化运维工具Ansible详细部署

    一.基础介绍 ================================================================================= 1.简介 ansibl ...

最新文章

  1. 可复现的图像降噪算法总结——超赞整理
  2. java人名识别_HanLP中人名识别分析(示例代码)
  3. 一次ctf中代码审计分析
  4. JavaScript规范和工具 JSlint
  5. 函数包装器,函数私有类处理
  6. JavaScript中String的slice(),substr(),substring()三者区别
  7. 【使用注意】Boolean是final类型,值初始化后不能被更改
  8. Oracle GoldenGate简介
  9. 怎样一次性将一个word文档中所有图片保存
  10. python管道怎么使用_python中管道用法入门实例
  11. Storm实验 -- 单词计数4
  12. Eclipse 一直提示 loading descriptor for 的解决方法
  13. Atitit.java jar hell解决方案-----Djava.ext.dirs in ide envi..
  14. 三星手机双微信设置方法,三星手机如何双开微信
  15. FasterR-CNN,R-FCN,SSD,FPN,RetinaNet,YOLOv3速度和准确性比较
  16. 阿里旺旺自动回复工具开发一
  17. 学习方法--找书,背书,利器
  18. 如何排版 微信公众号「代码块」之 MarkEditor
  19. Bootstrap按钮样式
  20. 根据流程图写python程序_根的解释|根的意思|汉典“根”字的基本解释

热门文章

  1. 遇到三件好事,再兴奋也要忍住,别告诉同事,谨防小人背后捅刀子
  2. matlab 全1矩阵,matlab全为1的矩阵
  3. Endnote引用文献时期刊名称不缩写问题-论文投稿经验总结-第1期
  4. 电脑常识——host文件修改(屏蔽网站或解开屏蔽)
  5. OpenSSH算法协议漏洞修复
  6. flv.js解析与使用
  7. python编程常用英语单词_Python必备常用英语词汇1(吐血整理)
  8. 东方Project题目 1975 红魔馆爆炸了
  9. android 程序后台运行,定时刷新,像qq那样,即使程序不启动也照样运行
  10. wordcloud实例之陈奕迅歌词