天天看点

ansible使用及YAML语法介绍

一、简介 

1、ansible 简介

    ansible官方的title是“Ansible is Simple IT Automation”——简单的自动化IT工具。这个工具的目标有这么几项:自动化部署APP;自动化管理配置项;自动化的持续交付;自动化的(AWS)云服务管理。

    所有的这几个目标本质上来说都是在一个台或者几台服务器上,执行一系列的命令而已,而如果你要管理的服务器是成千上万台的,那你用一台服务器去管理控制这大批量的服务器,势必会造成这台主控机的相当可观的资源消耗和性能的低下(即使可以使用 ansible -f 参数并行执行),这时就需要有种 p2p 的概念,让每一台被同步、配置的服务器也可以做为一台 ansible 中控机去同步配置其它的服务器。

    Ansible 无需安装服务端和客户端,只要 SSH 即可。这意 味着,任何一台装有 Ansible 的机器都可以成为强大的管理端。Ansible 上手十分快,用 Ad-Hoc 可以应付简单的管理任务,麻烦点的也可以定义 Playbook 文 件来搞定。

2、强大的自动化运维工具

    强大的自动化工具有:ansible,puppet,saltstack

    puppet与saltstack这2个软件都需要安装客户端,而saltstack与ansible很相似,都是属于python流的,但saltstack不是很稳定,所以ansible的搜索率是saltstack的3倍也不是没有原因的。puppet虽然稳定,但命令执行的时候,需要配置模块儿,非常麻烦,而且还需要安装客户端,如果公司和别的公司有合作关系的话,很显然,安装客户端是一个不得不考虑的因素;因此,ansible在性能方面并不弱于这两个工具,而且使用还并不繁琐,关键ansible是基于paramiko 开发的,paramiko是一个纯Python实现的ssh协议库。ansible不需要在远程主机上安装client/agents,因为它是基于ssh来和远程主机通讯的。

3、ansible的特点

(1) No agents:不需要在被管控主机上安装任意客户端;

(2) No server:无服务器端,使用时直接运行命令即可;

(3) Modules in any languages:基于模块工作,可使用任意语言开发模块

(4) YAML,not code:使用yaml语言定制剧本playbook;

(5) SSH by default:基于SSH工作;

(6) Strong multi-tier solution:可实现多级指挥;

二、ansible基本使用

1、安装ansible

1

<code> </code><code>[root@localhost ~]</code><code># yum install -y ansible</code>

2、主要文件

2

3

<code>[root@DBSlave ~]</code><code># ls /etc/ansible/</code>

<code>ansible.cfg  </code><code>#主配置文件,可不修改</code>

<code>hosts        </code><code>#添加需操作的主机组</code>

3、ansible使用格式

4

5

6

7

<code>ansible &lt;host-pattern&gt; [-f forks] [-m module_name] [-a args]</code>

<code>    </code><code>host-pattern </code><code># 可以是all,或者配置文件中的主机组名</code>

<code>    </code><code>-f forks  </code><code># 指定并行处理的进程数</code>

<code>    </code><code>-m module </code><code># 指定使用的模块,默认模块为command</code>

<code>    </code><code>-a args   </code><code># 指定模块的参数</code>

<code>如果你有多台服务器的话,想并发运行,可以使用-f参数,默认是并发5</code>

4、查看各模块的使用方法

<code>ansible-doc [options] [modules]  :Show Ansible module documentation</code>

<code> </code><code>-l 列出所有的ansible模块</code>

<code> </code><code>-s 列出该模块的相关指令</code>

5、首次使用ansible

(1)安装ansible

<code>[root@localhost ~]</code><code># yum install -y ansible</code>

(2)设置主机组(host-pattern)

8

9

10

<code># vim /etc/ansible/hosts</code>

<code>[web servers]</code>

<code>192.168.200.211</code>

<code>192.168.200.212</code>

