ansible安装配置以及一些常用模块

摘要

ansible是目前非常火的运维自动化批量管理工具之一

  • saltstack
  • ansible
  • puppet
  • chef

ansible和saltstack都是使用python语言写的,而在选择以及使用的过程中,ansible相对saltstack具有以下几个优势

  • 使用ssh-key控制agent,无需安装agent
  • 配置起来相对简单,学习门槛低
  • 并发以及性能方面还是saltstack占优的,不过在小集群(300以下)的表现上ansible也非常给力;
  • 二次开发扩展:由于两个都是python语言写的,这方面都还不错,不过在日常使用中吗,saltstack的api调用要比ansible的好用很多,state和playbook孰强孰若还真不好说
  • 操作界面,没用过ui
  • 第三方插件的丰富程度这点ansible完胜
  • 支持windows
  • 开源社区的活跃程度这点ansible完胜
  • 安全性:saltstack相对要更好一些
  • 自动注册:这点ansible貌似没有

安装

1
pip install ansible

配置

1
2
3
4
5
6
7
8
9
10
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# cat /etc/ansible/ansible.cfg
[defaults]
inventory = /etc/ansible/hosts
remote_tmp = $HOME/.ansible/tmp
roles_path = /data/ansible/roles:/etc/ansible/roles
transport = smart
gathering = smart
fact_caching_timeout = 30
require_sudo = False
module_name = shell
private_key_file = /root/.ssh/id_rsa
ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}
#action_plugins = /data/ansible/ansible_plugins/action_plugins
#connection_plugins = /data/ansible/ansible_plugins/connection_plugins
#lookup_plugins = /data/ansible/ansible_plugins/lookup_plugins
#vars_plugins = /data/ansible/ansible_plugins/vars_plugins
#filter_plugins = /data/ansible/ansible_plugins/filter_plugins
nocolor = 0
fact_caching = memory
host_key_checking = False
timeout = 10
pattern = *
forks = 20
poll_interval = 15
remote_user = devops
remote_port = 9555
log_path = /data/logs/ansible/ansible.log
[inventory]
[privilege_escalation]
become=True
become_exe=sudo
become_method=sudo
become_user=root
become_ask_pass=False
[paramiko_connection]
record_host_keys=False
[ssh_connection]
pipelining = True
[persistent_connection]
[accelerate]
accelerate_port = 5099
accelerate_timeout = 30
accelerate_connect_timeout = 5.0
accelerate_daemon_timeout = 30
#accelerate_multi_key = yes
[selinux]
[colors]
[diff]
1
2
3
4
5
6
7
8
9
10
11
cat /etc/ansible/hosts
[all: children]
manager
other
[manager]
ansible ansible_ssh_host=172.16.1.1
jenkins ansible_ssh_host=172.16.1.2
[other]
other ansible_ssh_host=172.16.1.3

运行

1
2
ansible all -m ping
ansible all -m shell -a "uptime"

playbook

  • shell –> 命令
  • playbook –> ansible命令

tower

1
wget http://releases.ansible.com/ansible-tower/setup/ansible-tower-setup-latest.tar.gz

模块

ansible本身是没有部署能力的,它只是个框架,它的模块才有真正的部署能力。

1
ansible -i hosts all -m ping

它就是用的ansible命令行,-i 表示使用当前目录下的hosts文件,all表示Host文件内声明的所有服务器,-m ping 表示使用module名为ping的module,这个module没有参数,所以就这样调用就行了。

Command

command 模块用于运行系统命令,比如echo hello, 你安装在系统里的python,或者make 一类。大家能领悟就行了。

常用参数:

parameter required default choices comments
chdir no 运行command命令前先cd到这个目录
creates no 如果这个参数对应的文件存在,就不运行command
executable no 将shell切换为command执行,这里的所有命令需要使用绝对路径
removes no 如果这个参数对应的文件不存在,就不运行command

案例

1
2
#ansible 命令调用command:
ansible -i hosts all -m command -a "uptime"

ansible命令行调用-m command模块 -a表示使用参数 “”内的为执行的command命令。
那么对应的节点都会执行关机。

1
2
# Run the command if the specified file does not exist.
ansible -i hosts all -m command -a "/usr/bin/make_database.sh arg1 arg2 creates=/path/to/database"

利用creates参数,判断/path/to/database这个文件是否存在,存在就跳过command命令,不存在就执行command命令。

shell

