ansible学习总结

 

 

1      前言

Ansible是新出现的运维工具是基于Python研发的糅合了众多老牌运维工具的优势实现了批量操做系统配置、批量程序的部署、批量运行命令等功能。html

ansible是基于模块工做的ansible自己没有批量部署的能力。真正具备批量部署的是ansible所运行的模块ansible只是提供一种框架。python

2      ansible的基本使用

2.1   安装

其实ansible的安装的方式有不少中,以下:linux

从源码运行git

经过Yum安装最新发布版本web

经过Apt (Ubuntu)安装最新发布版本shell

经过 Portage (Gentoo)安装最新发布版本apache

经过 pkg (FreeBSD)安装最新发布版本编程

经过 Homebrew (Mac OSX)安装最新发布版本windows

经过 Pip 安装最新发布版本centos

发行版的Tarball。

我这儿就只介绍在centos系统上经过yum来安装ansible

2.1.1    关闭防火墙和selinux

# service iptables stop

 

能够看到防火墙已经关闭了

 

#setenforce 0

能够看到selinux已经关闭了

 

2.1.2    安装EPEL第三方yum源:

# rpm -Uvh http://ftp.linux.ncsu.edu/pub/epel/6/i386/epel-release-6-8.noarch.rpm

 

2.1.3    安装Ansible

# yum install ansible –y

 

2.2   Ansible配置

众所周知任何软件的使用须要先配置成本身的配置,ansible也不例外,Ansible 可同时操做属于一个组的多台主机,组和主机之间的关系经过 inventory 文件配置. 默认的文件路径为 /etc/ansible/hosts 。

除默认文件外,你还能够同时使用多个 inventory 文件(后面会讲到),也能够从动态源,或云上拉取 inventory 配置信息。

2.2.1    主机与组

 

/etc/ansible/hosts 文件的格式与windows的ini配置文件相似:

 

mail.example.com

 

[webservers]

foo.example.com

bar.example.com

 

[dbservers]

one.example.com

two.example.com

three.example.com

个人例子

方括号[]中是组名,用于对系统进行分类,便于对不一样系统进行分类的管理,。主机能够是ip地址也能够是域名。

 

一个系统能够属于不一样的组,好比一台服务器能够同时属于 webserver组 和 dbserver组.这时属于两个组的变量均可觉得这台主机所用,至于变量的优先级关系将于之后的章节中讨论.

 

若是有主机的SSH端口不是标准的22端口,可在主机名以后加上端口号,用冒号分隔.SSH 配置文件中列出的端口号不会在 paramiko 链接中使用,会在 openssh 链接中使用.

 

端口号不是默认设置时,可明确的表示为:

badwolf.example.com:5309

假设你有一些静态IP地址,但愿设置一些别名,但不是在系统的 host 文件中设置,又或者你是经过隧道在链接,那么能够设置以下:

jumper ansible_ssh_port=5555 ansible_ssh_host=192.168.1.50

在这个例子中,经过 “jumper” 别名,会链接 192.168.1.50:5555.记住,这是经过 inventory 文件的特性功能设置的变量. 通常而言,这不是设置变量(描述你的系统策略的变量)的最好方式.后面会说到这个问题.

一组类似的 hostname , 可简写以下:

[webservers]

www[01:50].example.com

数字的简写模式中,01:50 也可写为 1:50,意义相同.你还能够定义字母范围的简写模式:

[databases]

db-[a:f].example.com

对于每个 host,你还能够选择链接类型和链接用户名:

[targets]

 

localhost              ansible_connection=local

other1.example.com     ansible_connection=ssh     ansible_ssh_user=mpdehaan

other2.example.com     ansible_connection=ssh     ansible_ssh_user=mdehaan

全部以上讨论的对于 inventory 文件的设置是一种速记法,后面咱们会讨论如何将这些设置保存为 ‘host_vars’ 目录中的独立的文件.

2.2.2    主机变量

前面已经提到过,分配变量给主机很容易作到,这些变量定义后可在 playbooks 中使用:

[atlanta]

