1:使用playbook理由:
执行一些简单的任务,使用命令行模式可以方便的解决问题,但是有时一个设施过于复杂,需要大量的操作时候,执行命令行模式是不适合的,这时最好使用playbook,就像执行shell命令与写shell脚本一样,也可以理解为批处理任务,不过playbook有自己的语法格式。
2、playbook文件的格式
playbook文件由YAML语言编写。 YAML是一个类似 XML、JSON的标记性语言,YAML强调以数据为中心,并不是以标识语言为重点。因而YAML本身的定义比较简单,号称“一种人性化的数据格式语言”。首先学习了解一下YAML的格式,对后面书写playbook很有帮助。以下为playbook常用到的YAML格式。
playbook文件是通过ansible-playbook命令进行解析的,ansbile-playbook命令会根据自上而下的顺序依次执行playbook文件中的内容。同时,playbook开创了很多特性,它可以允许传输某个命令的状态到后面的指令,它也可以从一台机器的文件中抓取内容并附为变量,然后在另一台机器中使用,这使得playbook可以实现一些复杂的部署机制,这是ansible命令无法实现的。
3、playbook的构成
playbook是由一个或多个“play”组成的列表。play的主要功能在于,将事先合并为一组的主机装扮成事先通过ansible定义好的角色。将多个play组织在一个playbook中就可以让它们联同起来按事先编排的机制完成一系列复杂的任务。
其主要有以下四部分构成
(1)、Hosts和Users
playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。
hosts:用于指定要执行指定任务的主机,每个playbook都必须指定hosts,hosts也可以使用通配符格式。主机或主机组在inventory清单中指定,可以使用系统默认的/etc/ansible/hosts,也可以自己编辑,在运行的时候加上-i选项,可指定自定义主机清单的位置。在运行清单文件的时候,–list-hosts选项会显示那些主机将会参与执行任务的过程中。
remote_user:用于指定在远程主机上执行任务的用户。可以指定任意用户,也可以使用sudo,但是用户必须要有执行相应任务的权限。
(2)、任务列表(tasks list)
play的主体部分是task list。
task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。在运行自上而下某playbook时,如果中途发生错误,则所有已执行任务都将回滚,因此在更正playbook后需要重新执行一次。
task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的(幂等性; 即一个命令,即使执行一次或多次, 其结果也一样),这意味着多次执行是安全的,因为其结果均一致。tasks包含name和要执行的模块,name是可选的,只是为了便于用户阅读,建议加上去,模块是必须的,同时也要给予模块相应的参数。
定义tasks推荐使用module: options”的格式,例如:
service: name=httpd state=running
(3)、handlers
用于当关注的资源发生变化时采取一定的操作。handlers是和“notify”配合使用的。
“notify”这个动作可用于在每个play的最后被触发,这样可以避免多次有改变发生时,每次都执行指定的操作,通过“notify”,仅在所有的变化发生完成后一次性地执行指定操作。
在notify中列出的操作称为handler,也就是说notify用来调用handler中定义的操作。
注意:在 notify中定义的内容一定要和handlers中定义的“ - name”内容一样,这样才能达到触发的效果,否则会不生效。
(4)、tags
tags用于让用户选择运行或略过playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分;但是当一个playbook任务比较多时,一个一个的判断每个部分是否发生了变化,也需要很长时间。因此,如果确定某些部分没有发生变化,就可以通过tags跳过这些代码片断。
4、Playbook执行结果解析
使用ansible-playbook运行playbook文件,输出的内容为JSON格式。并且由不同颜色组成,便于识别。一般而言,输出内容中:
绿色代表执行成功,但系统保持原样
黄色代表系统状态发生改变,也就是执行的操作生效
红色代表执行失败,会显示错误信息。
在远程节点上执行命令,用法和command模块一样,不过shell模块执行命令的时候使用的是/bin/sh,所以shell模块可以执行任何命令。
- hosts: 172.16.213.231
remote_user: root
tasks:
- name: ansible shell
shell: ps -ef|grep sshd&&mkdir /opt/hdp
- name: ansible command
command: touch /opt/hdp/hadoop.txt
上面这个命令是执行远程机器上的脚本,脚本路径为/tmp/install.sh(远程主机上的脚本,非本机的),然后将执行命令的结果存放在远程主机路径/tmp/install.log中,注意在进行保存文件的时候,写上全路径,否则就会保存在登录之后的默认路径中。
raw模块功能类似与前面说的command、shell能够完成的操作,raw也都能完成。不同的是,raw模块不需要远程主机上的python环境。
ansible要执行自动化操作,需要管理机上装ansible,客户机上也需要安装python,如果客户机上没有安装python模块,那么command、shell模块将无法工作,而raw却可以正常工作,因此,如果有的机器是没有装python,或者说安装的python版本在python2.4以下,就可以使用raw模块来装python、python-simplejson等。
- hosts: 172.16.213.231
remote_user: root
tasks:
- name: ansible raw1
raw: ps -ef|grep sshd|awk '{print $2}'>/tmp/ssh.log
- name: ansible raw2
raw: dnf -y install python36-devel
file模块主要用于远程主机上的文件操作,file模块包含如下选项:
force:需要在两种情况下强制创建软链接,一种是源文件不存在但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
group:定义文件/目录的属组
mode:定义文件/目录的权限
owner:定义文件/目录的属主
path:必选项,定义文件/目录的路径
recurse:递归的设置文件的属性,只对目录有效
src:要被链接的源文件的路径,只应用于state=link的情况
dest:被链接到的目标路径,只应用于state=link的情况
state: 有如下几个选项:
directory:表示目录,如果目录不存在,则创建目录。
link:创建软链接
hard:创建硬链接
touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent:删除目录、文件或者取消链接文件。
使用示例:
- hosts: 172.16.213.231
remote_user: root
tasks:
- name: mkdir cdh directory
file: path=/opt/cdh state=directory mode=0755
- name: chmod bin
file: dest=/opt/bigdata/jdk/bin mode=0755 recurse=yes
- name: link files
file: src=/etc/ssh/sshd_config dest=/mnt/sshd_config owner=sshd state=link
- name: delete files
file: path=/tmp/hadoop.tar.gz state=absent
- name: chown files
file: path=/mnt/syncfile.txt owner=nobody group=nobody mode=0644
Copy模块用于复制文件到远程主机,copy模块包含如下选项:
backup:在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no
dest:必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录
directory_mode:递归的设定目录的权限,默认为系统默认权限
force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes
src:要复制到远程主机的文件在本地的地址,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用”/”来结尾,则只复制目录里的内容,如果没有使用”/”来结尾,则包含目录在内的整个内容全部复制,类似于rsync。
copy模块举例:
- hosts: 172.16.213.231
remote_user: root
gather_facts: false
tasks:
- name: copy and chown
copy: src=/etc/sudoers dest=/mnt/sudoers owner=root group=root mode=440 backup=yes
- name: checking files
copy: src=/etc/sudoers dest=/mnt/sudoers validate='visudo -cf %s'
- name: copy directory
copy: src=/etc/yum/ dest=/mnt/bak owner=hadoop group=hadoop directory_mode=644
synchronize模块常用的选项有如下几个。
compress:是否开启压缩,默认开启。
copy_links:复制链接文件,默认为no,注意后面还有一个links参数。
delete:表示删除管理机中没有但远程主机存在的文件,使两边内容一样,以管理机为主,默认为no。
src:要复制到远程主机的文件在管理机上的路径。
dest:要将文件复制到的远程主机的绝对路径。
dest_prot:默认为22端口,走ssh协议,表示远程主机端口。
mode:可选push和pull模块,push模块的话,一般用于从管理机向远程主机上传文件,pull模式用于从远程主机上取文件到管理机。
注意,使用这个模块的时候,必须保证远程主机上有rsync这个命令,不然会报错。
- hosts: 172.16.213.231
remote_user: root
gather_facts: false
tasks:
- name: synchronize rsync directory
synchronize: src=/usr/share/nginx/modules dest=/mnt/bak1 delete=yes
unarchive模块用来实现解压缩,也就是将压缩文件解压分发到远程不同节点上。只需记住如下几个参数即可:
src: 源文件路径,这个源文件在管理机上。
dest: 指定远程主机的文件路径。
mode:设置远程主机上文件权限
例子:
- hosts: 172.16.213.231
remote_user: root
gather_facts: false
tasks:
- name: unarchive spark files
unarchive: src=/src/spark.tar.gz dest=/opt
用于管理远程主机上的服务,该模块包含如下选项:
enabled:是否开机启动 yes|no
name:必选项,服务名称
pattern:定义一个模式,如果通过status指令来查看服务的状态时,没有响应,就会通过ps指令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然在运行
sleep:如果执行了restarted,在则stop和start之间沉睡几秒钟
state:对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)
使用示例:
- hosts: 172.16.213.231
remote_user: root
gather_facts: false
tasks:
- name:
service: name=nginx state=restarted enabled=yes
用于管理计划任务,包含如下选项:
backup:对远程主机上的原任务计划内容修改之前做备份
cron_file:用来指定一个计划任务文件,也就是将计划任务写到远程主机上/etc/cron.d目录下,创建一个文件对应的计划任务。
day:日(1-31,,/2,……)
hour:小时(0-23,,/2,……)
minute:分钟(0-59,,/2,……)
month:月(1-12,,/2,……)
weekday:周(0-7,*,……)
job:要执行的任务,依赖于state=present
name:定义定时任务的描述信息
special_time: 特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时)
state:确认该任务计划是创建还是删除,有两个值可选,分别是present和absent,present表示创建定时任务,absent表示删除定时任务,默认为present。
user:以哪个用户的身份执行job指定的任务。
- hosts: 172.16.213.231
remote_user: root
gather_facts: false
tasks:
- name: cron examples
cron: backup=true name=autobackup weekday=6 minute=30 hour=1 user=root job="/home/ixdba/backup.sh"
- name: delete cron
cron: name=autobackup state=absent
使用yum包管理器来管理软件包,其选项有:
config_file:yum的配置文件
disable_gpg_check:关闭gpg_check
disablerepo:不启用某个源
enablerepo:启用某个源
name:要进行操作的软件包的名字,也可以传递一个url或者一个本地的rpm包的路径
state:表示要安装还是删除软件包,要安装软件包,可选择present(安装)、installed(安装)、 latest(安装最新版本),删除软件包可选择absent、removed。
示例如下:
- hosts: 172.16.213.231
remote_user: root
gather_facts: false
tasks:
- name: dnf install redis
dnf: name=redis state=latest enablerepo=epel
- name: remove redis
dnf: name=redis state=removed
user模块是请求的是useradd, userdel, usermod三个指令,goup模块请求的是groupadd, groupdel, groupmod 三个指令。
name # 指定用户名
group # 指定用户的主组
groups # 指定附加组,如果指定为(‘groups=’)表示删除所有组。
shell # 指定默认shell
state #设置帐号状态,不指定为默认为present,表示创建,指定值为absent表示删除
remove #当使用状态为state=absent时使用,类似于userdel --remove选项。
- name: create user
hosts: 172.16.213.231
user: root
gather_facts: false
tasks:
- name: start createuser
user: name="{{item.value}}" groups=hadoop,wheel
with_items:
- {value: "hadoopuser001"}
- {value: "hadoopuser002"}
lineinfile模块实现对文件进行内容替换,常用参数含义如下
path:操作的远程主机上的文件路径
regexp:正则表达式,要替换的内容规则
line:指定替换后的文本内容
state:当设置为absent代表删除匹配的行
insertafter:insertafter参数可以将文本插入到“指定的行”之后
insertbefore:insertbefore参数可以将文本插入到“指定的行”之前
backup:进行替换操作前是否进行备份
lineinfile模块几个例子:
- hosts: 172.16.213.231
remote_user: root
tasks:
- lineinfile: dest=/etc/profile insertafter='ulimit(.*)' line="ulimit -c unlimited"
- lineinfile: dest=/etc/profile line="export JAVA_HOME=/usr/jdk"
- lineinfile: dest=/etc/selinux/config regexp='SELINUX=(.*)' line='SELINUX=disabled'
- lineinfile: dest=/etc/resolv.conf regexp='search(.*)' state=absent
Ansible facts是远程主机上的系统信息,主要包含IP地址,操作系统版本,网络设备,mac地址,内存、磁盘、硬件等信息。这些信息对于需要根据远程主机的信息作为执行条件操作的场景非常有用. Ansible提供了一个setup模块来收集远程主机的系统信息,这些facts信息可以直接以变量的形式使用.
playbooks中,经常会用到的一个参数gather_facts就与该模块相关。gather_facts默认值为yes,也就是说,在使用Ansible对远程主机执行任何一个playbook之前,总会先通过setup模块获取facts,并将信息暂存在内存中,直到该playbook执行结束。
[root@ansible playbook]# ansible 172.16.213.231 -m setup
所有数据格式都是JSON格式,facts还支持查看指定信息,如下所示:
[root@ansible playbook]# ansible 172.16.213.231 -m setup -a ‘filter=ansible_all_ipv4_addresses’
12、register、set_fact、debug模块
- hosts: 172.16.213.231
remote_user: root
tasks:
- name: hostname command
shell: hostname
register: host_result
- debug: var=host_result.stdout
- debug: 'msg="output: {{host_result.stdout}}"'
- hosts: 172.16.213.231
remote_user: root
tasks:
- name: hostname command
shell: hostname
register: host_result
- set_fact: var1="{{host_result.stdout}}"
- set_fact: var2="This is a string"
- debug: var=var1
- debug: var=var2
- hosts: 172.16.213.231
remote_user: root
gather_facts: true
tasks:
- name: connection
shell: echo "connection . {{inventory_hostname}} $(hostname) ." >> /tmp/local.log
connection: local
- name: delegate_to
shell: echo "delegate_to . {{inventory_hostname}} $(hostname) ." >> /tmp/local.log
delegate_to: localhost
- name: local_action
local_action: shell echo "local_action. {{inventory_hostname}} $(hostname)" >> /tmp/local.log