设为首页 收藏本站
查看: 1409|回复: 0

[经验分享] 自动化运维工具Ansible之Playbooks基础应用

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-7-30 08:55:58 | 显示全部楼层 |阅读模式
记得自己当初最早使用Ansible的时候,网上搜到的中文资料的都是零零散散的,后来只能硬着头皮看官方的英文文档。发现好多事情都没有什么捷径可走,最好的资料还是官方的文档。最近又抽时间按照官方文档对Ansible做了一个较为系统的学习与研究,主要是为了整理一份较为完善的学习笔记供自己以后查阅,哎,年纪大了,记性不好了,写文档才能把有些细节记下来。

Playbooks可以称为是Ansible的配置,部署,编排语言。在Playbooks中,你可以定义远程节点要执行的某组动作。如:希望远程节点要先安装httpd,创建一个vhost,最后启动httpd。

Playbooks使用了YAML格式,具有较少的语法格式。其特意的避免将自己设计为一门语言或者脚本,而是一个纯粹的配置和过程模型。
每个playbooks都有一个或者多个play组成。
play简单来说就是一些主机节点要执行一些任务。最基本的,一个任务也就是调用一个Ansible模块。
通过为Playbooks编写多个play ,可以协调多主机的部署。如,按照一定的步骤在webservers组内的所有主机上执行操作,然后按照一定的步骤在databaseserver组内的主机上执行,然后再有其他更多的命令在webservers组内主机上执行,等等。

下边是个只包含一个play的playbooks:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
[iyunv@web1 ~]# cat /etc/ansible/http.yml
---
- hosts: webservers
vars:
http_port: 80 #定义变量
max_clients: 200 #定义变量
remote_user: root
tasks:
- name: ensure apache is at the latest version
   yum: pkg=httpd state=latest
- name: write the apache config file
   template: src=/etc/ansible/httpd.j2 dest=/etc/httpd.conf
notify:
  - restart apache
- name: ensure apache is running (and enable it at boot)
   service: name=httpd state=started enabled=yes
handlers:
  - name: restart apache
    service: name=httpd state=restarted
[iyunv@web1 ~]# ansible-playbook /etc/ansible/http.yml
PLAY [webservers] *************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.1.65]
TASK: [ensure apache is at the latest version] ********************************
changed: [192.168.1.65]
TASK: [write the apache config file] ******************************************
changed: [192.168.1.65]
TASK: [ensure apache is running (and enable it at boot)] **********************
changed: [192.168.1.65]
NOTIFIED: [restart apache] ****************************************************
changed: [192.168.1.65]
PLAY RECAP ********************************************************************
192.168.1.65 : ok=5 changed=4 unreachable=0 failed=0



上边的playbooks只定义了对webservers组内的主机所执行的一系列任务。

在模板httpd.j2中会引用上边定义的两个变量,如{{ max_clients }}

notify表示当配置文件发生变化时会触发restart apache动作 handlers定义一些要
被触发的动作。

playbooks也可以包含多个play ,如下边的示例,在同一个playbooks中既可以对web servers组操作,也可以对datavase servers组操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
- hosts: webservers
  remote_user: root
  tasks:
    - name: ensure apache is at the latest version
      yum: pkg=httpd state=latest
    - name: write the apache config file
      template: src=/srv/httpd.j2 dest=/etc/httpd.conf
- hosts: databases
  remote_user: root
  tasks:
   - name: ensure postgresql is at the latest version
     yum: name=postgresql state=latest
   - name: ensure that postgresql is started
     service: name=postgresql state=running



play就像任务一样按照在playbooks中的定义顺序从上到下依次执行。

Playbooks中的主机和用户

Playbooks中的每个play ,都需要指定一个远程主机节点(或一组节点主机)和要以哪个远程用户执行任务。
hosts指定主机组的列表,或者是一个主机的匹配正则表达式。多个主机组或者多个匹配模式之间以冒号隔开,如,one*.com:dbserversremote_user指定一个用户账户。
1
2
3
---
- hosts: webservers
  remote_user: root



远程用户也可以在每个任务中指定:
1
2
3
4
5
6
7
---
- hosts: webservers
  remote_user: root
  tasks:
   - name: test connection
   ping:
   remote_user: yourname