host1 http_port=80 maxRequestsPerChild=808

host2 http_port=303 maxRequestsPerChild=909

2.2.3    组的变量

也能够定义属于整个组的变量:

[atlanta]

host1

host2

 

[atlanta:vars]

ntp_server=ntp.atlanta.example.com

proxy=proxy.atlanta.example.com

2.2.4    把一个组做为另外一个组的子成员

能够把一个组做为另外一个组的子成员,以及分配变量给整个组使用. 这些变量能够给 /usr/bin/ansible-playbook 使用,但不能给 /usr/bin/ansible 使用:

[atlanta]

host1

host2

 

[raleigh]

host2

host3

 

[southeast:children]

atlanta

raleigh

 

[southeast:vars]

some_server=foo.southeast.example.com

halon_system_timeout=30

self_destruct_countdown=60

escape_pods=2

 

[usa:children]

southeast

northeast

southwest

northwest

 

若是你须要存储一个列表或hash值,或者更喜欢把 host 和 group 的变量分开配置,请看下一节的说明.

2.2.5    分文件定义 Host 和 Group 变量

在 inventory 主文件中保存全部的变量并非最佳的方式.还能够保存在独立的文件中,这些独立文件与 inventory 文件保持关联. 不一样于 inventory 文件(INI 格式),这些独立文件的格式为 YAML.详见YAML 语法 .

假设 inventory 文件的路径为:

/etc/ansible/hosts

假设有一个主机名为 ‘foosball’, 主机同时属于两个组,一个是 ‘raleigh’, 另外一个是 ‘webservers’. 那么如下配置文件(YAML 格式)中的变量能够为 ‘foosball’ 主机所用.依次为 ‘raleigh’ 的组变量,’webservers’ 的组变量,’foosball’ 的主机变量:

/etc/ansible/group_vars/raleigh

/etc/ansible/group_vars/webservers

/etc/ansible/host_vars/foosball

举例来讲,假设你有一些主机,属于不一样的数据中心,并依次进行划分.每个数据中心使用一些不一样的服务器.好比 ntp 服务器, database 服务器等等. 那么 ‘raleigh’ 这个组的组变量定义在文件 ‘/etc/ansible/group_vars/raleigh’ 之中,可能相似这样:

---

ntp_server: acme.example.org

database_server: storage.example.org

这些定义变量的文件不是必定要存在,由于这是可选的特性.

还有更进一步的运用,你能够为一个主机,或一个组,建立一个目录,目录名就是主机名或组名.目录中的能够建立多个文件, 文件中的变量都会被读取为主机或组的变量.以下 ‘raleigh’ 组对应于 /etc/ansible/group_vars/raleigh/ 目录,其下有两个文件 db_settings 和 cluster_settings, 其中分别设置不一样的变量:

/etc/ansible/group_vars/raleigh/db_settings

/etc/ansible/group_vars/raleigh/cluster_settings

‘raleigh’ 组下的全部主机,均可以使用 ‘raleigh’ 组的变量.当变量变得太多时,分文件定义变量更方便咱们进行管理和组织. 还有一个方式也可参考,详见 Ansible Vault 关于组变量的部分. 注意,分文件定义变量的方式只适用于 Ansible 1.4 及以上版本。

Tip: Ansible 1.2 及以上的版本中,group_vars/ 和 host_vars/ 目录可放在 inventory 目录下,或是 playbook 目录下. 若是两个目录下都存在,那么 playbook 目录下的配置会覆盖 inventory 目录的配置。

Tip: 把你的 inventory 文件 和 变量 放入 git repo 中,以便跟踪他们的更新,这是一种很是推荐的方式。

2.2.6    Inventory 参数的说明

如同前面提到的,经过设置下面的参数,能够控制 ansible 与远程主机的交互方式,其中一些咱们已经讲到过:

ansible_ssh_host

      将要链接的远程主机名.与你想要设定的主机的别名不一样的话,可经过此变量设置.

 

ansible_ssh_port

      ssh端口号.若是不是默认的端口号,经过此变量设置.

 

ansible_ssh_user

      默认的 ssh 用户名

 

