标签:ansible playbooks 自动化运维 python
记得自己当初最早使用Ansible的时候,网上搜到的中文资料的都是零零散散的,后来只能硬着头皮看官方的英文文档。发现好多事情都没有什么捷径可走,最好的资料还是官方的文档。最近又抽时间按照官方文档对Ansible做了一个较为系统的学习与研究,主要是为了整理一份较为完善的学习笔记供自己以后查阅,哎,年纪大了,记性不好了,写文档才能把有些细节记下来。
Playbooks可以称为是Ansible的配置,部署,编排语言。在Playbooks中,你可以定义远程节点要执行的某组动作。如:希望远程节点要先安装httpd,创建一个vhost,最后启动httpd。
Playbooks使用了YAML格式,具有较少的语法格式。其特意的避免将自己设计为一门语言或者脚本,而是一个纯粹的配置和过程模型。
每个playbooks都有一个或者多个play组成。
play简单来说就是一些主机节点要执行一些任务。最基本的,一个任务也就是调用一个Ansible模块。
通过为Playbooks编写多个play ,可以协调多主机的部署。如,按照一定的步骤在webservers组内的所有主机上执行操作,然后按照一定的步骤在databaseserver组内的主机上执行,然后再有其他更多的命令在webservers组内主机上执行,等等。
下边是个只包含一个play的playbooks:
[root@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 [root@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组操作:
--- - 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:dbservers。remote_user指定一个用户账户。
--- - hosts: webservers remote_user: root
远程用户也可以在每个任务中指定:
--- - hosts: webservers remote_user: root tasks: - name: test connection ping: remote_user: yourname
也可以以其他用户的身份来执行任务(sudo):
--- - hosts: webservers remote_user: yourname sudo: yes
示例:
[root@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 [root@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 #远程节点 [root@db2 ~]# ll /tmp/testfile2 -rw-r--r--. 1 root root 0 Jul 27 15:01 /tmp/testfile2
也可以为每个任务指定是否使用sudo,而不是应用于整个play中:
--- - hosts: webservers remote_user: yourname tasks: - service: name=nginx state=started become: yes become_method: sudo
也可以先以自己的账户登录,然后切换为其他非root用户:
--- - hosts: webservers remote_user: yourname become: yes become_user: postgres
示例:
[root@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 [root@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 #远程节点 [root@db2 ~]# ll /tmp/sufile -rw-r--r--. 1 tom tom 0 Jul 27 15:21 /tmp/sufile
-k,--ask-become-pass表示需要命令提示用户输入远程用户及su用户的密码。
也可以使用su来提升用户权限:
--- - hosts: webservers remote_user: yourname become: yes become_method: su
示例:
[root@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 [root@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 #远程节点 [root@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。
下边是一个简单的任务示例:
tasks: - name: make sure apache is running service: name=httpd state=running
command和shell模块只需要一个参数列表既可:
tasks: - name: disable selinux command: /sbin/setenforce 0
command和shell会关注它的返回码,如果有一个自定义的脚本或者命令,成功执行后的退出码为非0值,可以进行以下操作:
tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand || /bin/true
或者:
tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand ignore_errors: True
如果参数较多的话也可以将其换行书写:
tasks: - name: Copy ansible inventory file to client copy: src=/etc/ansible/hosts dest=/etc/ansible/hosts owner=root group=root mode=0644
同样也可以在tasks中引用变量:
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只会重启一次,这样就避免了一些不必要的重启动作。
下边的例子,表名当文件内容发生变化的时候,重启两个服务:
- 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定义格式如下:
handlers: - name: restart memcached service: name=memcached state=restarted - name: restart apache service: name=apache state=restarted
示例:
[root@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 [root@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命令:
ansible-playbook playbook.yml -f 10
-f|--forks 指定使用的并发进程数。
OK,关于playbooks的简单使用就介绍到这里,这基本上就可以做很多平时运维中的自动化工作了,playbooks高效的组织了ansible对远程节点所执行的操作。而且playbooks还有其他很多特性及语法可以更好地组织自动化操作,并且可以很方便的复用某些操作,不需要在不同的地方重复定义同一个操作行为,这些抽时间都会整理上来的。
本文出自 “diannaowa” 博客,请务必保留此出处http://diannaowa.blog.51cto.com/3219919/1679837
标签:ansible playbooks 自动化运维 python
原文地址:http://diannaowa.blog.51cto.com/3219919/1679837