ansible模块命令讲解、剧本

前言

版本:CentOS Linux release 7.9.2009 (Core) ansible 2.9.27 python 2.7.5

ansible的颜色

Ansible的返回结果非常友好,一般会用三种颜色来表示执行结果:

颜色 是否成功 说明
绿色 成功 没有对目标机器做修改
橘黄色 成功 执行后目标机器有状态变化
红色 失败 执行过程出现异常

ansible语法

ansible [-h] [--version] [-v] [-b] [--become-method BECOME_METHOD]
               [--become-user BECOME_USER] [-K] [-i INVENTORY] [--list-hosts]
               [-l SUBSET] [-P POLL_INTERVAL] [-B SECONDS] [-o] [-t TREE] [-k]
               [--private-key PRIVATE_KEY_FILE] [-u REMOTE_USER]
               [-c CONNECTION] [-T TIMEOUT]
               [--ssh-common-args SSH_COMMON_ARGS]
               [--sftp-extra-args SFTP_EXTRA_ARGS]
               [--scp-extra-args SCP_EXTRA_ARGS]
               [--ssh-extra-args SSH_EXTRA_ARGS] [-C] [--syntax-check] [-D]
               [-e EXTRA_VARS] [--vault-id VAULT_IDS]
               [--ask-vault-pass | --vault-password-file VAULT_PASSWORD_FILES]
               [-f FORKS] [-M MODULE_PATH] [--playbook-dir BASEDIR]
               [-a MODULE_ARGS] [-m MODULE_NAME]
               pattern

-i :指定主机清单,不指定默认是/etc/ansible/hosts;
--list-hosts: 列出指定组里有哪些主机;
-o :简化输出,显示为一行;
-u,--user=REMOTE_USER : 远程执行时受控主机的用户;
-k, --ask-pass :提示输入ssh密码,默认key验证;
-K, --ask-become-pass : 提示输入sudo时的密码口令;
-b,--become:特权方式运行命令;
-T,--timeout=TIMEOUT : 执行命令时的超时时间,默认10s;
-f 10 :指定ansible并行线程数,在高并发场景下可以指定ansible的线程数,可以让ansible执行时启动多个线程发送命令到受控主机从而提高效率。默认是5个线程;
-m: 指定模块,m是module的缩写,不指定模块缺省值默认是command,可以在ansible.cfg配置文件中配置默认模块。
-a:指定模块所要执行的命令,参数等。
-l,--limit: 指只针对某个组的某些主机执行。
演示示例:

ansible -i /etc/ansible/hosts node --list-hosts 			#查看/etc/ansible/hosts主机清单的node组有哪些主机
ansible all  --list-hosts									#查看默认主机文件/etc/ansible/hosts主机清单的全部受控主机
ansible -i /etc/ansible/hosts node -u guo -b -k -K -T 20 -m shell -a 'ls -l  /root'  #-u指定远程执行的用户为guo,-b指定以root特权方式运行命令,-k表示输入ssh登陆密码,-K表示特权方式时输入sudo密码,-T指定命令超时时间,-m指定要使用模块是shell模块,-a指定要运行的命令.

ansible all -m ping --limit 192.168.118.133					#针对全部主机里的192.168.118.133执行
ansible node -m ping -l 192.168.118.133						#针对node组里的192.168.118.133执行			

ansible的Host-pattern



all:表示主机清单所有的主机,如下所示:
ansible -i /etc/ansible/hosts all -m ping					#all表示主机清单所有的主机

指定主机清单的某个组,如指定node组,如下所示:
ansible -i /etc/ansible/hosts node -m ping             		#指定node组

指定主机清单的某个主机IP,如下所示:
ansible -i /etc/ansible/hosts 192.168.118.132 -m ping		#指定主机清单里面的192.168.118.132这台受控主机

*使用通配符模糊匹配组,如下所示:
ansible -i /etc/ansible/hosts *web -m ping					#模糊匹配带有web后缀的组

或关系,表示在A组或B组中的主机,如下所示:
ansible -i /etc/ansible/hosts 'node:web' -m ping			#表示在node组或web组中的主机
ansible '192.168.118.132:192.168.118.133' -m ping			#也表示或关系