ansible_ssh_pass

      ssh 密码(这种方式并不安全,咱们强烈建议使用 --ask-pass 或 SSH 密钥)

 

ansible_sudo_pass

      sudo 密码(这种方式并不安全,咱们强烈建议使用 --ask-sudo-pass)

 

ansible_sudo_exe (new in version 1.8)

      sudo 命令路径(适用于1.8及以上版本)

 

ansible_connection

      与主机的链接类型.好比:local, ssh 或者 paramiko. Ansible 1.2 之前默认使用 paramiko.1.2 之后默认使用 'smart','smart' 方式会根据是否支持 ControlPersist, 来判断'ssh' 方式是否可行.

 

ansible_ssh_private_key_file

      ssh 使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的状况.

 

ansible_shell_type

      目标系统的shell类型.默认状况下,命令的执行使用 'sh' 语法,可设置为 'csh' 或 'fish'.

 

ansible_python_interpreter

      目标主机的 python 路径.适用于的状况: 系统中有多个 Python, 或者命令路径不是"/usr/bin/python",好比  \*BSD, 或者 /usr/bin/python

      不是 2.X 版本的 Python.咱们不使用 "/usr/bin/env" 机制,由于这要求远程用户的路径设置正确,且要求 "python" 可执行程序名不可为 python之外的名字(实际有可能名为python26).

 

      与 ansible_python_interpreter 的工做方式相同,可设定如 ruby 或 perl 的路径....

一个主机文件的例子:

some_host         ansible_ssh_port=2222     ansible_ssh_user=manager

aws_host          ansible_ssh_private_key_file=/home/example/.ssh/aws.pem

freebsd_host      ansible_python_interpreter=/usr/local/bin/python

ruby_module_host  ansible_ruby_interpreter=/usr/bin/ruby.1.9.3

 

2.3   Ansible—ac-hoc命令

      若是咱们敲入一些命令去比较快的完成一些事情,而不须要将这些执行的命令特别保存下来, 这样的命令就叫作 ad-hoc 命令。

 

 Ansible提供两种方式去完成任务,一是 ad-hoc 命令,一是写 Ansible playbook, 前者能够解决一些简单的任务, 后者解决较复杂的任务。

 

通常而言,在学习了 playbooks 以后,你才能体会到 Ansible 真正的强大之处在哪里

 

那咱们会在什么情境下去使用ad-hoc 命令呢?

好比说由于圣诞节要来了,想要把全部实验室的电源(系统)关闭,咱们只须要执行一行命令 就能够达成这个任务,而不须要写 playbook 来作这个任务。

 

至于说作配置管理或部署这种事,仍是要借助 playbook 来完成,即便用 ‘/usr/bin/ansible-playbook’ 这个命令.

 

(关于 playbook 的使用,请参考 Playbooks )

 

若是你尚未阅读 Inventory文件 ,最好先看一看,而后咱们继续往下.

 

 

咱们先来看一条很基本的命令

若是没有免密码登陆的话,可使用以下命令:

 在ansible中还有一个Module(模块)的概念,这个模块能够理解为一个库,全部的ac-hoc命令都须要经过模块来执行,好比上面的那个命令: ansible test-servers -m ping,实际上是调用了ping模块,-m后面表示用什么模块, 除了ping模块还有其余不少模块,下面介绍一下比较经常使用的模块 。

执行ansible-doc –l命令列出全部已安装的模块文档:

2.3.1    ansible的command模块

ansible的command模块是默认的模块,若是你不写模块名,就是调用这个模块。使用command命令能够在远程节点上执行bash上面的命令。

实例1关机

ansible test-servers -m command -a "init 0" -u root

 

 

实例二:查看系统linux内核

ansible test-servers -m command -a "uname -r" -u root

 

实例三:查看系统的运行了多长时间

ansible test-servers -m command -a "uptime" -u root

基本上大部分命令均可以执行,可是command 模块不支持 shell 变量,也不支持管道等 shell 相关的东西.若是你想使用 shell相关的这些东西, 请使用’shell’ 模块。