也可以以其他用户的身份来执行任务(sudo):
1
2
3
4
---
- hosts: webservers
  remote_user: yourname
  sudo: yes




示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[iyunv@web1 ~]# cat /etc/ansible/sudo.yml
---
- hosts: webservers
  remote_user: liuzhenwei
  sudo: yes
  tasks:
    - name: create file as root
      file: path=/tmp/testfile2 state=touch
[iyunv@web1 ~]# ansible-playbook /etc/ansible/sudo.yml -K -k
SSH password:
SUDO password[defaults to SSH password]:
PLAY [webservers] *************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.1.65]
TASK: [create file as root] ***************************************************
changed: [192.168.1.65]
PLAY RECAP ********************************************************************
192.168.1.65 : ok=2 changed=1 unreachable=0 failed=0
#远程节点
[iyunv@db2 ~]# ll /tmp/testfile2
-rw-r--r--. 1 root root 0 Jul 27 15:01 /tmp/testfile2



也可以为每个任务指定是否使用sudo,而不是应用于整个play中:
1
2
3
4
5
6
7
---
- hosts: webservers
  remote_user: yourname
  tasks:
    - service: name=nginx state=started
      become: yes
      become_method: sudo



也可以先以自己的账户登录,然后切换为其他非root用户:
1
2
3
4
5
---
- hosts: webservers
  remote_user: yourname
  become: yes
  become_user: postgres



示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[iyunv@web1 ~]# cat /etc/ansible/become.yml
---
- hosts: webservers
  remote_user: liuzhenwei
  become: yes
  become_user: tom
  tasks:
   - name: touch file
     file: path=/tmp/sufile state=touch
[iyunv@web1 ~]# ansible-playbook /etc/ansible/become.yml -k --ask-become-pass
SSH password:
SU password[defaults to SSH password]:
PLAY [webservers] *************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.1.65]
TASK: [touch file] ************************************************************
changed: [192.168.1.65]
PLAY RECAP ********************************************************************
192.168.1.65 : ok=2 changed=1 unreachable=0 failed=0
#远程节点
[iyunv@db2 ~]# ll /tmp/sufile
-rw-r--r--. 1 tom tom 0 Jul 27 15:21 /tmp/sufile



-k,--ask-become-pass表示需要命令提示用户输入远程用户及su用户的密码。

也可以使用su来提升用户权限:
1
2
3
4
5
---
- hosts: webservers
  remote_user: yourname
  become: yes
  become_method: su



示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[iyunv@web1 ~]# cat /etc/ansible/become.yml
---
- hosts: webservers
  remote_user: liuzhenwei
  become: yes
  become_method: su
  tasks:
   - name: touch file
     file: path=/tmp/sufiles state=touch
[iyunv@web1 ~]# ansible-playbook /etc/ansible/become.yml -k --ask-su-pass
SSH password:
SU password[defaults to SSH password]:
PLAY [webservers] *************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.1.65]
TASK: [touch file] ************************************************************
changed: [192.168.1.65]
PLAY RECAP ********************************************************************
192.168.1.65 : ok=2 changed=1 unreachable=0 failed=0
#远程节点
[iyunv@db2 ~]# ll /tmp/sufiles
-rw-rw-r--. 1 root root 0 Jul 27 15:23 /tmp/sufiles



注意-k,--ask-su-pass表示需要命令提示用户输入远程用户及su用户的密码。

任务列表

每个play都包含了一个任务列表,任务是按照顺序执行的,且每个任务会都在指定的所有远程节点上执行,然后再执行下一个任务。
playbooks从上到下执行,如果某个主机的某个任务执行失败则退出。
每个任务实际上都是执行了一个模块,并且为该模块指定了特定的参数。文件上边定义的变量,可以用在模块的参数内。
模块都是等幂的,意思就是当你再次运行的 时候,他们只做他们必须要做的操作(改变某些文件状态等),以使系统达到所需的状态。这样的话,当
你重复运行多次相同的playbooks时,也是非常安全的。
每个任务都应该有一个名称,这个名称会在运行playbook的时候输出,如果没有指定名称,那么对主机做的操作行为将会被用来输出到屏幕上。
任务可以以这种格式来定义: module:options

下边是一个简单的任务示例:
1
2
3
tasks:
- name: make sure apache is running
  service: name=httpd state=running



