自动化运维之Ansible详解
1.Ansible安装以及配置认证
ansible也是有Python开发的。
ansible特点:
不需要安装客户端,通过sshd去通信
基于模块工作,模块可以由任何语言开发
不仅支持命令行使用模块,也支持编写yaml格式的playbook
支持sudo
又提供UI(浏览器图形化)www.ansible.com/tower 10台主机以内免费
开源UI http://github.com/alaxli/ansible_ui
ansible安装:
两台机器:
服务端:192.168.147.137
客户端:192.168.147.138
在两台机器的/etc/hosts文件里加入:
192.168.147.137 server
192.168.147.138 client
只需要在服务端上安装ansible即可
服务端:
yum install -y epel-release
yum install -y ansible
ansible配置密钥:
服务端:
生成秘钥对(默认放在/root/.ssh/目录下,也可以自定义):
ssh-keygen -t rsa
直接回车即可,不用设置秘钥密码
把公钥(id_rsa.pub)内容放到客户端(192.168.147.138)的/root/.ssh/authorized_keys里面:scp /root/.ssh/id_rsa.pub 192.168.147.138:/root/.ssh/authorized_keys
也在服务端上的/root/.ssh/authorized_keys里面复制一份公钥,后面要用本机做一个客户端,即127.0.0.1:scp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
客户端:
更改文件权限:
chmod 600 /root/.ssh/authorized_keys
关闭selinux:
setenforce0
测试服务端连接客户端:
ssh client
如果ssh命令不存在,安装一下:
yum insall -y openssh-clients
2.ansible远程执行命令
服务端:
定义一个主机组:
vim /etc/ansible/hosts
添加一个主机组:
[testhost]
127.0.0.1
192.168.147.138
说明:testhost为主机组名字,自定义的。下面两个IP为组内的机器IP,也可以写主机名,前提是能解析为IP。
对这组主机执行w命令:
ansible testhost -m command -a 'w'
这样就可以批量执行命令了。这里的testhost为主机组名,-m后边是模块名字,-a后面是命令。当然我们也可以直接写一个IP,针对某一台机器来执行命令。
ansible 127.0.0.1 -m command -a 'hostname'
错误:“msg”:"Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!"
解决:yum install -y libselinux-python
还有一个模块就是shell同样也可以实现,支持管道:
ansible testhost -m shell -a 'cat /etc/passwd | grep root'
shell功能比command功能多。
3.ansible拷贝目录或者文件
ansible testhost -m copy -a "src=/etc/ansible dest=/tmp/ansibletest owner=root group=root mode=0755"
注意:源目录会放到目标目录下面去,如果目标指定的目录不存在,它会自动创建。如果拷贝的是文件,dest指定的名字和源如果不同,并且它不是已经存在的目录,相当于拷贝过去后又重命名。但相反,如果dest是目标机器上已经存在的目录,则会直接把文件拷贝到该目录下面,例如:
ansible testhost -m copy -a "src=/etc/passwd dest=/tmp/123"
这里的/tmp/123和源机器上的/etc/passwd是一致的,但如果目标机器上已经有/tmp/123目录,则会在/tmp/123/目录下建立passwd文件。
4.ansible远程执行脚本
首先创建一个shell脚本:
vim /tmp/test.sh
#!/bin/bash
echo `date` > /tmp/ansible_test.txt
然后把该脚本分发到各个机器上
ansible testhost -m copy -a "src=/tmp/test.sh dest=/tmp/test.sh mode=0755"
最后是批量执行该shell脚本
ansible testhost -m shell -a "/tmp/test.sh"
shell模块,还支持远程执行命令并且带管道:
ansible testhost -m shell -a "cat /etc/passwd | wc -l"
5.ansible实现任务计划
服务端:
创建一个任务计划:
ansible testhost -m cron -a "name='test cron' job='/bin/touch /tmp/1212.txt' weekday=6"
如果删除该cron只需要加一���字段state=absent
ansible testhost -m cron -a "name='test cron' state=absent"
其他的时间表示:
分:minute
时:hour
日:day
月:month
周:weekday
客户端:
查看任务计划:
crontab -l
6.ansible安装rpm包和管理服务
安装httpd:
ansible testhost -m yum -a "name=httpd"
在name后面还可以加上state=installed,默认不加也可以安装
开启httpd服务,并设为开机启动:
ansible testhost -m service -a "name=httpd state=started enabled=yes"
这里的name是CentOS系统里的服务名,可以通过chkconfig --list查看。
ansible文档的使用:
ansible-doc -l 查看所有的模块
ansible-doc cron 查看指定的模块
7.ansible playbook介绍
类似于shell脚本,相当于把命令写入到文件里,例如:
vim /etc/ansible/test.yml
---
- hosts: testhost
remote_user: root
tasks:
- name: test_playbook
shell: touch /tmp/test.txt
说明:hosts参数制定了对哪些主机进行操作;
user参数制定了使用什么用户登录远程主机操作;
tasks制定了一个任务,其下面的name参数同样是对任务的描述,在执行过程中会打印出来。
执行:ansible-playbook /etc/ansible/test.yml
再来一个创建用户的例子:
vim /etc/ansible/create_user.yml
---
- name: create_user
hosts: testhost
user: root
gather_facts: false
vars:
- user: "test"
tasks:
- name: create user
user: name="{{ user }}"
执行:ansible-playbook /etc/ansible/create_user.yml
说明:name参数对该playbook实现的功能做一个概述,后面执行过程中,会打印name变量的值,可以省略;gather_facts参数制定了在以下任务执行前,是否先执行setup模块获取相关信息,这在后面的task或使用到setup获取的信息时用到;vars参数制定了变量,这里指一个user变量,其值为test,需要注意的是,变量值一定要引号括起来;user制定了调用user模块,name是user模块里的一个参数,而增加的用户名字调用了上面user变量的值。
收集客户端的信息:
ansible client -m setup
8.ansible playbook循环
修改testhost组下主机的/tmp/目录下的1.txt,2.txt,3.txt(首先保证这些文件存在)的权限修改为600,属主改为root,属组改为root:
编辑一个loop.yml脚本:
vim /etc/ansible/loop.yml
---
- hosts: testhost
user: root
tasks:
- name: change mode for file
file: path=/tmp/{{ item }} mode=600 owner=root group=root
with_items:
- 1.txt
- 2.txt
- 3.txt
执行:
ansible-playbook /etc/ansible/loop.yml
9.ansible playbook判断
当满足条件ansible_hostname == "client"时执行命令:
touch /tmp/when.txt:
编辑一个when.yml脚本:
vim /etc/ansible/when.yml
---
- hosts: testhost
remote_user: root
gather_facts: True
tasks:
- name: use when
shell: touch /tmp/when.txt
when: ansible_hostname == "client"
执行:ansible-playbook /etc/ansible/when.yml
10.ansible playbook 中的 handlers
在执行task之后,服务器发生变化之后要执行的一些操作,比如我们修改了一些配置问价后,需要重启一下服务:
vim /etc/ansinle/handlers.yml
---
- name: handlers test
hosts: testhost
user: root
tasks:
- name: copy file
copy: src=/etc/passwd dest=/tmp/aaa.txt
notify: test handlers
handlers:
- name: test handlers
shell: echo "111111" >> /tmp/aaa.txt
说明:只有copy模块执行成功后,才会去调用下面的handlers相关的操作。也就是说如果passwd和aaa.txt内容是一样的,并不会去执行handlers里面的shell相关命令。这种比较适合配置文件发生更改后,重启服务的操作。
执行:ansible-playbook /etc/ansinle/handlers.yml
11.ansible实例-安装Nginx
思路:先在一台机器上编译安装好Nginx、打包,然后再用ansible去下发
进入ansible配置文件目录:cd /etc/ansible
创建一个nginx_install目录,方便管理:mkdir nginx_install
进入该目录:cd nginx_install
mkdir -p roles/{common,install}/{handlers,files,meta,tasks,templates,vars}
说明:roles目录下有两个角色,commen为一些准备操作,install为安装nginx的操作。每个角色下面又有几个目录,handlers下面是当发生改变时要执行的操作,通常用在配置文件发生改变,重启服务。files为安装时用到的一些文件,meta为说明信息,说明角色依赖等信息,tasks里面是核心的配置文件,templates通常存一些配置文件,启动脚本等模块文件,vars下为定义的变量。
详细步骤:
1.编译安装Nginx可以参考LNMP部分
2.安装完Nginx后可以看到安装目录下的内容:ls /usr/local/nginx/
3.切换目录:cd /usr/local/
4.打包压缩Nginx安装目录:tar czf nginx.tar.gz nginx
5.切换到ansible配置文件目录:cd /etc/ansible
6.创建nginx_install目录:mkdir nginx_install
7.进入该目录:cd nginx_install
8.创建子目录:mkdir -p roles/{common,install}/{handlers,files,meta,tasks,templates,vars}
9.将相关文件拷贝到指定目录下:
cp /usr/local/nginx.tar.gz /etc/ansible/nginx_install/roles/install/files/
cp /usr/local/nginx/conf/nginx.conf /etc/ansible/nginx_install/roles/install/templates/
cp /etc/init.d/nginx /etc/ansible/nginx_install/roles/install/templates/
10.编写common/tasks的总入口配置文件:
vim /etc/ansible/nginx_install/roles/common/tasks/main.yml
- name: Install initialization require software
yum: name={{ item }} state=installed
with_items:
- zlib-devel
- pcre-devel
- openssl-devel
11.编写install/vars的总入口配置文件:
vim /etc/ansible/nginx_install/roles/install/vars/main.yml
nginx_user: www
nginx_basedir: /usr/local/nginx
12.编写install/tasks的copy配置文件:
vim /etc/ansible/nginx_install/roles/install/tasks/copy.yml
- name: Copy Nginx Sofrware
copy: src=nginx.tar.gz dest=/tmp/nginx.tar.gz owner=root group=root
- name: Uncompression Nginx Software
shell: tar zxf /tmp/nginx.tar.gz -C /usr/local/
- name: Copy Nginx Start Script
template: src=nginx dest=/etc/init.d/nginx owner=root group=root mode=0755
- name: Copy Nginx Config
template: src=nginx.conf dest={{ nginx_basedir }}/conf/ owner=root group=root mode=0644
13.编写install/tasks的install配置文件:
vim /etc/ansible/nginx_install/roles/install/tasks/install.yml
- name: Create Nginx User
user: name={{ nginx_user }} state=present createhome=no shell=/sbin/nologin
- name: Start Nginx Service
service: name=nginx state=started
- name: Add Boot Start Nginx Service
shell: chkconfig --level 345 nginx on
- name: Delete Nginx compression files
shell: rm -rf /tmp/nginx.tar.gz
14.编写install/tasks的总入口配置文件:
vim /etc/ansible/nginx_install/roles/install/tasks/main.yml
- include: copy.yml
- include: install.yml
15.编写整个程序的总入口配置文件:
vim /etc/ansible/nginx_install/install.yml
---
- hosts: 192.168.147.138
remote_user: root
gather_facts: True
roles:
- common
- install
16.执行:ansible-playbook /etc/ansible/nginx_install/install.yml
客户端:
查看上述三个包是否已经安装成功:rpm -qa | egrep 'pcre|openssl|zlib'
查看Nginx是否安装成功:ls /usr/local/nginx/
查看服务是否启动成功:ps aux | grep nginx
查看加入服务列表是否成功:chkconfig --list nginx
11.ansible实例-管理Nginx配置文件
生产环境中大多时候是需要管理配置文件的,安装软件包只是在初始化环境的时候用一下。下面我们来写个管理Nginx配置文件的playbook
mkdir -p /etc/ansible/nginx_config/roles/{new,old}/{files,handlers,vars,tasks}
其中new为更新时用到的,old为回滚时用到的,files下面为nginx.conf和vhosts目录,handlers为重启Nginx服务的命令
关于回滚,需要在执行playbook之前备份一下旧的配置,所以对于老配置文件的管理一定要严格,千万不要随便去修改线上机器的配置,并且要保证new/files下面的配置和线上的配置一致
先把nginx.conf和vhosts目录放到files目录下面
cd /usr/local/nginx/conf/
cp -r nginx.conf vhosts /etc/ansible/nginx_config/roles/new/files
详细步骤:
1.级联创建所需要的目录:
mkdir -p /etc/ansible/nginx_config/roles/{new,old}/{files,handlers,vars,tasks}
2.将Nginx的配置文件拷贝到指定目录:
cp /usr/local/nginx/conf/nginx.conf /etc/ansible/nginx_config/roles/new/files/
cp -r /usr/local/nginx/conf/vhosts /etc/ansible/nginx_config/roles/new/files/
3.定义vars:
vim /etc/ansible/nginx_config/roles/new/vars/main.yml
nginx_basedir: /usr/local/nginx
4.定义handlers:
vim /etc/ansible/nginx_config/roles/new/handlers/main.yml
- name: restart nginx
shell: /etc/init.d/nginx reload
5.定义tasks:
vim /etc/ansible/nginx_config/roles/new/tasks/main.yml
- name: copy conf file
copy: src={{ item.src }} dest={{ nginx_basedir }}/{{ item.dest }} backup=yes owner=root group=root mode=0644
with_items:
- { src: nginx.conf, dest: conf/nginx.conf }
- { src: vhosts, dest: conf/ }
notify: restart nginx
6.定义一个update程序的入口文件:
vim /etc/ansible/nginx_config/update.yml
---
- hosts: 192.168.147.138
user: root
roles:
- new
7.执行更新:ansible-playbook /etc/ansible/nginx_config/update.yml
上面实现了更新,即在服务端修改配置文件,执行playbook即可同步到客户端。
回滚的实现更简单:在每次更新之前,先将new/目录下的配置文件备份到old/目录下,定义一个rollback程序的入口文件:
vim /etc/ansible/nginx_config/rollback.yml
---
- hosts: 192.168.147.138
user: root
roles:
- old
如果更新失败,可以执行回滚:ansible-playbook /etc/ansible/nginx_config/rollback.yml
ansible样例库:
git clone git://github.com/dl528888/ansible-examples.git
git命令需要yum安装一下:yum install -y git
下面关于Ansible的文章您也可能喜欢,不妨参考下:
Ansible 的详细介绍:请点这里
Ansible 的下载地址:请点这里