ansible test-servers -m command -a "ls |grep log" -u root

 

 

2.3.2    Ansible的shell和script模块

实例一:管道命令使用

ansible test-servers -m s      -a "ls ~|grep log"

 

实例二:查看该组主机的变量TERM

ansible test-servers -m shell -a 'echo $TERM'

 

使用 Ansible ad hoc 命令行接口时(与使用 Playbooks 的状况相反),尤为注意 shell 引号的规则. 好比在上面的例子中,若是使用双引号”echo $TERM”,会求出TERM变量在当前系统的值,而咱们实际但愿的是把这个命令传递 到其它机器执行。

 

实例三:执行远程主机上面的shell脚本

71和72上面的/ h脚本内容以下:

在本机上面没有这个脚本

ansible test-servers -m shell -a "/root/a.sh"

 

实例四:将管理主机(本机)上的脚本到远程主机上面执行(scp+shell)

 

脚本在主控端,有一个/root/b.sh

 

远程主机71和72上面都没有

用shell模块执行会失败

ansible test-servers -m shell -a "/root/b.sh"

 

应该使用script模块来执行

ansible test-servers -m script -a "/root/b.sh"

 

优势:

1比起来其余自动化集群管理和运维工具 Puppet、Chef、Ansible 显得很简单而且轻量级, 可是 Ansible 又不像 Fab 那样功能单一只能作批量命令,也能够和puppet同样进行模块扩展。

2轻量级的好处是学习门槛低、问题少、安装快、执行快。操做彻底依赖 SSH 而不须要安装 agent 。这样的好处是再也不须要维护 agent 的状态,不用担忧 Agent 挂掉。而 SSH 是每台服务器必备的服务。它很是适合安全补丁更新的场景。好比,100 台服务器打 bash vulnerability 安全补丁只须要 10 分钟。

3.Ansible 结合 Docker、Mesos、Puppet、Vagrant、Git 等系统能够构建出很是好的自动化运维平台。Ansible 比起其余自动化运维工具更适合对 Docker 实例进行维护和管理。若是你的机器实例数量超过 1000,也能够选择Ansible 的 Web 控制工具 Ansible Tower 。

缺点

1.一样这样的简单设计的劣势是没有依赖管理功能(感受不适合咱们公司,或者和别的一块儿用)。可是 Ansible 对于通常的使用场景已经足够了。

2.3.3    Ansible的copy模块

复制文件到远程主机,这是 /usr/bin/ansible 的另外一种用法.Ansible 可以以并行的方式同时 SCP 大量的文件到多台机器。这个的适用场景于文件发布,这种需求不少,好比平常的配置文件更新,程序版本发布等,基本都会用到。

输入的命令以下:

ansible test-servers -m copy -a "src=/opt/file dest=/opt/file"

 

注意:目标主机上面的目录层级结构以下:

 

命令参数以下:

backup:在覆盖以前,将源文件备份,备份文件包含时间信息。有两个选项:yes|no

content:用于替代“src”,能够直接设定指定文件的值

dest:必选项。要将源文件复制到的远程主机的绝对路径,若是源文件是一个目录,那么该路径也必须是个目录,若是该目录不存在则会自动建立。且

directory_mode:递归设定目录的权限,默认为系统默认权限

force:若是目标主机包含该文件,但内容不一样,若是设置为yes,则强制覆盖,若是为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes

others:全部的file模块里的选项均可以在这里使用

src:被复制到远程主机的本地文件,能够是绝对路径,也能够是相对路径。若是路径是一个目录,它将递归复制。在这种状况下,若是路径使用“/”来结尾,则只复制目录里的内容,若是没有使用“/”来结尾,则包含目录在内的整个内容所有复制,相似于rsync。

 

2.3.4    Ansible的file模块

实例一:使用 file 模块能够作到修改文件的属主和权限:

ansible test-servers -m file -a "dest=/opt/file/file/3.c mode=600"

 

实例二:使用 file 模块也能够建立目录,与执行 mkdir -p 效果相似:

