ansible常用模块详解(三)
1.模块介绍
明确一点:模块的执行就类似是linux命令的一条命令,就单单的是为了执行一条语句,不是批量的操作,批量操作需要用到playbook内类似shell编写脚本进行批量。
1.1 模块的使用方法
查看ansible支持的所有模块:ansible-doc -l 然后在 ansible-doc -l | grep [ module_name ] 找到想用的模块名字 ;再使用ansible-doc -s [module_name]来查看此模块的用法,也可以使用ansible-doc help module来查看该模块更详细的信息。下面给出
官方模块列表和说明:https://docs.ansible.com/ansible/latest/modules_by_category.html
1.2 模块注意事项
关于模块的使用方法,需要注意的是"state"。很多模块都会有该选项,且其值几乎都包含有"present"和"absent",表示肯定和否定的意思,
另ansible的多数的模块都是具有幂等性的,只有极少数模块如shell和command模块不具备幂等性。所谓的幂等性是指多次执行同一个操作不会影响最终结果,ansible具有幂等性的模块在执行时,都会自动判断是否要执行。
例如: file模块创建目录时,如果创建过的目录已经创建过了,则再次或多次执行安装操作都不会真正的执行下去。
再例如:copy模块拷贝文件时,如果目标主机上已经有了完全相同的文件,则多次执行copy模块不会真正的拷贝。
2.常用模块
2.1 setup和ping 模块
功能:收集远端主机的系统信息,如网络,硬件,等
setup:
1 ansible-doc -s setup 2 - name: Gathers facts about remote hosts 3 setup: 4 gather_timeout #设置收集的主机信息默认超时时间(秒)
ping:用于ping 测主机是否连通
1 ansible-doc -s ping 2 - name: Try to connect to host, verify a usable python and return `pong' on success 3 ping:
使用方法:
1 [root@log1 ~]# ansible all -m ping -o 2 192.168.188.136 | SUCCESS => {"changed": false, "ping": "pong"}
2.2 command 和shell 模块
默认的ansible使用的摸块是command,用法是一样的,好多场景的是shell模块他们两个很像,但是shell要比command强大
1 ansible-doc -s command 2 - name: Executes a command on a remote node 3 command: 4 chdir: #在执行命令之前,先切换到指定的目录 5 creates: #判断该命令是否执行,如果指定的文件存在(支持通配符)命令不执行 6 removes: #判断该命令是否执行,如果指定的文件不存在(支持通配符)命令不执行 7 executable: #切换shell来执行指令,该执行路径必须是一个绝对路径
注意:
(1)使用Command模块执行脚本时,要注意规范,shebang机制,否则将执行失败
(2)不支持管道“|”,变量“$”,“&”,以及重定向,需使用shell模块替代
(3)在使用这2个模块的时候,因为他们没有幂等性,多次执行会导致重复执行一条语句,但是有特殊场景是不可以这样做的例如:mysql初始化的时候,执行一次就可以的了,多次执行会导致不必要的麻烦,这里就需要使用模块的creates和removes选项进行判断,但无论如何,在执行这两个模块的时候都需要考虑要执行的命令是否应该实现幂等性。
2.3 Hostname模块
功能:
1 ansible-doc -s hostname 2 - name: Manage hostname 3 hostname: 4 name: # 修改后的主机名名称
使用方法:
1 ansible all -m hostname -a “name=webserver1”
注意:
(1)Host模块不会修改/etc/hosts文件中的主机名解析,注意修改
(2)批量修改主机名时最好加变量,防止所有主机名一致
2.4 copy复制模块
功能:复制文件到远端主机
1 ansible-doc -s copy 2 - name: Copies files to remote locations 3 copy 4 owner: #设置文件的所有者 5 mode: #设置远程文件的权限。使用数值表示时不能省略第一位,如0644。# 也可以使用'u+rwx'或'u=rw,g=r,o=r'等方式设置。 6 backup=[yes|no] #在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no,默认为no 7 content: #用于替代"src",可以直接设定指定文件的值 8 dest: #必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录 9 directory_mode: #递归的设定目录的权限,默认为系统默认权限 10 force=[yes|no] #如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes 11 others: #所有的file模块里的选项都可以在这里使用 12 src: #要复制到远程主机的文件在本地的地址,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。
在这种情况下,如果路径使用"/"来结尾,则只复制目录里的内容,
如果没有使用"/"来结尾,则包含目录在内的整个内容全部复制,类似于rsync。
使用方法:
将本地的host.sh 复制到远端的/tmp 目录下,如果文件存在就优先备份。
1 [root@log1 ~]# ansible all -m copy -a "src=/root/host.sh dest=/tmp/ backup=yes" 2 192.168.188.136 | SUCCESS => { 3 "changed": true, 4 "checksum": "4080c03edf24ad1ca3a9e83c54a363236df4432b", 5 "dest": "/tmp/host.sh", 6 "gid": 0, 7 "group": "root", 8 "md5sum": "6c65510d520b68b9ef4d5f76552e8a98", 9 "mode": "0644", 10 "owner": "root", 11 "size": 21, 12 "src": "/root/.ansible/tmp/ansible-tmp-1568616290.57-158008154450274/source", 13 "state": "file", 14 "uid": 0 15 }
验证远端文件是否复制成功:
1 [root@log1 ~]# ansible all -m shell -a "ls /tmp" 2 192.168.188.136 | SUCCESS | rc=0 >> 3 host.sh ===>复制过来的文件
content 简单生成文件内容:
1 [root@log1 ~]# ansible all -m copy -a "content='test content\n' dest=/tmp/test_content.txt " 2 192.168.188.136 | SUCCESS => { 3 "changed": true, 4 "checksum": "4fe2b8dd12cd9cd6a413ea960cd8c09c25f19527", 5 "dest": "/tmp/test_content.txt", 6 "gid": 0, 7 "group": "root", 8 "md5sum": "d6eb32081c822ed572b70567826d9d9d", 9 "mode": "0644", 10 "owner": "root", 11 "size": 13, 12 "src": "/root/.ansible/tmp/ansible-tmp-1568617451.79-5160211289281/source", 13 "state": "file", 14 "uid": 0 15 } 16 17 验证文件内容: 18 [root@log1 ~]# ansible all -m shell -a "cat /tmp/test_content.txt " 19 192.168.188.136 | SUCCESS | rc=0 >> 20 test content ===>生成的文件内容
2.5 File文件模块
功能:创建目录,管理目录和文件属性。
1 ansible-doc -s file 2 - name: Sets attributes of files 3 file: 4 force=[yes|no]#需要在两种情况下强制创建软链接,一种是源文件不存在但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链, 5 group: #定义文件/目录的属组 6 mode: #定义文件/目录的权限 7 owner: #定义文件/目录的属主 8 path: #必选项,定义文件/目录的路径 9 name: #定义文件/目录的路径 (不用path的时候) 10 recurse: #递归的设置文件的属性,只对目录有效 11 src: #要被链接的源文件的路径,只应用于state=link的情况 12 dest: #被链接到的路径,只应用于state=link的情况 13 state: 14 directory: #如果目录不存在,创建目录 15 file: #即使文件不存在,也不会被创建 16 link: #创建软链接 17 hard: #创建硬链接 18 touch: #如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间 19 absent: #删除目录、文件或者取消链接文件
注意:
file模块可以递归创建目录,但是不能在不存在的目录中创建文件,只能先创建目录,再在此目录中创建文件。
使用方法:
1 创建新目录: 2 ansible all -m file -a 'name=/data state=directory' 3 创建新文件: 4 ansible all -m file -a 'name=/data/f3 state=touch' 5 删除文件: 6 ansible all -m file -a 'name=/data/f3 state=absent' 7 删除目录下的所有文件:(建议使用shell好用) 8 ansible all -m shell -a 'rm -rf /data/*' 9 创建目录: 10 ansible all -m file -a 'name=/data/dir1 state=directory' 11 删除目录: 12 ansible all -m file -a 'name=/data/dir1 state=absent' 13 创建软连接 14 ansible all -m file -a 'src=/etc/fstab dest=/data/fstab.link state=link' 15 ansible all -m file -a 'dest=/data/fstab.link state=absent' 16 创建文件指定所有者,权限: 17 ansible all -m file -a 'path=/root/a.sh owner=liych mode=755' 18 ansible all -m file -a 'src=/data/testfile dest=/data/testfile-link state=link'
2.6 Fetch 拉取文件模块
功能:拉取远端文件到本地控制端,和cop工作模式相反。
1 ansible-doc -s fetch 2 - name: Fetches a file from remote nodes 3 action: fetch 4 dest= # 本地存储拉取文件的目录。例如dest=/data,src=/var/log/messages 5 # 远程主机名192.168.188.136,则保存的路径为/data/192.168.188.136/var/log/messages 6 fail_on_missing=[yes|no] # 当设置为yes时,如果拉取的源文件不存在,则此任务失败。在2.4以前是默认为no。2.4中默认为yes 7 8 flat=[yes|no] # 允许您重写将主机名/路径/文件/文件附加到目的地的默认行为。如果dest以“/”结尾,则将使用源文件的基名称,类似于复制模块。很明显这很方便,如果文件名是唯一的。
# 显然,应该考虑多个主机拉取时的文件覆盖情况,不建议使用。 9 src= # 远程主机上的源文件。只能是文件,不支持目录。在未来的版本中可能会支持目录递归拉取。 10 validate_checksum # 获取文件后验证源和目标校验和是否匹配
使用方法:
默认拉取存的路径。
[root@log1 data]# ansible all -m fetch -a "src=/root/checkport.py dest=/data" 192.168.188.136 | SUCCESS => { "changed": true, "checksum": "2507bb0864955618080ebb8123749d256733689d", "dest": "/data/192.168.188.136/root/checkport.py", "md5sum": "31408377a8a5acf9fa69ea1f8f973038", "remote_checksum": "2507bb0864955618080ebb8123749d256733689d", "remote_md5sum": null } 检验本地是否存在: [root@log1 root]# ll /data/192.168.188.136/root/checkport.py ===》默认存格式 -rw-r--r-- 1 root root 1925 9月 16 15:58 /data/192.168.188.136/root/checkport.py ===>已经存在
指定目录存储:
需要注意的dest=/tmp/ 需要/ 为结尾,否则会报错。
指定目录储存: [root@log1 root]# ansible all -m fetch -a "src=/etc/fstab dest=/tmp/ flat=yes" 192.168.188.136 | SUCCESS => { "changed": true, "checksum": "7ea9f3eb5cc7823805111e1b08b5855718c473b5", "dest": "/tmp/fstab", "md5sum": "c1925b75df004697fc46f525a6f81656", "remote_checksum": "7ea9f3eb5cc7823805111e1b08b5855718c473b5", "remote_md5sum": null } [root@log1 root]# ll /tmp/fstab ===》指定目录存储 -rw-r--r-- 1 root root 609 9月 16 16:27 /tmp/fstab ===>已经拉取到文件
指定目录存储格式:
使用参数
调用inventory_hostname #host的主机
[root@log1 root]# ansible all -m fetch -a "src=/etc/fstab dest=/tmp/fstab-{{inventory_hostname}} flat=yes" 192.168.188.136 | SUCCESS => { "changed": true, "checksum": "7ea9f3eb5cc7823805111e1b08b5855718c473b5", "dest": "/tmp/fstab-192.168.188.136", "md5sum": "c1925b75df004697fc46f525a6f81656", "remote_checksum": "7ea9f3eb5cc7823805111e1b08b5855718c473b5", "remote_md5sum": null } [root@log1 root]# ll /tmp/fstab-192.168.188.136 ===》格式存储 fstab-192.168.188.136
注意:拉取多个文件的时候,需要将多个远端文件打包,之后再拉取。
2.7 yum 模块
ansible-doc -s yum - name: Manages packages with the `yum' package manager yum: config_file: # yum的配置文件 disable_gpg_check: # 关闭gpg_check disable_gpg_check # 安装包时禁止gpgcheck,仅在state=present或latest时生效。 disablerepo # 禁用指定的repoid,多个repoid使用逗号分隔。 enablerepo # 明确使用该repoid为源启用 exclude # 排除哪些包不安装,仅在state=present或latest时生效。 list # 类似于yum list name= # 指定安装的包名,可带上版本号.也可以传递一个url或者一个本地的rpm包的路径 state # 状态。('present'、'installed','latest')用于安装包,('absent'、'removed')用于移除已安装包。 update_cache # 强制更新yum的cache。
使用方法:
yum安装vsftpd包:(默认state=installd) 列出和ansible相关的包。 ansible all -m yum -a "list=ansible" ansible all -m yum -a ‘name=nginx’ 安装多个包用逗号隔开: ansible all -m yum -a ‘name=nginx,vsftpd’ 显示所有已安装的包: ansible all -m yum -a ‘name=vsftpd list=installd’ 卸载vsftpd包: ansible all -m yum -a ‘name=nvsftpd state=removed’ 安装从互联网下载的包: ansible all -m yum -a 'name=https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm state=present' 安装本地的包,且排除某些包不安装。 ansible all -m yum -a "name=/tmp/*.rpm exclude=*unix* state=present" 更新缓存: ansible all -m yum -a ‘update_cache=yes’ 更新缓存同时安装dstat包 ansible all -m yum -a ‘name=dstat update_cache=yes’
name=[Package name] 需要和state使用。状态。('present'、'installed','latest')用于安装包,('absent'、'removed')用于移除已安装包。在命令介绍的时候就说过,state的状态在很多模块中都会用到,需要特别注意。
2.8 service模块
功能:管理服务
ansible-doc -s service - name: Manage services. service: enabled=[yes|no] #是否开机启动 默认no name: #必选项,服务名称 pattern: #定义一个模式,如果通过status指令来查看服务的状态时,没有响应,就会通过ps指令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然在运行 sleep: #如果执行了restarted,在则stop和start之间沉睡几秒钟 state: #对当前服务执行启动,停止、重启、重新加载等操作 #(started,stopped,restarted,reloaded)
使用方法:
停止httpd服务: ansible all -m service -a ‘name=httpd state=stopped’ 开启httpd服务: ansible all -m service -a ‘name=httpd state=started’ 重新加载httod服务: ansible all -m service -a ‘name=httpd state=reloaded’ 重启httpd服务: ansible all -m service -a ‘name=httpd state=restarted’ 开启ftp服务,同时设置开机自动启动: ansible all -m service -a ‘name=vsftpd state=started enabled=yes’ 重启ftp服务: ansible all -m service -a ‘name=vsftpd state=restarted’
2.9 cron 定时任务
功能:设置管理定时任务。
ansible-doc -s cron - name: Manage cron.d and crontab entries. cron: backup=[yes|no] # 如果已设置,请在修改crontab之前创建它的备份。备份的位置由以下命令在“backup_file”变量中返回 cron_file # 自定义cron_file的文件名,使用相对路径则在/etc/cron.d中。必须同时指定user选项,文件名部分仅由大写和小写字母、数字、下划线。 user # 修改其crontab的特定用户。 minute # 分(0-59, *, */N),不写时,默认为* hour # 时(0-23, *, */N),不写时,默认为* day # 日(1-31, *, */N),不写时,默认为* month # 月(1-12, *, */N),不写时,默认为* weekday # 周(0-6 for Sunday-Saturday, *),不写时,默认为* disabled # 禁用crontab中的某个job,要求state=present env # (yes/no)设置一个环境变量,将添加在crontab的顶端。使用name和value定义变量名和值 job # 需要执行的命令。如果设置了env,则表示环境变量的值,此时job="XXXX"等价于value="XXXX"。 # 要求state=present name # 定时任务的备注名。但如果设置的是env,则name为环境变量的名称。要求state=absent # 注意,若未设置name,且state=present,则总会创建一个新job条目,而不管现有条目如何 special_time # 定时任务的别称,用于定义何时运行job条目。 # 有效值有reboot/hourly/daily/weekly/monthly/yearly/annually。 state # job或者env的状态是present(默认)还是absent。present用于创建,absent用于移除
使用方法:
1.1 计划任务存在默认crontal -l即可查看
创建计划任务:每周1,3,5,每分钟打印warning,任务名称:test ansible all -m cron -a 'minute=* weekday=1,3,5 job="/usr/bin/wall warning" name=test' 注释禁用cronname=test的计划任务:也可以用yes/no ansible all -m cron -a 'disabled=true job="/usr/bin/wall warning" name=test' 给cronname=test的计划任务去掉注释:也可以用yes/no ansible all -m cron -a 'disabled=false job="/usr/bin/wall warning" name=test' 删除计划任务: ansible all -m cron -a 'job="/usr/bin/wall warning" name=test state=absent' 查看计划任务: ansible all -m shell -a 'crontab -l'
执行过程:
root@log1 ~]# ansible all -m cron -a 'minute=* weekday=1,3,5 job="/usr/bin/wall warning" name=test' -o 192.168.188.136 | SUCCESS => {"changed": true, "envs": [], "jobs": ["test"]} [root@log1 ~]# ansible all -m shell -a 'crontab -l' 192.168.188.136 | SUCCESS | rc=0 >> #Ansible: test * * * * 1,3,5 /usr/bin/wall warning [root@log1 ~]# ansible all -m cron -a 'disabled=true job="/usr/bin/wall warning" name=test' 192.168.188.136 | SUCCESS => { "changed": true, "envs": [], "jobs": [ "test" ] } [root@log1 ~]# ansible all -m shell -a 'crontab -l' 192.168.188.136 | SUCCESS | rc=0 >> #Ansible: test #* * * * * /usr/bin/wall warning [root@log1 ~]# ansible all -m cron -a 'disabled=false job="/usr/bin/wall warning" name=test' 192.168.188.136 | SUCCESS => { "changed": true, "envs": [], "jobs": [ "test" ] } [root@log1 ~]# ansible all -m shell -a 'crontab -l' 192.168.188.136 | SUCCESS | rc=0 >> #Ansible: test * * * * * /usr/bin/wall warning [root@log1 ~]# ansible all -m cron -a 'job="/usr/bin/wall warning" name=test state=absent' 192.168.188.136 | SUCCESS => { "changed": true, "envs": [], "jobs": [] } [root@log1 ~]# ansible all -m shell -a 'crontab -l' 192.168.188.136 | SUCCESS | rc=0 >>
1.2 自定义的定时任务不能使用crontab-l查看
创建一个job,每5分钟进行一次时间同步,并且自定义cron_file。 ansible all -m cron -a 'name="ntpdate_time" job="/usr/sbin/ntpdate ntp1.aliyun.com" cron_file=ntpdate_cron user=root minute=*/5' -o 移除一个job,要求name必须匹配,需要同时指定cron_file和user。 ansible all -m cron -a 'name="ntpdate_time" state=absent cron_file=ntpdate_cron user=root' -o #查看定时任务 ansible all -m shell -a 'cat /etc/cron.d/ntpdate_cron'
执行过程: [root@log1 ~]# ansible all -m cron -a 'name="ntpdate_time" job="/usr/sbin/ntpdate ntp1.aliyun.com" cron_file=ntpdate_cron user=root minute=*/5' -o 192.168.188.136 | SUCCESS => {"changed": true, "cron_file": "ntpdate_cron", "envs": [], "jobs": ["ntpdate_time"]} [root@log1 ~]# ansible all -m shell -a 'cat /etc/cron.d/ntpdate_cron' 192.168.188.136 | SUCCESS | rc=0 >> #Ansible: ntpdate_time */5 * * * * root /usr/sbin/ntpdate ntp1.aliyun.com [root@log1 ~]# ansible all -m cron -a 'name="ntpdate_time" state=absent cron_file=ntpdate_cron user=root' -o 192.168.188.136 | SUCCESS => {"changed": true, "cron_file": "ntpdate_cron", "envs": [], "jobs": []} [root@log1 ~]# ansible all -m shell -a 'cat /etc/cron.d/ntpdate_cron' 192.168.188.136 | SUCCESS | rc=0 >>