0%

ansible的学习

一、ansible的安装

1. 安装ansible,ansible需要python支持,所有一并安装python

1
[root@student01 ~]# yum -y install python ansible

2.创建一个工作目录,hosts包含一台主机

1
2
3
[root@student01 ~]# mkdir playbook
[root@student01 ~]# cat playbook/inventory/hosts
student02 ansible_ssh_host=172.25.0.12 ansible_ssh_port=22

3. ansible服务器与其他机器创建信任关系

1
2
[root@student01 ~]# ssh-keygen
[root@student01 ~]# ssh-copy-id root@student02

4. 使用ping模块测试连通状态

1
2
3
4
5
[root@student01 ~]# ansible student02 -i playbook/inventory/hosts -m ping
student02 | SUCCESS => {
"changed": false,
"ping": "pong"
}

注:如果命令执行失败,可以在命令后面加上-vvvv,查看详细信息

1
[root@student01 ~]# ansible student02 -i playbook/inventory/hosts -m ping -vvvv

5. 查看服务器启动时间

1
2
3
[root@student01 ~]# ansible student02 -i playbook/inventory/hosts -a "uptime"
student02 | SUCCESS | rc=0 >>
16:33:32 up 1:22, 2 users, load average: 0.00, 0.01, 0.05

6. 安装nginx服务以及重启nginx服务

1
2
[root@student01 ~]# ansible student02 -i playbook/inventory/hosts -m yum -a "name=nginx"
[root@student01 ~]# ansible student02 -i playbook/inventory/hosts -m service -a "name=nginx state=restarted"

二、YAML语法介绍

1. 文件的起始

YAML文件以---开头以标记文件的开头,如果忘记开头三个减号,也不会影响Ansible的运行

1
---

2. 注释

注释以#开头,一直到本行的结束

1
#This is a YAML comment

3. 字符串

YAML字符串不需要使用""引起来

1
Ansible playbook

4. 布尔值

Ansible经常使用的布尔值有turefalseyesno

5. 列表

列表中的所有成员都开始于相同的缩进级别, 并且使用一个- 作为开头

1
2
3
- bash shell
- python
- c++

6. 字典

由一个简单的键: 值的形式组成

1
2
3
hostname: student01
ip: 172.25.0.11
server: web

7. 折行

在需要向模块传递很多参数的时候,为了美观可以把很长的段落写成多行,使用>标记折行,YAML会把折行替换为空格

1
2
3
ip: >
172.25.0.11
172.25.0.12

注:JSON文件可以直接当做YAML文件使用,但是不建议把playbook写成JSON脚本,因为YAML的亮点就是易于阅读

三、playbook简介

playbook是用于配置管理的脚本,使用Ansible时大部分时间在编写playbook

1. 我们先写一个简单的playbook,搭建web服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@student01 ~]# cat playbook/web-configure.yml 
- name: configure webserver with nginx
hosts: webserver
sudo: Ture
tasks:
- name: install nginx
yum: name=nginx update_cache=yes

- name: copy nginx config file
copy: src=files/nginx_8080_localhost.conf dest=/etc/nginx/conf.d/8080
_localhost.conf

- name: copy index.html
template: src=templates/index.html.j2 dest=/usr/share/nginx/html/inde
x.html mode=0644

- name: restart nginx
service: name=nginx state=restarted

在playbook中,建议向模块传递参数的时候用yes和no,在其他地方使用ture和false

2. 把nginx的配置文件放在playbook/files/nginx_8080_localhost.conf ,用这个配置文件覆盖默认的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
	[root@student01 ~]# cat playbook/files/nginx_8080_localhost.conf 