这个是一个很神奇的模块,它也是ansible的核心模块之一。它跟command模块一样负责在被ansible控制的节点(服务器)执行命令行。它与command模块有着相似的地方,也有不同的地方,看完这篇文章将告诉你答案。

常用参数

parameter required default choices comments
chdir no 跟command一样的,运行shell之前cd到某个目录
creates no 跟command一样的,如果某个文件存在则不运行shell
removes no 跟command一样的,如果某个文件不存在则不运行shell

案例

让所有节点运行somescript.sh并把log输出到somelog.txt。

1
$ ansible -i hosts all -m shell -a "sh somescript.sh >> somelog.txt"

先进入somedir/ ,再在somedir/目录下让所有节点运行somescript.sh并把log输出到somelog.txt。

1
$ ansible -i hosts all -m shell -a "somescript.sh >> somelog.txt" chdir=somedir/

体验shell和command的区别,先cd到某个需要编译的目录,执行condifgure然后,编译,然后安装。

1
$ ansible -i hosts all -m shell -a "./configure && make && make insatll" chdir=/xxx/yyy/

yum

用于包管理

常用参数

参数名 是否必须 默认值 选项值 参数说明
conf_file 设定远程yum执行时所依赖的yum配置文件
disable_gpg_check No Yes/No 在安装包前检查包,只会影响state参数为present或者latest的时候
list No 只能由ansible调用,不支持playbook,这个干啥的大家都懂
name Yes 你需要安装的包的名字,也能如此使用name=python=2.7安装python2.7
state no present present/latest/absent 用于描述安装包最终状态,present/latest用于安装包,absent用于remove安装包
update_cache no no yes/no 用于安装包前执行更新list,只会影响state参数为present/latest的时候

案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- name: 安装最新版本的apache
yum: name=httpd state=latest
- name: 移除apache
yum: name=httpd state=absent
- name: 安装一个特殊版本的apache
yum: name=httpd-2.2.29-1.4.amzn1 state=present
- name: 升级所有的软件包
yum: name=* state=latest
- name: 从一个远程yum仓库安装nginx
yum: name=http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present
- name: 从本地仓库安装nginx
yum: name=/usr/local/src/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present
- name: 安装整个Development tools相关的软件包
yum: name="@Development tools" state=present
1
2
3
4
5
6
7
8
- name: Install Base Require Software
yum:
name: "{{ item }}"
state: present
with_items:
- gcc
- fping
ignore_errors: yes

apt

这个模块是ubuntu作为远端节点的OS的时候,用的最多的。Apt是啥就不多说了,ubuntu/debian的包管理工具。

常用参数

参数名 是否必须 默认值 选项值 参数说明
cache_valid_time no 如果update_cache参数起作用的时候,这个参数才会起作用。其用来控制update_cache的整体有效时间
deb no 这个用于安装远程机器上的.deb后缀的软件包
default_release no 等同于apt命令的-t选项,这里就不多说了
force no no yes/no 强制执行apt install/remove
install_recommends no Ture yes/no 这个参数可以控制远程电脑上是否只是下载软件包,还是下载后安装,默认参数为true,设置为false的时候光下载软件包,不安装
name no apt要下载的软件包名字,支持name=git=1.6 这种制定版本的模式
purge no yes/no 如果state参数值为absent,这个参数为yes的时候,将会强行干净的卸载
state no present latest/absent/present 定义软件包的最终状态,latest时为安装最新软件
update_cache no yes/no 当这个参数为yes的时候等于apt-get update
upgrade no yes yes/safe/full/dist 如果参数为yes或者safe,等同于apt-get upgrade.如果是full就是完整更新。如果是dist等于apt-get dist-upgrade。

案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 在安装foo软件包前更新然后安装foo
- apt: name=foo update_cache=yes
# 移除foo软件包
- apt: name=foo state=absent
# 安装foo软件包
- apt: name=foo state=present
# 安装foo 1.0软件包
- apt: name=foo=1.00 state=present
# 安装nginx最新的名字为squeeze-backport发布包,并且安装前执行更新
- apt: name=nginx state=latest default_release=squeeze-backports update_cache=yes
# 只下载openjdk-6-jdk最新的软件包,不安装
- apt: name=openjdk-6-jdk state=latest install_recommends=no
# 安装所有软件包到最新版本
- apt: upgrade=dist
# 更新apt-get的list
- apt: update_cache=yes
# 3600秒后停止update_cache
- apt: update_cache=yes cache_valid_time=3600
# 安装远程节点上的/tmp/mypackage.deb软件包
- apt: deb=/tmp/mypackage.deb