<code>192.168.200.213</code>

<code>192.168.200.214</code>

<code>[db servers]</code>

<code>192.168.200.215</code>

<code>192.168.200.216</code>

(3)创建SSH公钥与私钥

<code> </code><code>[root@localhost ~]</code><code># ssh-keygen</code>

(4)将公钥文件复制到目标服务器  [注: ssh-copy-id 把公钥追加到远程主机的 .ssh/authorized_key 上.]

<code>[root@localhost ~]</code><code># ssh-copy-id [email protected]</code>

<code>[root@localhost ~]</code><code># ssh-copy-id [email protected]</code>

<code>[root@localhost ~]</code><code># ssh-copy-id [email protected]</code>

<code> </code><code>...</code>

(5)连接与验证测试 

<code>[root@localhost ~]</code><code># ansible -i /etc/ansible/hosts all -m ping</code>

(6)模块儿

    查看各模块的使用方法

<code>可以直接使用 ansible-doc 模块儿名 来查看模块儿的使用,如</code>

<code># ansible-doc htpasswd</code>

    几个示例

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

<code>ansible all -a </code><code>"/bin/echo hello"</code>  <code>(不写-m,默认模块是shell)</code>

<code>ansible all -m </code><code>command</code> <code>-a </code><code>"/bin/echo hello, world"</code>

<code>ansible all -m shell -a </code><code>"ping baidu.com -c 1"</code>

<code>ansible all -m </code><code>ping</code> <code># ping操作   -i 参数可不指定,默认找 /etc/ansible/hosts</code>

<code>ansible </code><code>"web servers"</code> <code>-a </code><code>'date'</code> <code>(可省略-m </code><code>command</code><code>) </code><code># 执行date命令</code>

<code>ansible </code><code>"db servers"</code> <code>-m copy -a “src=</code><code>/root/ansible</code><code>.rpm dest=</code><code>/tmp/</code><code>” </code><code># 复制文件</code>

<code>ansible all -m </code><code>cron</code> <code>-a ‘name=</code><code>"custom job"</code> <code>minute=*</code><code>/3</code> <code>hour=* day=* month=* weekday=* job=</code><code>"/usr/sbin/ntpdate 192.168.200.16"</code><code>’ </code><code># 配置crontab任务</code>

<code>ansible all -m user -a </code><code>'name=mysql shell=/sbin/nologin createhome=no'</code>

<code>ansible all -m user -a </code><code>"name=tester remove=yes state=absent"</code>

<code>ansible all -m group -a </code><code>"name=mysql gid=36 system=yes"</code> <code># 创建组</code>

<code>ansible all -m yum -a </code><code>"name=httpd state=present"</code> <code># 通过yum安装httpd</code>

<code>ansible all -m service -a </code><code>"name=httpd state=started enabled=yes"</code> <code># 配置服务开启启动</code>

<code>ansible </code><code>test</code> <code>-m </code><code>file</code> <code>-a </code><code>'dest=/root/test.txt  owner=text group=text mode=644 state=touch'</code>

<code>ansible </code><code>test</code> <code>-m </code><code>file</code> <code>-a </code><code>'src=/root/test.txt  dest=/tmp/test.txt mode=440 owner=test group=test state=link'</code>

<code>创建递归文件夹</code>

<code>    </code><code># ansible 192.168.200.225 -m file -a "dest=/tmp/a/b/c owner=root group=root mode=755 state=directory"</code>

<code>    </code><code>192.168.200.225 | success &gt;&gt; {</code>

<code>    </code><code>"changed"</code><code>: </code><code>true</code><code>, </code>

<code>    </code><code>"gid"</code><code>: 0, </code>

<code>    </code><code>"group"</code><code>: </code><code>"root"</code><code>, </code>

<code>    </code><code>"mode"</code><code>: </code><code>"0755"</code><code>, </code>

<code>    </code><code>"owner"</code><code>: </code><code>"root"</code><code>, </code>

<code>    </code><code>"path"</code><code>: </code><code>"/tmp/a/b/c"</code><code>, </code>

<code>    </code><code>"size"</code><code>: 4096, </code>

<code>    </code><code>"state"</code><code>: </code><code>"directory"</code><code>, </code>

<code>    </code><code>"uid"</code><code>: 0</code>

<code>}</code>