command和shell模块只需要一个参数列表既可:
1
2
3
tasks:
- name: disable selinux
  command: /sbin/setenforce 0



command和shell会关注它的返回码,如果有一个自定义的脚本或者命令,成功执行后的退出码为非0值,可以进行以下操作:
1
2
3
tasks:
- name: run this command and ignore the result
  shell: /usr/bin/somecommand || /bin/true



或者:
1
2
3
4
tasks:
- name: run this command and ignore the result
  shell: /usr/bin/somecommand
  ignore_errors: True



如果参数较多的话也可以将其换行书写:
1
2
3
4
tasks:
- name: Copy ansible inventory file to client
  copy: src=/etc/ansible/hosts dest=/etc/ansible/hosts
         owner=root group=root mode=0644



同样也可以在tasks中引用变量:
1
2
3
tasks:
- name: create a virtual host file for {{ vhost }}
  template: src=somefile.j2 dest=/etc/httpd/conf.d/{{ vhost }}



这些变量都会在vars中定义。关于变量和某些常用模块的使用方法后续也会介绍。

Handlers:当某些操作发生改变时触发执行的任务

正如前面提到的,Ansible模块都是幂等的,而且当在远程主机上做了改变之后也可以传递change这个事件。Playbooks有一个基本的事件系统来对‘改
变’做出响应。
notify中指定的行为会在每个任务的最后触发,如果在多个不同的任务里指定了相同的触发事件,那么只会触发一次。
例如,多个任务都表明需要重启Apache,因为他们都修改了配置文件。但是Apache只会重启一次,这样就避免了一些不必要的重启动作。
下边的例子,表名当文件内容发生变化的时候,重启两个服务:
1
2
3
4
5
- name: template configuration file
  template: src=template.j2 dest=/etc/foo.conf
  notify:
   - restart memcached
   - restart apache



notify中的任务称为handlers

handlers也是一个任务列表,与普通tasks不同的是hanlders下边的每个操作行为都需要指定一个全局唯一的名称。如果没有任务操作触发该
hanlders,那么它将不会运行。如论有多少个操作都触发了同一个handlers,在所有的任务执行完成后,也只会触发执行一次该handlders。
handlers定义格式如下:
1
2
3
4
5
handlers:
  - name: restart memcached
    service: name=memcached state=restarted
  - name: restart apache
     service: name=apache state=restarted



示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[iyunv@web1 ~]# cat /etc/ansible/notify.yml
---
- hosts: webservers
  remote_user: root
  vars:
   http_port: 8083
   max_clients: 220
  tasks:
   - name: template config file
     template: src=/etc/ansible/httpd.j2 dest=/etc/httpd.conf
  notify:
   - restart apache
  handlers:
   - name: restart apache
   service: name=httpd state=restarted
[iyunv@web1 ~]# ansible-playbook /etc/ansible/notify.yml
PLAY [webservers] *************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.1.65]
TASK: [template config file] **************************************************
changed: [192.168.1.65]
NOTIFIED: [restart apache] ****************************************************
changed: [192.168.1.65]
PLAY RECAP ********************************************************************
192.168.1.65 : ok=3 changed=2 unreachable=0 failed=0



vars是定义的变量内容,varname:value的形式,在该playbooks中和在template指定的模板文件中都可以引用变量,关于template模块和变量在其他文档中会详细说明。

notify hanlders都会按照书写的循序运行。
hanlders名称必须是全局唯一。
如果有两个handlers定义了相同的名称,只会有一个handlers会运行。

其实上边已经无形中说明了playbooks的执行方法,使用ansible-playbook命令:
1
ansible-playbook playbook.yml -f 10



-f|--forks 指定使用的并发进程数。
OK,关于playbooks的简单使用就介绍到这里,这基本上就可以做很多平时运维中的自动化工作了,playbooks高效的组织了ansible对远程节点所执行的操作。而且playbooks还有其他很多特性及语法可以更好地组织自动化操作,并且可以很方便的复用某些操作,不需要在不同的地方重复定义同一个操作行为,这些抽时间都会整理上来的。

评分

参与人数 1经验 +4 收起 理由
myron11 + 4

查看全部评分


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-92058-1-1.html 上篇帖子: ansible的使用 下篇帖子: 自动化运维工具Ansible之Playbooks的roles和include
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表