逻辑与:表示同时在A组和B组中的主机,如下所示:
ansible -i /etc/ansible/hosts 'node:&web' -m ping			#同时在node组和web组中的主机

逻辑非:表示在A组,但不在B组中的主机,如下所示:
ansible -i /etc/ansible/hosts 'node:!web' -m ping			#同时在node组但不在web组中的主机
ansible -i /etc/ansible/hosts '!web:node' -m ping			#同上,表示在node组但不在web组中的主机

综合逻辑:可以把上面的逻辑组合起来形成综合逻辑,如下所示:
ansible -i /etc/ansible/hosts 'web:node:&redis!db:' -m ping	#表示在web组或node组同时又在redis组但不在db组中的主机

正则表达式:
ansible -i /etc/ansible/hosts '~(web|node)servers' -m ping	#表示匹配以web或node开头servers结尾的组中的主机

file模块

作用:主要用于在目标受控主机上创建文件,目录,删除文件等操作。

参数:
path:指定路径,path的别名是dest, name
state:表示状态,absent 删除文件或目录, directory 创建目录, file, hard 创建硬链接, link 创建软链接, touch 创建普通文件,默认是:file
owner:属主
group:属组
mode:设置权限
src:表示创建的是软硬链接时链接到的源文件

#查看file模块帮助文档
ansible-doc file

#创建一个普通文件
ansible -i /etc/ansible/hosts all -m file -a 'path=/root/test.txt  state=touch'

#创建一个目录
ansible -i /etc/ansible/hosts all -m file -a 'path=/root/k8s  state=directory'

#创建一个可执行文件属组是root,属组也是root,权限是755
ansible -i /etc/ansible/hosts all -m file -a 'path=/root/run.sh  state=touch mode=755 owner=root group=root'

#删除文件或目录(会级联删除)
ansible -i /etc/ansible/hosts all -m file -a 'name=/root/k8s state=absent'

copy模块

作用:主要用于复制ansible主控端的文件到受控端上

#查看copy模块帮助文档
ansible-doc cppy  		
				
# src指定源文件,dest指定目标路径
ansible -i /etc/ansible/hosts node -m copy -a  'src=/root/test_file1 dest=/root/'

# src指定源文件,dest指定目标路径,owner  group  mode等参数可以指定文件属性
ansible -i /etc/ansible/hosts node -m copy -a  'src=/root/test_file2 dest=/root/ owner=root group=fuji mode=755'

# backu=yes 表示当src源文件改变了,目标机器上具有同名文件时,备份同名的目标文件,默认backup=no不备份直接覆盖目标主机上同名文件,备份的文件名会加上年月日时分秒
ansible -i /etc/ansible/hosts node -m copy -a  'src=/root/test_file2 dest=/root/ owner=root group=fuji mode=755 backup=yes'

fetch模块

作用:从远程主机上抓取文件到主控端上。fetch模块功能与copy模块功能整好相反。

#从远程主机上抓取/var/log/messages文件到/root/logs/目录下
# src参数表示远程文件,必须是一个文件,不能是目录;dest是本地目录
ansible all -m fetch -a 'src=/var/log/messages  dest=/root/logs/'

#抓取后的文件,其实是用主机地址为目录做了区分,同时被抓取的文件连同绝对路径也一起抓取过来了,如下所示:
[root@master ~]# tree logs/			#查看抓取后的文件
logs/
├── 192.168.118.132					#以远程主机IP为目录做了区分
│   └── var							#被抓取的文件连同绝对路径也一起抓取过来
│       └── log						#被抓取的文件连同绝对路径也一起抓取过来
│           └── messages			#被抓取的文件名
└── 192.168.118.133					#以远程主机IP为目录做了区分
    └── var							#被抓取的文件连同绝对路径也一起抓取过来
        └── log						#被抓取的文件连同绝对路径也一起抓取过来
            └── messages			#被抓取的文件名

6 directories, 2 files
[root@master ~]#

cron模块

作用:添加、删除Linux的定时计划任务。
参数:

