1  概述


ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。

ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。主要包括如下的特性:

(1)、连接插件connection plugins:负责和被监控端实现通信;

(2)、host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;

(3)、模块化,调用特定的模块,完成特定任务,各种模块核心模块、command模块、还支持自定义模块;

(4)、借助于插件完成记录日志邮件等功能;

(5)、支持playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。

(6)、基于Python语言实现,由Paramiko, PyYAML和Jinja2三个关键模块;

(7)、部署简单,无agent

(8)、支持幂等性;

(9)、ansible:用于Configuration和Command and Control

本文将通过例子介绍ansible的配置和ansible的常用模块使用



2  ansible配置介绍


安装服务包

服务包在epel源中,直接安装

yum -y install ansible

配置文件:/etc/ansible/ansible.cfg

主机清单:/etc/ansible/hosts

主程序:

ansible

ansible-playbook

ansible-doc

ansible的简单使用格式:

ansible  HOST-PATTERN  -m MOD_NAME  -a  MOD_ARGS -f FORKS -C -u USERNAME -c CONNECTION

简要命令介绍

-m指明要加载的模块,因为不同的功能需要调用不同的模块,模块才是完成功能的核心,如果不指定模块,默认是command命令,在目标主机上执行一个命令

-a 定义模块的操作

-f:指定一批要执行机器的数量

查看所有主机

ansible all --list-hosts

查看对应组 websrvs 的所有的主机

ansible websrvs --list-hosts

检查状态

ansible all -m ping

执行命令,默认是模块是command

如执行ifconfig命令

ansible all -a 'ifconfig'

等价于如下命令

ansible all -m command -a 'ifconfig'

查看模块类列表,和模块的功能解释,自带模块叫标准模块,可以自定义模块。

ansible-doc -l



3  ansible的常用模块


获取模块列表:ansible-doc  -l

查看对应模块详细介绍的命令: ansible-doc -s module

Ansible:无代理模式,建议通过ssh管理, 由模块实现相应的管理  

      常用模块:

      文件管理  copy, file, fetch, get_url

      软件包安装管理:yum, easy_install, pip,apt

      服务管理: service

      用户管理:   group, user

      任务计划:     cron, at

      命令管理:    command, shell

      自动将脚本复制到远端执行后删除:   script

      测试管理: ping

3.1  实验环境准备

73是ansible主机,63,,65,72,75是被管理的主机,操作前同步时间

ansibles服务包在epel源中,或者extras(仅次于os外的仓库)包中。配置好yum源后

yum -y install ansible

在ansible主机端生成密钥 ,或者直接在hosts文件定义时,直接写入密码,但是这种方式不安全,建议生成ssh 的key文件

生成ssh key,分发到到每台需要管控的主机上,命令如下

ssh-keygen -t rsa -P ''
for i in 63 65 72 75 ;do ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.18.50.$i;done

#注意,这里如果机器太多,可以通过except命令输入yes和密码实现自动化分发ssh key,语句如下

#!/bin/bash
for i in 63 65 72 75;do
expect -c "
        spawn ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.18.50.$i;
expect {
\"*assword\" {set timeout 300; send \"Pass1234\r\"; }
\"yes/no\" { send \"yes\r\"; exp_continue; }
}
expect efo"
done
如果发送key失败,建议将对应主机的ssh的配置文件修改三个配置后重试,一般情况下可以解决
sed -i 's/#UseDNS yes/UseDNS no/g' /etc/ssh/sshd_config
sed -i 's/GSSAPICleanupCredentials yes/GSSAPICleanupCredentials no/g' /etc/ssh/sshd_config
sed -i 's/GSSAPIAuthentication yes/GSSAPIAuthentication no/g' /etc/ssh/sshd_config
#重启sshd服务
service sshd restart

73上配置如下/

在hosts文件定义要管理的主机,纳入同一组,一个主机可以纳入多个组,