fetch

copy

copy模块在ansible里的角色就是把ansible执行机器上的文件拷贝到远程节点上。
与fetch模块相反的操作。

常用参数

参数名 是否必须 默认值 选项值 参数说明
src no 用于定位ansible执行的机器上的文件,需要绝对路径。如果拷贝的是文件夹,那么文件夹会整体拷贝,如果结尾是”/”,那么只有文件夹内的东西被考过去。一切的感觉很像rsync
content no 用来替代src,用于将指定文件的内容,拷贝到远程文件内
dest yes 用于定位远程节点上的文件,需要绝对路径。如果src指向的是文件夹,这个参数也必须是指向文件夹
backup no no yes/no 备份远程节点上的原始文件,在拷贝之前。如果发生什么意外,原始文件还能使用。
directory_mode no 这个参数只能用于拷贝文件夹时候,这个设定后,文件夹内新建的文件会被拷贝。而老旧的不会被拷贝
follow no no yes/no 当拷贝的文件夹内有link存在的时候,那么拷贝过去的也会有link
force no yes yes/no 默认为yes,会覆盖远程的内容不一样的文件(可能文件名一样)。如果是no,就不会拷贝文件,如果远程有这个文件
group no 设定一个群组拥有拷贝到远程节点的文件权限
mode no 等同于chmod,参数可以为“u+rwx or u=rw,g=r,o=r”
owner no 设定一个用户拥有拷贝到远程节点的文件权限

案例

1
2
3
4
5
6
7
8
9
10
11
# 把/srv/myfiles/foo.conf文件拷贝到远程节点/etc/foo.conf,并且它的拥有者是foo,拥有它的群组是foo,权限是0644
- copy: src=/srv/myfiles/foo.conf dest=/etc/foo.conf owner=foo group=foo mode=0644
# 跟上面的案例一样,不一样的只是权限的写法
- copy: src=/srv/myfiles/foo.conf dest=/etc/foo.conf owner=foo group=foo mode="u=rw,g=r,o=r"
# 另外一个权限的写法
- copy: src=/srv/myfiles/foo.conf dest=/etc/foo.conf owner=foo group=foo mode="u+rw,g-wx,o-rwx"
# 拷贝/mine/ntp.conf到远程节点/etc/ntp.conf,并且备份远程节点的/etc/ntp.conf。
- copy: src=/mine/ntp.conf dest=/etc/ntp.conf owner=root group=root mode=644 backup=yes

常用参数返回值

参数名 参数说明 返回值 返回值类型 样例
src 位于ansible执行机上的位置 changed string /home/httpd/.ansible/tmp/ansible-tmp-1423796390.97-147729857856000/source
backup_file 将原文件备份 changed and if backup=yes string /path/to/file.txt.2015-02-12@22:09~
uid 在执行后,拥有者的ID success int 100
dest 远程节点的目标目录或文件 success string /path/to/file.txt
checksum 拷贝文件后的checksum值 success string 6e642bb8dd5c2e027bf21dd923337cbb4214f827
md5sum 拷贝文件后的md5 checksum值 when supported string 2a5aeecc61dc98c4d780b14b330e3282
state 执行后的状态 success string file
gid 执行后拥有文件夹、文件的群组ID success int 100
mode 执行后文件的权限 success string 0644
owner 执行后文件所有者的名字 success string httpd
group 执行后文件所有群组的名字 success string httpd
size 执行后文件大小 success int 1220

file

在之前ansible命令行的时候有copy模块,在playbook的时代自然也有一个模块专门负责文件的拷贝,当然这个时代它不仅仅是文件拷贝那么简单。

来自官方的解释:

file模块它包含了文件、文件夹、超级链接类的创立、拷贝、移动、删除操作。

常用参数

