本章主要介绍ansible中最常见模块的使用。
目录
- ansible 机器名 ‐m 模块× ‐a "模块的参数”?
对被管理机器执行不同的操作,只需要调用不同的模块就可以了。ansible中内置了很多的模块,可以通过ansible-doc -l查看系统中所有的模块。?
[bdqn@rhel01 ~]$ ansible-doc -l
a10_server Manage A10 Networks AX/SoftAX/Thunder/vThunder devices' server object
a10_server_axapi3 Manage A10 Networks AX/SoftAX/Thunder/vThunder devices
a10_service_group Manage A10 Networks AX/SoftAX/Thunder/vThunder devices' service groups
a10_virtual_server Manage A10 Networks AX/SoftAX/Thunder/vThunder devices' virtual servers
aci_aaa_user Manage AAA users (aaa:User)
aci_aaa_user_certificate Manage AAA user certificates (aaa:UserCert)
aci_access_port_block_to_access_port Manage port blocks of Fabric interface policy leaf profile interface selectors (infra:HPor...
aci_access_port_to_interface_policy_leaf_profile Manage Fabric interface policy leaf profile interface selectors (infra:HPortS, infra:RsAcc...
aci_access_sub_port_block_to_access_port Manage sub port blocks of Fabric interface policy leaf profile interface selectors (infra:...
aci_aep Manage attachable Access Entity Profile (AEP) objects (infra:AttEntityP, infra:ProvAcc)
aci_aep_to_domain Bind AEPs to Physical or Virtual Domains (infra:RsDomP)
aci_ap Manage top level Application Profile (AP) objects (fv:Ap)
按【Enter】键会一行一行地往下显示,按空格键会一页一页地往下显示,按【q】键退出。?
不同的模块有不同的参数,如果要查看某个模块的参数,可以通过如下语法来查看。?
- ansible‐doc 模块名?
ansible中有很多模块,每个模块也有很多参数,我们是不可能把所有的模块、每个模块的所有参数都掌握的。所以,下面我们只讲解最常见的模块及这些模块中最常见的参数的使用方法。?
shell模块可以在远端执行操作系统命令,具体用法如下。?
- ansible 主机组 ‐m shell ‐a "系统命令"?
练习1:在server2上执行hostname命令,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "hostname"
server2 | CHANGED | rc=0 >>
rhel02
[bdqn@rhel01 ~]$
这里rc=0的意思是执行此命令之后的返回值为0,rc的意思是returm code(返回值),为0说明正确执行了,非零说明没有正确执行。?
练习2:在 server2上执行一个错误的命令,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "hostnamexxx"
server2 | FAILED | rc=127 >>
/bin/sh: hostnamexxx: 未找到命令non-zero return code
[bdqn@rhel01 ~]$
这里rc=127的意思是执行此命令之后的返回值为127,非零说明没有正确执行。
file模块用于创建和删除文件/目录,修改文件/目录属性,其常见的参数包括以下几个。?
练习1:在server2上创建一个文件/opt/hosts,并设置所有者为root,所属组为tom,权限为444,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m file -a "path=/opt/hosts owner=root group=tom mode=444 state=touch"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"dest": "/opt/hosts",
"gid": 1001,
"group": "tom",
"mode": "0444",
"owner": "root",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
[bdqn@rhel01 ~]$
需要注意的是,此处用path指定的文件,替换成name也是可以的,即 name=/opt/hosts。
查看文件的属性,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "ls -l /opt/hosts"
server2 | CHANGED | rc=0 >>
-r--r--r--. 1 root tom 0 12月 18 10:18 /opt/hosts
[bdqn@rhel01 ~]$
练习2:为/opt/hosts创建一个软链接/opt/hosts123,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m file -a "src=/opt/hosts dest=/opt/hosts123 state=link"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"dest": "/opt/hosts123",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 10,
"src": "/opt/hosts",
"state": "link",
"uid": 0
}
[bdqn@rhel01 ~]$
验证,命令如下?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "ls -l /opt/"
server2 | CHANGED | rc=0 >>
总用量 0
-r--r--r--. 1 root tom 0 12月 18 10:18 hosts
lrwxrwxrwx. 1 root root 10 12月 18 10:42 hosts123 -> /opt/hosts
[bdqn@rhel01 ~]$
练习3:删除/opt/hosts123,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m file -a "path=/opt/hosts123 state=absent"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"path": "/opt/hosts123",
"state": "absent"
}
[bdqn@rhel01 ~]$
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "ls -l /opt/"
server2 | CHANGED | rc=0 >>
总用量 0
-r--r--r--. 1 root tom 0 12月 18 10:18 hosts
[bdqn@rhel01 ~]$
练习4:创建目录/op/xx,上下文设置为default_t,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m file -a "path=/opt/xx setype=default_t state=directory"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/opt/xx",
"secontext": "unconfined_u:object_r:default_t:s0",
"size": 6,
"state": "directory",
"uid": 0
}
[bdqn@rhel01 ~]$
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "ls -dZ /opt/xx"
server2 | CHANGED | rc=0 >>
unconfined_u:object_r:default_t:s0 /opt/xx
[bdqn@rhel01 ~]$
练习5:把/opt/hosts的权限改成000,所有者改成tom,所属组改成users,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m file -a "path=/opt/hosts owner=tom group=users mode=000"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"gid": 100,
"group": "users",
"mode": "0000",
"owner": "tom",
"path": "/opt/hosts",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 0,
"state": "file",
"uid": 1001
}
[bdqn@rhel01 ~]$
验证,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "ls -l /opt/"
server2 | CHANGED | rc=0 >>
总用量 0
----------. 1 tom users 0 12月 18 10:18 hosts
drwxr-xr-x. 2 root root 6 12月 18 10:46 xx
[bdqn@rhel01 ~]$
注意:指定文件时用name或 path都是可以的。?
清空server2 上/opt中所有的内容,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "rm -rf /opt/*"
[WARNING]: Consider using the file module with state=absent rather than running 'rm'. If you need to use command because file is insufficient you can add
'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.
server2 | CHANGED | rc=0 >>
[bdqn@rhel01 ~]$
上面的WARNING可以忽略不管,如果不想显示此消息,则在ansible.cfg的[defaults]字段下添加 command_warnings=False即可。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "rm -rf /opt/*"
server2 | CHANGED | rc=0 >>
[bdqn@rhel01 ~]$
copy用于把本地的文件拷贝到被管理机器,语法如下。
- ansible 主机组 ‐m copy ‐a "src=/path1/file1 dest=path2/"?
作用是把本地的/path1/file1拷贝到目的主机的/path2中。?
copy模块常见的参数包括以下几个。?
练习1:把本地的文件/etc/ansible/hosts拷贝到目标机器的/opt目录中,并设置权限为 000,所有者为tom,命令如下。
[bdqn@rhel01 ~]$ ansible server2 -m copy -a "src=/etc/ansible/hosts dest=/opt/ mode=000 owner=tom"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "da996f1a52dbae3b6b43a6c50d761e4ed5ec9a9f",
"dest": "/opt/hosts",
"gid": 0,
"group": "root",
"md5sum": "1564b951dc7c8511c6f9ee842653c541",
"mode": "0000",
"owner": "tom",
"secontext": "system_u:object_r:usr_t:s0",
"size": 1016,
"src": "/home/bdqn/.ansible/tmp/ansible-tmp-1702868727.7016883-2991-275806566218902/source",
"state": "file",
"uid": 1001
}
[bdqn@rhel01 ~]$
验证,命令如下?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "ls -l /opt/"
server2 | CHANGED | rc=0 >>
总用量 4
----------. 1 tom root 1016 12月 18 11:05 hosts
[bdqn@rhel01 ~]$
copy模块也可以利用content参数往某个文件中写内容,如果此文件不存在则会创建出来。?
练习2:在被管理机器的/opt目录中创建11.txt,内容为123123,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m copy -a 'content="123123" dest=/opt/11.txt'
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "601f1889667efaebb33b8c12572835da3f027f78",
"dest": "/opt/11.txt",
"gid": 0,
"group": "root",
"md5sum": "4297f44b13955235245b2497399d7a93",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:usr_t:s0",
"size": 6,
"src": "/home/bdqn/.ansible/tmp/ansible-tmp-1702868878.2056031-3054-148973904145530/source",
"state": "file",
"uid": 0
}
[bdqn@rhel01 ~]$
验证/opt/11.txt的内容,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "cat /opt/11.txt"
server2 | CHANGED | rc=0 >>
123123
[bdqn@rhel01 ~]$
fetch用于把文件从被管理机器拷贝到本机当前目录中,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "cat /opt/11.txt"
server2 | CHANGED | rc=0 >>
123123
[bdqn@rhel01 ~]$ ansible server2 -m fetch -a "src=/opt/hosts dest=."
server2 | CHANGED => {
"changed": true,
"checksum": "da996f1a52dbae3b6b43a6c50d761e4ed5ec9a9f",
"dest": "/home/bdqn/server2/opt/hosts",
"md5sum": "1564b951dc7c8511c6f9ee842653c541",
"remote_checksum": "da996f1a52dbae3b6b43a6c50d761e4ed5ec9a9f",
"remote_md5sum": null
}
[bdqn@rhel01 ~]$
查看,命令如下。?
ansible.cfg hosts server2
[bdqn@rhel01 ~]$ tree server2/
server2/
└── opt
└── hosts
1 directory, 1 file
[bdqn@rhel01 ~]$
利用yum_repository设置yum 源,一个标准的repo配置文件如下所示。?
[root@rhel01 ~]# cat /etc/yum.repos.d/aa.repo
[aa]
name=aa
baseurl=file:///mnt/AppStream
enabled=1
gpgcheck=1
gpgkey=ftp://192.168.23.31/dvd/RPM‐GPG‐KEY‐redhat‐release
其中门中的名称用于区分不同的yum 源。这里参数的含义如下。
对于yum_repository模块来说,常见的参数包括以下几个。
练习:给server2配置yum源,地址是ftp://192.168.23.31/dvd/AppStream.
[bdqn@rhel01 ~]$ ansible server2 -m yum_repository -a "name=app description='this is appstream' baseurl=ftp://192.168.23.31/dvd/AppStream"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"repo": "app",
"state": "present"
}
[bdqn@rhel01 ~]$
执行之后的效果如下
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "ls -l /etc/yum.repos.d/"
server2 | CHANGED | rc=0 >>
总用量 12
-rw-r--r--. 1 root root 150 12月 18 11:30 aa.repo
-rw-r--r--. 1 root root 76 12月 18 11:51 app.repo
-rw-r--r--. 1 root root 358 12月 15 12:30 redhat.repo
[bdqn@rhel01 ~]$
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "cat /etc/yum.repos.d/app.repo"
server2 | CHANGED | rc=0 >>
[app]
baseurl = ftp://192.168.23.31/dvd/AppStream
name = this is appstream
[bdqn@rhel01 ~]$
给server2配置第二个yum源,地址是 ftp://192.168.23.31/dvd/BaseOS,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m yum_repository -a "name=baseos description='this is baseos' baseurl=ftp://192.168.23.31/dvd/BaseOS"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"repo": "baseos",
"state": "present"
}
[bdqn@rhel01 ~]$
yum模块常见的参数包括以下几个。
①present或installed:用于安装软件包,没有指定state时的默认值就是installed。?
②absent或removed:用于卸载软件包。
③latest:用于更新。?
注意:yum模块可以用package模块替代,用于在 Ubuntu等其他系统上管理软件包。?
练习1:在server2上安装vsftpd,命令如下。
[bdqn@rhel01 ~]$ ansible server2 -m yum -a "name=vsftpd state=installed"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: vsftpd-3.0.3-34.el8.x86_64"
]
}
[bdqn@rhel01 ~]$
验证,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "rpm -qa | grep vsftpd"
server2 | CHANGED | rc=0 >>
vsftpd-3.0.3-34.el8.x86_64
[bdqn@rhel01 ~]$
练习2:在server2上卸载vsftpd,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m yum -a "name=vsftpd state=absent"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Removed: vsftpd-3.0.3-34.el8.x86_64"
]
}
[bdqn@rhel01 ~]$
如果server2没有安装vsftpd,下面的命令就是安装,如果已经安装则更新到最新版。?
[bdqn@rhel01 ~]$ ansible server2 -m yum -a "name=vsftpd state=latest"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: vsftpd-3.0.3-34.el8.x86_64"
]
}
[bdqn@rhel01 ~]$
如果要安装组或模块,需要在组名或模块名前加@,这个模块要使用引号引起来。?
练习3:安装 RPM开发工具,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m yum -a "name='@RPM 开发工具' state=installed"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Group rpm-development-tools installed.",
"Installed: rpmdevtools-8.10-8.el8.noarch"
]
}
[bdqn@rhel01 ~]$
可以通过systemctl对服务进行启动、重启、关闭等操作,在ansible中可以调用service模块来实现对服务的管理,service模块常见的参数包括以下几个。?
首先判断server2上的vsftpd是否启动,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "systemctl is-active vsftpd"
server2 | FAILED | rc=3 >>
inactivenon-zero return code
[bdqn@rhel01 ~]$
这里返回值为3(rc=3),说明server2上的vsftpd没有启动。?
练习:启动vsftpd并设置开机自动启动,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m service -a "name=vsftpd enabled=yes state=started"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
验证命令如下?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "systemctl is-active vsftpd"
server2 | CHANGED | rc=0 >>
active
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "systemctl is-enabled vsftpd"
server2 | CHANGED | rc=0 >>
enabled
[bdqn@rhel01 ~]$
或者到 server2上验证,命令如下。?
[root@rhel02 ~]# systemctl is-active vsftpd
active
[root@rhel02 ~]# systemctl is-enabled vsftpd
enabled
[root@rhel02 ~]#
在 ansible中如果对分区进行管理,使用的是parted模块,parted模块常见的参数包括以下几个。?
自行在server2上新添加一块类型为SCSI、大小为20G的硬盘,命令如下。?
[root@rhel02 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
sr0 11:0 1 10.2G 0 rom
nvme0n1 259:0 0 100G 0 disk
├─nvme0n1p1 259:1 0 1G 0 part /boot
├─nvme0n1p2 259:2 0 1G 0 part [SWAP]
└─nvme0n1p3 259:3 0 98G 0 part /
[root@rhel02 ~]#
练习1:在server2上对/dev//sda创建一个大小为2GiB的分区/dev/sda1,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m parted -a "device=/dev/sda number=1 part_end=2GiB state=present"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"disk": {
"dev": "/dev/sda",
"logical_block": 512,
"model": "VMware, VMware Virtual S",
"physical_block": 512,
"size": 20971520.0,
"table": "msdos",
"unit": "kib"
},
"partitions": [
{
"begin": 1024.0,
"end": 2097152.0,
"flags": [],
"fstype": "",
"name": "",
"num": 1,
"size": 2096128.0,
"unit": "kib"
}
],
"script": "unit KiB mklabel msdos mkpart primary 0% 2GiB"
}
[bdqn@rhel01 ~]$
此例是对/dev/sda创建第一个分区,因为从硬盘头开始,所以不需要指定part_start,此分区到2GB位置结束。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "lsblk"
server2 | CHANGED | rc=0 >>
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
└─sda1 8:1 0 2G 0 part
sr0 11:0 1 10.2G 0 rom
nvme0n1 259:0 0 100G 0 disk
├─nvme0n1p1 259:1 0 1G 0 part /boot
├─nvme0n1p2 259:2 0 1G 0 part [SWAP]
└─nvme0n1p3 259:3 0 98G 0 part /
[bdqn@rhel01 ~]$
练习2:在server2上对/dev/sda创建一个大小为2GB的分区/dev/sda2,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m parted -a "device=/dev/sda number=2 part_start=2GiB part_end=4GiB state=present"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"disk": {
"dev": "/dev/sda",
"logical_block": 512,
"model": "VMware, VMware Virtual S",
"physical_block": 512,
"size": 20971520.0,
"table": "msdos",
"unit": "kib"
},
此例是对/dev/sda创建第二个分区,从2GiB位置开始,到4GiB位置结束。?
在server2上查看分区,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "lsblk"
server2 | CHANGED | rc=0 >>
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 2G 0 part
└─sda2 8:2 0 2G 0 part
sr0 11:0 1 10.2G 0 rom
nvme0n1 259:0 0 100G 0 disk
├─nvme0n1p1 259:1 0 1G 0 part /boot
├─nvme0n1p2 259:2 0 1G 0 part [SWAP]
└─nvme0n1p3 259:3 0 98G 0 part /
[bdqn@rhel01 ~]$
练习3:删除server2上的/dev/sda2,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m parted -a "device=/dev/sda number=2 state=absent"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
验证,命令如下?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "lsblk"
server2 | CHANGED | rc=0 >>
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
└─sda1 8:1 0 2G 0 part
sr0 11:0 1 10.2G 0 rom
nvme0n1 259:0 0 100G 0 disk
├─nvme0n1p1 259:1 0 1G 0 part /boot
├─nvme0n1p2 259:2 0 1G 0 part [SWAP]
└─nvme0n1p3 259:3 0 98G 0 part /
[bdqn@rhel01 ~]$
可以看到,/dev/sda2已经被删除了。?
请自行创建出/dev/sda2和/dev/sda3备用,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "lsblk"
server2 | CHANGED | rc=0 >>
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 2G 0 part
├─sda2 8:2 0 2G 0 part
└─sda3 8:3 0 2G 0 part
sr0 11:0 1 10.2G 0 rom
nvme0n1 259:0 0 100G 0 disk
├─nvme0n1p1 259:1 0 1G 0 part /boot
├─nvme0n1p2 259:2 0 1G 0 part [SWAP]
└─nvme0n1p3 259:3 0 98G 0 part /
[bdqn@rhel01 ~]$
分区创建好之后,需要对分区进行格式化操作,格式化的模块为filesystem,filesystem 模块常见的参数包括以下几个。?
练习:把 server2上的/dev/sda3格式化为XFS文件系统,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m filesystem -a "dev=/dev/sda3 fstype=xfs"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true
}
[bdqn@rhel01 ~]$
如果想重新格式化,需要加上 force选项,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m filesystem -a "dev=/dev/sda3 fstype=xfs force=yes"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true
}
[bdqn@rhel01 ~]$
格式化之后就需要挂载分区,挂载用的是mount模块,mount模块常见的参数包括以下几个。?
①mounted:挂载的同时,也会写入/etc/fstab。
②present:只是写入/etc/fstab,但当前并没有挂载。
③unmounted:只卸载,并不会把条目从/etc/fstab中删除。
④absent:卸载并从/etc/fstab中删除。?
练习1:把server2上的/dev/sda3挂载到/123目录上,挂载选项为只读,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "mkdir /123"
server2 | CHANGED | rc=0 >>
[bdqn@rhel01 ~]$ ansible server2 -m mount -a "src=/dev/sda3 path=/123 state=mounted fstype=xfs opts=defaults,ro"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"dump": "0",
"fstab": "/etc/fstab",
"fstype": "xfs",
"name": "/123",
"opts": "defaults,ro",
"passno": "0",
"src": "/dev/sda3"
}
[bdqn@rhel01 ~]$
这里指定了挂载选项为defaults,ro,多个选项用逗号隔开。?
验证,命令如下。
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "df -Th | grep sda3"
server2 | CHANGED | rc=0 >>
/dev/sda3 xfs 2.0G 256K 2.0G 1% /123
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "grep sda3 /etc/fstab"
server2 | CHANGED | rc=0 >>
/dev/sda3 /123 xfs defaults,ro 0 0
[bdqn@rhel01 ~]$
因为挂载时state的值是mounted,所以不仅把/dev/sda3挂载了,也写人/etc/fstab 了。?
练习2:在server2上卸载并从/etc/fstab中删除/dev/sda3,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m mount -a "src=/dev/sda3 path=/123 state=absent"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"dump": "0",
"fstab": "/etc/fstab",
"name": "/123",
"opts": "defaults",
"passno": "0",
"src": "/dev/sda3"
}
[bdqn@rhel01 ~]$
注意:如果卸载,path是一定要指定的,src指定不指定都无所谓。?
使用lvg模块管理卷组,此模块常见的参数包括以下几个。
练习1:在server2上创建名称为vg0的卷组,所使用的分区为/dev/sda1和/dev/sda2/pesize指定为16M。
先确认server2上不存在任何PV 和VG,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "vgs"
server2 | CHANGED | rc=0 >>
[bdqn@rhel01 ~]$
开始创建vg0,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m lvg -a "pvs=/dev/sda1,/dev/sda2 vg=vg0 pesize=16 state=present"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true
}
[bdqn@rhel01 ~]$
这里如果不指定pesize选项,则默认为4。?
验证,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "vgs"
server2 | CHANGED | rc=0 >>
VG #PV #LV #SN Attr VSize VFree
vg0 2 0 0 wz--n- <3.97g <3.97g
[bdqn@rhel01 ~]$
练习2:删除卷组 vg0,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m lvg -a "vg=vg0 pesize=16 state=absent"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true
}
[bdqn@rhel01 ~]$
验证,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "vgs"
server2 | CHANGED | rc=0 >>
[bdqn@rhel01 ~]$
可以看到,vg0已经没有了。?
请使用ansible server2 -m lvg -a "pvs=ldev/sdb1,/dev/sdb2 vg-vg0 pesize=16 state-present"命令再次把vg0创建出来。
卷组创建好之后就要创建逻辑卷了,管理逻辑卷的模块是Ivol,lvol模块常见的参数包含以下几个。?
练习1:在server2的卷组 vg0上,创建大小为1G、名称为lv0的逻辑卷。?
先判断server2上是否存在逻辑卷,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "lvs"
server2 | CHANGED | rc=0 >>
[bdqn@rhel01 ~]$
可以看到,不存在任何逻辑卷。下面开始创建逻辑卷,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m lvol -a "vg=vg0 lv=lv0 size=1G"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": ""
}
[bdqn@rhel01 ~]$
验证,命令如下?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "lvs"
server2 | CHANGED | rc=0 >>
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv0 vg0 -wi-a----- 1.00g
[bdqn@rhel01 ~]$
可以看到,此逻辑卷已经创建出来了。?
练习2:在 server2上删除逻辑卷/dev/vg0/lv0,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m lvol -a "vg=vg0 lv=lv0 state=absent force=yes"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true
}
[bdqn@rhel01 ~]$
在ansible中可以通过firewalld模块对防火墙进行管理,firewalld模块常见的参数包括以下几个。?
①enabled:用于创建规则。
②disabled:用于删除规则。
练习1:在server2上开放服务http,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m firewalld -a "service=http immediate=yes permanent=yes state=enabled"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "Permanent and Non-Permanent(immediate) operation, Changed service http to enabled"
}
[bdqn@rhel01 ~]$
验证,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "firewall-cmd --list-all"
server2 | CHANGED | rc=0 >>
public (active)
target: default
icmp-block-inversion: no
interfaces: ens160
sources:
services: cockpit dhcpv6-client http ssh
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[bdqn@rhel01 ~]$
练习2:在server2上配置防火墙,允许tcp端口808通过,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m firewalld -a "port=808/tcp immediate=yes permanent=yes state=enabled"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "Permanent and Non-Permanent(immediate) operation, Changed port 808/tcp to enabled"
}
[bdqn@rhel01 ~]$
在server2上验证刚才的操作,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m shell -a "firewall-cmd --list-all"
server2 | CHANGED | rc=0 >>
public (active)
target: default
icmp-block-inversion: no
interfaces: ens160
sources:
services: cockpit dhcpv6-client http ssh
ports: 808/tcp
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[bdqn@rhel01 ~]$
练习3:在server2上配置防火墙,删除开放的端口808和服务http,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m firewalld -a "port=808/tcp immediate=yes permanent=yes state=disabled"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "Permanent and Non-Permanent(immediate) operation, Changed port 808/tcp to disabled"
}
[bdqn@rhel01 ~]$ ansible server2 -m firewalld -a "service=http immediate=yes permanent=yes state=disabled"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "Permanent and Non-Permanent(immediate) operation, Changed service http to disabled"
}
[bdqn@rhel01 ~]$
平时写shell脚本时,要替换文件的内容,可以直接使用vim或sed命令来进行替换操作。 在 ansible中也有相关的替换模块:replace和 lineinfile,这里先讲replace模块的使用。?
replace模块常见的参数包括以下几个。
练习1:把server2 上 /opt/aa.txt中开头为aa那行的内容替换为xx=666。?
在server2的lopt目录中创建aa.txt,内容如下。?
[root@rhel02 ~]# cat /opt/aa.txt
aa=111
bb=222
[root@rhel02 ~]#
在ansible主机上执行replace模块,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m replace -a "path=/opt/aa.txt regexp=^aa replace=xx=666"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "1 replacements made"
}
[bdqn@rhel01 ~]$
这里的意思是把server2 上/opt/aa.txt这个文件中行开头是aa的字符替换成xx=666。记住,这里只是对regexp表示的字符进行替换,替换之后的内容如下。?
[root@rhel02 ~]# cat /opt/aa.txt
xx=666=111
bb=222
[root@rhel02 ~]#
可以看到,只是把原来的字符aa替换成replace后面的内容了,并不是把这行内容替换掉。 如果想把整行内容进行替换,需要在regexp后面表示出来整行内容。?
练习2:把 server2上 /opt/aa.txt中开头为bb那行的内容替换为xx=666,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m replace -a "path=/opt/aa.txt regexp=^bb.+ replace=xx=666"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "1 replacements made"
}
[bdqn@rhel01 ~]$
这里path指明了要替换的文件,regexp的写法是^bb.+,比上面的例子中多了.+,意思是开头是bb及后续所有的字符(这就表示以bb开头的那一整行内容),替换成xx=666,运行 结果如下。?
[root@rhel02 ~]# cat /opt/aa.txt
xx=666=111
xx=666
[root@rhel02 ~]#
lineinfile模块的用法与replace基本一致,也是用于替换的,常见的参数包括以下几个。
练习:把server2 上/opt/bb.txt中开头为aa=111那行的内容替换为xx=666。
在server2上创建文件/opt/bb.txt,内容如下。?
[root@rhel02 ~]# cat /opt/bb.txt
aa=111
bb=222
[root@rhel02 ~]#
在ansible主机上执行lineinfile模块,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m lineinfile -a "path=/opt/bb.txt regexp=^aa line=xx=666"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": true,
"msg": "line replaced"
}
[bdqn@rhel01 ~]$
这里的意思是把path所指定的文件/opt/bb.txt,regexp后面跟的^aa,即以aa开头的行 (需要注意的是,这里和 replace模块有区别),替换成xx=666,运行结果如下。?
[root@rhel02 ~]# cat /opt/bb.txt
xx=666
bb=222
[root@rhel02 ~]#
总结:replace是对字符进行替换,lineinfile是对行进行替换,如果replace想对行进行替换,在regexp后面必须写上正则表达式来表示一整行内容。?
debug模块一般用于打印提示信息,类似于shell中的echo命令,其他语言如Python等中的print,其常见的参数包括以下几个。?
注意:var 和 msg 不可以同时使用。?
练习:在server2上打印“hello ansible”,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m debug -a "msg='hello ansible'"
server2 | SUCCESS => {
"msg": "hello ansible"
}
[bdqn@rhel01 ~]$
如果在本地写了一个脚本,想在所有被管理节点上执行,没有必要事先把脚本分发到被管理机器上,使用script模块即可快速实现。?
先写一个简单的脚本test1.sh 用于显示主机名,内容如下。?
[bdqn@rhel01 ~]$ cat test1.sh
#!/bin/bash
hostname
[bdqn@rhel01 ~]$ chmod +x test1.sh
[bdqn@rhel01 ~]$
下面在server2上执行,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m script -a "./test1.sh"
server2 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to server2 closed.\r\n",
"stderr_lines": [
"Shared connection to server2 closed."
],
"stdout": "rhel02\r\n",
"stdout_lines": [
"rhel02"
]
}
[bdqn@rhel01 ~]$
这样本地脚本直接在所有被管理主机上执行了。
如果对系统的组进行管理,那么可以使用group模块。group模块常见的参数包括以下几个。?
①present:用于创建组。
②absent:用于删除组。?
下面在server2上创建组 group1。
先判断server2上是否存在group1,命令如下。?
[root@rhel02 ~]# grep group1 /etc/group
[root@rhel02 ~]#
没有任何输出,说明server2上是没有group1这个组的。下面创建组group1,命令如 下。?
[bdqn@rhel01 ~]$ ansible server2 -m group -a "name=group1 state=present"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"gid": 1002,
"name": "group1",
"state": "present",
"system": false
}
[bdqn@rhel01 ~]$
然后切换到server2上进行验证,命令如下。?
[root@rhel02 ~]# grep group1 /etc/group
group1:x:1002:
[root@rhel02 ~]#
删除这个组,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m group -a "name=group1 state=absent"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"name": "group1",
"state": "absent"
}
[bdqn@rhel01 ~]$
对用户的管理可以使用user模块,对于user模块来说,常见的参数包括以下几个。
①present:用于创建用户。
②absent:用于删除用户。
下面创建一个用户lisi,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m user -a "name=lisi group=root password={{'cisco@123' | password_hash('sha512')}} state=present"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 0,
"home": "/home/lisi",
"name": "lisi",
"password": "NOT_LOGGING_PASSWORD",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1002
}
[bdqn@rhel01 ~]$
这里password=({'cisco@123' | password hash('sha512')}}的意思是,用password hash 函数调用sha512这个哈希算法对字符串 haha001进行加密。?
到server2 上验证,因为root用su命令切换到任何用户都不需要密码,所以这里先切换到 lduan用户,然后再切换到lisi用户,测试密码是不是正确。
[root@rhel02 ~]# su - bdqn
[bdqn@rhel02 ~]$ su - lisi
密码:
[lisi@rhel02 ~]$ exit
注销
[bdqn@rhel02 ~]$
下面把lisi用户删除,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m user -a "name=lisi state=absent remove=yes"
server2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"force": false,
"name": "lisi",
"remove": true,
"state": "absent"
}
[bdqn@rhel01 ~]$
这里remove=yes的意思类似于userdel 中的-r选项,删除用户的同时把家目录也删除。?
如果想获取被管理主机的系统信息,可以使用setup模块。下面获取server2上的信息,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m setup
server2 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.23.32",
"192.168.122.1"
],
"ansible_all_ipv6_addresses": [
"fe80::20c:29ff:fe71:975c"
],
"ansible_apparmor": {
"status": "disabled"
},
setup中所获取的变量叫作fact变量,这里都是以key:value的格式输出,大致结构如下。
键1:值
键2:{
子键a: 值a
子键b: 值b
...
}?
如果想获取“键1”的值,可以通过参数“filter=键”或“filter=键.子键”来过滤。例如, 要获取server2上所在机器BIOS的版本,可以通过键值ansible_bios_version来获取,命令如 下。?
[bdqn@rhel01 ~]$ ansible server2 -m setup -a "filter=ansible_bios_version"
server2 | SUCCESS => {
"ansible_facts": {
"ansible_bios_version": "6.00",
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false
}
[bdqn@rhel01 ~]$
如果想获取server上ipv4的所有信息,可以通过键值ansible default ipv4来获取,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m setup -a "filter=ansible_default_ipv4"
server2 | SUCCESS => {
"ansible_facts": {
"ansible_default_ipv4": {
"address": "192.168.23.32",
"alias": "ens160",
"broadcast": "192.168.23.255",
"gateway": "192.168.23.2",
"interface": "ens160",
"macaddress": "00:0c:29:71:97:5c",
"mtu": 1500,
"netmask": "255.255.255.0",
"network": "192.168.23.0",
"type": "ether"
},
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false
}
[bdqn@rhel01 ~]$
如果仅仅想获取IP地址信息,其他网络信息不需要,可以通过 ansible_default_ipv4的子 键来获取,命令如下。?
[bdqn@rhel01 ~]$ ansible server2 -m setup -a "filter=ansible_default_ipv4.address"
server2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false
}
[bdqn@rhel01 ~]$
不过在命令行中如果filter含有子键,结果是不会显示的,所以上面的命令没有看到IP.不 过如果把这个键写入playbook,是会显示值的,关于 playbook后面会讲。?