ansible七种武器
-
第一种武器 :ansible命令,用于执行临时性的工作,必须掌握
-
第二种武器 :ansible-doc是模块的文档说明,针对每个模块都有详细的说明及应用案例介绍,功能和Linux系统man命令类似,必须掌握
-
第三种武器 : ansible-console是ansible为用户提供的交互式工具, 用户可以在 ansible- console虚拟出来的终端上像Shell 一样使用 ansible内置的各种命令,这为习惯使用 Shell交互方式的用户提供了良好的使用体验
-
第四种武器 : ansible-galaxy从 github上下载管理 Roles的一款工具与 python的pip类似
-
第五种武器: ansible-playbook 是日常应用中使用频率最高的命令,工作机制:通过读取先编写好的playbook文件实现批量管理, 可以理解为按一定条件组成的 ansible任务集,必须掌握
-
第六种武器: ansible-vault 主要用于配置文件加密,如编写的 playbook文件中包含敏感信息,不想其他人随意查看,可用它加密/解密这个文件
-
第七种武器 :ansible-pull
- ansible有两种工作模式pull/push,默认使用push模式工作,pull和push工作模式机制刚好相反
- 适用场景:有大批量机器需要配置,即便使用高并发线程依旧要花费很多时间,通常在配置大批量机器的场景下使用,灵活性稍有欠缺,但效率几乎可以无限提升,对运维人员的技术水 平和前瞻性规划有较高要求
- 工作原理:与git和crontab结合使用,通过crontab定期拉取指定的Git版本到本地,并以指定模式自动运行预先制订好的指令
json
1)json是什么
- json是JavaScript对象表示法,它是一种基于文本独立于语言的轻量级数据交换格式
- json中的分隔符限于单引号
'
、小括号()
、中括号[]
、大括号{}
、冒号:
和逗号,
2)json特性
- json是纯文本
- json具有“自我描述性“
- json具有层级结构
- json可通过JavaScript进行解析
3)json语法规则
- 数据在键/值对中
- 数据由逗号分隔
- 大括号保存对象
- 中括号保存数组
{"KEY": "VALUE"} #键值对
["aa", "bb", "cc"] #数组
{"KEY": ["aa", "bb"]}
["aa", {"KEY": "VALUE"}, "bb"]
yaml
1)yaml是什么
- yaml是一个可读性高,用来表达数据序列的格式
- yaml参考了多种语言,如:C、Python、Perl等,目前已有数种编程语言或脚本语言支持这种语言
2)yaml基础语法
- yaml的结构通过空格来展示
- 数组使用
-
(减号空格)来表示 - 键值对使用
:
(冒号空格)来表示 - yaml使用一个固定的缩进风格表示数据层级结构关系
- 一般每个缩进级别由两个以上空格组成
#
表示注释- 不可以使用
tab
- 同一层缩进必须对齐
3)yaml键值表示方法
- 采用冒号分隔
- 冒号后必须有一个空格
"KEY": "VALUE"
"KEY":
"VALUE"
"KEY":
"KEY1": "VALUE1"
"KEY2": "VALUE2"
"KEY":
"KEY1":
"VALUE1"
"KEY2":
"VALUE2"
4)yaml数组表示方法
- 使用一个减号加一个空格
- "aa"
- "bb"
- "cc"
"KEY":
- "aa"
- "bb"
- "cc"
jinja2
- jinja2是基于Python的模板引擎,包含变量和表达式两部分,两者在模板求值时会被替换为值,模板中还有标签,控制模板的逻辑
- playbook的模板使用Python的jinja2模块来处理
1)jinja2模板基本语法
- 模板的表达式都是包含在分隔符
{{ }}
内的 - 控制语句都是包含在分隔符
{% %}
内的 - 模板支持注释,包含在分隔符
{# #}
内 - 调用变量
{{varname}}
- 计算
{{2+3}}
- 判断
{{1 in [1,2,3]}}
2)jinja2模板简介
- 变量可以通过过滤器修改。过滤器与变量用管道符分隔,也可以用圆括号传递参数,多个过滤器可以链式调用,前一个过滤器的输出会被作为后一个过滤器的输入
- 例:
{{ 'astr' | password_hash('sha512')}}
- 在线文档:http://docs.jinkan.org/docs/jinja2/templates.html#builtin-filters
Playbook
- playbook是ansible用于配置,部署和管理托管主机剧本通过playbook的详细描述,执行其中的一系列tasks,可以让远端主机达到预期状态
- 也可以说,playbook字面意思即剧本,现实中由演员按剧本表演,在ansible中由计算机进行安装,部署应用,提供对外服务,以及组织计算机处理各种各样的事情
为什么使用playbook?
- 执行一些简单的任务,使用ad-hoc命令可以方便的解决问题,但有时一个设施过于复杂时,执行ad-hoc命令是不合适的,最好使用playbook
- playbook可以反复使用编写的代码,可以放到不同的机器上面,像函数一样,最大化的利用代码,在使用ansible的过程中,处理的大部分操作都是在编写playbook
playbook语法格式
- playbook由YAML语言编写,遵循YAML标准
- 在同一行中,#之后的内容表示注释
- 同一个列表中的元素应该保持相同的缩进
- playbook由一个或多个play组成
- play中hosts,variables,roles,tasks等对象的表示方法都是键值中间以”:“分隔表示
- 文件开始行都应该是—,这是YAML格式的一部分,表明一个文件的开始
playbook构成
- hosts:定义将要执行 playbook的远程主机组
- vars:定义 playbook运行时需要使用的变量
- tasks:定义将要在远程主机上执行的任务列表
- handlers:定义task执行完成以后需要调用的任务
playbook执行结果
- 使用 ansible-playbookplaybook-运行文件,输出内容 为JSON格式,由不同颜色组成便于识别
- 绿色代表执行成功
- 其他颜色代表系统代表系统状态发生改变
- 红色代表执行失败
playbook示例
] vim ping.yml
---
- name: "test host ping "
hosts: all #指定主机集合,all代表所有主机,多个集合以逗号分隔
tasks:
- ping:
] ansible-playbook ping.yml -f 5 #-f并发进程数量,默认为5
tasks
命令的集合 每一个play包含了一个task列表(任务列表) 一个task在其所对应的所 host有主机上(通过 pattern匹配的所有主机)执行完毕之后,下一个task才会执行hosts
主机的集合 定义要执行任务的主机
---
- name: Install apache service to web server
hosts: web
tasks:
- name: Install httpd
yum:
name: httpd
state: latest
- name: Modify listen port
lineinfile:
path: /etc/httpd/conf/httpd.conf
regexp: "Listen 80"
line: "Listen 8080"
- name: Configure default home page
copy:
src: ./index.html
dest: /var/www/html/
mode: 0644
owner: apache
group: apache
- name: Start httpd service and configure boot from boot
service:
name: httpd
state: started
enabled: yes
playbook进阶语法
- 变量
] vim user.yml
---
- name: add user
hosts: web
vars: #定义变量
username: lisi #变量名:变量值
tasks:
- name: add user "{{ username }}" #调用变量,注意格式
user:
name: "{{ username }}"
state: present
group: users
password: "{{ '123qqq...A' | password_hash('sha512') }}" #"|"为管道
] ansible-playbook user.yml
在user.yml文件中删除变量定义,可以通过传递变量的方式定义变量,-e
] ansible-playbook user.yml -e "{"username": "ooxx"}" #使用json格式
] vim args.yml #采用yml格式
---
username: lisi
] ansible-playbook user.yml -e '@args.yml' #使用yaml格式,需要编写yml文件,-e '@文件名'
- error处理方式
- 默认处理方式为如果$?返回值不为0,则不继续进行后续tasks
] vim error.yml
---
- name: error test
hosts: web
tasks:
- name: mkdir directory
shell: mkdir /var/www/cache
ignore_errors: True #默认为False,指定为Ture,代表遇到执行出错时忽略错误继续执行
- name: restart httpd
service:
name: httpd
state: restarted
- tags&handlers
- tags:给tasks定义一个调用标识
- handlers:当关注的资源发生变化时采取的操作
- notify这个action可用于在每个play的最后被触发,这样可以避免有多次改变发生时每次都执行指定操作,取而代之仅在所有的变化发生完成后一次性执行指定操作
- 在notify中列出的操作被称为handlers,即notify调用handlers中定义的操作
] vim apache.yml
---
- name: apache service
hosts: web
tasks:
- name: Configure default home page
tags: config_index
copy:
src: ./index.html
dest: /var/www/html/
mode: 0644
owner: apache
group: apache
- name: Modify listen port
tags: modify_conf #给tasks定义一个标识,执行时可以-t指定,表示只执行该标识的任务
notify: restart_httpd #指定触发的handlers,值为handlers的name的值,注意需要完全匹配,包括空格
lineinfile:
path: /etc/httpd/conf/httpd.conf
regexp: "Listen 80"
line: "Listen 8080"
handlers: #与tasks平级
- name: restart_httpd #定义的名字为notify指定时使用
service:
name: httpd
state: started
] ansible-playbook apache.yml -t modify_conf #指定执行的tags,此时会被触发restart_httpd
] ansible-playbook apache.yml -t config_index #此时不会触发restart_httpd
- 注意事项:
- notify调用的是handlers的name定义的字符串,必须一致(包括空格),否则无法触发
- 多个task触发同一个notify的时候,同一个服务只会触发一次
- notify可以触发多个条件,在生产环境中往往涉及到一个配置文件的改变要重启若干服务的场景,handlers非常合适
notify: #同时触发多个handlers
- restart_php-fpm
- restart_httpd
- restart_memcached
- 结合vars可以写出非常普适的服务管理脚本
- when®ister
- when:有些时候需要在满足特定的条件后再触发某一项操作,或在特定的条件下终止某个行为,这时候需要进行判断,远程中的系统变量facts作为when的条件,可以通过setup模块获取
---
- name: Install VIM
hosts: all
tasks:
- name: Install VIM yum
yum:
name: vim-enhanced
state: installed
when: ansible_os_family == "RedHat"
- name: Install VIM apt
apt:
name: vim
state: installed
when: ansible_os_family == "Debian"
- register:用来保存前一个命令的返回状态
--- #获取web集群中服务器的负载情况,将分均负载大于0.7的服务器的apache关闭
- name: 系统负载管理
hosts: web
tasks:
- name: 获取系统负载情况
shell: uptime |awk '{printf("%.2f",$(NF-2))}'
register: result #result为变量名
- name: 关闭 httpd 服务
service:
name: httpd
state: stopped
when: result.stdout|float > 0.7
#由于ansible的数据交换以json格式保存(文本),所以使用float过滤为浮点数,再与0.7进行比较,result.stdout为标准输出(stdin为标准输入)
5.调试
- debug模块可以在运行时输出更为详细的信息,帮助排错
--- #获取web集群中服务器的负载情况,将分均负载大于0.7的服务器的apache关闭
- name: 系统负载管理
hosts: web
tasks:
- name: 获取系统负载情况
shell: uptime |awk '{printf("%.2f",$(NF-2))}'
register: result #result为变量名
- name: 关闭 httpd 服务
service:
name: httpd
state: stopped
when: result.stdout|float > 0.7
- debug: var=result #运行时会输出变量result的信息
6.with_items
- with_items是playbook标准循环,可以用于迭代一个列表(数组)或字典(键值对),通过
{{ item }}
获取每次迭代的值
---
- name: add user
hosts: db
tasks:
- name: add user "{{ item.username }}"
user:
name: "{{ username }}"
group: users
password: "{{ '123qqq...A' | password_hash('sha512') }}"
with_items:
["aa", "bb", "cc", "dd"] #以json格式定义数组
或者:
---
- name: add user
hosts: db
tasks:
- name: add user "{{ item.username }}"
user:
name: "{{ item.username }}"
group: "{{ item.group }}"
password: "{{ item.password | password_hash('sha512') }}"
with_items:
-
username: "bb"
password: "123456"
group: "users"
-
username: "wk"
password: "banana"
group: "bin"
-
username: "dd"
password: "book"
group: "daemon"
-
username: "jj"
password: "123qqq...A"
group: "mysql"
-
username: "xx"
password: "a"
group: "root"
7.include&roles
- 在编写playbook的时候随着项目越来越大,playbook也越来越复杂,修改也很麻烦。这时可以把一些play/task/handler放在其他文件中,通过include指定包含进去
tasks:
- include: tasks/setup.yml
- include: tasks/users.yml user=aaa #users.yml中可以使用变量user
handlers:
- include: handlers/handlers.yml
- roles像是加强版的include,它可以引入一个项目的文件和目录
- 一般所需的目录层级有
- vars:变量层
- tasks:任务层
- handlers:触发任务
- files:文件
- templates:模板
- default:默认,优先级最低
如果:
---
- hosts: all
roles:
- x
这个play包含了名为"x"的roles,则:
x/tasks/main.yml
x/vars/main.yml
x/handlers/main.yml
x/.../main.yml
都会被包含进这个play。
8.其他命令
ansible-playbook --syntax-check xxx.yml #检测语法
ansible-playbook -C xxx.yml #测试运行
ansible-playbook --list-hosts xxx.yml #显示收到影响的主机
ansible-playbook --list-tasks xxx.yml #显示工作的task
ansible-playbook --list-tags xxx.yml #显示将要运行的tag
补充:
- template模块
- 类似于copy模块,不同之处是可以使用jinja2模板引用setup模块的变量
- 可以用来更改集群中服务器的配置文件,例如需要每个主机写入本机主机名时:
拷贝模板文件进行修改:
wsrep_node_name={{ ansible_hostname }}
# ansible_hostname为setup模块的变量,使用template模块拷贝该文件,变量值是每个主机的主机名
- setup模块变量查找方法
] ansible web -m setup | grep hostname
"ansible_hostname": "test", # KEY:VALUE KEY即变量名,VALUE为值
复杂变量调用:
] ansible web -m setup
"ansible_default_ipv4": {
"address": "192.168.1.111",
调用默认ipv4地址:
{{ ansible_default_ipv4['address'] }}
调用eth0网卡的ipv4地址:
{{ ansible_eth0['ipv4']['address'] }}
注意层级结构即可轻松使用