name :指定计划任务的名称;
minute、hour、day、month、weekday:分时日月周,默认是*
job:表示计划任务要执行的命令
state:状态,状态有两种,present表示添加计划任务含义,absent表示删除计划任务;
user:表示计划任务的所属的用户,默认是root;
disabled:disabled=true表示禁用计划任务,disabled=false表示启用计划任务,默认是false表示启用计划任务;
#每十分钟执行
ansible node -m cron -a 'name="sync-date" minute=*/10 user=root job="/usr/sbin/ntpdate ntp1.aliyun.com" state=present'  
#每小时执行
ansible node -m cron -a 'name="sync-date" hour=*/1 user=root job="/usr/sbin/ntpdate ntp1.aliyun.com" state=present'
#每天一点执行
ansible node -m cron -a 'name="sync-date" minute=00 hour=1 user=root job="/usr/sbin/ntpdate ntp1.aliyun.com" state=present '
#每周一凌晨两点整执行
ansible node -m cron -a 'name="sync-date" minute=00 hour=2 weekday=1 user=root job="/usr/sbin/ntpdate ntp1.aliyun.com" state=present'
#在远程主机上查看第一条的计划任务
[root@node1 ~]# crontab -l
#Ansible: sync-date
*/10 * * * * /usr/sbin/ntpdate ntp1.aliyun.com
[root@node1 ~]# 

# 使用disabled=yes禁用计划任务,必须指明name和job才能唯一标识一个计划任务,user不指定默认就是root
ansible node -m cron -a 'name="sync-date" user=root job="/usr/sbin/ntpdate ntp1.aliyun.com" disabled=yes'
[root@node1 ~]# crontab -l									#查看远程主机,计划任务已经被注释掉了
#Ansible: sync-date
#* * * * * /usr/sbin/ntpdate ntp1.aliyun.com
[root@node1 ~]# 

# 使用disabled=no重新启用计划任务,必须指明name和job才能唯一标识一个计划任务,user不指定默认就是root
ansible node -m cron -a 'name="sync-date" user=root job="/usr/sbin/ntpdate ntp1.aliyun.com" disabled=no'
[root@node1 ~]# crontab  -l									#查看远程主机,计划任务已经重启启用了
#Ansible: sync-date
* * * * * /usr/sbin/ntpdate ntp1.aliyun.com
[root@node1 ~]#

#删除计划任务
ansible node -m cron -a 'name="sync-date" user=root job="/usr/sbin/ntpdate ntp1.aliyun.com"  state=absent'

user模块

作用:主要用于用户信息管理,包括用户创建,密码修改,组等基本操作。

#查看user模块的帮助文档
ansible-doc user

#在所有主机组上创建一个xiaoming用户
ansible -i /etc/ansible/hosts  all -m user -a 'name=xiaoming'

#在所有主机组上创建一个xiaoming用户
#如果创建的用户需要密码,则密码需要使用 openssl命令和passwd命令从标准输入中先加密,然后再ansible使用password指定,如下所示: 
echo "123456" | openssl passwd -1 -stdin		#-1是密码加密的复杂度
$1$v9/AfSPE$Ojk8HUwrbeEQ5jdtw9aYy0
ansible -i /etc/ansible/hosts  all -m user -a 'name=xiaoming group=root uid=1009 shell=/usr/bin/bash comment="I am xiaoming,I am new." password="$1$v9/AfSPE$Ojk8HUwrbeEQ5jdtw9aYy0"'

#删除xiaoming用户,家目录也一起删除
ansible -i /etc/ansible/hosts  all -m user -a 'name=xiaoming state=absent remove=yes'

yum模块

作用:yum模块主要用于包管理,如安装、升级、卸载包等操作。

#更新nginx,state参数:present、installed 都可以表示安装,latest 表示更新、removed、absent 表示卸载
ansible -i /etc/ansible/hosts node -m yum -a 'name=nginx state=latest'

#同时安装多个,使用道号隔开
ansible -i /etc/ansible/hosts node -m yum -a 'name=nginx,vsftpd state=present'

#安装本地的包,首先需要把包上传到远程目标主机上才能安装
ansible -i /etc/ansible/hosts node -m copy -a  'src=/root/grafana-8.3.3-1.x86_64.rpm dest=/root/'
ansible -i /etc/ansible/hosts node -m yum -a 'name=/root/grafana-8.3.3-1.x86_64.rpm state=present'