vim  /etc/ansible/hosts
[websrvs]
172.18.50.72
172.18.50.75
[dbsrvs]
172.18.50.63
172.18.50.65

完成hosts配置和认证后,不需要重启任何服务,可以直接使用ansible

3.2  常用模块介绍

command模块:在远程主机运行命令;

chdir:执行命令前切换工作目录至指定的位置;

create=/PATH/TO/SOMEFILE+OR_DIR:如果此次给定的文件或者目录存在,则不执行命令

remove,

removes=/PATH/TO/SOMEFILE_OR_DIR:如果此处给定的文件或目录不存在,则不执行命令;与create相反,意为:令此处给定的文件或目录存在时方执行命令;

例子

在172.18.50.63的/tmp下创建文件73abc和目录test,但是遵循幂等原则,mkdir命令如果对应目录以及存在,就会报错

ansible 172.18.50.63 -m command -a "touch 73abc chdir=/tmp"
ansible 172.18.50.63 -m command -a "mkdir test chdir=/tmp"

查看管理主机的当前路径,如果不更改路径,默认在该路径下执行操作

ansible 172.18.50.63 -m command -a "pwd"

shell模块:在远程主机在shell进程下运行命令,支持shell特性,如管道等;

chdir=:执行命令前切换工作目录至指定的位置;

creates=/PATH/TO/SOMEFILE_OR_DIR:如果此处给定的文件或目录存在,则不执行命令;

removes=/PATH/TO/SOMEFILE_OR_DIR:如果此处给定的文件或目录不存在,则不执行命令;意为:令此处给定的文件或目录存在时方执行命令;

executable=/PATH/TO/SHELL:指定运行命令使用的shell解释器;

例子

完成高级shell命令,如管道命令和重定向命令,需要用shell模块来执行,跟command命令相似

如执行以下命令,虽然没有保存,但是更改密码没有成功,模块需要指定shell模块执行成功

ansible 172.18.50.63 -m command -a "echo test6666 | passwd --stdin test66"

正确命令

ansible 172.18.50.63 -m shell -a "echo test6666 | passwd --stdin test66"

将每台主机上的/root/host1重定向到文件/etc/hosts里

ansible all -m shell -a "cat /root/host1 >> /etc/hosts"

group模块:管理组账号

    name=

    state= #创建用present,删除用absent

    system=

    gid=

例子

创建组test89,指定gid为1008

ansible 172.18.50.63 -m group -a "name=test89 gid=1008"

user模块:管理用户账号

name=

system=

uid=

shell=

group=

groups=

comment=

home=

generate_ssh_key={true | false}

local=

例子

创建账号sunny99,指定uid为1990

ansible 172.18.50.63 -m user -a "name=sunny99 uid=1990"

copy模块:将文件拷贝到远程主机 

用法:

(1) src=  dest=

(2) content=  dest=

owner, group, mode 

例子

拷贝当前目录下的hello.sh文件到所有主机/tmp目录下

ansible all -m copy -a "src=hello.sh dest=/tmp/ owner=daemon group=sunny mode=755"

用content直接在所有主机的目录/tmp下生成文件hi.txt,并写入内容

ansible all -m copy -a "content='hello,sunny\nhow are you\n' dest=/tmp/hi.txt owner=sunny group=sunny mode=664"

fetch模块:从远端节点取文件,会在本地对应的目录下,即dest指定的目录下,创建一个以主机ip命令的目录,同时在该ip目录下,创建src指定的目录,将文件放到对应的目录下

例子

从远端的主机的/tmp下获取hi.txt文件,放到本地的/tmp下,那么在本地tmp下会生成以所有主机ip命名的目录

ansible all -m fetch -a "src=/tmp/hi.txt dest=/tmp/"

get_url模块:从互联网上下载模块到每一台管理的主机,是幂等的。

get_url模块:从互联网上(http,https,ftp协议)下载模块到每一台管理的主机,是幂等的。 

    url=

    dest=

    sha256sum=

    owner, group, mode

