Ansible 自动化工具使用

Posted by Sunday on 2018-05-18

Ansible简介

ansible 是个什么东西呢?基于 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用 YMAL 及 Jinja2模板语言,更强的远程命令执行操作。这个工具的目标有这么几项:自动化部署APP;自动化管理配置项;自动化的持续交互;自动化的(AWS)云服务管理。所有的这几个目标从本质上来说都是在一个台或者几台服务器上,执行一系列的命令而已。通俗的说就是批量的在远程服务器上执行命令 。当然,最主要的是它是基于 paramiko 开发的。这个paramiko是什么呢?它是一个纯Python实现的ssh协议库。因此fabric和ansible还有一个共同点就是不需要在远程主机上安装client/agents,因为它们是基于ssh来和远程主机通讯的。

Ansible特点

轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可。
批量任务执行可以写成脚本,而且不用分发到远程就可以执行。
使用python编写,维护更简单,ruby语法过于复杂。
支持sudo。

  • ansible提供的框架
    连接插件connection plugins:负责和被监控端实现通信。
    host inventory:指定操作的主机,是一个配置文件里面定义监控的主机。
    各种模块核心模块、command模块、自定义模块。
    借助于插件完成记录日志邮件等功能。
    playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。
  • 类似的自动化运维工具有很多常用的还有
    Puppet:基于 Ruby 开发,采用 C/S 架构,扩展性强,基于 SSL,远程命令执行相对较弱。
    SaltStack:基于 Python 开发,采用 C/S 架构,相对 puppet 更轻量级,配置语法使用 YMAL,使得配置脚本更简单。

Ansible的安装

centos

1
2
sudo yum install epel-release -y
sudo yum install ansible -y

ubuntu

1
2
3
4
shell> sudo apt-get install software-properties-common
shell> sudo apt-add-repository ppa:ansible/ansible
shell> sudo apt-get update
shell> sudo apt-get install ansible

配置密钥

1
2
3
shell> ssh-keygen 
shell> ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.36
shell> ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.37

客户端设置允许root登陆

1
2
vim /etc/ssh/sshd_config
#PermitRootLogin yes

ansible控制端

1
ssh root@192.168.1.36

配置Ansible主机管理

普通分组和组中组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sudo vi /etc/ansible/hosts
[web36]
192.168.1.36
[web37]
192.168.1.37

#普通分组
[webs]
192.168.1.[36:37] #:可以表示to的含义,如[01:50]表示从0150

[db1]
192.168.1.41
[db2]
192.168.1.42

#dbs 组中组
[dbs:children]
db1
db2

变量

系统预设变量
ansible_connection=ssh #定义连接类型
ansible_ssh_user=root #连接用户名
ansible_ssh_pass=pass #连接密码
ansible_ssh_port=22 #连接主机的端口
ansible_sudo_pass=’4kX5KyVmk3/zq #sudo用户密码

主机变量
在主机定义时,直接定义相关变量.

1
2
192.168.1.36 http_port=80 maxRequestsPerChild=808
192.168.1.37 http_port=8280 maxRequestsPerChild=909

组变量
同一组的主机具有相同的变量时使用组变量比较方便,同样适用vars来进行识别。

1
2
3
4
5
[dbs]
192.168.1.41
192.168.1.42
[dbs:vars]
ntp_server=ntp.sundayle.com

修改默认远程ssh端口、用户名

1
2
3
vim /etc/ansible/ansible.cfg
remote_port = 2880
remote_user = sunday

Ansible命令行参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Usage: ansible <host-pattern> [options]
Options:
-m MODULE_NAME, --module-name=MODULE_NAME 要执行的模块,默认为command
-a MODULE_ARGS, --args=MODULE_ARGS 模块的参数
-u REMOTE_USER, --user=REMOTE_USER ssh连接的用户名,默认用root,ansible.cfg中可以配置
-k, --ask-pass 提示输入ssh登录密码,当使用密码验证登录的时候用
-s, --sudo sudo模式运行
-U SUDO_USER, --sudo-user=SUDO_USER sudo到哪个用户,默认为root
-K, --ask-sudo-pass 提示输入sudo密码,当不是NOPASSWD模式时使用
-B SECONDS, --background=SECONDS run asynchronously, failing after X seconds(default=N/A)
-P POLL_INTERVAL, --poll=POLL_INTERVAL set the poll interval if using -B (default=15)
-C, --check 只是测试一下会改变什么内容,不会真正去执行
-c CONNECTION 连接类型(default=smart)
-f FORKS, --forks=FORKS fork多少个进程并发处理,默认5
-i INVENTORY, --inventory-file=INVENTORY 指定hosts文件路径,默认default=/etc/ansible/hosts
-l SUBSET, --limit=SUBSET 指定一个pattern,对<host_pattern>已经匹配的主机中再过滤一次
--list-hosts 只打印有哪些主机会执行这个playbook文件,不是实际执行该playboo
-M MODULE_PATH, --module-path=MODULE_PATH 要执行的模块的路径,默认为/usr/share/ansible/
-o, --one-line 压缩输出,摘要输出
--private-key=PRIVATE_KEY_FILE 私钥路径
-T TIMEOUT, --timeout=TIMEOUT ssh连接超时时间,默认10秒
-t TREE, --tree=TREE 日志输出到该目录,日志文件名会以主机名命名
-v, --verbose verbose mode (-vvv for more, -vvvv to enable connection debugging)

