一、简单介绍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',依然如此。当换成双引号后成功了,看来@#¥%这些
#符号必须加双引号才可以。