参数名 是否必须 默认值 选项 说明
follow no no yes/no 如果原来的文件是link,拷贝后依旧是link
force no no yes/no 强制执行,没说的
group no 设定一个群组拥有拷贝到远程节点的文件权限
mode no 等同于chmod,参数可以为“u+rwx or u=rw,g=r,o=r”
owner no 设定一个用户拥有拷贝到远程节点的文件权限
path yes 目标路径,也可以用dest,name代替
src yes 待拷贝文件/文件夹的原始位置。
state no file file/link/directory/
hard/touch/absent
file代表拷贝后是文件;
link代表最终是个软链接;
directory代表文件夹;
hard代表硬链接;
touch代表生成一个空文件;
absent代表删除

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 修改文件的所有组、人、权限。
- file: path=/etc/foo.conf owner=foo group=foo mode=0644
# 操作链接的案例
- file: src=/file/to/link/to dest=/path/to/symlink owner=foo group=foo state=link
#参数化案例
- file: src=/tmp/{{ item.path }} dest={{ item.dest }} state=link
with_items:
- { path: 'x', dest: 'y' }
- { path: 'z', dest: 'k' }
# 使用touch来创建一个空文件并定义权限
- file: path=/etc/foo.conf state=touch mode="u=rw,g=r,o=r"
# touch一个空文件,并且修改权限
- file: path=/etc/foo.conf state=touch mode="u+rw,g-wx,o-rwx"
- name: link Zabbix Agent Link
#shell: ln -s {{ install_dir }}/zabbix-{{ zabbix_version }} {{ zabbix_dir }}
file:
src: "{{ install_dir }}/zabbix-{{ zabbix_version }}"
dest: "{{ zabbix_dir }}"
owner: root
group: root
state: link

template

template使用了Jinjia2格式作为文件模版,进行文档内变量的替换的模块。它的每次使用都会被ansible标记为”changed”状态。

常用参数

参数名 是否必须 默认值 选项值 参数说明

backup no no yes/no 建立个包括timestamp在内的文件备份,以备不时之需.
dest yes 远程节点上的绝对路径,用于放置template文件。
group no 设置远程节点上的的template文件的所属用户组
mode no 设置远程节点上的template文件权限。类似Linux中chmod的用法
owner no 设置远程节点上的template文件所属用户
src yes 本地Jinjia2模版的template文件位置。

案例

1
2
3
4
5
# 把/mytemplates/foo.j2文件经过填写参数后,复制到远程节点的/etc/file.conf,文件权限相关略过
- template: src=/mytemplates/foo.j2 dest=/etc/file.conf owner=bin group=wheel mode=0644
# 跟上面一样的效果,不一样的文件权限设置方式
- template: src=/mytemplates/foo.j2 dest=/etc/file.conf owner=bin group=wheel mode="u=rw,g=r,o=r"

service

service模块说白了,就是Linux下的service命令。但是它更简单。这个是playbook中用的非常多的模块。

常用参数

参数名 是否必须 默认值 选项值 参数说明
enabled no yes/no 启动os后启动对应service的选项。使用service模块的时候,enabled和state至少要有一个被定义
name yes 需要进行操作的service名字
state no stared/stoped/restarted/reloaded service最终操作后的状态。

案例

1
2
3
4
5
6
7
8
9
10
11
12
# 不管当前什么情况,启动apache
- service: name=httpd state=started
# 不管当前什么情况,停止apache
- service: name=httpd state=stopped
# 不管当前什么情况,重启apache
- service: name=httpd state=restarted
# 系统重启后,启动apache
- service: name=httpd enabled=yes

wait_for

当你利用service 启动tomcat,或数据库后,他们真的启来了么?这个你是否想确认下?
wait_for模块就是干这个的。等待一个事情发生,然后继续。它可以等待某个端口被占用,然后再做下面的事情,也可以在一定时间超时后做另外的事。

常用参数

参数名 是否必须 默认值 选项值 参数说明
connect_timeout no 5 在下一个事情发生前等待链接的时间,单位是秒
delay no 延时,大家都懂,在做下一个事情前延时多少秒
host no 127.0.0.1 执行这个模块的host
path no 当一个文件存在于文件系统中,下一步才继续。
port no 端口号,如8080
state no started present/started/
stopped/absent
对象是端口的时候start状态会确保端口是打开的,
stoped状态会确认端口是关闭的;
对象是文件的时候,present或者started会确认文件是存在的,
而absent会确认文件是不存在的。

案例

1
2
3
4
5
6
7
8
9
10
11
# 10秒后在当前主机开始检查8000端口,直到端口启动后返回
- wait_for: port=8000 delay=10
# 检查path=/tmp/foo直到文件存在后继续
- wait_for: path=/tmp/foo
# 直到/var/lock/file.lock移除后继续
- wait_for: path=/var/lock/file.lock state=absent
# 直到/proc/3466/status移除后继续
- wait_for: path=/proc/3466/status state=absent