#卸载nginx,同时卸载多个的话也要使用道号隔开
ansible -i /etc/ansible/hosts node -m yum -a 'name=nginx state=absent'

# 仅下载nginx,不安装
ansible -i /etc/ansible/hosts node -m yum -a 'name=nginx download_only=true'

service模块

作用:用于管理服务,包括启动服务,停止服务,设置服务开机自启等操作。

#查看service模块的帮助文档
ansible-doc service

#启动nginx服务
#state参数可选值:reloaded 重新加载, restarted 重启, started 启动, stopped 停止
ansible -i /etc/ansible/hosts all -m service -a 'name=nginx state=started'

#停止服务,state=stopped 表示停止
ansible -i /etc/ansible/hosts all -m service -a 'name=nginx state=stopped'

#设置服务开机自启
ansible -i /etc/ansible/hosts all -m service -a 'name=nginx enabled=yes'

#启动ntpd服务,并设置服务开机自启
ansible -i /etc/ansible/hosts all -m service -a 'name=ntpd  state=started enabled=yes'

setup模块

作用:收集指定目标受控主机的基本信息

#查看setup模块帮助文档
ansible-doc setup

#查看基本信息,会输出所有信息
ansible -i /etc/ansible/hosts all -m setup

#查看主机的总内存信息,通过使用 filter 参数过滤
ansible -i /etc/ansible/hosts all -m setup -a 'filter=ansible_memtotal_mb'

command 模块

作用:command模块用于执行一些简单的命令,command不能识别特殊字符,使用shell模块能识别特殊字符。

#查看command模快帮助文档
ansible-doc command

#查看主机名
ansible -i /etc/ansible/hosts node -m command -a 'hostname'

#查看用户信息,但是由于有管道符,所以会报错,command模块不能识别不了特殊字符
ansible all  -m shell -a 'cat /etc/passwd | grep ssh' 			#报错

shell模块

作用:shell模块能实现平时Linux全部操作,即shell模块能实现上面所讲的各个模块全部功能。

#查看shell帮助文档
ansible-doc shell

#查看ntpd服务状态
ansible -i /etc/ansible/hosts node -m shell -a 'systemctl status ntpd'


#重启ntpd服务状态
ansible -i /etc/ansible/hosts node -m shell -a 'systemctl restart ntpd'

#查看Linux版本和内核版本
ansible -i /etc/ansible/hosts node -m shell -a 'cat /etc/redhat-release ;uname -a'

#查看系统启动时间和系统负载,以及登陆用户数
ansible -i /etc/ansible/hosts node -m shell -a 'uptime'

playbook剧本

ansible-playbook命令常用参数:

 --list-hosts :列出剧本的主机
 --list-tags :列出剧本的tags
 --syntax-check :语法检查,检查剧本的语法有无错误
 -l SUBSET, --limit SUBSET :指定主机组里哪些主机执行剧本
 -t TAGS, --tags TAGS:只执行指定tags的步骤

palybook特性:

#号表注释
--- 表示文件的开始
区别大小写
一个name只能写一个task,不能一个nginx下写多个task,不然只会应用最后的一个task;
文件名后缀通常是.yaml或.yml
hosts:执行的远程主机列表
tasks:任务集
template:模板
handlers: 与notify结合使用,有特定条件触发执行操作,满足条件执行,不满足不执行。

编写一个playbook剧本,剧本是以yaml格式语法进行编写的,并在ansible服务器上创建一个/root/httpd.conf配置文件,端口是8000,然编写剧本,如下:

[root@master ~]# vim  install_httpd.yaml 
- hosts: node														#指定主机
  tasks:															#任务
  - name: install httpd												#名字,可自定义
    yum: name=httpd state=present									#yum模块,安装httpd服务
  - name: copy apache conf file										#名字,可自定义
    copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf		#copy模块,复制httpd.conf去替换远程主机的httpd.conf
  - name: start apache running										#名字,可自定义
    service: name=httpd state=started enabled=yes					#service模块,启动httpd服务
#剧本语法检查,没有报错输出说明剧本语法ok
[root@master ~]# ansible-playbook install_httpd.yaml --syntax-check

playbook: install_httpd.yaml
#列出剧本要运行的主机
[root@master ~]# ansible-playbook install_httpd.yaml --list-hosts