<code>查看结果:</code>

<code>    </code><code>192.168.200.225 | success | rc=0 &gt;&gt;</code>

<code>/tmp</code>

<code>|-- a</code>

<code>|   `-- b</code>

<code>|       `-- c</code>

<code>`-- hsperfdata_root</code>

<code>    </code><code>`-- 14306</code>

<code>4 directories, 1 </code><code>file</code>

    常用模块儿

    常用的模块:copy、command、service、yum、apt、file、raw、shell、script、cron、user、state、template、

<code>ansible -i </code><code>/etc/ansiblehosts</code> <code>all -m </code><code>'service'</code> <code>-a </code><code>'name=httpd state=stoped'</code>

<code>ansible -m yum -a </code><code>'name=gcc state=present'</code>

    yum模块常用来安装软件

    service模块常用来对服务的开关操作

    shell模块可以用来执行命令以及脚本

    raw和command、shell类似,但是它可以传递管道

三、YAML语法

    YAML Ain't Markup Language,即YAML不是XML。不过,在开发的这种语言时,YAML的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。

    YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用"-"来代表,Map里的键值对用":"分隔。下面是一个示例。

    YAML文件扩展名通常为.yaml,如example.yaml。

<code>name: John Smith</code>

<code>age: 41</code>

<code>gender: Male</code>

<code>spouse:</code>

<code>    </code><code>name: Jane Smith</code>

<code>    </code><code>age: 37</code>

<code>    </code><code>gender: Female</code>

<code>children:</code>

<code>    </code><code>-  name: Jimmy Smith</code>

<code>       </code><code>age: 17</code>

<code>       </code><code>gender: Male</code>

<code>    </code><code>-  name: Jenny Smith</code>

<code>       </code><code>age 13</code>

<code>       </code><code>gender: Female</code>

四、ansible playbook(剧本)

    playbook使用:ansible-playbook test.yaml

    playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联同起来按事先编排的机制同唱一台大戏

    下面就是一个只包含了一个play的playbook,在写playbook的时候,一定要记住在 hosts,yum(模块儿名)等后带空格,否则会报错

<code>#这个是你选择的主机</code>

<code>- hosts: webservers</code>

<code>#这个是变量</code>

<code>  </code><code>vars:</code>

<code>    </code><code>http_port: 80</code>

<code>    </code><code>max_clients: 200</code>

<code>#远端的执行权限</code>

<code>  </code><code>remote_user: root</code>

<code>  </code><code>tasks:</code>

<code>#利用yum模块来操作</code>

<code>  </code><code>- name: ensure apache is at the latest version</code>

<code>    </code><code>yum: pkg=httpd state=latest</code>

<code>  </code><code>- name: write the apache config </code><code>file</code>

<code>    </code><code>template: src=</code><code>/srv/httpd</code><code>.j2 dest=</code><code>/etc/httpd</code><code>.conf</code>

<code>#触发重启服务器</code>

<code>    </code><code>notify:</code>

<code>    </code><code>- restart apache</code>

<code>  </code><code>- name: ensure apache is running</code>

<code>    </code><code>service: name=httpd state=started</code>

<code>#这里的restart apache 和上面的触发是配对的。这就是handlers的作用。相当于tag</code>

<code>  </code><code>handlers:</code>

<code>    </code><code>- name: restart apache</code>

<code>      </code><code>service: name=httpd state=restarted</code>

