1 前言
Ansible是新出现的运维工具是基于Python研发的糅合了众多老牌运维工具的优点实现了批量操作系统配置、批量程序的部署、批量运行命令等功能。
ansible是基于模块工作的ansible本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块ansible只是提供一种框架。
2 ansible的基本使用
2.1 安装
其实ansible的安装的方式有很多中,如下:
从源码运行
通过Yum安装最新发布版本
通过Apt (Ubuntu)安装最新发布版本
通过 Portage (Gentoo)安装最新发布版本
通过 pkg (FreeBSD)安装最新发布版本
通过 Homebrew (Mac OSX)安装最新发布版本
通过 Pip 安装最新发布版本
发行版的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常用参数
- hosts:定义远程主机组
- user:执行该任务的用户
- sudo: 设置为yes的时候,执行任务的时候使用root权限
- sudo_user 如果你设置用户为tshare365,那么你执行的时候会使用tshare365用户的权限
- connection 通过什么方式连接到远程主机,默认是ssh
- 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)还不如现在自己开发一个比较靠谱。
来源:oschina
链接:https://my.oschina.net/u/1540325/blog/651251