ansible test-servers -m file -a "dest=/opt/file/file/ccc mode=755 owner=root group=root state=directory"

 

 

 

远程目标机器上面的目录结构以下:

实例三:删除目录(递归的删除)和删除文件:

ansible test-servers -m file -a "dest=/opt/file/file/ccc mode=755 owner=root group=root state=absent"

 

再查看目标主机上面,能够看获得,ccc目录已经被删除了。

相关参数选项以下:

force:须要在两种状况下强制建立软连接,一种是源文件不存在,但以后会创建的状况下;另外一种是目标软连接已存在,须要先取消以前的软链,而后建立新的软链,有两个选项:yes|no

group:定义文件/目录的属组

mode:定义文件/目录的权限

owner:定义文件/目录的属主

path:必选项,定义文件/目录的路径

recurse:递归设置文件的属性,只对目录有效

src:被连接的源文件路径,只应用于state=link的状况

dest:被连接到的路径,只应用于state=link的状况

state:

       directory:若是目录不存在,就建立目录

       file:即便文件不存在,也不会被建立

       link:建立软连接

       hard:建立硬连接

       touch:若是文件不存在,则会建立一个新的文件,若是文件或目录已存在,则更新其最后修改时间

       absent:删除目录、文件或者取消连接文件

 

2.3.5    Ansible的更多其余模块

其余经常使用模块,好比:service、cron、yum、synchronize就不一一例举,能够结合自身的系统环境进行测试。

service:系统服务管理

cron:计划任务管理

yum:yum软件包安装管理

synchronize:使用rsync同步文件

user:系统用户管理

group:系统用户组管理

 

更多模块能够参考:

#ansible-doc –l

2.4   Playbook

像不少其它配置文件管理方法同样,Ansible使用一种比较直白的方法来描述本身的任务配置文件。

Ansible 的任务配置文件被称之为“playbook”,咱们能够称之为“剧本”。每一出剧本(playbook)中都包含一系列的任务,这每一个任务在ansible中又被称为一出“戏剧”(play)。一个剧本(playbook)中包含多出戏剧(play),这很容易理解。

 

Playbooks 与 adhoc 相比,是一种彻底不一样的运用 ansible 的方式,是很是之强大的。

 

简单来讲,playbooks 是一种简单的配置管理系统与多机器部署系统的基础.与现有的其余系统有不一样之处, 且很是适合于复杂应用的部署。

 

Playbooks 可用于声明配置,更强大的地方在于,在 playbooks 中能够编排有序的执行过程,甚至于作到在多组机器间,来回有序的执行特别指定的步骤,而且能够同步或异步的发起任务。

 

咱们使用 adhoc 时,主要是使用 /usr/bin/ansible 程序执行任务.而使用 playbooks 时,更可能是将之放入源码控制之中,用之推送你的配置或是用于确认你的远程系统的配置是否符合配置规范。

2.4.1    Playbook的组成部分

Playbook主要由如下四部分组成:

 

Target section:定义将要执行playbook的远程主机组

Variable section:定义playbook运行时须要使用的变量

Task section:定义将要在远程主机上执行的任务列表

Handler section:定义task执行完成之后须要调用的任务

 

2.4.2    Playbook的每一部分经常使用参数

2.4.2.1     Target section经常使用参数

  1. hosts:定义远程主机组
  2. user:执行该任务的用户
  3. sudo: 设置为yes的时候,执行任务的时候使用root权限
  4. sudo_user 若是你设置用户为tshare365,那么你执行的时候会使用tshare365用户的权限
  5. connection 经过什么方式链接到远程主机,默认是ssh
  6. gather_facks 是否启用在远程主机执行setup模块,默认是会执行的,可用同setup模块获取远程主机的信息,在定义变量的时候使用

2.4.2.2     Variabler section经常使用参数

1.    vars  定义格式 变量名:变量值

2.    vars_files  指定变量文件

3.    vars_prompt  用户交互模式自定义变量

4.    setup 模块去远程主机的值

2.4.2.3     Task ssection

1.    name:输出到屏幕的信息

