文章目录
一、YAML语言
1.1 YAML介绍
- 另一种标记语言,是用来写配置文件的语言,非常简洁和强大;
- YAML语言和其他语言类似,也可以表达散列表、标量等数据结构;
- 结构通过空格来展示,序列里配置项通过-来代表,Map里键值用。
1.2 基本语法规则
- 大小写敏感
- 是用缩进表示层级关系
- 缩进时不允许是用tab键,只允许使用空格
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
1.3 YAML支持的数据结构
-
对象:键值对的集合,又称为映射(mapping)/哈希(hashes)/字典(directory)
例如:name:Example Developer -
数组:一组按次序排列的值,又称为序列(sequence)/列表(list)
例如:-Apple
-orange -
纯量:单个的,不可再分的值
例如:number:12.30
二、Ansible的脚本—playbook剧本
playbook是通过task调用ansible的模块将多个play组织在一个playbook中运行
2.1 playbook的组成
- Tasks:任务,即调用模块完成的某操作
- Variables:变量
- Templates:模板
- Handles:处理器,当满足某条件是,触发执行的操作
- Roles:角色
2.2 补充命令
ansible-playbook mysql.yaml --syntax-check # 检查yaml文件的额语法是否正确
ansible-playbook mysql.yaml --list-task # 检查task任务
ansible-playbook mysql.yaml --list-hosts # 检查生效的主机
ansible-playbook mysql.yaml --start-at-task="copy Nginx.conf" # 指定从某个task开始运行
2.3 tasks和action
2.3.1 事务执行与回滚
- Play的主体部分是task列表,task列表中的各任务按次序逐个在hosts中指定的主机上执行,即在所有主机上完成第一个任务后再开始第二个任务
- 在运行playbook时(从上到下执行),如果一个host执行task失败,整个tasks都会回滚,请修正playbook中的错误,然后重新执行即可。
- Task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量,模块执行时幂等的,这意味着多次执行是安全的,因为其结果一致.
2.3.2 name的必要性
每一个task必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个task的。如果没有定X
2.3.3 task的格式
定 一个task,常见的格式:”module: options”例如 : yum: name=httpd
2.3.4 其他注意点
ansible的自带模块中,command模块和shell模块无需使用key=value格式
三、编写playbook剧本
3.1 备份文件到已知用户的家目录下
[root@server1 opt]# vim sudo1.yaml
- hosts: mysql
remote_user: root
become: yes
become_user: wangwu
tasks:
- name: copy file
copy: src=/etc/fstab dest=/home/wangwu/fstab.bak
[root@server1 opt]# ansible-playbook sudo1.yaml --syntax-check # 对剧本的语法进行检测
playbook: sudo1.yaml # 显示这样的为检测通过
[root@server1 opt]# ansible-playbook sudo1.yaml # 执行剧本
PLAY [mysql] **************************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [192.168.10.13]
TASK [copy file] **********************************************************************************
changed: [192.168.10.13]
PLAY RECAP ****************************************************************************************
192.168.10.13 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3.2 创建新用户
[root@server1 opt]# vim create.yml
- hosts: mysql
remote_user: root
tasks:
- name: create group
group: name=tomcat gid=303
- name: create user
user: name=tomcat uid=303 group=tomcat
[root@server1 opt]# ansible-playbook create.yml --syntax-check # 检查剧本的语法
playbook: create.yml
[root@server1 opt]# ansible-playbook create.yml # 执行剧本
PLAY [mysql] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.10.13]
TASK [create group] ************************************************************
ok: [192.168.10.13]
TASK [create user] *************************************************************
ok: [192.168.10.13]
PLAY RECAP *********************************************************************
192.168.10.13 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3.3 安装服务及开启服务
[root@server1 opt]# vim httpd.yaml
- hosts: mysql
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
- name: stop firewlld
service: name=firewalld state=stopped
- name: start httpd
service: name=httpd state=started
- name: touch file
copy: content="this is web!!" dest=/var/www/html/index.html
[root@server1 opt]# ansible-playbook httpd.yaml # 执行剧本
PLAY [mysql] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.10.13]
TASK [install httpd] ***********************************************************
changed: [192.168.10.13]
TASK [stop firewlld] ***********************************************************
ok: [192.168.10.13]
TASK [start httpd] *************************************************************
changed: [192.168.10.13]
TASK [touch file] **************************************************************
changed: [192.168.10.13]
PLAY RECAP *********************************************************************
192.168.10.13 : ok=5 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3.4 示例事务回滚操作
验证以下的结论,回滚操作使得在错误事务之前的操作完成,但是错误操作及以后的事务都没有执行,这样,让检查和维护的工作量减轻了很多
3.5 忽略错误,强制返回成功
对应上一个实验,我们可以认为干预当碰见错误时,不让程序直接实现回滚,而让程序跳过错误,继续执行下面的操作。
3.6 多任务在同一剧本中
[root@server1 opt]# vim aa.yaml
- hosts: webserver
remote_user: root
tasks:
- name: create group
group: name=aaa gid=666
- name: create user
user: name=aaa uid=666 group=aaa
- hosts: webserver
remote_user: root
become: yes
become: aaa
tasks:
- name: copy file
copy: src=/etc/fstab dest=/home/aaa/fstab.bak
[root@server1 opt]# ansible-playbook aa.yaml # 执行剧本
[root@server2 ~]# id aaa # 到指定客户机上面查看执行情况
uid=666(aaa) gid=666(aaa) groups=666(aaa)
四、handlers介绍及剧本编写
4.1 handlers介绍
- handlers也是一些tasks的列表,和一般的task并没有什么区别
- 是由通知者进行的notify,无果没有notify,则handles不会执行,加入被notify了,则handles会执行
- 不管有多少个通知者进行了notify,等到play嘚瑟所有task执行完成后,handlers也只会被执行一次
4.2 编写剧本
[root@server1 opt]# vim www.yaml
- hosts: mysql
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
- name: start httpd
service: name=httpd state=started enabled=true
notify: # 通知名称,可以同时多个
- touch file
handlers: # 通知名称必须一致
- name: touch file
copy: content="this is web" dest=/var/www/html/index.html
[root@server1 opt]# ansible-playbook www.yaml --syntax-check
playbook: www.yaml
[root@server1 opt]# ansible-playbook www.yaml
PLAY [mysql] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.10.13]
TASK [install httpd] ***********************************************************
changed: [192.168.10.13]
TASK [start httpd] *************************************************************
changed: [192.168.10.13]
RUNNING HANDLER [touch file] ***************************************************
changed: [192.168.10.13]
PLAY RECAP *********************************************************************
192.168.10.13 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
五、变量设置
5.1 直接在剧本中赋值变量
[root@server1 opt]# vim www.yaml
- hosts: mysql
remote_user: root
vars:- aa: httpd
tasks: - name: install httpd
yum: name={{aa}} - name: start httpd
service: name={{aa}} state=started enabled=true
notify:- touch file
handlers:
- touch file
- name: touch file
copy: content=“this is web” dest=/var/www/html/index.html
- aa: httpd
在mysql节点上查看httpd的状态信息:
5.2 通过ansible命令传递
[root@server1 opt]# vim www.yaml
- hosts: mysql
remote_user: root
vars:- aa: ## 可根据需要在传递变量的时候床底多个变量
tasks: - name: install httpd
yum: name={{aa}} - name: start httpd
service: name={{aa}} state=started enabled=true
notify:- touch file
handlers:
- touch file
- name: touch file
copy: content=“this is web” dest=/var/www/html/index.html
- aa: ## 可根据需要在传递变量的时候床底多个变量
通过ansible命令传递变量执行剧本:
在mysql节点上查看httpd的状态信息:
5.3 传递系统固定变量
[root@server1 opt]# vim gdbl.yml
- hosts: mysql
remote_user: root
tasks:- name: print
copy: content="{{ansible_all_ipv4_addresses}}" dest=/opt/add.txt
- name: print
5.4 在hosts配置文件中定义
[root@server1 opt]# grep -v "^#" /etc/ansible/hosts | grep -v "^$"
[webserver]
192.168.10.12
[mysql]
192.168.10.13 zhangsan="123456" # 在hosts里面赋值
[root@server1 opt]# vim gdbl.yml
- hosts: mysql
remote_user: root
tasks:
- name: print
copy: content="{{zhangsan}}" dest=/opt/zhangsan.txt
[root@server1 opt]# ansible-playbook gdbl.yml --syntax-check # 语法的检测
playbook: gdbl.yml
[root@server1 opt]# ansible-playbook gdbl.yml # 执行剧本
PLAY [mysql] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.10.13]
TASK [print] *******************************************************************
changed: [192.168.10.13]
PLAY RECAP *********************************************************************
192.168.10.13 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
服务变量:
- 剧本使用的 服务器名称,数据
- 命令 ip地址,测试
- 固定变量
- 节点hosts 以系统的参数值
六、条件测试
- 如果需要根据变量、facts (setup) 或此前任务的执行结果来作为某task执行与否的前提时要用到条件测试,在Playbook中条件测试使用when
- 在task后添加when子句即可使用条件测试: when子句支持jinjia2表达式或语法
6.1 单条件测试
[root@server1 opt]# vim xt.yml
- hosts: mysql
remote_user: root
tasks:
- name: shutdown Cent
command: /sbin/shutdown -h now
when: ansible_distribution == "CentOS"
6.2 多条件判断
[root@server1 opt]# vim xt.yml
- hosts: mysql
remote_user: root
tasks:
- name: shutdown Cent
command: /sbin/shutdown -h now
when:
- ansible_distribution == "CentOS"
- ansible_distribution_major_version == "7"
6.3 组条件判断
[root@server1 opt]# vim xt.yml
- hosts: mysql
remote_user: root
tasks:- name: shutdown Cent
command: /sbin/shutdown -h now
when: (ansible_distribution == “CentOS” and ansible_distribution_major_version == “7”) or
(ansible_distribution == “Debian” and ansible_distribution_major_version == “7”)
- name: shutdown Cent
七、迭代
- 当有需要重复性执行的任务时,可以使用迭代机制,其使用格式为将需要迭代的内容定义为item变量引用,并通过with_items语句指明迭代的元素
7.1 应用
-
迭代的安装软件
[root@server1 opt]# vim install.yml - hosts: mysql remote_user: root tasks: - name: install httpd ftpd yum: name={{item}} with_items: - httpd - tomcat
安装完成:
-
通过迭代来添加用户和组
[root@server1 opt]# vim useradd.yaml - hosts: mysql remote_user: root tasks: - name: create group group: name={{item.name}} gid={{item.gid}} with_items: - { name: 'zhaoming',gid: '333'} - { name: 'chenqian',gid: '444'} - name: create user user: name={{item.xingming}} uid={{item.uid}} group={{item.group}} with_items: - { xingming: 'zhaoming',uid: '333',group: 'zhaoming'} - { xingming: 'chenqian',uid: '444',group: 'chenqian'}
八、Templates模板模块
- Jinja是基于Python的模板引擎。template类是Jinja的另一个重要组件,可以看作一个编译过的模块文件,用来生产目标文本,传递Python的变量给模板去替换模板中的标记。
- jinja2是基于python的模板引擎,功能比较类似于PHP的smarty,J2ee的Freemark和velocity。它能完全支持unicode,并具有集成的沙盒执行环境,应用广泛。jinja2使用BSD授权
8.1 实例
以安装apache为例,具体来说明Templates模块的工作流程
-
首先要拷贝模板配置文件到ansible管理端来
scp root@192.168.10.13:/etc/httpd/conf/httpd.conf /opt/
-
对拷贝过来的文件进行修改,改成我们需要的格式类型,并修改此时配置文件的格式
# vim httpd.conf Listen {{http_port}} ServerName {{server_name}} Maxclients {{access_num}} # mv httpd.conf httpd.conf.j2
-
进入ansible只配置文件,赋值变量
[root@server1 opt]# vi /etc/ansible/hosts [webserver] 192.168.10.12 http_port=192.168.10.12:80 server_name=www.aa.com:80 access_num=600
-
剧本的编写
[root@server1 opt]# vim apache.yaml - hosts: webserver remote_user: root tasks: - name: install httpd yum: name=httpd - name: congfig file template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf - name: start httpd service: name=httpd state=started - name: stop firewalld service: name=firewalld state=stopped
我们进入到webserver节点检查已经安装好的httpd服务,并查看其配置文件,是否根据我们的要求更改完成。
[root@server2 ~]# vi /etc/httpd/conf/httpd.conf
Listen 192.168.10.12:80
ServerName www.aa.com:80
Maxclients 600
九、tags标签模块
- 在一个playbook中,我们一般会定义很多个task,如果我们只想执行其中的某一个或者多个task时就可以使用tags标签功能了
9.1 单标签任务
[root@server1 opt]# vim biaoqian.yml
- hosts: webserver
remote_user: root
tasks:- name: copy hosts
copy: src=/etc/hosts dest=/opt/hosts1
tags:- aaa
- name: touch hosts2
file: path=/opt/hosts2 state=touch - name: touch hosts3
file: path=/opt/hosts3 state=directory
- name: copy hosts
9.2 多标签任务
-
当剧本中有多个任务,但存在两个标签任务,且标签名一样时,执行时,只执行这两给任务
[root@server1 opt]# vim biaoqian.yml - hosts: webserver remote_user: root tasks: - name: copy hosts copy: src=/etc/hosts dest=/opt/hosts1 tags: - aaa - name: touch hosts2 file: path=/opt/hosts2 state=touch tags: - aaa - name: touch hosts3 file: path=/opt/hosts3 state=directory
9.3 always标签
-
事实上不光可以为单个或多个task指定同一个tags,playbook还提供了一个特殊的tags为always,作用就是当使用always当tags的task时,无论执行哪个tags时,定义有always的任务必须强制执行
[root@server1 opt]# vim biaoqian.yml - hosts: webserver remote_user: root tasks: - name: copy hosts copy: src=/etc/hosts dest=/opt/hosts1 tags: - aaa - name: touch hosts2 file: path=/opt/hosts2 state=touch tags: - aaa - name: touch hosts3 file: path=/opt/hosts3 state=directory tags: - always
说明always标签无论是否选中的情况下,都进行了执行。
十、role模块
- roles(角色)能够根据层次型结构自动装载变量文件、task以及handlers等。 简单来讲,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地include
10.1 roles内各目录含义解释
目录 | 描述 |
---|---|
files | 用来存放由copy模块或script模块调用的文件 |
templates | 用来存放jinjia2模板,template模块会自动在此目录中寻找jinjia2模板文件 |
tasks | 此目录应当包含一个main.yml文件, 用于定义此角色的任务列表,此文件可以使用include包含其它的位于此目录的task文件 |
handlers | 此目录应当包含一个main.yml文件,用于定义此角色中触发条件时执行的动作 |
vars | 此目录应当包含一个main.yml文件,用于定义此角色用到的变量 |
defaults | 此目录应当包含一个main.yml文件,用于为当前角色设定默认变量 |
meta | 此目录应当包含一个main.yml文件, 用于定义此角色的特殊设定及其依赖关系 |
10.2 通过roles模块来完成LAMP架构
# 创建所需的三部分的功能模块
cd /etc/ansible/roles/
mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta} -p
# 创建各模块所需的main.yml文件(空文件)
touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/php/{defaults,vars,tasks,meta,handlers}/main.yml
配置 main.yml 文件内容
cd /etc/ansible/roles/
vim httpd/tasks/main.yml
- name: install httpd
yum: pkg=httpd
vim mysql/tasks/main.yml
- name: install mysql
yum: pkg=mariadb*
vim php/tasks/main.yml
- name: install php
yum: pkg=php
配置执行剧本文件
cd /etc/ansible/
vim site.yml
- hosts: mysql
remote_user: root
roles:
- httpd
- mysql
- php
执行剧本
[root@server1 ansible]# ansible-playbook site.yml --syntax-check
playbook: site.yml
[root@server1 ansible]# ansible-playbook site.yml
PLAY [mysql] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.10.13]
TASK [install httpd] ***********************************************************
changed: [192.168.10.13]
TASK [install mysql] ***********************************************************
ok: [192.168.10.13]
TASK [install php] *************************************************************
changed: [192.168.10.13]
PLAY RECAP *********************************************************************
192.168.10.13 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
到指定的主机进行验证:
[root@server3 ~]# rpm -qa httpd
httpd-2.4.6-95.el7.centos.x86_64
[root@server3 ~]# rpm -qa php
php-5.4.16-48.el7.x86_64
[root@server3 ~]# cd /etc/my.cnf.d/
[root@server3 my.cnf.d]# ll
total 4
-rw-r--r--. 1 root root 232 Apr 30 2017 mysql-clients.cnf