1、HOSTS和Users

    playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。

    hosts用于指定要执行指定任务的主机,其可以是一个或多个由冒号分隔主机组;

    remote_user则用于指定远程主机上的执行任务的用户。如上面示例中的

<code>-hosts: webnodes</code>

<code> </code><code>remote_user: root</code>

    不过,remote_user也可用于各task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户。

<code>- hosts: webnodes</code>

<code>    </code><code>- name: </code><code>test</code> <code>connection</code>

<code>      </code><code>ping</code><code>:</code>

<code>      </code><code>remote_user: root</code>

<code>      </code><code>sudo</code><code>: </code><code>yes</code>

2、任务列表和cation

    play的主体部分是task list。task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。在运行自下而下某playbook时,如果中途发生错误,所有已执行任务都将回滚,因此,在更正playbook后重新执行一次即可。

    task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。

    每个task都应该有其name,用于playbook的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出。

    定义task的可以使用“action: module options”或“module: options”的格式,推荐使用后者以实现向后兼容。如果action一行的内容过多,也中使用在行首使用几个空白字符进行换行。

<code>tasks:</code>

<code>  </code><code>- name: </code><code>make</code> <code>sure apache is running</code>

<code>    </code><code>service: name=httpd state=running</code>

    在众多模块中,只有command和shell模块仅需要给定一个列表而无需使用“key=value”格式,例如:

<code>     </code><code>- name: disable selinux</code>

<code>       </code><code>command</code><code>: </code><code>/sbin/setenforce</code> <code>0</code>

    如果命令或脚本的退出码不为零,可以使用如下方式替代:

<code>   </code><code>- name: run this </code><code>command</code> <code>and ignore the result</code>

<code>     </code><code>shell: </code><code>/usr/bin/somecommand</code> <code>|| </code><code>/bin/true</code>

    或者使用ignore_errors来忽略错误信息:

<code>  </code><code>- name: run this </code><code>command</code> <code>and ignore the result</code>

<code>    </code><code>shell: </code><code>/usr/bin/somecommand</code>

<code>    </code><code>ignore_errors: True</code>

3、handlers

    用于当关注的资源发生变化时采取一定的操作。

    “notify”这个action可用于在每个play的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,取而代之,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作。

<code>- name: template configuration </code><code>file</code>

<code>  </code><code>template: src=template.j2 dest=</code><code>/etc/foo</code><code>.conf</code>

<code>  </code><code>notify:</code>

<code>     </code><code>- restart memcached</code>

<code>     </code><code>- restart apache</code>

    handler是task列表,这些task与前述的task并没有本质上的不同。

<code>handlers:</code>

<code>    </code><code>- name: restart memcached</code>

<code>      </code><code>service:  name=memcached state=restarted</code>

<code>      </code><code>service: name=apache state=restarted</code>

五、playbook案例

1、heartbeat.yaml

<code>heartbeat.yaml</code>

<code>    </code><code>- hosts: hbhosts</code>

<code>    </code><code>remote_user: root</code>

<code>    </code><code>tasks:</code>

<code>        </code><code>- name: ensure heartbeat latest version</code>

<code>          </code><code>yum: name=heartbeat state=present</code>

<code>        </code><code>- name: authkeys configure </code><code>file</code>

<code>          </code><code>copy: src=</code><code>/root/hb_conf/authkeys</code> <code>dest=</code><code>/etc/ha</code><code>.d</code><code>/authkeys</code>

<code>        </code><code>- name: authkeys mode 600</code>

<code>          </code><code>file</code><code>: path=</code><code>/etc/ha</code><code>.d</code><code>/authkeys</code> <code>mode=600</code>

<code>          </code><code>notify:</code>

<code>            </code><code>- restart heartbeat</code>

<code>        </code><code>- name: ha.cf configure </code><code>file</code>

<code>          </code><code>copy: src=</code><code>/root/hb_conf/ha</code><code>.cf dest=</code><code>/etc/ha</code><code>.d</code><code>/ha</code><code>.cf</code>

