Ansible playbook
简单的playbook
编写playbook
#hello.yml
#---可写可不写,习惯表示yml的开始
---
#对websrvs里的主机操作
- hosts: websrvs
#用root身份登录
remote_user: root
#指定命令
tasks:
#name是说明性的,说明等下我要做的是什么操作
- name: hello
#模块名,后面跟参数,相当于 -a里的值
commmand: hostname
运行playbook
ansible-playbook hello.yml
执行上述playbook,是看不到结果的。查看playbook帮助:
ansible-playbook --help
。
playbook具体使用
工具
ansible-vault
管理加密解密yml文件
ansible-vault encrypt hello.yml
对hello.yml进行加密,并且输入口令。加密后无法看到原文件内容,且无法运行。
ansible-vault decrypt hello.yml
对hello.yml进行解密。
ansible-vault view hello.yml
看hello.yml内容,需要口令。
ansible-vault edit hello.yml
对hello.yml进行编辑。
ansible-vault rekey hello.yml
修改口令。
ansible-vault create hello2.yml
创建新的yml。
ansible-console
可执行交互式命令,支持tab。
ansible-console
进入控制台。
root@all (3)[f:5]$
提示符:用户:root,默认对主机清单的哪些主机操作:all,包括主机数:(3),并发执行个数:f:5。
切换操作的主机:cd websrvs
即可对websrvs主机操作。
修改并发:forks 10
修改为10个并发。
了解用法:?
返回的即各个模块。
执行一个命令:command hostname
;hostname name=boxker.node1
。
playbook使用
YAML介绍
yaml是一个可读性高的用来表达资料序列的格式。
语法简介
- 在单一档案中,可用三个连字符区分多个档案,另外可选择性的连续三个点号来表示档案结尾
- 次行开始写playbook内容,一般建议写明该playbook功能
- 使用#注释
- 缩进必须统一,不能混用空格和tab
- 缩进级别也必须统一,同样的缩进表示同样的级别,程序判别配置的级别是通过缩进结合换行实现的
- YAML打下些判断和Linux一致,区分大小写
- k/v值可以换行饿也可以同行写,用:分隔
- v可以是字符串,也可以是另一个列表
- 一个完整的功能块最少元素包括:name:task
- 一个name只能包括一个task
- YAML文件扩展名通常为yml或yaml
列表
所有元素用-开头,表示同一类型的元素
字典
有多个键值对组成,:分隔
name:hi
job:dev
skill:elite
也可以将key:value放在{}中,用逗号分隔多个kv
{name:hi,job:dev,skill:elite}
playbook 核心元素
- Hosts 远程主机列表
- Tasks 任务集
- Varniables 内部变量或自定义变量在playbook中调用
- Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
- Handlers 和 Notity综合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
- tags 标签指定莫条任务执行,用于选择运行playbook中的部分代码。
创建文件、用户、安装httpd、复制网页、运行服务
---
- hosts: websrvs
remote_name: root
tasks:
- name: create new file
file: name=/data/newfile state=touch
- name: create new user
user: name=test1 system=yes shell=/sbin/nologin
- name: install package
yum: name=httpd
- name: copy html
copy: src=/var/www/html/index.html dest=/var/www/html/
- name: start service
service: name=httpd state=started enabled=yes
检查:ansible-playbook -C file.yml
运行:ansible-playbook file.yml
-C
即担心有错,用来检查,不会有改变。ss是Socket Statistics的缩写。查看80端口情况:
ss -tln | grep :80
。ss命令详解
#ss 参数:
Usage: ss [ OPTIONS ]
ss [ OPTIONS ] [ FILTER ]
-h, --help this message
-V, --version output version information
-n, --numeric don't resolve service names
-r, --resolve resolve host names
-a, --all display all sockets
-l, --listening display listening sockets
-o, --options show timer information
-e, --extended show detailed socket information
-m, --memory show socket memory usage
-p, --processes show process using socket
-i, --info show internal TCP information
--tipcinfo show internal tipc socket information
-s, --summary show socket usage summary
-b, --bpf show bpf filter socket information
-E, --events continually display sockets as they are destroyed
-Z, --context display process SELinux security contexts
-z, --contexts display process and socket SELinux security contexts
-N, --net switch to the specified network namespace name
-4, --ipv4 display only IP version 4 sockets
-6, --ipv6 display only IP version 6 sockets
-0, --packet display PACKET sockets
-t, --tcp display only TCP sockets
-S, --sctp display only SCTP sockets
-u, --udp display only UDP sockets
-d, --dccp display only DCCP sockets
-w, --raw display only RAW sockets
-x, --unix display only Unix domain sockets
--tipc display only TIPC sockets
--vsock display only vsock sockets
-f, --family=FAMILY display sockets of type FAMILY
FAMILY := {inet|inet6|link|unix|netlink|vsock|tipc|help}
-K, --kill forcibly close sockets, display what was closed
-H, --no-header Suppress header line
-A, --query=QUERY, --socket=QUERY
QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram|tipc}[,QUERY]
-D, --diag=FILE Dump raw information about TCP sockets to FILE
-F, --filter=FILE read filter information from FILE
Tasks 格式
- action:module arguments
- module: arguments (建议)
大部分都是 key: value,除了shell 和 command后面跟命令。
意外退出默认中断执行
如果命令或脚本退出码不为零:
#方法1
#错误返回真,便可以继续执行
tasks:
- name: run this command and ignore the restul
shell: /usr/bin/somecommand || /bin/true
#方法2
#使用ignore_errors,无论成功错误都忽略
tasks:
- name: run this command and ignore the restul
shell: /usr/bin/somecommand
ignore_errors: True
常见选项
--check 只检测可能发生的改变,但不真正的操作
--list-hosts 列出运行任务的主机
--list-tasks 列出任务列表
--list-tags 列出tags
--limit 主机列表,只针对主机列表中的主机执行
-v 显示过程,vv,vvv
一个模块对应一个name,不能混在一起写,只会保留最后一个,会有警告。执行中没有写绝对路径则以当前目录为环境。
Handlers、Notify
task列表,这些task和前面的task没有本质的不同,用于当关注的资源发生变化时,才会采取一定的操作。相当于一个触发器。和Tasks时并列的关系,可以监控其中一个task的action动作,其中发现一个action动作执行成功了,将会触发handlers定义的一些命令。(例如修改了配置文件,重新执行yml文件,像serice便不会restarted)。
Notify此action可用于每个play的最后触发,这样可以避免多次改变发生时每次都执行指定的操作,竟在所有变化发生完成后一次性的执行指定操作。在Notify中列出的操作称为handler,也即Notify中调用Handler中定义的操作。
---
- hosts: websrvs
remote_name: root
tasks:
- name: install httpd package
yum: name=httpd
- name: copy conf file
copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=yes
notify: restart service
- name: start service
service: name=httpd state=started enabled=yes
handlers:
- name: restart service
service: name=httpd state=restarted
notify 触发多个动作,用列表
notify:
- restart service
- Check
当文件和远程文件一模一样,copy的backup不会生效。
Tags
起标签,将来可以调用标签的内容
---
- hosts: websrvs
remote_name: root
tasks:
- name: install httpd package
yum: name=httpd
tags: inshttpd
- name: copy conf file
copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=yes
notify: restart service
- name: start service
service: name=httpd state=started enabled=yes
tags: rshttpd
handlers:
- name: restart service
service: name=httpd state=restarted
执行 ansible-playbook -t rshttpd httpd.yml
,只执行rshttpd部分。
执行安装开启服务 ansible-playbook -t inshttpd,rshttpd httpd.yml
若有多个task的tags都相同,则在-t执行时均会操作。多个动作可公用一个标签。
ansible-playbook httpd.yml --list-tags
只看标签信息。
playbook中变量的使用
变量名:只能由字母、数字、下划线组成,且只能以字母开头
变量来源:
1.ansible setup facts 远程主机的所有变量都可以直接调用
setup模块,系统信息。
ansible all -m setup -a 'filter=ansible_hostname'
查看hostname信息。filter还支持通配符。ansible_hostname
即为一个变量。
2.在/etc/ansible/hosts
中定义
普通变量:主机组中单独定义,优先级高于公共变量
公共(组)变量:针对主机组中所有主机定义统一变量
#/etc/ansible/hosts
[websrvs]
192.168.1.111 http_port=81
192.168.1.112 http_port=82
#hostname.yml
---
- hosts: websrvs
remote_name: root
tasks:
- name: set hostname
hostname: name=www{{ http_port }}.boxker.com
#/etc/ansible/hosts
[websrvs]
192.168.1.111 http_port=81
192.168.1.112 http_port=82
[websrvs:vars]
nodename=www
domainname=boxker.com
#hostname.yml
---
- hosts: websrvs
remote_name: root
tasks:
- name: set hostname
hostname: name={{ nodename }}{{ http_port }}.{{ domainname }}
设置hostname:
hostnamectl set-hostname node1
3.通过命令行指定变量,优先级最高
ansible-playbook -e varname=value
4.在playbook中定义
var:
- var1: value1
- var2: value2
5.在role中定义
安装自定义包并开启服务
---
- hosts: websrvs
remote_name: root
tasks:
- name: install package
yum: name={{ pkname }}
- name: start service
service: name={{ pkname }} state=started enabled=yes
执行:ansible-playbook -e 'pkname=vsftpd' app.yml
安装两个包
---
- hosts: websrvs
remote_name: root
tasks:
- name: install 1 package
yum: name={{ pkname1 }}
- name: install 2 package
yum: name={{ pkname2 }}
执行:ansible-playbook -e 'pkname1=httpd pkname2=memcached' app.yml
playbook中定义
---
- hosts: websrvs
remote_name: root
vars:
- pkname1: httpd
- pkname2: memcached
tasks:
- name: install 1 package
yum: name={{ pkname1 }}
- name: install 2 package
yum: name={{ pkname2 }}
执行:ansible-playbook app.yml