一、简单介绍Ansible
ansible是一个基于Python开发的自动化运维工具!其功能实现基于SSH远程连接服务!ansible可以实现批量系统配置、批量软件部署、批量文件拷贝、批量运行命令等功能。批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。主要包括:
(1)、连接插件connection plugins:负责和被监控端实现通信;
(2)、host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
(3)、各种模块核心模块、command模块、自定义模块;
(4)、借助于插件完成记录日志邮件等功能;
(5)、playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。
特点:
1、不需要单独安装客户端,基于系统自带的sshd服务,sshd就相当于ansible的客户端。
2、不需要服务端。
3、需要依靠大量的模块实现批量管理。
4、配置文件/etc/ansible/ansible.cfg。
特性
(1)、no agents:不需要在被管控主机上安装任何客户端;
(2)、no server:无服务器端,使用时直接运行命令即可;
(3)、modules in any languages:基于模块工作,可使用任意语言开发模块;
(4)、yaml,not code:使用yaml语言定制剧本playbook;
(5)、ssh by default:基于SSH工作;
(6)、strong multi-tier solution:可实现多级指挥。
优点
(1)、轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
(2)、批量任务执行可以写成脚本,而且不用分发到远程就可以执行;
(3)、使用python编写,维护更简单,ruby语法过于复杂;
(4)、支持sudo。
中文手册参考地址:http://www.ansible.com.cn/docs/intro.html
官方文档参考地址:http://docs.ansible.com/
二、安装Ansible管理端
Ansible安装的方式很多,可以是源码、APT、PIP、YUM等方式安装。
RPM适用于 EPEL6/7, 以及仍在支持中的Fedora发行版。托管节点的操作系统版本可以是更早的版本(如 EL5), 但必须安装 Python 2.4 或更高版本的Python。Fedora 用户可直接安装Ansible, 但RHEL或CentOS用户,需要配置EPEL。
PIP安装方式
步骤1:CentOS/Rhel都需要安装epel源,有的系统是自带epel源的,不同的版本请看情况而设置。
rpm -ivh https://mirrors.aliyun.com/epel/6/x86_64/epel-release-6-8.noarch.rpm
步骤2:安装python-pip及python-devel程序包
yum install python-pip python-devel -y
步骤3:安装Ansible服务。
安装请前确保服务器的gcc、glibc开发环境均已安装,系统几乎所有的软件包编译环境均基于gcc,如不确认可先执行如下命令:
yum install gcc glibc-devel zlib-devel rpm-build openssl-devel -y
升级本地PIP至最新版本
pip install --upgrade pip
安装Ansible服务
pip install ansible --upgrade
执行命令ansible --version,有类似如下返回结果则表示Ansible安装成功并可正常使用。
[root@aa-77-0001 ~]# ansible --version
ansible 2.3.0.0
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
python version = 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) [GCC 4.4.7 20120313 (Red Hat 4.4.7-17)]
|
YUM安装方式
YUM(Yellow dog Updater,Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包,无需烦琐地一次次下载、安装。YUM安装Ansible过程如下:
步骤1:CentOS/Rhel都需要安装epel源,有的系统是自带epel源的,不同的版本请看情况而设置。
rpm -ivh https://mirrors.aliyun.com/epel/6/x86_64/epel-release-6-8.noarch.rpm
安装absible
yum install ansible -y
安装速度视网络情况而定,因为安装过程会安装非常多的依赖包,又因各系统环境的差异性,如返回类似如下结果则表示安装成功:
Installed:
  ansible.noarch  0:2.3.0.0-3.el6                                                                                        
Dependency Installed:
  python-babel.noarch  0:0.9.4-5.1.el6      python-crypto2.6.x86_64  0:2.6.1-2.el6  python-httplib2.noarch  0:0.7.7-1.el6  
  python-jinja2-26.noarch  0:2.6-3.el6      python-keyczar.noarch  0:0.71c-1.el6 python-markupsafe.x86_64  0:0.9.2-4.el6
  python-simplejson.x86_64  0:2.0.9-3.1.el6  sshpass.x86_64  0:1.06-1.el6          
Complete!
执行命令ansible --version,有类似如下返回结果则表示Ansible安装成功并可正常使用。
[root@aa-66-0001  ~]# ansible --version
ansible  2.3.0.0
  config file  =  /etc/ansible/ansible.cfg
  configured module search path  =  Default  w/o  overrides
  python version  =  2.6.6  (r266:84292,  Aug  18  2016,  15:13:37)  [GCC  4.4.7  20120313  (Red Hat  4.4.7-17)]
APT-GET安装方式
Apt-get全称是Advanced Package Tool,是一款适用于UNIX和Linux系统的应用程序管理器,适用于Ubuntu、Debian等deb包管理式的操作系统,主要用于自动地从互联网的软件仓库中搜索、安装、升级、卸载软件或操作系统。
演示ubuntu16.04
安装software-properties-common,旧的ubuntu为python-software-propertiesa
apt-get  install software-properties-common
添加Ansible源,用于2.0版本,2.0以前ppa:ansible / ansible - 1.9
apt-add-repository ppa:ansible/ansible
升级库文件
apt-get  update
安装ansible
apt-get  install ansible
源码安装方式
安装git
yum  -y  install git
安装ansible
git clone  git://github.com/ansible/ansible.git  --recursive
切换到程序目录
cd  ./ansible
执行env_setup脚本安装ansible
source  ./hacking/env-setup
如上列举了互联网主流系统的Ansible安装方式,如整个过程均无报错,则执行如下命令应有类似结果返回:
[root@ansible  ~]# ansible --version
ansible  2.3.0.0
  config file  =  /etc/ansible/ansible.cfg
  configured module search path  =  Default  w/o  overrides
  python version  =  2.6.6  (r266:84292,  Aug  18  2016,  15:13:37)  [GCC  4.4.7  20120313  (Red Hat  4.4.7-17)]
如上述命令能正常执行,表示Ansible安装成功,并可正常使用。通常情况下,Ansible的安装简单顺利,但确实会有安装报错的情况发生,多数情况是由本地复杂的系统环境导致的。
本人是yum安装,且基于CentOS7.3系统。
rpm  -ivhU https://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-9.noarch.rpm
yum  -y  install ansible
[root@ansible  ~]# ansible --version
ansible  2.3.0.0
  config file  =  /etc/ansible/ansible.cfg
  configured module search path  =  Default  w/o  overrides
  python version  =  2.7.5  (default,  Nov  6  2016,  00:28:07)  [GCC  4.8.5  20150623  (Red Hat  4.8.5-11)]
三、Ansible环境配置
修改Ansible配置文件
ansible默认配置文件为/etc/ansible/ansible.cfg,如果不存在ansible目录,需要自己创建
vim  /etc/ansible/ansible.cfg
inventory      =  /etc/ansible/hosts    #默认主机清单配置文件
private_key_file  =  /root/.ssh/id_rsa #指定默认验证key。可以使用--private-key指定其他key
sudo_user      =  root                  #sudo使用的默认用户 ,默认是root
remote_user    =  fsp #指定远端登录用户为fsp,默认是root
module_name  =  command                  #执行命令时候的默认模块,建议改成shell模块
forks  =  20 #默认5个进程并行处理操作,可以设置为20个
log_path  =  /var/log/ansible.log        #执行命令的log记录
......
更多配置参数和说明参见官方文档
当你主机数量很多时候,期初应该是可以使用root和密码来登录,我们可以配置一个主机组来检测这些主机存活状态,配置如下:
/etc/ansible/hosts这个是默认的主机组配置文件,默认不需要在命令中指定。
当然,也可以是别的文件,但是使用时候需用-i参数指定你的这个文件。
这里配置一个cnagroup的组,组包含了主机的ip地址,且配置文件单独创建
vim  /etc/ansible/hosts_cna
[cnagroup]
192.168.1.80
使用如下命令就可以检测主机存活,输入root密码。需要注意,比较适用于root密码一致的主机来批量操作。
[root@ansible  ~]# ansible all -i /etc/ansible/hosts_cna -u root -k -m ping
SSH password:
192.168.1.80  |  SUCCESS  =>  {
    "changed":  false,
    "ping":  "pong"
}
参数:
-i                  INVENTORY,  --inventory-file=INVENTORY,default=/etc/ansible/hosts
-k                  --ask-pass      ask for  connection password
-u                  REMOTE_USER,  --user=REMOTE_USER,default  root
-m                  MODULE_NAME,  --module-name=MODULE_NAME,(default=command)
-a                  MODULE_ARGS,  --args=MODULE_ARGS
查看当前用户
[root@ansible  ~]# ansible all -i /etc/ansible/hosts_cna -u root -k  -m shell -a 'whoami'
SSH password:
192.168.1.80  |  SUCCESS  |  rc=0  >>
root
需要注意,如果所有主机都是root,但是密码不一样话。就需要指定密码、用户等信息以下是Hosts部分中经常用到的变量部分
参数解释:
ansible_host #指定被管理的主机的真实IP,用于指定别名时候使用(2.0以前ansible_ssh_host)
ansible_port #指定被管理主机的ssh端口号,默认是22(2.0以前ansible_ssh_port)
ansible_user #ssh连接时默认使用的用户名(2.0以前ansible_ssh_user)
ansible_ssh_pass #ssh连接时的密码
ansible_sudo_pass            #使用sudo连接用户时的密码
ansible_sudo_exec            #如果sudo命令不在默认路径,需要指定sudo命令路径
ansible_ssh_private_key_file  #秘钥文件路径,秘钥文件如果不想使用ssh-agent管理时可以使用此选项
ansible_shell_type #目标系统的shell的类型,默认sh
ansible_connection #SSH连接的类型:local,ssh,paramiko, 1.2之前默认paramiko(若要用则跟ansible_connection=paramiko),后来智能选择,优先使用基于ControlPersist的ssh(支持的前提)
ansible_python_interpreter #用来指定python解释器的路径,默认为/usr/bin/python 同样可以指定ruby 、perl 的路径
.......
后续都会用到,其中ansible_ssh_pass密码是明文,不安全。ansible 极力推荐使用 --ask-pass 选项或使用 SSH keys.
这个时候可以将密码配置好之后使用shell模块检测当前登录用户
配置主机配置文件,指定默认root用户的密码,第一条是指定了root的密码。
第二条指定了连接remote的用户,如果默认使用root用户话可以不写,因为default is root。
[cnagroup]
192.168.1.80  ansible_ssh_pass=123.comA
#192.168.1.80 ansible_user=root ansible_ssh_pass=123.comA
#检测
ansible all  -i  /etc/ansible/hosts_cna  -m  ping
#也可以执行简单的命令
[root@ansible  ~]# ansible all -i /etc/ansible/hosts_cna -m command -a 'whoami'
192.168.1.80  |  SUCCESS  |  rc=0  >>
root
下面进行简单安全配置,步骤如下:
#在客户端上创建普通用户fsp,且具有su权限。并设置fsp用户密码。可以批量执行。
ansible all  -i  /etc/ansible/hosts_cna  -m  shell  -a  '/usr/sbin/useradd -G wheel fsp && /bin/echo 123.comAB|passwd --stdin fsp'
#查询用户是否存在和所在的wheel组
ansible all  -i  /etc/ansible/hosts_cna  -m  command  -a  'id fsp'
#同时root禁止远程登录,只能fsp登录之后再su - root。
ansible all  -i  /etc/ansible/hosts_cna  -m  command  -a  'sed -i "s/^#PermitRootLogin.*/PermitRootLogin no/g" /etc/ssh/sshd_config'
#确认是否拒绝root远程登录
ansible all  -i  /etc/ansible/hosts_cna  -m  shell  -a  'grep -i PermitRootLogin.* /etc/ssh/sshd_config'
#重启sshd服务
ansible all  -i  /etc/ansible/hosts_cna  -m  command  -a  '/etc/init.d/sshd restart'
#这时候root登录就被拒绝,即Ansible管理端也使用不了,这时候需要命令指定普通用户和密码,su切换到root等参数,注意清单中无需指定主机变量。
在2.0以前版本方法如下(普通用户和提权root用户):
ansible all  -i  /etc/ansible/hosts_cna  -u  fsp  -k  -m  shell  -a  'whoami'
ansible all  -i  /etc/ansible/hosts_cna  -u  fsp  -k  --su  --su-user=root  --ask-su-pass  -m  shell  -a  'whoami'
在2.0以后版本方法如下,仅仅是提权不一样,1.9命令会被弃用:
ansible all  -i  /etc/ansible/hosts_cna  -u  fsp  -k  -b  --become-method=su  --become-user=root  --ask-become-pass  -m  shell  -a  'whoami'
普通用户使用key验证,禁止密码登录:
#在这之前,需要考虑如何将公钥一次性分发到所有客户端。可以使用expect、sshpass写循环分发或ansible等工具,这里使用后者。
#如何分发公钥呢?首先以root登陆ansible,在上执行如下命令生成空密码的私钥和公钥的密钥对
[root@ansible  ~]# ssh-keygen -t rsa -P ''
#这时候在root目录下生成.ssh目录,.ssh下有id_rsa和id_rsa.pub文件。
#使用如下命令将公钥id_rsa.pub复制到客户端/home/fsp/.ssh目录下即可。可以批量操作。
#创建/home/fsp/.ssh,且.ssh权限为700
ansible all  -i  /etc/ansible/hosts_cna  -u  fsp  -k  -m  shell  -a  'mkdir -m 700 -p /home/fsp/.ssh'
#创建文件authorized_keys且权限改为600
ansible all  -i  /etc/ansible/hosts_cna  -u  fsp  -k  -m  shell  -a  'touch /home/fsp/.ssh/authorized_keys && chmod 600 /home/fsp/.ssh/authorized_keys'
#追加公钥到authorized_keys文件中,$key为公钥,复制粘贴即可,注意不能引用变量。
ansible all  -i  /etc/ansible/hosts_cna  -u  fsp  -k  -m  shell  -a  'echo "$key" >/home/fsp/.ssh/authorized_keys'
#需要注意,scp等操作,这样复制过去还得需要在客户端上改名为authorized_keys,权限还得设置600。这些上面已经做了操作。如果么有.ssh目录还得创建且权限为700
#如果使用ssh-copy-id命令复制不需要操作。
#使用key指定验证,看是否OK
ansible all  -i  /etc/ansible/hosts_cna  -u  fsp  --private-key=/root/.ssh/id_rsa  -m  shell  -a  'whoami'
#如果上面都回显OK,那么就可以批量配置所有主机不接受密码验证登录。注意,先配置好普通用户key。在做这个操作。
ansible all  -i  /etc/ansible/hosts_cna  -u  fsp  --private-key=/root/.ssh/id_rsa  --su  --su-user=root  --ask-su-pass  -m  shell  -a  'sed -i "s/^PasswordAuthentication.*/PasswordAuthentication no/g" /etc/ssh/sshd_config'
#检查和加载
ansible all  -i  /etc/ansible/hosts_cna  -u  fsp  --private-key=/root/.ssh/id_rsa  --su  --su-user=root  --ask-su-pass  -m  shell  -a  'grep -i "^PasswordAuthentication.*" /etc/ssh/sshd_config'
ansible all  -i  /etc/ansible/hosts_cna  -u  fsp  --private-key=/root/.ssh/id_rsa  --su  --su-user=root  --ask-su-pass  -m  shell  -a  '/etc/init.d/sshd reload'
#优化命令使用,比较简短
private_key_file  =  /root/.ssh/id_rsa  #在ansible.cfg中指定key,
sudo_user      =  root #sudo使用的默认用户 ,默认是root
remote_user    =  fsp                  #指定远端登录用户为fsp,默认是root
#最后可以使用如下命令
ansible all  -i  /etc/ansible/hosts_cna  --su  --ask-su-pass  -m  shell  -a  'whoami'
四、Ansible常用模块
帮助信息说明,其中ansible-doc -l是查看所有自带的模块,ansible-doc shell查看模块具体用法和参数等
ansible-doc
 -h,  --help show this  help message and  exit
 -l,  --list List available modules
 -M  MODULE_PATH,  --module-path=MODULE_PATH
 -s,  --snippet  #搜索
 -v,  --verbose verbose mode  (-vvv for  more,  -vvvv to  enable connection debugging)
 --version show program's  version number and  exit
执行ping模块:ping
#ping模块的参数:
#该模块并无参数,仅仅是检查主机是否存活
#用于检测主机是否存活
[root@ansible  ~]# ansible all -i /etc/ansible/hosts_cna --su --ask-su-pass -m ping
SU password:
192.168.1.182  |  SUCCESS  =>  {
    "changed":  false,
    "ping":  "pong"
}
执行命令模块:command
#需要注意,此模块不支持 "<",">","|","&"等复杂的参数,需要支持该参数的话,请使用shell模块。由于默认是command模块,所以不需要指定 -m command参数
#command模块参数:
chdir            运行这个命令之前先进入到目录
creates          如果这个参数对应的文件存在,就不运行command
executable 将shell切换为command执行,这里的所有命令需要使用绝对路径
removes          如果这个参数对应的文件不存在,就不运行command
#例如当前登录用户
[root@ansible  ~]# ansible all -i /etc/ansible/hosts_cna --su --ask-su-pass -a 'id'
SU password:
192.168.1.105  |  SUCCESS  |  rc=0  >>
uid=0(root)  gid=0(root)  groups=0(root)
执行Shell模块:shell
shell模块参数:
chdir            运行这个命令之前先进入到目录
creates          如果这个参数对应的文件存在,就不运行command
executable 将shell切换为command执行,这里的所有命令需要使用绝对路径
removes          如果这个参数对应的文件不存在,就不运行command
#比如过滤一个进程号
[root@ansible  ~]# ansible all -i /etc/ansible/hosts_cna --su --ask-su-pass -m shell -a "ps -ef|grep sshd"
SU password:
192.168.1.160  |  SUCCESS  |  rc=0  >>
root      22102      1  0  15:52  ?        00:00:00  /usr/sbin/sshd
root      27027  22102  0  22:40  ?        00:00:00  sshd:  fsp  [priv]
fsp 27029  27027  0  22:40  ?        00:00:00  sshd:  fsp@pts/0  
root      27097  27096  0  22:40  pts/0    00:00:00  /bin/sh  -c  ps  -ef|grep  sshd
root      27099  27097  0  22:40  pts/0    00:00:00  grep  sshd
#先进入tmp/ ,在tmp/目录下让所有节点运行ss.sh并把log输出到logs.txt
ansible all  -i  /etc/ansible/hosts_cna  --su  --ask-su-pass  -m  shell  -a  "sh ss.sh >> logs.txt chdir=/tmp/"
执行copy模块:copy
copy模块参数:
src            被复制到远程主机的本地文件,可以是绝对路径,也可以是相对路径,如果路径是一个目录,它将递归复制,在这种情况下,如果路径使用"/"结尾,则只复制目录里的内容,如果没有使用"/"结尾,则包含目录在内的整个内容全部复制,类似rsync。
content        用于替代src,可以直接设定指定文件的内容,拷贝到远程文件内
dest 必选项,绝对路径,如果源文件是一个目录,那么dest也必须是一个目录
backup 在覆盖前将源文件备份,备份文件包含时间信息,有两个选项yes/no
directory_mode  递归设定目录的权限,默认为系统默认权限
force          如果目录主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目录位置不存在该文件时,才复制。默认为yes
group  设定一个群组拥有拷贝到远程节点的文件权限
mode  等同于chmod,参数可以为“u+rwx or  u=rw,g=r,o=r”
owner  设定一个用户拥有拷贝到远程节点的文件权限
others 所有的file模块里的选项都可以在这里使用
#把/root/fsp.conf文件拷贝到远程节点/tmp/fsp.conf,拥有者fsp,群组fsp,权限是0644
ansible all  -i  /etc/ansible/hosts_cna  --su  --ask-su-pass  -m  copy  -a  "src=/root/fsp.conf dest=/tmp/fsp.conf owner=fsp group=fsp mode=0700"
#复制本地ss.sh脚本到远端/tmp/目录下
ansible all  -i  /etc/ansible/hosts_cna  --su  --ask-su-pass  -m  copy  -a  "src=/root/ss.sh dest=/tmp/ owner=root group=root mode=0700"
#过滤出IP地址信息
ansible all  -i  /etc/ansible/hosts_cna  --su  --ask-su-pass  -m  shell  -a  "source /etc/profile;ifconfig eth0|grep -Po '(?<=addr:)\S+'"
执行file模块:file
file模块参数:
force 需要在两种情况下强制创建链接,一种是源文件不存在,但之后会建立的情况;另一种是目录软件链接已存在,需要先取消之前的软链接,然后创建新的软链接,有两个选项:yes/no
owner 定义文件/目录的所有者
group 定义文件/目录的归属组
mode        定义文件/目录的权限
path        必选项,定义文件/目录的路径
recurse 递归设置文件的属性,只对目录有效
src 被链接的源文件路径,只应用于state=link的情况
dest        补链接到的路径,只应用于state=link的情况
state:
      directory 如果目录不存在,就创建目录
      file        即使文件不存在,也不会被创建
      link        创建软链接
      hard        创建硬链接
      touch 如果文件不存在,则会创建一个新的文件,哪果文件或目录已存在,则更新其最后的修改时间
      absent      删除目录、文件或取消链接文件
#修改文件权限,所有者,分组(这些参数可以用在copy模块中
ansible all  -i  /etc/ansible/hosts_cna  --su  --ask-su-pass  -m  file  -a  "dest=/tmp/ss.sh mode=0777 owner=root group=fsp"
#创建文件夹和删除文件夹psswd
ansible all  -i  /etc/ansible/hosts_cna  --su  --ask-su-pass  -m  file  -a  "dest=/tmp/psswd mode=0755 owner=root group=root state=directory"
ansible all  -i  /etc/ansible/hosts_cna  --su  --ask-su-pass  -m  file  -a  "dest=/tmp/psswd state=absent"
执行user模块:user
user模块参数:
home        指定用户的家目录,需要与createhome配合使用
groups      指定用户的属组
uid 指定用户的uid
password    指定用户的密码
name        指定用户名
createhome  是否创建家目录  yes|no
system      是否为系统用户
remove      当state=absent时,remove=yes则表示连同家目录一起删除,等价于userdel  -r
state 是创建还是删除
shell 指定用户的shell环境
#创建一个test用户,注意用户设置密码话需要将密码进行加密处理,否则密码明文过去在/etc/shadow中
ansible all  -i  /etc/ansible/hosts_cna1  --su  --ask-su-pass  -m  user  -a  "name=test password=$1$XHdqEQxr$UWpgwPBpo/U95SWqH4wAx1"
echo  "123.comA"  |openssl passwd  -1  -salt  $(<  /dev/urandom tr  -dc  '[:alnum:]'  |  head  -c  32)  -stdin
或
openssl passwd  -1  123.comA
#备注,感觉不是很好使用,暂时滤过
执行yum模块:yum
yum模块参数:
config_file          yum的配置文件
disable_gpg_check:  关闭gpg_check
disablerepo          不启用某个源
enablerepo 启用某个源
name 要进行操作的软件包的名字,也可以传递一个url或者一个本地的rpm包的路径
state                Whether to  install  (`present' or `installed',  `latest'), or remove (`absent'  or  `removed')  a  package.
 present:如果有就不进行安装
 latest:安装最新
 absent:删除
 latest:更新
#安装httpd
ansible all  -i  /etc/ansible/hosts_cna1  --su  --ask-su-pass  -m  yum  -a  "state=present name=httpd"
执行service模块:service
该模块包含如下选项:
enabled:  是否开机启动  yes|no
name:    必选项,服务名称
state: 对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)
pattern:  定义一个模式,如果通过status指令来查看服务的状态时,没有响应,就会通过ps指令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然在运行
runlevel:运行级别
sleep: 如果执行了restarted,在则stop和start之间沉睡几秒钟
还有很多模块,比较常用如下,后期工作中按需求更新使用方法:
cron模块
group模块
script模块
raw模块
get_url模块
synchronize模块
五、Playbooks简单配置使用
像很多其它配置文件管理方法一样,Ansible使用一种比较直白的方法来描述自己的任务配置文件。Ansible 的任务配置文件被称之为“playbook”,我们可以称之为“剧本”。每一出剧本(playbook)中都包含一系列的任务,这每个任务在ansible中又被称为一出“戏剧”(play)。一个剧本(playbook)中包含多出戏剧(play),这很容易理解。
在Ansible中,我们就充当编剧的角色,亲自编写剧本(一系列的服务器操作),让一出出精彩的戏剧(play)巧妙配合,完成对服务器的一系列精确控制。
Playbook语法简介
Playbook采用一种可读性很高的且容易被人类阅读的语法的YAML语法编写,YAML: “YAML Ain’t a Markup Language”(YAML不是一种置标语言)。该语言在被开发时,YAML 的意思其实是:”Yet Another Markup Language”(仍是一种置标语言),格式如下所示:
YAML
house:
  family:
    name: Doe
    parents:
      -  John
      -  Jane
    children:
      -  Paul
      -  Mark
      -  Simone
  address:
    number: 34
    street: Main Street
    city: Nowheretown
  zipcode: 12345
对于 Ansible, 每一个 YAML 文件都是从一个列表开始. 列表中的每一项都是一个键值对, 通常它们被称为一个 “哈希” 或 “字典”. 所以, 我们需要知道如何在 YAML 中编写列表和字典.
YAML 还有一个小的怪癖. 所有的 YAML 文件(无论和 Ansible 有没有关系)开始行都应该是 ---. 这是 YAML 格式的一部分, 表明一个文件的开始.
列表中的所有成员都开始于相同的缩进级别, 并且使用一个 "- " 作为开头(一个横杠和一个空格):
YAML特性
YAML的可读性好
YAML和脚本语言的交互性好
YAML使用实现语言的数据类型
YAML有一个一致的信息模型
YAML易于实现
YAML语法
1  YAML使用可打印的Unicode字符,可使用UTF-8或UTF-16。
2  使用空白字符未文件缩排来表示结构;不过不能使用跳格字符。
3  注解由井字号(  # )开始,可以出现在一行中的任何位置,而且范围只有一行(也就是一般所谓的单行注解)
4  每个清单成员以单行表示,并用短杠+空白(  -  )起始。或使用方括号(  [ ]  ),并用逗号+空白(  ,  )分开成员。
5  每个杂凑表的成员用冒号+空白(  : )分开键值和内容。或使用大括号( {  }  ),并用逗号+空白(  ,  )分开。  杂凑表的键值可以用问号  (  ?  )起始,用来明确的表示多个词汇组成的键值。
6  字串平常并不使用引号,但必要的时候可以用双引号  (  "  )或单引号  (  '  )框住。使用双引号表示字串时,可用倒斜线(  \  )开始的跳脱字符(这跟C语言类似)表示特殊字符。
7  区块的字串用缩排和修饰词(非必要)来和其他资料分隔,有新行保留(preserve)(使用符号  |  )或新行折叠(flod)(使用符号  >  )两种方式。
8  在单一档案中,可用连续三个连字号(——)区分多个档案。另外,还有选择性的连续三个点号(  ...  )用来表示档案结尾。
9  重复的内容可使从参考标记星号  (  *  )复制到锚点标记(  &  )。
10  指定格式可以使用两个惊叹号  (  !!  ),后面接上名称。
11  档案中的单一文件可以使用指导指令,使用方法是百分比符号(  %  )。有两个指导指令
shell脚本与Playbook的转换
现在越来越多的DevOPS也开始将目光移向了Ansible,因为Ansible可以轻松的将shell脚本或简单的shell命令转换为Ansible plays。下面有一个安装apache的shell脚本,大家来感受一下:
#!/bin/bash
#安装Apache
yum  -y  install httpd httpd-devel
#备份配置文件
/bin/cp  /etc/httpd/conf/httpd.conf  /etc/httpd/conf/httpd.conf_back
#启动Apache,并设置开机启动
service httpd start
chkconfig httpd on
将其转换为一个完整的playbook后:
#表示指定主机清单中的所有主机,也可以指定具体的主机组
-  hosts:  all
#指定登陆远程的用户
  remote_user:  fsp
#启用使用提权
  become:  yes
#提权用户为root
  become_user:  root
#提权的方式为su
  become_method:  su
  tasks:
  -  name:  install apache server
    yum:  name=httpd name=httpd-devel state=latest
  -  name:  backup httpd.conf
    command:  cp  /etc/httpd/conf/httpd.conf  /etc/httpd/conf/httpd.conf_back
  -  name:  start apache,  auto start apache
    service:  name=httpd state=restarted enabled=yes
#执行时候需要-i指定主机清单信息,-K指定切换root的密码。普通用户是key验证登陆的。已经在配置文件中指定。命令如下:
[root@ansible roles]# ansible-playbook command.yml -i /etc/ansible/hosts_cna1 -K
SUDO password:
PLAY  [all]  ************************************************************************************************************************************************************************************
TASK  [Gathering Facts]  ************************************************************************************************************************************************************************
ok:  [192.168.1.80]
TASK  [install apache server]  ******************************************************************************************************************************************************************
changed:  [192.168.1.80]
TASK  [backup httpd.conf]  **********************************************************************************************************************************************************************
changed:  [192.168.1.80]
TASK  [start apache,  auto start apache]  ********************************************************************************************************************************************************
changed:  [192.168.1.80]
PLAY RECAP  ************************************************************************************************************************************************************************************
192.168.1.80 :  ok=4    changed=3    unreachable=0    failed=0
由于目前暂时不使用,暂不测试。后续工作需要在添加,以上内容来自:http://www.jianshu.com/p/41c4ed3ce779
参考文档:http://www.ansible.com.cn/docs/playbooks_intro.html
六、工作中的案例记录
七、Ansible FAQ
故障1:
如果客户端不在know_hosts里可能提示
[root@ansible  ~]# vim /etc/ansible/hosts_cna
[root@ansible  ~]# ansible all -i /etc/ansible/hosts_cna -m ping
The authenticity of host  '192.168.1.80 (192.168.1.80)'  can't  be established.
RSA key fingerprint is  3b:30:3c:94:59:dc:23:64:ea:20:14:11:3b:73:7d:55.
Are you sure you want to  continue  connecting  (yes/no)?
解决方法:
编辑/etc/ansible/ansible.cfg文件,取消注释以禁用SSH密钥主机检查
host_key_checking  =  False
故障2:
在Ansible2.0.0-2.3.0的版本(我是2.3.0版本测试出来的)。
执行su提权的时候总是报错Timeout  (12s)  waiting for  privilege escalation prompt。当然,无论是2.0以后的提权命令,还是2.0以前提权都报错。在经过一天查看和翻阅之后,原来是bug导致。证明:https://github.com/ansible/ansible/issues/13278
错误提示:
root@ansible:/etc/ansible# ansible all -i /etc/ansible/hosts_cna -u fsp -k --su --su-user=root --ask-su-pass -m shell -a 'whoami'
SSH password:
SU password[defaults to  SSH password]:
192.168.1.42  |  FAILED  |  rc=-1  >>
Timeout  (12s)  waiting for  privilege escalation prompt:
root@ansible:/etc/ansible# ansible all -i /etc/ansible/hosts_cna -m shell -a 'whoami' -u fsp -k --become-user=root --become-method=su -K --become
SSH password:
SU password[defaults to  SSH password]:
192.168.1.42  |  FAILED  |  rc=-1  >>
Timeout  (12s)  waiting for  privilege escalation prompt:
解决方法:
既然想解决,肯定是看有没有最新版本,安装试一下,下载2.3.1版本,地址如下。
http://dl.fedoraproject.org/pub/epel/testing/7/x86_64/a/ansible-2.3.1.0-1.el7.noarch.rpm
然后(Cent0S7.3系统)在系统wget下。在wget到系统。执行yum  -y  install ansible-2.3.1.0-1.el7.noarch.rpm。这样就会安装新版本,自动解决依赖。需要有epel源。
故障3:
[root@ansible  ~]# ansible all -i /etc/ansible/hosts_cna --su --ask-su-pass -m shell -a 'ip a'
SU password:
192.168.1.168  |  FAILED  |  rc=127  >>
/bin/sh:  ip:  command  not  found
解决方法:
加载source  /etc/profile环境变量
ansible all  -i  /etc/ansible/hosts_cna  --su  --ask-su-pass  -m  shell  -a  'source /etc/profile;ip a'
故障4:
在执行ansible-playbook  -i  /etc/ansible/hosts_cna1 command.yml  -K。有如下警告:
[WARNING]:  Consider using file  module with state=touch  rather than running touch
解决方法:
上面的命令其实是执行成功了,但是有一个Warning,提示我们可以用Ansible的file模块来替代我们写的touch命令,于是我们把YAML改成下面的这样:
old:
tasks:
  -  name:  touch  files
    command:  touch  /root/123.txt
new:
  tasks:
  -  name:  touch  files
    file:  path=/root/123.txt  state=touch
故障5:
在主机清单中定义了10.252.143.38 ansible_ssh_user=root ansible_ssh_pass=DSD@#hw5,报错认证失败
SUSE操作系统
ansible  2.4.1.0
  config file  =  /etc/ansible/ansible.cfg
  configured module search path  =  [u'/root/.ansible/plugins/modules',  u'/usr/share/ansible/plugins/modules']
  ansible python module location  =  /usr/lib/python2.7/site-packages/ansible-2.4.1.0-py2.7.egg/ansible
  executable location  =  /usr/bin/ansible
  python version  =  2.7.9  (default,  Dec  21  2014,  11:02:59)  [GCC]
localhost:/etc/ansible  # ansible all -i /etc/ansible/test -m command -a 'id'
s192.168.99.12  |  UNREACHABLE!  =>  {
    "changed":  false,
    "msg":  "Authentication failure.",
    "unreachable":  true
}
#同时messages和warn都是认证失败,初步以为是bug,但是使用123.aaA就可以成功。看来是变量传的有
#问题,通过单引号ansible_ssh_pass='I0T@#hw5',依然如此。当换成双引号后成功了,看来@#¥%这些
#符号必须加双引号才可以。