例子

下载url对应的目录,并且保存到主机172.18.50.63的/root/blog1里

ansible 172.18.50.63 -m get_url -a "url=https://blog.51cto.com/ghbsunny/2044309 dest=/root/blog1"

file模块:设置文件属性,注意file的stat比较特殊

用法:

(1) 创建链接文件(必须的):*path=  src=  state=link

(2) 修改属性:path=  owner= mode= group= 

(3) 创建目录:path=  state=directory

幂等, state=directory会自动创建一个目录

注意:state属性的可用值:file,directory,link,hard,touch,absent

例子

创建连接

ansible 172.18.50.63 -m file -a "path=/tmp/hidirlink src=/tmp/hidir state=link"

创建目录/tmp/hidir

ansible 172.18.50.63 -m file -a "path=/tmp/hidir state=directory"

修改目录/tmp/hidir的属性

ansible 172.18.50.63 -m file -a "path=/tmp/hidir mode=666 owner=sunny"

创建文件hitxt,并修改相关属性

ansible 172.18.50.63 -m file -a "path=/tmp/hitxt state=touch owner=sunny mode=770"

cron 模块:管理 cron.d 和 crontab条目.

minute=

day=

month=

weekday=

hour=

*job= #定制任务

*name= #表示以谁的身份身份编辑,不是远端运行的账号,crontab条目的描述,或者如果设置了env,则是环境变量的名称。 如果state = absent,则是必需的。注意,如果没有设置name和state = present,那么总是会创建一个新的crontab条目,而不管现有条目是什么。

user= #表示该计划任务在远程主机以谁的身份运行,远程主机需要拥有该账号

state=

present:创建

absent:删除

例子

创建一个计划任务,其中,远程主机以sunny账号执行该计划任务

ansible 172.18.50.63 -m cron -a "minute=00 hour=*/6 day=3 state=present user=sunny job='/usr/sbin/ntpdate 172.18.50.61'"

hostname模块:管理主机名

name=

例子

更改主机名为CentOS6CC

ansible 172.18.50.63 -m hostname -a "name=CentOS6C"

pip模块:管理python的库依赖管理模块

    name=

    state=

    version=

npm模块:用npm管理node.js包,:实现安装功能的组件

yum模块:使用“yum”包管理器管理包

         name=:程序包名称,可以带版本号;

state=

        present, latest,installed:安装

absent,remove:卸载

其他的包管理工具:apt(debian),zypper(suse), dnf(fedora),rpm,dpkg

例子

安装tree包

ansible 172.18.50.63 -m yum -a "name=tree state=latest"

查看tree包信息,这里使用默认的command模块查看

ansible 172.18.50.63  -a "rpm -qi tree"

service模块:管理服务

*name=  *星号表示必须选项

state=

started

stopped

restarted

enabled=

runlevel=

例子

启动mysql服务

ansible 172.18.50.63 -m service -a "name=mysqld state=started"

setup模块:获取facts,收集每个主机的变量

例子

获取172.18.50.72主机的变量

ansible 172.18.50.72 -m setup

git模块:版本追踪和管理的工具

repo:仓库路径

dest=目标路径

version=指明获取的版本,默认是获得最新的版本

例子

从git hub上下载代码

推送git 版本,服务器和远程主机都要安装git命令才能实现

ansible 172.18.50.63 -m git -a "repo=https://github.com/happyfish100/fastdfs.git dest=/tmp/fastdfs"

实现如下命令的作用

直接下载git hub上的代码

git clone https://github.com/happyfish100/fastdfs.git

deploy_helper:部署模块

haprxoy 模块:

backend=

host=

state=

weight=

执行脚本

自动将脚本复制到远端执行后删除,如本地有脚本/root/reset.sh,在hosts这组主机上执行如下

[root@CentOS7A ~]#ansible hosts -m script -a /root/reset.sh