server {
listen 8080 default_server;
listen [::]:8080 default_server;

root /usr/share/nginx/html;
index index.html index.htm;
server_name localhost;

location / {
}

error_page 404 /404.html;
location = /40x.html {
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

安装惯例,我们把一般文件放在files目录中,将jinja2模板文件放在templates目录中

3. 创建一个首页

1
2
3
4
5
6
7
8
9
[root@student01 templates]# cat index.html.j2 
<html>
<head>
<body>
<h1>nginx, configured by ansible</h1>
<p> if you can see this, ansible successfully installed nginx.</p>
<p>{{ ansible_managed }}</p>
</body>
</html>

这个模板引用了一个ansible变量ansible_managed,当ansible渲染这个模板的时候,会将变量替换成这个模板文件生成时间相关信息

4. 在hosts文件的主机前面加上[webserver],创建一个webserver群组,表明下面的主机属于webserver

1
2
3
4
[root@student01 ~]# cat playbook/inventory/hosts 
[webserver]
student02 ansible_ssh_host=172.25.0.12 ansible_ssh_port=22
student03 ansible_ssh_host=172.25.0.13 ansible_ssh_port=22

5. 执行playbook

1
[root@student01 ~]#ansible-playbook -i playbook/inventory/hosts      playbook/web-configure.yml

6. 如果没有任何报错,现在可以通过浏览器访问http://localhost:8080并看到HTML网页

四、playbook深入剖析

1. play

通过观察YAML发现,playbook就是一组play组成的列表,每个play都必须包含两项

host:需要配置一组主机

task:需要在这些主机上执行的任务

play还支持一些可选的配置,先介绍三个最常用的

name:一个注释,描述这个play是做什么的

sudo:如果为真,Ansible会在执行task的时候运行sudo切换root用户执行

var:变量和值组成的列表

2. task

举例一个安装nginx的task

1
2
- name: install nginx
yum: name=nginx update_cache=yes

这个task告诉yum安装一个叫nginx的软件包,安装前更新安装包缓存

如果想要把参数写成多行的话,可以使用折行语法

1
2
3
4
- name: install nginx
yum: >
name=nginx
update_cacha=yes

3. 模块

模块是由Ansible包装后在主机上执行的一系列脚本,常用的有以下模块
yum:使用yum包管理器安装和删除软件包
copy:将文件从本地复制到主机
file:设置文件、符号链接或者目录属性
service:启动、停止或者重启服务
template:从模板生成文件并复制到主机

ansible-doc命令工具可以查看官方文档

1
[root@student01 ~]# ansible-doc service

4. 将他们整合到一起,组成一个play

这是一张实体关系图,他描述了playbook、play、host、task和module之间的关系

1
2
3
4
5
graph LR
playbook-->play
play-->host
play-->task
task-->module

5. 跟踪主机状态

当运行ansible-playbook时,Ansible便会输出他在play中执行每一个task的状态信息

有些任务的状态是changed,显示的黄色,状态ok,显示的是绿色

Ansible模块会在采取任何行动之前查看主机的状态是否需要改变,如果主机的参数与模块的参数相匹配,那么不会做任何操作,直接响应ok,如果参数不匹配,则会改变主机的状态并的返回changed

6. vars

在playbook的play中可以使用vars区段定义变量

1
2
vars:
server_name: localhost

7. handler

handler是Ansible提供的条件机制之一,handler和task很相似,但是他只有被task通知后才会执行,Ansible识别到task改变了系统的状态,task就会触发通知机制

1
2
3
4
5
6
7
8
9
tasks:
- name: install nginx
yum: name=nginx update_cache=yes
notify: restart nginx
handler:
- name: restart nginx
service: >
name=nginx
state=restarted
  task将handler的名字`restart nginx`作为参数传递,只有`install nginx`这个task被执行成功了,才会触发`restart nginx`

注意:handler只会在task执行完毕了才会执行,即使触发了很多次也只会执行一次

五、inventory:描述你的服务器

1. inventory描述

在Ansible中,描述主机的方法是把它们写到inventory文件中,一个简单的inventory可以只包含一些主机列表

1
2
3
student01
student02.example.com
172.25.0.13

2. inventory行为参数

名称 默认值 描述
ansible_ssh_host 主机的名字 ssh目的主机
ansible_ssh_port 22 ssh目的端口
ansible_ssh_user root ssh登录用户
ansible_ssh_pass none ssh认证密码
ansible_connection smart ssh连接主机的连接模式
ansible_ssh_private_key_file none ssh认证秘钥
ansible_shell_type bash 命令使用的shell
ansible_python_interpreter /usr/bin/python python解释器路径

3. 群组

在执行task的时候,我们希望针对一组主机执行操作,这时候就可以定义群组,Ansible有一个默认的群组all,包含了所有的主机

1
2
3
4
5
6
[root@student01 ~]# ansible all -i playbook/inventory/hosts -a 'date'
student02 | SUCCESS | rc=0 >>
Fri May 19 16:11:53 CST 2017

student03 | SUCCESS | rc=0 >>
Fri May 19 16:11:53 CST 2017

我们可以在inventory文件中定义自己的群组,inventory文件是.ini格式的,在.ini格式中,同类的配置值归类在一起组成区段,我定义了一个群组webserver,包含两台主机

1
2
3
4
[root@student01 ~]# cat playbook/inventory/hosts 
[webserver]
student02 ansible_ssh_host=172.25.0.12 ansible_ssh_port=22
student03 ansible_ssh_host=172.25.0.13 ansible_ssh_port=22

上面的playbook/inventory/hosts中,student02是主机172.25.0.12的别名,指定ssh端口为22

4. 群组嵌套

Ansible还支持群组嵌套,定义一个群组包含已经定义的两个群组

1
2
3
4
5
6
7
8
[root@student01 ~]# cat playbook/inventory/hosts 
[webserver02]
student02 ansible_ssh_host=172.25.0.12 ansible_ssh_port=22
[webserver03]
student03 ansible_ssh_host=172.25.0.13 ansible_ssh_port=22
[webserver]
webserver02
webserver03

5. 编号主机

当inventory包含很多主机的时候,可以通过编号范围指定主机

1
2
3
[root@student01 ~]# cat playbook/inventory/hosts 
[webserver]
student[01:20] ansible_ssh_port=22

6. 群组变量

可以在工作目录playbook目录中新建目录host_vars/production来存放变量

1
2
3
[root@student01 ~]# cat playbook/host_vars/production/webserver 
webserver:
name=webserver