playbook: install_httpd.yaml

  play #1 (node): node  TAGS: []
    pattern: [u'node']
    hosts (2):
      192.168.118.132
      192.168.118.133
[root@master ~]# 
#执行剧本,没有报错,远程主机上已经运行起来了httpd服务
[root@master ~]# ansible-playbook install_httpd.yaml
[root@master ~]# 
[root@node1 local]# lsof  -i:8000			#在node1节点上查看,8000端口起来了,说明我们的剧本copy模块复制式成功的
COMMAND   PID   USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
httpd   53560   root    4u  IPv6 1602043      0t0  TCP *:irdmi (LISTEN)
httpd   53561 apache    4u  IPv6 1602043      0t0  TCP *:irdmi (LISTEN)
httpd   53562 apache    4u  IPv6 1602043      0t0  TCP *:irdmi (LISTEN)
httpd   53563 apache    4u  IPv6 1602043      0t0  TCP *:irdmi (LISTEN)
httpd   53564 apache    4u  IPv6 1602043      0t0  TCP *:irdmi (LISTEN)
httpd   53565 apache    4u  IPv6 1602043      0t0  TCP *:irdmi (LISTEN)
[root@node1 local]# 

我们修改本地的/root/httpd.conf文件端口为8111。然后重新执行ansible-playbook install_httpd.yaml,如下:

#修改/root/httpd.conf文件端口为8111,然后重新执行剧本
[root@master ~]# ansible-playbook install_httpd.yaml
[root@node1 local]# lsof  -i:8000							#查看远程受控主机上查看,还是之前的8000端口
COMMAND   PID   USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
httpd   53560   root    4u  IPv6 1602043      0t0  TCP *:irdmi (LISTEN)
httpd   53561 apache    4u  IPv6 1602043      0t0  TCP *:irdmi (LISTEN)
httpd   53562 apache    4u  IPv6 1602043      0t0  TCP *:irdmi (LISTEN)
httpd   53563 apache    4u  IPv6 1602043      0t0  TCP *:irdmi (LISTEN)
httpd   53564 apache    4u  IPv6 1602043      0t0  TCP *:irdmi (LISTEN)
httpd   53565 apache    4u  IPv6 1602043      0t0  TCP *:irdmi (LISTEN)
[root@node1 local]# lsof  -i:8111							#没有8111端口
[root@node1 local]# grep 8111 /etc/httpd/
conf/           conf.d/         conf.modules.d/ logs/           modules/        run/            
[root@node1 local]# grep 8111 /etc/httpd/conf/httpd.conf 	#查看配置文件,配置问价已经是8111端口了
Listen 8111
[root@node1 local]# 

handlers的使用

细心的网友会发现问题所在,我们的剧本中,当文件发生改变了,copy会重新复制httpd.conf文件到远程主机,但是httpd服务并没有重启,如果在剧本后面写上重启httpd视乎是可行的,但是每执行一次剧本都重启一次httpd服务,视乎有点不合理。此时,我们引入一个handlers来监听某个事件然后触发某种操作,如下所示:

[root@master ~]# vim install_httpd.yaml 
- hosts: node
  tasks:
  - name: install httpd
    yum: name=httpd state=present
  - name: copy apache conf file
    copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify: restart httpd service		#notify定义当copy模块的文件发生了改变时去执行对应名字的handlers,注意,这里的“restart httpd service“要与handlers的name的内容一样,不然对应不上
  - name: start apache running
    service: name=httpd state=started enabled=yes
  handlers:												#引入一个handlers
  - name: restart httpd service							#定义一个name
    service: name=httpd state=restarted					#操作是,使用service模块,重启httpd服务
[root@master ~]# vim httpd.conf 						#修改端口为8222
[root@master ~]# ansible-playbook install_httpd.yaml	#执行剧本
[root@node1 local]# lsof  -i:8222						#查看受控主机,端口8222已经启动了
COMMAND   PID   USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
httpd   60105   root    4u  IPv6 1621895      0t0  TCP *:8222 (LISTEN)
httpd   60106 apache    4u  IPv6 1621895      0t0  TCP *:8222 (LISTEN)
httpd   60107 apache    4u  IPv6 1621895      0t0  TCP *:8222 (LISTEN)
httpd   60108 apache    4u  IPv6 1621895      0t0  TCP *:8222 (LISTEN)
httpd   60109 apache    4u  IPv6 1621895      0t0  TCP *:8222 (LISTEN)
httpd   60110 apache    4u  IPv6 1621895      0t0  TCP *:8222 (LISTEN)
[root@node1 local]# 

