概述
ansible那点事——playbook知识
- 一、ansible-play
- 二、ansible-playbook
- 1、playbook demo 批量部署nginx
- 2、playbook常用的参数、操作
- 1)tags标记
- 2)playbook包含多个play
- 3)变量的使用
- 4)条件判断 when
- 5)include参数
- 6)register参数
- 7)应用vars变量
- 8)交互式 prompt参数
- 三、playbook报错
一、ansible-play
playbook是由一个或多个play组成的列表。play的主要作用是将事先归位一组的主机通过预先的编排来实现批量操作。也可以理解是一个简单的剧本,由多个task组成的剧本,格式为YAML,遵循YAML语法。
基本组件:
name:定义playbook或者task的名称
hosts:playbook中的每一个play的目的都是为了让某个或某些以某个指定用户的身份执行任务。hosts用于指定要执行指定任务的主机,其可以是一个或多个由冒号分割主机组。与命令模式下的ansible匹配规则一样
user:remote_user则用于指定远程主机上的执行任务的用户,也可以使用user
tasks:任务列表。play的主体部分是task list. task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。
vars:定义变量
vars_files:定义变量文件
notify:任务执行结果如果是发生更改了的则触发定义在handler的任务执行
handlers:用于当前关注的资源发生变化时采取一定指定的操作
include:能包含的包括task,handler和playbook ,可以在include的时候传递变量
一个简答的play demo,apache安装,如果httpd.conf发生改变则重启httpd
- hosts: node-2 # 操作的主机
user: root # 操作用户
tasks: # 任务
- name: install apache # 任务名称,自定义
yum: name=httpd state=present # yum模块
- name: start apache # 任务名称,自定义
service: name=httpd state=started # service模块
- name: change apache # 任务名称,自定义
copy: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf # copy模块
notify: restart apache # 触发。如果change apache任务执行成功则会执行 restart apache任务
handlers: # 触发操作,与notify同用
- name: restart apache # 触发任务的名称
service: name=httpd state=restarted # service模块
二、ansible-playbook
playbook是将多个play组织在一个playbook中,即可以让他们联通起来按事先编排的机制共同“表演”。playbook由YMAL(YAML Ain’t Makup Language)语言编写。
相较于play来说,playbook有了元素的概念,以下为核心元素:
- Variables 变量元素,可传递给Tasks/Templates使用;
- Tasks 任务元素,由模块定义的操作的列表,即调用模块完成任务;
- Templates 模板元素,使用了模板语法的文本文件,可根据变量动态生成配置文件;
- Handlers 处理器元素,通常指在某事件满足时触发的操作;
- Roles 角色元素
1、playbook demo 批量部署nginx
- 创建目录结构,并准备index.html文件及nginx.conf文件
mkdir -p roles/nginx/{files,handlers,tasks,templates,vars}
touch roles/site.yaml roles/nginx/{handlers,tasks,vars}/main.yaml
echo "<h1>Ansible-playbook test</h1>" >/etc/ansible/test/roles/nginx/files/index.html
cp /etc/nginx/nginx.conf /etc/ansible/test/roles/nginx/templates/nginx.conf.j2 # 程序的模板配置文件以.j2结尾
目录结构:
roles/
├── nginx
│ ├── files
│ │ └── index.html
│ ├── handlers
│ │ └── main.yaml
│ ├── tasks
│ │ └── main.yaml
│ ├── templates
│ │ └── nginx.conf.j2
│ └── vars
│ └── main.yaml
└── site.yaml
- 编写tasks/main.yaml
# 所有需要执行的task都放在这个文件下
- name: install nginx
yum: name={{ item }} state=latest
with_items:
- nginx
- name: copy index.html
copy: src=/etc/ansible/test/roles/nginx/files/index.html dest=/usr/share/nginx/html/index.html
- name: copy nginx.conf
template: src=/etc/ansible/test/roles/nginx/templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
- name: run nginx
service: name=nginx state=started enabled=yes
- 编写handlers/main.yaml
# 这个文件下对应的task都对应着 tasks/main.yaml 下的 notify
- name: restart nginx
service: name=nginx state=restarted
- 修改templates/nginx.conf.j2
worker_processes {{ ansible_processor_cores }};# 调用内部已知变量,setup模块获取
worker_connections {{ worker_connections }};# 自定义变量 在vars/main.yaml里定义
- 编写vars/main.yaml
worker_connections: 10240 # 变量赋值
- 编写site.yaml
- hosts: node-2 # 目标主机(组)
roles: # 调用roles中的nginx
- nginx
- 执行playbook
ansible-playbook site.yaml --syntax-check # playbook语法测试
ansible-playbook site.yaml # 执行playbook
2、playbook常用的参数、操作
1)tags标记
#给task做个标记,可以控制任务执行
- hosts: all #注意-后面的空格 指定执行本play的主机组
user: root # 指定运行本play的远程主机用户
tasks:
- name: playbook_test # 任务描述
shell: touch /tmp/playbook.txt # shell模块
tags: suibian # 这是一个任务标记,可用来控制此任务
# 只运行指定标记的任务:-t tags
ansible-playbook -t 标记名称 test.yml
# 跳过某一个被标记的任务:--skip-tags=SKIP_TAGS
ansible-playbook --skip-tags=标记名称 test.yml
# 从某一个任务开始往下运行:--start-at-task 任务名称
ansible-playbook --start-at-task "start httpd service" test.yml
2)playbook包含多个play
- hosts: all # play1
remote_user: root
tasks:
- name: install a group
group: name=mygrp system=true
- hosts: webservers # play2
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd
3)变量的使用
- name: create_user # 剧本描述信息
hosts: node-2
user: root
gather_facts: false
vars:
- user: "liang" # 变量值一定要用引号引住
tasks:
- name: create user
user: name="{{ user }}"
基于字典列表给出元素示例:
- hosts: all
remote_user: root
tasks:
- name: create groups
group: name={{ item }} state=present
with_items:
- groupx1
- groupx2
- groupx3
- name: create users
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- {name: 'userx1', group: 'groupx1'}
- {name: 'userx2', group: 'groupx2'}
- {name: 'userx3', group: 'groupx3'}
4)条件判断 when
# 条件判断,当满足when条件时才会执行task
- name: use when
shell: touch /tmp/when.txt
when: ansible_hostname == "node-2" # 如果主机名为node-2才创建文件
- name: use when
shell: touch /tmp/when.txt
when: ansible_all_ipv4_addresses[0] == "192.168.93.137" # 如果ip地址为192.168.93.137才会创建文件
- hosts: webservers
tasks:
- name: haha
command: /bin/uname
register: result # uname结果赋给result
ignore_errors: True # 忽略errors
- command: /bin/df
when: result|failed # 如果result(uname)失败,则执行df
register: aaa # df结果赋给aaa
- command: /bin/ls
when: result|success # 如果result(uname)成功,则执行ls
- command: /bin/lsblk
when: aaa|skipped # 如果aaa被跳过,则执行lsblk
5)include参数
# 避免编写重复的yaml,我们把重复功能的yaml单独拿出来。类似于shell中function,脚本中调用function
- hosts: node-2
name: create_user
vars:
- user: "liang"
tasks:
- name: create user
user: name="{{ user }}"
- include: handlers.yml # 2.8版本之后includd被遗弃,使用import_playbook代替
- import_playbook: handlers.yml
6)register参数
# register类似shell中的变量的用法,可以将task获取的信息赋值通过register参数赋值给一个变量
- hosts: all
tasks:
- shell: hostname
register: Hostname
ignore_errors: True
- name: print pwd_status value
file: name=/tmp/{{ Hostname.stdout }} state=touch # 在/tmp下创建一个以主机名命名的文件
7)应用vars变量
#vars,可以在playbook中直接声明的变量,在task中使用变量
- hosts: all
vars:
user:
name: haha
groups: haha
tasks:
- name: create file haha
file: path=/tmp/{{ user.name }} state=touch # touch /tmp/haha
8)交互式 prompt参数
# prompt 类似shell中的except,实现交互式的playbook
- hosts: 192.195.23.51
vars_prompt: # 引用交互式,类似except
- name: "Name"
prompt: "please enter your name:" # prompt 与用户交互
private: no
- name: "sex"
prompt: "please enter your sex: n
A: mann
B: womann"
private: no # private no为显示用户输入 yes为隐藏
default: man
tasks:
- name: print information
debug: msg="{{ Name }} his sex is {{ sex }}"
- name: touch file
file: path=/tmp/{{ Name }} state=touch
三、playbook报错
一般playbook除了语法及逻辑的错误,其他很少有错误信息,不过在使用shell模块时有一种特殊的情况。
- hosts: 192.168.93.128
tasks:
- name: found process
shell: ps -ef |grep java |egrep -v "grep|snc-agent"
执行ansible-play返回错误:
192.168.93.128 | FAILED | rc=1 >>
non-zero return code
报错信息是因为shell返回结果为空,ansible就以为shell出错了,然后返回错误,也就是我们的 ps 命令没有查出来任何进程。这实际上对于我们的逻辑来说是没有问题的。比如我们没有查到某个进程才去启动它。
解决方案:
1、忽略这个错误,在task中添加 ignore_errors 不会因为这个task影响整个playbook,可以保证playbook的完整运行,不过前台还是会返回错误。
2、使用shell模块时,在命令后面加|cat 将命令命令通过管道符给cat
shell: ps -ef |grep java |egrep -v "grep|snc-agent" |cat
或者使用wc -l的方式去判断进程数
shell: ps -ef |grep java |egrep -v "grep|snc-agent" |wc -l
推荐方案2的第一种方法,可以满足我们的需求还避免shell返回控制。
最后
以上就是多情跳跳糖为你收集整理的ansible那点事——playbook知识一、ansible-play二、ansible-playbook三、playbook报错的全部内容,希望文章能够帮你解决ansible那点事——playbook知识一、ansible-play二、ansible-playbook三、playbook报错所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复