2.    action:定义执行的动做调用ansible的模块例如:yum name=http state=installed就是安装apache服务

3.    copy:复制本地文件到远程主机

4.    template:复制本地文件到远程主机可是他能够在本地文件中调用变量

5.    service :定义服务的状态

2.4.3    Playbook的实例

Playbooks 的格式是YAML(详见:YAML 语法),语法作到最小化,意在避免 playbooks 成为一种编程语言或是脚本,但它也并非一个配置模型或过程的模型。

 

playbook 由一个或多个 ‘plays’ 组成.它的内容是一个以 ‘plays’ 为元素的列表。

 

在 play 之中,一组机器被映射为定义好的角色.在 ansible 中,play 的内容,被称为 tasks,即任务.在基本层次的应用中,一个任务是一个对 ansible 模块的调用,这在前面章节学习过。

首先一个简单的playbook的实例

实例一:,把当前用户名输出到whoami.rst文件中:

# playbook.yml

---

- hosts: test-serviers  # hosts中指定

  remote_user: root  # 若是和当前用户同样,则无需指定

  tasks:

    - name: whoami

      shell: 'whoami > whoami.rst'

执行这个playbook:

ansible-playbook  playbook.yml

 

 

在远程目标主机上,已经生成这个文件,且里面有内容:

 

实例二:将shell脚本转换为playbook

下面有一个安装apache的shell脚本,你们来感觉一下:

#!/bin/bash

# 安装Apache

yum install --quiet -y httpd httpd-devel

# 复制配置文件

cp /path/to/config/httpd.conf /etc/httpd/conf/httpd.conf

cp /path/to/httpd-vhosts.conf /etc/httpd/conf/httpd-vhosts.conf

# 启动Apache,并设置开机启动

service httpd start

chkconfig httpd on

将其转换为一个完整的playbook后:

---

- hosts: all

 

  tasks:

   - name: "安装Apache"

     command: yum install --quiet -y httpd httpd-devel

   - name: "复制配置文件"

     command: cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf

     command: cp /tmp/httpd-vhosts.conf /etc/httpd/conf/httpd-vhosts.conf

   - name: "启动Apache,并设置开机启动"

     command: service httpd start

     command: chkconfig httpd on


也就是说,只要你有编写shell脚本的基本能力,你就能够快速的学会利用playbook来发挥Ansible的强大威力。

在上述playbook中,咱们使用了“command”模块来运行了标准的shell命令。咱们还给了每一出play一个“name”,所以当咱们运行playbook时,每个play都会有很是易读的的信息输出:

上面的playbook已经能够很好的运行shell脚本了,可是Ansible还有不少其余内置模块,能够大幅提高处理复杂配置的能力。

---

- hosts: all

  sudo: yes

 

  tasks:

   - name: 安装Apache

     yum: name={{ item }} state=present

     with_items:

     - httpd

     - httpd-devel

   - name: 复制配置文件

     copy:

       src: "{{ item.src }}"

       dest: "{{ item.dest }}"

       owner: root

       group: root

       mode: 0644

     with_items:

     - {

       src: "/tmp/httpd.conf",

         dest: "/etc/httpd/conf/httpd.conf" }

     - {

       src: "/tmp/httpd-vhosts.conf",

       dest: "/etc/httpd/conf/httpd-vhosts.conf"

       }

   - name: 检查Apache运行状态,并设置开机启动

     service: name=httpd state=started enabled=yes

运行结果以下:

 

Ansible讲解比较好的网站以下,写的很是到位:

http://www.jianshu.com/p/41c4ed3ce779

http://doc.178linux.com/docs/playbooks_intro.html#playbook

2.5   Ansible的拓展

咱们能够对ansible进行扩展,ansible提供了Ansible API用Ansible的Python API来管理节点,能够经过扩展Ansible来响应大量的Python事件,你能够写各类的插件,而且,你能够经过插件来调取外部数据源。

3      总结

     Ansible感受仍是不是挺适合咱们的业务,主要是因为过于简单,且语言也不合适(python)还不如如今本身开发一个比较靠谱。

相关文章
相关标签/搜索