<code>    </code><code>handlers:</code>

<code>        </code><code>- name: restart heartbeat</code>

<code>            </code><code>service: name=heartbeat state=restarted</code>

2、corosync.yaml

<code>- hosts: hanodes      </code><code>#指定要执行任务的主机,可由冒号分隔主机组</code>

<code>  </code><code>remote_user: root   </code><code>#指定远程主机上执行任务的用户</code>

<code>  </code><code>vars:  </code><code>#定义如下2个变量</code>

<code>    </code><code>crmsh: crmsh-1.2.6.4.el6.x86_64.rpm</code>

<code>    </code><code>pssh: pssh-2.3.1-2.el6.x86_64.rpm</code>

<code>  </code><code>tasks:    </code><code>#指定需执行的任务列表,每个task都有其name和使用的模块及参数</code>

<code>      </code><code>ping</code><code>:        </code><code>#ping模块无需执行参数</code>

<code>      </code><code>remote_user: jason  </code><code>#在task中指定远程主机上执行任务的用户</code>

<code>      </code><code>sudo</code><code>: </code><code>yes</code>   <code>#使用sudo在远程主机上执行任务</code>

<code>    </code><code>- name: corosync installing</code>

<code>      </code><code>yum: name=corosync state=present</code>

<code>    </code><code>- name: pacemaker installing          </code><code>#定义一个软件安装任务</code>

<code>      </code><code>yum: name=pacemaker state=present   </code><code>#使用yum安装,并配置需安装的软件名(name),及状态(state)</code>

<code>    </code><code>- name: crmsh rpm packages</code>

<code>      </code><code>copy: src=</code><code>/ansible/corosync/packages/</code><code>{{ crmsh }} dest=</code><code>/tmp/</code><code>{{ crmsh }}</code>

<code>    </code><code>- name: pssh rpm packages</code>

<code>      </code><code>copy: src=</code><code>/ansible/corosync/packages/</code><code>{{ pssh }} dest=</code><code>/tmp/</code><code>{{ pssh }}</code>

<code>    </code><code>- name: crmsh installing</code>

<code>      </code><code>command</code><code>: yum -y reinstall </code><code>/tmp/</code><code>{{ crmsh }} </code><code>/tmp/</code><code>{{ pssh }}</code>

<code>    </code><code>- name: authkey configure </code><code>file</code>

<code>      </code><code>copy: src=</code><code>/ansible/corosync/conf/authkey</code> <code>dest=</code><code>/etc/corosync/authkey</code>

<code>    </code><code>- name: authkey mode 400   </code><code>#定义一个文件权限设置任务</code>

<code>      </code><code>file</code><code>: path=</code><code>/etc/corosync/authkey</code> <code>mode=400</code>

<code>      </code><code>notify:   </code><code>#定义一个通知,当此任务执行时,可以激发响应的handler</code>

<code>        </code><code>- restart corosync</code>

<code>    </code><code>- name: corosync.conf configure </code><code>file</code>

<code>      </code><code>copy: src=</code><code>/ansible/corosync/conf/corosync</code><code>.conf dest=</code><code>/etc/corosync/corosync</code><code>.conf</code>

<code>      </code><code>tags:</code>

<code>        </code><code>- conf</code>

<code>      </code><code>notify:</code>

<code>    </code><code>- name: ensure the corosync service startup on boot</code>

<code>      </code><code>service: name=corosync state=started enabled=</code><code>yes</code>

<code>  </code><code>handlers:   </code><code>#定义当关注的资源发生变化时,需采取的操作</code>

<code>    </code><code>- name: restart corosync  </code><code>#定义一个服务重启任务</code>

<code>      </code><code>service: name=corosync state=restarted</code>

本文转自 nmshuishui 51CTO博客,原文链接:http://blog.51cto.com/nmshuishui/1573941,如需转载请自行联系原作者