使用–list-hosts查看组内的主机
使用参数-f 指定任务执行的并发数,加速执行,和主机cpu数相同即可.
通过参数–sudo [-K]来使用sudo模式

参数-m与-a
-m指定执行模块,-a指定命令参数,当没有指定模块的时候使用的是command模块,这个模块不能用于管道什么的。所以命令复杂时要-m shell -a find … | xargs …,命令不复杂时直接-a就可以了,如-a date.

简单的Ansible命令

查看webs组中的主机

1
2
3
4
shell> ansible webs --list-hosts
hosts (2):
192.168.1.36
192.168.1.37

测试连通性

1
2
3
4
5
6
7
8
9
shell> ansible webs -m ping 
192.168.1.36 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.1.37 | SUCCESS => {
"changed": false,
"ping": "pong"
}

指定用户

1
2
3
4
-u 指定运行的用户(默认为root) 
-s 使用sudo权限 客户端visudo添加sunday ALL=(ALL:ALL) NOPASSWD:ALL
ansible webs -m ping -u sunday
ansible webs -m ping --sudo

切换root执行命令

1
ansible web37 -m ping --su -R root"

查看时间

-m shell -a 可简写为 -a

1
2
3
4
5
6
shell> ansible webs -a "date"
192.168.1.36 | SUCCESS | rc=0 >>
Fri May 18 14:04:17 CST 2018

192.168.1.37 | SUCCESS | rc=0 >>
Fri May 18 14:04:17 CST 2018

查看内存

1
2
3
4
5
shell> ansible web37 -m shell -a 'free -h'
192.168.1.37 | SUCCESS | rc=0 >>
total used free shared buff/cache available
Mem: 11G 5.1G 244M 172M 6.4G 6.1G
Swap: 7.5G 262M 7.2G

创建文件

1
2
3
shell> ansible webs -a "rm /home/sunday/hello"
192.168.1.37 | SUCCESS | rc=0 >>
192.168.1.36 | SUCCESS | rc=0 >>

复制

将本地文件/文件夹发送到远程主机,ansible的copy模块是围绕rsync的包装,所以它是增量而不是全量的拷贝。

  • src 本地文件/文件夹位置
  • dest 发送到远程主机的位置
  • owner(可选) 所属用户
  • group(可选) 所属用户组
  • mode(可选) 权限
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
shell> ansible webs -m copy -a "src=/root/hello.txt dest=/tmp/ owner=sunday group=sunday mode=0644"
192.168.1.36 | SUCCESS => {
"changed": true,
"checksum": "f572d396fae9206628714fb2ce00f72e94f2258f",
"dest": "/tmp/hello.txt",
"gid": 1000,
"group": "xwx",
"md5sum": "b1946ac92492d2347c6235b4d2611184",
"mode": "0644",
"owner": "xwx",
"size": 6,
"src": "/home/xwx/.ansible/tmp/ansible-tmp-1526624444.38-111678557215170/source",
"state": "file",
"uid": 1000
}
192.168.1.37 | SUCCESS => {
"changed": true,
"checksum": "f572d396fae9206628714fb2ce00f72e94f2258f",
"dest": "/tmp/hello.txt",
"gid": 1000,
"group": "xwx",
"md5sum": "b1946ac92492d2347c6235b4d2611184",
"mode": "0644",
"owner": "xwx",
"size": 6,
"src": "/home/xwx/.ansible/tmp/ansible-tmp-1526624444.39-132387955034592/source",
"state": "file",
"uid": 1000
}

Ansible-playbook

playbook的编写使用YAML语言格式,它的标准格式是心”—“开始”…”结束
帮助: ansible-doc -s module_name

1
2
3
4
5
6
7
8
9
10
11
12
13
14
---
- hosts: webs
tasks: // Task任务,定义具体做哪些事,以及如何做
- name: make sure httpd is running
service: name=httpd state=running
- name: disable selinux
command: /sbin/setenforce 0
- name: create a virtual host file for {{ vhost }}
template: src=somefile.j2 dest=/etc/httpd/conf.d/{{ vhost }}
notify:
- restart httpd

handlers: //管理/调用,用于被Task中某个具体任务执行完成后调用。承上notify: restart httpd操作。
service: name=httpd state=restarted

#ansible-playbook apache.yml –extra-vars “vhost=sunday.conf”

查看模块

ansible-doc -l
常用模块

  • command: 用于在目标主机执行命令
  • shell: 与command相同,但是还支持变量和管道等特性
  • file: 对目标主机的文件进行操作,如权限,创建,删除等
  • copy: 将本地文件,推送到目标主机上
  • template: 模板管理,用于管理服务的配置文件,可以定义变量
  • git: 使用git来发布程序或版本
  • yum或apt: 管理服务状态,如启动或停止服务
  • setup: 数据采集,用于从目标主机收集系统信息

使用Include、Roles组织Playbook

对于一个需要上百个task自动化任务来说,全部写在一个playbook中,是非常混乱的。
那么将一个复杂的playbook拆分为多个简单的playbook就会灵活多了。
Roles是通过规范目录结构,自动include对应目录下的任务。格式上不再需要通过include来明确定义引入哪个playbook.

帮助

ansible -h 查看其帮助信息
ansible-doc module_name来查看,
ansible-doc -l查看系统模块有哪些。

https://zhuanlan.zhihu.com/p/25368281
https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-ansible-on-centos-7
https://www.jianshu.com/p/c56a88b103f8