tags的使用

tags其实相当于一个标签,在为某个tasks打上一个tags,然后执行剧本时可以指定tags名字,这样就能单独执行tags那行的任务,如下所示:

[root@master ~]# vim install_httpd.yaml 
- hosts: node
  tasks:
  - name: install httpd
    yum: name=httpd state=present
  - name: copy apache conf file
    copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify: restart httpd service		
  - name: start apache running
    service: name=httpd state=started enabled=yes
    tags: start apache									#定义一个名叫start apache的tags
  handlers:	
  - name: restart httpd service	
    service: name=httpd state=restarted	

#列出剧本有哪些tags
ansible-playbook install_httpd.yaml --list-tags
#指定tags执行剧本(假设剧本已经执行过,现在要启动nginx,那么可以指定tags来执行剧本)
ansible-playbook -t "start apache" install_httpd.yaml

注意:可以将一个tags放在不同的task下,这样执行剧本的时候就会执行多个task;同时,执行剧本时指定tag也可以指定多个tags,使用道号间隔即可。

ansible-vault 加密yaml文件

ansible-vault 命令主要用于加密yaml文件,当我们的yaml文件有敏感信息时,可以使用使用ansible-vault命令加密yaml文件,加密过的yaml文件,直接cat vim 看到的会是一串乱码,所以还是要使用ansible-vault 命令进行编辑,查看,解密等操作。
注意:加密后的yaml文件,需要解密后才能正常执行。

常用参数:
encrypt :加密文件
  {create,decrypt,edit,view,encrypt,encrypt_string,rekey}
    create              创建一个加密的yaml文件
    decrypt             解密一个加密文件
    edit                编辑加密文件
    view                查看加密文件
    encrypt             加密一个yaml文件
    encrypt_string      加密一个字符串
    rekey               Re-key a vault encrypted file

#创建一个秘文,创建的时候需要输入密码,然后ansible就直接打开文件可以写剧本了
ansible-vault create vault.yml

#解密一个加密过的文件,需要输入正确密码才能解密
ansible-vault decrypt  vault.yml

#加密install_httpd.yaml文件,加密后的文件就变成了密文,vim打开看到的是一串乱码
ansible-vault encrypt install_httpd.yaml 

#rekey更换口令密码
ansible-vault rekey   install_httpd.yaml

#解密加密install_httpd.yaml ,加密后的文件就变成了密文,vim打开看到的是一串乱码
ansible-vault encrypt install_httpd.yaml 

#查看加密后的文件,只能这样看,cat install_httpd.yaml 看还是乱码
ansible-vault view install_httpd.yaml 

#编辑加密文件,只能这样编辑,vim install_httpd.yaml 看的话会显示一串乱码
ansible-vault edit  install_httpd.yaml 

vars的使用

剧本中可以定义变量,变量的定义使用 vars定义,变量的引用使用{{ variable }},中间有空格,如下所示:

[root@master ansbile]# cat install_soft.yaml 
- hosts: node
  vars:												#定义变量,及其赋值
  - pkname1: httpd									#定义了一个pkname1变量,并赋值httpd
  - pkname2: vsftpd									#定义了一个pkname2变量,并赋值vsftpd
  tasks:
  - name: install httpd
    yum: name={{ pkname1 }} state=present			#定义一个pkname1变量
  - name: install vsftpd
    yum: name={{ pkname2 }} state=present			#定义一个pkname2变量
  - name: start httpd
    service: name=httpd state=started enabled=yes
  - name: start vsftpd
    service: name=vsftpd state=started enabled=yes
[root@master ansbile]# 
#如果基本里面没有定义变量,也没有给变量赋值,那么可以在命令行使用-e参数给变量赋值,如下:
ansible-playbook -e 'pkname1=httpd,pkname2=vsftpd' install_soft.yaml

你可能感兴趣的:(Ansible,ansible,linux,服务器)