1、模块化工具
用户可以任意添加,修改,删除功能模块的应用程序
2、安装部署ansible
环境:一台ansible服务器,3台客户端
服务器1:192.168.1.1
客户端1:192.168.1.2
客户端2:192.168.1.3
客户端3:192.168.1.4
1).配置IP(设置每台服务器的计算机名)
2).安装ansible服务
复制ansiblerepo软件包内所有文件到/media,修改yum源为本地源。
rm -rf /etc/yum.repos.d/*
vim /etc/yum.repos.d/yum.repo
[yum]
name=yum
baseurl=file:///media
enabled=1
gpgcheck=0
yum -y install ansible
查看版本号,验证结果。如能正常执行,表示可以使用。
[root@localhost ~]# ansible --version
3).创建SSH免交互登录
[root@localhost ~]# ssh-keygen -t rsa //一路回车
将公钥传送给其他客户端
[root@localhost ~]# ssh-copy-id root@192.168.1.2
[root@localhost ~]# ssh-copy-id root@192.168.1.3
[root@localhost ~]# ssh-copy-id root@192.168.1.4
yes+密码
连接测试,完成部署
[root@localhost ~]# ssh root@192.168.1.2
[root@localhost ~]# ip add
[root@localhost ~]# exit
4).ansible配置(分组管理客户端)
vim /etc/ansible/hosts
添加:
[web]
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
[mail]
mail.sohu.com
www.mail@163.com
[nfs]
192.168.1.2
192.168.1.4
5).ansible基本操作
设置主机信息的配置文件:
[root@localhost ~]# ansible -i /etc/ansible/hosts web -m ping
参数说明:
-i 指定配置文件
-m 执行命令
web 配置文件中的范围区域,all代表所有在配置文件中定义的客户端
使用默认配置文件:
[root@localhost ~]# ansible web -m ping
查看web区域中所有主机的httpd服务状态:
(commands是提供linux系统环境下支持使用shell命令的一个模块)
[root@localhost ~]# ansible web -m command -a 'systemctl status httpd'
注意:可以将某台客户端的httpd服务,用yum进行安装。并且启动服务再次查看,可以得到一个启动的效果。
查看web区域中指定主机的httpd服务状态:
[root@localhost ~]# ansible web -m command -a 'systemctl status httpd' --limit '192.168.1.2'
查看指定主机的httpd服务状态
[root@localhost ~]# ansible 192.168.1.2 -m command -a 'systemctl status httpd'
检查所有主机是否存活
[root@localhost ~]# ansible all -f 5 -m ping
列出web组所有主机列表
[root@localhost ~]# ansible web --list
批量显示web组中的磁盘使用空间
[root@localhost ~]# ansible web -m command -a 'df -hT'
批量显示web组中的内存使用情况
[root@localhost ~]# ansible web -m command -a 'free -h'
注:command模块,不允许使用会出现人机对话界面的命令,不允许使用一直进行更新数据的命令如top,不允许使用需要强制中断的或特殊退出模式的命令,不允许命令中带有shell语句或正则表达式。
6).ansible-doc基本操作
查看支持的模块
[root@localhost ~]# ansible-doc -l
查看指定模块的说明:
[root@localhost ~]# ansible-doc ping
7).ansible-console:交互式工具,类似于cmd和shell
[root@localhost usr]# ansible-console
root@all (9)[f:5]$ cd web
root@web (4)[f:5]$ list
root@web (4)[f:5]$ ls
root@web (4)[f:5]$ pwd
root@web (4)[f:5]$ echo "192.168.1.2 server1" >> /etc/hosts
root@web (4)[f:5]$ cat /etc/hosts
root@web (4)[f:5]$ exit
8).ansible模块
1>command模块:在远程主机执行命令,不支持管道、重定向等shell的特性
chdir:运行命令时提前转入指定的目录中
例:所有主机运行前切换到tmp目录下,并执行ls ./命令。
[root@localhost /]# ansible web -m command -a 'chdir=/tmp ls ./'
creates:创建文件时,如果文件已存在,则不会执行任务
例:创建tmp下的文件abc,若存在则不执行
[root@localhost /]# ansible web -m command -a 'creates=/tmp/abc touch /tmp/abc'
removes:在删除文件时,如果文件不存在,则不会执行任务
例:删除tmp下的文件abc,若不存在则不执行
[root@localhost /]# ansible web -m command -a 'removes=/tmp/abc rm -f /tmp/abc'
2>shell模块:在远程主机执行命令,相当于调用远程主机的shell,然后在shell下打开一个子shell。支持shell、管道符和重定向。
例:输入192.168.1.2 server2到文件/etc/hosts中。
[root@localhost /]# ansible web -m shell -a 'echo "192.168.1.2 server2" >> /etc/hosts'
例:查看每台客户端的文件/etc/hosts
[root@localhost /]# ansible web -m command -a 'cat /etc/hosts'
3>copy模块:用于复制指定文件到远程主机的指定位置。
[root@localhost ~]# vim /tmp/abc.txt (写入一些内容)
[root@localhost ~]# ansible web -m copy -a "src=/tmp/abc.txt dest=/tmp/ mode=777 owner=nobody group=root"
参数说明:
src=源文件
dest=目标路径
mode=目标文件权限 777
owner=目标文件属主
group=目标文件属组
4>yum模块:管理远程主机程序包
配置FTP yum源,发送yum配置文件
mkdir /dvd
mount /dev/sr0 /dvd/
vim /etc/yum.repos.d/yum.repo
[yum]
name=yum
baseurl=file:///dvd
enabled=1
gpgcheck=0
vim /etc/exports
/media *(rw)
(其他客户机的所有光盘都不需要要挂载,并且都需要重启nfs服务)
systemctl restart nfs-server
systemctl enable nfs-server
[root@localhost ~]# ansible web -m command -a 'mount 192.168.1.1:/media /media' //先将/media目录用nfs共享
在任意一台客户机上配置本地yum源(需要自己手动添加)
ansible web -m yum -a 'name=httpd state=present'
ansible web -m yum -a 'name=bind state=present'
选项说明:
state=present表示安装程序包 latest安装最新版 absent表示卸载
5>service模块:管理远程主机上的服务模块
ansible web -m service -a 'name=named state=started enabled=yes'
参数说明:
state=started启动服务 stopped停止服务 restarted重启服务
6>user模块:管理远程主机上的用户账号
ansible web -m user -a 'name=zhang3 system=yes uid=1001 group=root groups=sshd shell=/sbin/nologin home=/home/zhang3 password=123.com comment="test user"'
设置/etc/ansible/hosts
[web]
192.168.1.1
192.168.1.3
[web]
192.168.1.2
192.168.1.4
[mail]
mail.sohu.com
www.mail@163.com
[nfs]
192.168.1.1
192.168.1.2
设置vim /etc/ansible/a.yml
---
- hosts: web1
remote_user: root
tasks:
- name: adduser
user: name=user2 state=present
tags:
- aaa
- name: addgroup
user: name=root system=yes
tags:
- bbb
- hosts: web2
remote_user: root
tasks:
- name: copy file to web
user: src=/etc/passwd dest=/home
tags:
- ccc
测试:
ansible-playbook --syntax-check /etc/ansible/a.yml
playbook: /etc/ansible/a.yml //无报错
简介
随着移动互联网、物联网、互联网+、大数据、云计算等大规模的应用以及人们日常生活中的互联网化,互联网也逐渐地普及千家万户。互联网的发展不仅影响我们的生活,同时也影响了整个经济体。在体验互联网带来便利的同时,人们也不再满足于 “可以用” ,而 “用得简单和方便” 成为人们生活的标准。在国家政策、需求,利益的趋势下,互联网的发展速度可想而知。众所周知,智能的背后意味着复杂。意味着运维工程师的工作量加大,这一现象在互联网的发展中体现得淋漓尽致,在互联网迅速发展的同时,运维这个工作岗位也从默默无闻的后台逐步走向公众的视野,被更多的人所知晓。早期的互联网公司中服务器数量有十台、几十台的规模已经非常庞大,运维工程师同时操作十几乃至二十台机器,勉强可以完成。但是如何保证每个人的操作都完全一致呢?又如何保证所有的操作都能准确无误?
今天的互联网公司,像淘宝、京东、腾讯等企业,拥有几十台甚至上百台机器早已不稀奇,再沿用传统的办法逐台维护已然不现实。在这样的背景下,运维自动化应运而生,而 Ansible则是实现运维自动化的非常优秀的一款工具。
Ansible概述
Ansible是近年越来越火的一款开源运维自动化工具,通过 Ansible可以实现运维自动化,提高运维工程师的工作效率,减少人为的失误。Ansible通过本身集成的非常丰富的模块实现各种管理任务,其自带模块超过上千个,更为重要的是,它的操作非常简单,即使新手也比较容易上手。但它提供的功能却非常丰富在运维领域,它几乎可以做任何事情。
Ansible自2012年发布以来,很快在全球流行,其特点表现如下:
- Ansible基于 Python开发,运维工程师对其二次开发相对较容易。
- Ansible丰富的内置模块,基本可以满足一切需求。
- 管理模式非常简单,一条命令可以影响上千台机器。
- 无客户端模式,底层通过SSH通信。
- Ansible发布后,也陆续被AWS、Google Cloud Platform、Microsoft Azure、Cisco、HP、Vmware、Twitter等大公司接纳并投入使用。
Ansible没有客户端,也不需要在被管理主机添加代理程序,通过SSH完成底层通信,而SSH在Linux的发行版本中默认已经安装并启用。而在 Windows系统下,则依赖于 Powershell ,Ansible要求管理端必须是 Linux系统,在管理节点通过应用模块将指令发送到被管理主机上,并在执行完毕后自动删除产生的临时文件。根据 Ansible使用过程中的不同角色,可将其分为以下三个部分。
1. Ansible实现自动化运维。
2.Ansible可以实现的功能。
3.Ansible可以影响哪些主机。
1.使用者
如图所示, Ansible使用者可以采用多种方式和 Ansible交互,图中为我们展示了四种方式。
CMDB:CMDB存储和管理着企业架构中的各项配置信息,是构建ITIL项目的核心工具,运维人员可以组合CMDB和 Ansible,通过CMDB直接下发指令调用 Ansible工具集完成操作者所希望达到的目标。
PUBLIC/ PRIVATE方式: Ansible除了丰富的内置模块外,同时提供丰富的API语言接口,如PHP、Python,PEPL等多种流行语言,基于PUBLI/PRIVATE,Ansible以API调用的方式运行。
Ad-hoc命令集: Users直接通过Ad-Hoc命令集调用 Ansible工具集来完成任务。
Playbooks:Users预先编写好 Ansible Playbooks,通过执行 Playbooks 中预先编排好的任务集
按序执行任务。
2. Ansible工具集
Ansible工具集包含 Inventory、Modules、Plugins和API。其中,Inventory用来管理设备列表,可以通过分组实现,对组的调用直接影响组内的所有主机 Modules是各种执行模块,几乎所有的管理任务都是通过模块执行的;
Plugins提供了各种附加功能;
API为编程人员提供一个接口,可以基于此做Ansible的二次开发,具体表现如下。
Ansible Playbooks:任务脚本,编排定义 Ansible任务集的配置文件,由 Ansible按序依次执行,
通常是JSON格式的YML文件。
Inventory: Ansible管理主机清单。
Modules: Ansible执行命令功能模块,多数为内置的核心模块,也可以自定义。
Plugins:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用。
API:供第三方程序调用的应用程序编程接口。
Ansible:该部分图中表示得不明显,组合 Inventory、API、Modules、 Plugins可以理解为是 Ansible命令工具,其为核心执行工具。
3.作用对象
Ansible的作用对象不仅仅是 Linux和非 Linux操作系统的主机,也可以作用于各类 PUBLIC/ PRIVATE,商业和非商业设备的网络设施。
使用者使用 Ansible或 Ansible-playbooks时,在服务器终端输入 Ansible的Ad-Hoc命令集或Playbooks后, Ansible会遵循预先安排的规则将 Playbooks逐步拆解为Play,再将PIay组织成 Ansible可以识别的任务,随后调用任务涉及的所有模块和插件,根据 inventory中定义的主机列表通过SSH将任务集以临时文件或命令的形式传输到远程客户端执行并返回执行结果,如果是临时文件则执行完毕后自动删除。
Ansible的配置
1.Ansible安装
接下来我们来学习 Ansible的安装部署。Ansible的安装部署非常简单,以RPM安装为例,其依赖软件只有 Python和SSH,且系统默认均已安装。 Ansible的管理端只能是Linux,如 Redhat、Debian、Centos。下面介绍在 Centos7.3上安装部署 Ansible。
1)通过YUM安装 Ansible
复制提供的 ansiblerepo文件夹到 Linux本地目录,并设置为yum仓库,然后安装软件。
[root@www ~]# mkdir /good //把Ansible软件都放在此文件中
[root@www ~]# vim /etc/yum.repos.d/centos7.repo
[root@www ~]# cat /etc/yum.repos.d/centos7.repo
[base]
name=good
baseurl=file:///good
enabled=1
gpgcheck=0
[root@www ~]# yum clean all
已加载插件:fastestmirror, langpacks
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
正在清理软件源: base
Cleaning up everything
Cleaning up list of fastest mirrors
[root@www ~]# yum -y install ansible
//安装完成!
已安装:
ansible.noarch 0:2.3.1.0-3.el7
作为依赖被安装:
libtomcrypt.x86_64 0:1.17-26.el7 libtommath.x86_64 0:0.42.0-6.el7
python-babel.noarch 0:0.9.6-8.el7 python-httplib2.noarch 0:0.9.1-3.el7
python-jinja2.noarch 0:2.7.2-2.el7 python-markupsafe.x86_64 0:0.11-10.el7
python-paramiko.noarch 0:2.1.1-2.el7 python2-crypto.x86_64 0:2.6.1-15.el7
sshpass.x86_64 0:1.06-2.el7
完毕!
2)验证安装结果
[root@www ~]# ansible --version
ansible 2.3.1.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安装成功,并可正常使用。
3)创建SSH免交互登录
Ansible通过SSH对设备进行管理,而SSH包含两种认证方式:一种是通过密码认证,另一种是通过密钥对认证。前者必须和系统交互,而后者是免交互登录,如果希望通过 Ansible自动管理设备,应该配置为免交互登录被管理设备。
[root@www ~]# ssh-keygen -t rsa //生成密钥对
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): //密钥对存放路径
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): //输入私钥保护密码,直接按Enter键表示无密码
Enter same passphrase again: //再次确认
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
00:dc:ba:a0:43:6e:be:5a:b9:ae:f3:78:5a:23:d6:67 root@www
The key's randomart image is:
+--[ RSA 2048]----+
| ... |
| ... |
| .. |
| .. . . |
|o. . . S |
|oo... |
|+o=. E |
|o*.oo |
|*O= |
+-----------------+
[root@www ~]# ssh-copy-id root@192.168.8.136 //复制公钥到远端192.168.8.136
The authenticity of host '192.168.8.136 (192.168.8.136)' can't be established.
ECDSA key fingerprint is a5:96:30:89:68:fc:02:85:80:3d:4e:0c:17:76:0d:72.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.8.136's password: //输入8.136主机的密码
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@192.168.8.136'"
and check to make sure that only the key(s) you wanted were added.
[root@www ~]# ssh-copy-id root@192.168.8.139 //复制公钥到远端192.168.8.139
The authenticity of host '192.168.8.139 (192.168.8.139)' can't be established.
ECDSA key fingerprint is b0:31:48:10:28:ff:2c:b2:57:a5:66:52:c0:dc:d4:4a.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.8.139's password: //输入8.139主机的密码
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@192.168.8.139'"
and check to make sure that only the key(s) you wanted were added.
[root@www ~]# ssh 192.168.8.136 // 可以免密码登录192.168.8.136
Last login: Tue Dec 4 17:04:49 2018
[root@nt ~]# exit //退出192.168.8.136 she11环境
登出
Connection to 192.168.8.136 closed.
[root@www ~]# ssh 192.168.8.139 //可以免密码登录192.168.8.136
Last login: Tue Dec 4 17:04:54 2018
[root@os ~]# exit //退出192.168.8.136 she11环境
登出
Connection to 192.168.8.139 closed.
到此,已经完成 Ansible的部署,下面就可以通过 Ansible对设备进行管理了。
Ansible配置
Inventory是 Ansible管理主机信息的配置文件,相当于系统 Hosts文件的功能,默认存放在
/etc/ansible/hosts,在 hosts文件中,通过分组来组织设备, Ansible通过 inventory来定义主机和分组,通过在 ansible命令中使用选项 -i 或--inventory-file指定 Inventory。
[root@ansible-master ~]# ansible -i /etc/ansible/hosts web -m ping
如果使用默认的 Inventory文件( /etc/ansible/hosts ),也可以不指定 Inventory文件。例如:
[root@ansible-master ~]# ansible web -m ping
Ansible通过将设备列表以分组的方式添加到 /etc/ansible/hosts 文件来实现对设备的管理,所以在正式管理之前,首先要编写 hosts文件,hosts文件中,以 [ ] 包含的部分代表组名,设备列表支持主机名和IP地址,默认情况下,通过访问22端口(SSH)来管理设备。若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号标明,以行为单位分隔配置,另外,hosts文件还支持通配符。
[root@ansible-master ~]# vim /etc/ansible/hosts
[root@ansible-master ~]# grep -v ^# /etc/ansible/hosts | grep -v ^$
[web]
192.168.8.136
192.168.8.139
[test01]
www.bdqn.cn:222 //通过222端口管理设备
[mail]
zs1.kgc.cn
zs[2:5].kgc.cn //[2:5] 表示2~5之间的所有数字,即表示zs2.kgc.cn,zs3.kgc.cn……的所有
主机。
可以将同一个主机同时归置在多个不同的组中。
配置完成后,可以针对 hosts定义的组进行远程操作,也可以针对组中指定的某一个或多个主机
操作。下面介绍如何针对特定的服务器操作。
(1)只对web组中192.168.8.136主机操作。通过 --limit 参数限定主机的变更。
[root@ansible-master ~]# ansible web -m command -a "systemctl status httpd" --limit "192.168.8.136"
192.168.8.136 | SUCCESS | rc=0 >>
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since 二 2018-12-04 17:47:10 CST; 4min 24s ago
Docs: man:httpd(8)
man:apachectl(8)
Main PID: 4820 (httpd)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
CGroup: /system.slice/httpd.service
├─4820 /usr/sbin/httpd -DFOREGROUND
├─4821 /usr/libexec/nss_pcache 163843 off /etc/httpd/alias
├─4822 /usr/sbin/httpd -DFOREGROUND
├─4826 /usr/sbin/httpd -DFOREGROUND
├─4827 /usr/sbin/httpd -DFOREGROUND
├─4828 /usr/sbin/httpd -DFOREGROUND
├─4829 /usr/sbin/httpd -DFOREGROUND
└─4830 /usr/sbin/httpd -DFOREGROUND
12月 04 17:47:10 nt systemd[1]: Starting The Apache HTTP Server...
12月 04 17:47:10 nt httpd[4820]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::3467:3255:b0d6:ced7. Set the 'ServerName' directive globally to suppress this message
12月 04 17:47:10 nt systemd[1]: Started The Apache HTTP Server.
(2)只对192.168. 8.136主机操作。通过IP限定主机的变更。
[root@ansible-master ~]# ansible 192.168.8.136 -m command -a "systemctl status httpd"
192.168.8.136 | SUCCESS | rc=0 >>
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since 二 2018-12-04 17:47:10 CST; 9min ago
Docs: man:httpd(8)
man:apachectl(8)
Main PID: 4820 (httpd)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
CGroup: /system.slice/httpd.service
├─4820 /usr/sbin/httpd -DFOREGROUND
├─4821 /usr/libexec/nss_pcache 163843 off /etc/httpd/alias
├─4822 /usr/sbin/httpd -DFOREGROUND
├─4826 /usr/sbin/httpd -DFOREGROUND
├─4827 /usr/sbin/httpd -DFOREGROUND
├─4828 /usr/sbin/httpd -DFOREGROUND
├─4829 /usr/sbin/httpd -DFOREGROUND
└─4830 /usr/sbin/httpd -DFOREGROUND
12月 04 17:47:10 nt systemd[1]: Starting The Apache HTTP Server...
12月 04 17:47:10 nt httpd[4820]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::3467:3255:b0d6:ced7. Set the 'ServerName' directive globally to suppress this message
12月 04 17:47:10 nt systemd[1]: Started The Apache HTTP Server.
(3)只对192.168.8.0网段主机操作,通过通配符限定主机的变更。
[root@ansible-master ~]# ansible 192.168.8.* -m command -a "systemctl status httpd"
192.168.8.136 | SUCCESS | rc=0 >>
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since 二 2018-12-04 17:47:10 CST; 11min ago
Docs: man:httpd(8)
man:apachectl(8)
Main PID: 4820 (httpd)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
CGroup: /system.slice/httpd.service
├─4820 /usr/sbin/httpd -DFOREGROUND
├─4821 /usr/libexec/nss_pcache 163843 off /etc/httpd/alias
├─4822 /usr/sbin/httpd -DFOREGROUND
├─4826 /usr/sbin/httpd -DFOREGROUND
├─4827 /usr/sbin/httpd -DFOREGROUND
├─4828 /usr/sbin/httpd -DFOREGROUND
├─4829 /usr/sbin/httpd -DFOREGROUND
└─4830 /usr/sbin/httpd -DFOREGROUND
12月 04 17:47:10 nt systemd[1]: Starting The Apache HTTP Server...
12月 04 17:47:10 nt httpd[4820]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::3467:3255:b0d6:ced7. Set the 'ServerName' directive globally to suppress this message
12月 04 17:47:10 nt systemd[1]: Started The Apache HTTP Server.
192.168.8.139 | SUCCESS | rc=0 >>
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since 二 2018-12-04 17:47:19 CST; 11min ago
Docs: man:httpd(8)
man:apachectl(8)
Main PID: 4799 (httpd)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
CGroup: /system.slice/httpd.service
├─4799 /usr/sbin/httpd -DFOREGROUND
├─4800 /usr/libexec/nss_pcache 163843 off /etc/httpd/alias
├─4801 /usr/sbin/httpd -DFOREGROUND
├─4805 /usr/sbin/httpd -DFOREGROUND
├─4806 /usr/sbin/httpd -DFOREGROUND
├─4807 /usr/sbin/httpd -DFOREGROUND
├─4808 /usr/sbin/httpd -DFOREGROUND
└─4809 /usr/sbin/httpd -DFOREGROUND
12月 04 17:47:19 os systemd[1]: Starting The Apache HTTP Server...
12月 04 17:47:19 os httpd[4799]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::3f52:bb61:3cb9:b5fa. Set the 'ServerName' directive globally to suppress this message
12月 04 17:47:19 os systemd[1]: Started The Apache HTTP Server.
Ansible命令
Ansible的维护命令大多以 ansible开头,在终端输入 ansible后连续按两次Tab键,会补全所有以ansible字母开头的命令,下面介绍 Ansible的一些常用命令。
[root@ansible-master ~]# ansible //连续Tab键
ansible ansible-doc-2 ansible-pull
ansible-2 ansible-doc-2.7 ansible-pull-2
ansible-2.7 ansible-galaxy ansible-pull-2.7
ansible-connection ansible-galaxy-2 ansible-vault
ansible-console ansible-galaxy-2.7 ansible-vault-2
ansible-console-2 ansible-playbook ansible-vault-2.7
ansible-console-2.7 ansible-playbook-2
ansible-doc ansible-playbook-2.7
1. ansible
ansible是生产环境中使用非常频繁的命令之一,主要在以下场景使用。
- 非固化需求
- 临时一次性操作
- 二次开发接口调用
非固化需求是指临时性的维护,如查看web服务器组磁盘的使用情况、复制一个文件到其他机器等,类似这些没有规律的、临时需要做的任务,我们称为非固化需求、临时一次性操作,语法如下。
Ansible < host-pattern > [ options ]
可用选项如下。
- -v( --verbose ):输出详细的执行过程信息.可以得到执行过程所有信息。
- -i PATH( --Inventory=PATH ):指定 Inventory信息,默认为 /etc/ansible/hosts。
- -f HUM( --forks=NUM ):并发线程数,默认为5个线程。
- --private-key=PRIVATE_KEY_FILE:指定密钥文件。
- -m NAME,--module-name=NAME:指定执行使用的模块。
- -M DIRECTORY( --module-path= DIRECTORY ):指定模块存放路径,默认为/usr/share/ ansible。
也可以通过 ANSIBLE_LIBRARY设定默认路径。
- -a ARGUMENTS( --ags=ARGUMENTS ):指定模块参数。
- -u USERNAME( --user=USERNAME ):指定远程主机以 USERNAME运行命令。
- -l subset( --limit=SUBSET ):限制运行主机。
- --list-hosts:列出符合条件的主机列表,不执行任何命令。
(1)检查所有主机是否存活,具体执行命令如下。
[root@ansible-master ~]# ansible all -f 5 -m ping
192.168.8.139 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.8.136 | SUCCESS => {
"changed": false,
"ping": "pong"
}
其中,192.168.8.136和192.168.8.139是执行的主机, SUCCESS表示命令执行成功,“ =>{} ”
表示返回的结果, “ changed ” :false表示没有对主机做出更改,“ping” :“pong” 表示执行了ping命令的返回结果,命令中all关键字是系统默认存在的,代表了/etc/ansible/hosts中的所有主机,不需要在 hosts文件中定义all关键字。
(2)列出web组所有的主机列表,执行命令如下。
[root@ansible-master ~]# ansible web --list
hosts (2):
192.168.8.136
192.168.8.139
--list选项列出web组所有主机列表信息,web组中包括192.168.8.136和192.168.8.139两台主机。
(3)批量显示web组中的磁盘使用空间,执行命令如下。
[root@ansible-master ~]# ansible web -m command -a "df -hT"
192.168.8.139 | SUCCESS | rc=0 >>
文件系统 类型 容量 已用 可用 已用% 挂载点
/dev/mapper/cl-root xfs 87G 6.2G 81G 8% /
devtmpfs devtmpfs 897M 0 897M 0% /dev
tmpfs tmpfs 912M 144K 912M 1% /dev/shm
tmpfs tmpfs 912M 9.0M 903M 1% /run
tmpfs tmpfs 912M 0 912M 0% /sys/fs/cgroup
/dev/sda1 xfs 9.4G 175M 9.2G 2% /boot
tmpfs tmpfs 183M 12K 183M 1% /run/user/0
/dev/sr0 iso9660 4.1G 4.1G 0 100% /run/media/root/CentOS 7 x86_64
192.168.8.136 | SUCCESS | rc=0 >>
文件系统 类型 容量 已用 可用 已用% 挂载点
/dev/mapper/cl-root xfs 87G 6.0G 81G 7% /
devtmpfs devtmpfs 897M 0 897M 0% /dev
tmpfs tmpfs 912M 144K 912M 1% /dev/shm
tmpfs tmpfs 912M 9.0M 903M 1% /run
tmpfs tmpfs 912M 0 912M 0% /sys/fs/cgroup
/dev/sda1 xfs 9.4G 175M 9.2G 2% /boot
tmpfs tmpfs 183M 12K 183M 1% /run/user/0
/dev/sr0 iso9660 4.1G 4.1G 0 100% /run/media/root/CentOS 7 x86_64
web关键字需要提前在/etc/ansible/hosts文件中定义组。
Ansible的返回结果非常友好,一般会用三种颜色来表示执行结果:红色、绿色和橘黄色。
- 红色:表示执行过程有异常,
- 橘黄色:表示命令执行后目标有状态变化
- 绿色:表示执行成功且没有对目标机器做修改。
2. Ansible-doc
Ansible-doc用来查询 ansible模块文档的说明,类似于man命令,针对每个模块都有详细的用法说明及应用案例介绍。语法如下。
ansible-doc [ option ] [ module...... ]
列出支持的模块:
[root@ansible-master ~]# ansible-doc -l
查询ping模块的说明信息。
[root@ansible-master ~]# ansible-doc ping
> PING (/usr/lib/python2.7/site-packages/ansible/modules/system/ping.py)
A trivial test module, this module always returns `pong' on
successful contact. It does not make sense in playbooks, but it is
useful from `/usr/bin/ansible' to verify the ability to login and
that a usable python is configured. This is NOT ICMP ping, this is
just a trivial test module.
EXAMPLES:
# Test we can logon to 'webservers' and execute python with json lib.
ansible webservers -m ping
MAINTAINERS: Ansible Core Team, Michael DeHaan
METADATA:
Status: ['stableinterface']
Supported_by: core
3. Ansible-playbook
Ansible-playbook是日常应用中使用频率最高的命令,类似于 Linux中的sh或source命令,
执行系列任务,其工作机制是:通过读取预先编写好的 playbook文件实现集中处理任务。Ansible -playbook命令后跟yml格式的 playbook文件,playbook文件存放了要执行的任务代码,命令使用方式如下。
ansible-playbook playbook.yml
playbook.yml文件需要提前编写好,建议指定 playbook.yml的绝对路径。
4. Ansible-console
Ansible-console是 Ansible为用户提供的一款交互式工具,类似于Windows的cmd以及 Linux中的 Shell。用户可以在 ansible-console虚拟出来的终端上像 Shell一样使用 Ansible内置的各种命令,这为习惯于使用 Shell 交互方式的用户提供了良好的使用体验。在终端输入 ansible-console命令后,显示如下。
[root@ansible-master ~]# ansible-console
Welcome to the ansible console.
Type help or ? to list commands.
root@all (8)[f:5]$
root@all (8)[f:5]$ cd web //通过cd命令切换主机或分组
root@web (2)[f:5]$ list //列出当前的设备
192.168.8.136
192.168.8.139
所有的操作与 Shell类似,而且支持Tab键补全。按快捷键Ctrl+D或Ctrl+C即可退出当前的虚拟终端。
Ansible模块
1.command模块
command模块在远程主机执行命令,不支持管道、重定向等Shell的特性,常用参数如下。
- chdir:在远程主机上运行命令前要提前进入的目录。
- creates:在命令运行时创建一个文件,如果文件已存在,则不会执行创建任务。
- removes:在命令运行时移除一个文件,如果文件不存在,则不会执行移除任务。
- executable:指明运行命令的shell程序。
在所有主机上运行Is ./ 命令,运行前切换到 /home目录。操作如下。
[root@ansible-master ~]# ansible all -m command -a "chdir=/home ls ./"
192.168.8.139 | SUCCESS | rc=0 >>
wangfeng
192.168.8.136 | SUCCESS | rc=0 >>
wangfeng
2.shell模块
Shell模块在远程主机执行命令,相当于调用远程主机的Shell进程,然后在该Shell下打开一个
子shell运行命令,和 command模块的区别是它支持Shell特性,如管道、重定向等。
[root@ansible-master ~]# ansible web -m shell -a 'echo "hello" >> /tmp/hello.txt'
192.168.8.139 | SUCCESS | rc=0 >>
192.168.8.136 | SUCCESS | rc=0 >>
[root@ansible-master ~]# ssh 192.168.8.136 cat /tmp/hello.txt
hello
[root@ansible-master ~]# ssh 192.168.8.139 cat /tmp/hello.txt
hello
3.copy模块
copy模块用于复制指定主机文件到远程主机的指定位置,常见参数如下。
dest:指出复制文件的目标目录位置,使用绝对路径。如果源是目录,则目标也要是目录,如果目标文件已存在,会覆盖原有内容。
src:指出源文件的路径,可以使用相对路径和绝对路径,支持直接指定目录。如果源是目录,则目标也要是目录。
mode:指出复制时,目标文件的权限,可选。
owner:指出复制时,目标文件的属主,可选。
group:指出复制时,目标文件的属组,可选。
content:指出复制到目标主机上的内容,不能与src一起使用,相当于复制 content指明的数据到目标文件中。
[root@ansible-master ~]# ansible web -m copy -a "src=/etc/hosts dest=/tmp/ mode=777 owner=nobody group=root"
192.168.8.136 | SUCCESS => {
"changed": true,
"checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
"dest": "/tmp/hosts",
"gid": 0,
"group": "root",
"md5sum": "54fb6627dbaa37721048e4549db3224d",
"mode": "0777",
"owner": "nobody",
"size": 158,
"src": "/root/.ansible/tmp/ansible-tmp-1543934223.0-146594003682862/source",
"state": "file",
"uid": 99
}
192.168.8.139 | SUCCESS => {
"changed": true,
"checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa",
"dest": "/tmp/hosts",
"gid": 0,
"group": "root",
"md5sum": "54fb6627dbaa37721048e4549db3224d",
"mode": "0777",
"owner": "nobody",
"size": 158,
"src": "/root/.ansible/tmp/ansible-tmp-1543934223.0-132649515913157/source",
"state": "file",
"uid": 99
}
[root@ansible-master ~]# ssh 192.168.8.136 ls -l /tmp/hosts
-rwxrwxrwx 1 nobody root 158 12月 4 22:37 /tmp/hosts
[root@ansible-master ~]# ssh 192.168.8.139 ls -l /tmp/hosts
-rwxrwxrwx 1 nobody root 158 12月 4 22:37 /tmp/hosts
4.hostname模块
hostname模块用于管理远程主机上的主机名,常用参数如下。
- name:指明主机名。
[root@ansible-master ~]# ansible 192.168.8.136 -m hostname -a "name=demo"
192.168.8.136 | SUCCESS => {
"ansible_facts": {
"ansible_domain": "",
"ansible_fqdn": "demo",
"ansible_hostname": "demo",
"ansible_nodename": "demo"
},
"changed": true,
"name": "demo"
}
[root@nt ~]# hostname
demo
[root@nt ~]# cat /etc/hostname
demo
5.yum模块
yum模块基于yum机制、对远程主机管理程序包,常用参数如下。
name:程序包的名称、可以带上版本号,若不指明版本,则默认为最新版本
state=present | latest | absent:指明对程序包执行的操作,present表示安装程序包, latest表示安装最新版本的程序包,absent表示卸载程序包。
disablerepo:在用yum安装时,临时禁用某个仓库的ID。
enablerepo:在用yum安装时,临时启用某个仓库的ID。
conf_file:yum运行时的配置文件.而不是使用默认的配置文件。
diable_gpg_check=yes | no :是否启用完整性校验功能。
[root@nt ~]# yum remove -y httpd //8.136服务器先卸载已安装好的httpd服务,但需配置好yum
[root@os ~]# yum remove -y httpd //8.139服务器先卸载已安装好的httpd服务,但不需配置好yum
[root@ansible-master ~]# ansible web -m yum -a "name=httpd state=present"
192.168.8.139 | FAILED! => {
"changed": true,
"failed": true,
"msg": "Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast\nfile:///media/repodata/repomd.xml: [Errno 14] curl#37 - \"Couldn't open file /media/repodata/repomd.xml\"\nTrying other mirror.\n\n\nError downloading packages:\n httpd-2.4.6-45.el7.centos.x86_64: [Errno 256] No more mirrors to try.\n\n",
"rc": 1,
"results": [
"Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-45.el7.centos will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n httpd x86_64 2.4.6-45.el7.centos base 2.7 M\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 2.7 M\nInstalled size: 9.4 M\nDownloading packages:\n"
]
}
192.168.8.136 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-45.el7.centos will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n httpd x86_64 2.4.6-45.el7.centos base 2.7 M\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 2.7 M\nInstalled size: 9.4 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : httpd-2.4.6-45.el7.centos.x86_64 1/1 \n Verifying : httpd-2.4.6-45.el7.centos.x86_64 1/1 \n\nInstalled:\n httpd.x86_64 0:2.4.6-45.el7.centos \n\nComplete!\n"
]
}
管理端只是发送yum指令到被管理端,被管理端要存在可用的yum
仓库才可以成功安装。
6.service模块为用来管理远程主机上的服务的模块,常见参数如下。
- name:被管理的服务名称。
- state=started | stopped | restarted:动作包含启动,关闭或重启。
- enabled=yes | no:表示是否设置该服务开机自启动。
- runlevel:如果设定了enabled开机自启动,则要定义在哪些运行目标下自动启动。
//启动httpd服务,并设置为开机启动。
[root@nt ~]# yum -y install httpd //安装好httpd
[root@nt ~]# systemctl start httpd //8.136服务器开启httpd服务。
[root@os ~]# yum -y install httpd //8.139服务器只是安装httpd服务,而不开启。
[root@ansible-master ~]# ansible web -m service -a "name=httpd state=started enabled=yes"
192.168.8.136 | SUCCESS => {
"changed": false, //192.168.8.136已经开启httpd服务,所以没有更改,而且为绿色显示。
"enabled": true,
"name": "httpd",
"state": "started",
"status": {
"ActiveEnterTimestamp": "二 2018-12-04 23:14:04 CST",
//省略部分
192.168.8.139 | SUCCESS => {
"changed": true, //192.168.8.139没有开启httpd服务,所以发生更改,而且为黄色显示。
"enabled": true,
"name": "httpd",
"state": "started",
"status": {
"ActiveEnterTimestampMonotonic": "0",
//省略部分
7.user模块
user模块用于管理远程主机上的用户账号,常见参数如下。
- name:必选参数,账号名称。
- state=present | absent:创建账号或者删除账号, present表示创建, absent表示删除。
- system=yes | no:是否为系统账号。
- uid:用户UID。
- group:用户的基本组。
- groups:用户的附加组。
- shell:默认使用的shell。
- home:用户的家目录,
- move_home=yes | no:如果设置的家目录已经存在,是否将已存在的家目录进行移动
- password:用户的密码,建议使用加密后的字符串,
- comment:用户的注释信息。
- remove=yes | no:当 state= absent时,是否要删除用户的家目录。
创建用户示例如下。
[root@ansible-master ~]# ansible web -m user -a 'name=user1 system=yes uid=501 group=root groups=sshd shell=/sbin/nologin home=/home/user1 password=user1 comment="test user"'
192.168.8.139 | SUCCESS => {
"changed": true,
"comment": "test user",
"createhome": true,
"group": 0,
"groups": "sshd",
"home": "/home/********",
"name": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"password": "NOT_LOGGING_PASSWORD",
"shell": "/sbin/nologin",
"state": "present",
"system": true,
"uid": 501
}
192.168.8.136 | SUCCESS => {
"changed": true,
"comment": "test user",
"createhome": true,
"group": 0,
"groups": "sshd",
"home": "/home/********",
"name": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"password": "NOT_LOGGING_PASSWORD",
"shell": "/sbin/nologin",
"state": "present",
"system": true,
"uid": 501
}
[root@ansible-master ~]# ssh 192.168.8.136 tail -1 /etc/passwd
user1:x:501:0:test user:/home/user1:/sbin/nologin
[root@ansible-master ~]# ssh 192.168.8.139 tail -1 /etc/passwd
user1:x:501:0:test user:/home/user1:/sbin/nologin
删除用户及家目录示例如下。
[root@ansible-master ~]# ansible web -m user -a "name=user1 remove=yes state=absent"
192.168.8.139 | SUCCESS => {
"changed": true,
"force": false,
"name": "user1",
"remove": true,
"state": "absent",
"stderr": "userdel: user1 邮件池 (/var/spool/mail/user1) 未找到\n",
"stderr_lines": [
"userdel: user1 邮件池 (/var/spool/mail/user1) 未找到"
]
}
192.168.8.136 | SUCCESS => {
"changed": true,
"force": false,
"name": "user1",
"remove": true,
"state": "absent",
"stderr": "userdel: user1 邮件池 (/var/spool/mail/user1) 未找到\n",
"stderr_lines": [
"userdel: user1 邮件池 (/var/spool/mail/user1) 未找到"
]
}
[root@ansible-master ~]# ssh 192.168.8.136 tail -1 /etc/passwd
wangfeng:x:1000:1000:wangfeng:/home/wangfeng:/bin/bash
[root@ansible-master ~]# ssh 192.168.8.139 tail -1 /etc/passwd
wangfeng:x:1000:1000:wangfeng:/home/wangfeng:/bin/bash
playbook配置文件
1.执行配置文件
playbook配置文件使用YAML语法,具有简洁明了、结构清晰等特点。playbook配置文件类似于Shell脚本,是一个YAML格式的文件用于保存针对特定需求的任务列表。前面介绍的 ansible命令,虽然可以完成各种任务,但是当配置一些复杂任务时,逐条输入命令就显得效率非常低下。更有效的方案是在 playbook配置文件中放置所有的任务代码,利用 ansible-playbook命令执行该文件,可以实现自动化运维。YAML文件的扩展名通常为.yaml或 .yml。
YAML语法和其他高级语言类似,其结构通过缩进来展示,通过 “-” 来代表项,通过冒号 “:” 来分隔键和值,整个文件以 “- - -” 开始并以 “…” 结束,如下所示。
[root@ansible-master ~]# vim /etc/ansible/hosts
[root@ansible-master ~]# grep -v ^# /etc/ansible/hosts | grep -v ^$
[web1]
192.168.8.136
[web2]
192.168.8.139
[root@ansible-master ~]# vim /etc/ansible/a.yml //创建a.yml文件
---
- hosts: web1 //针对web1( 192.168.8.136 )的操作
remote_user: root //远端执行用户身份为root
tasks: //任务列表
- name: adduser //任务名称
user: name=user2 state=present //执行user模块,创建用户
tags: //创建tag标签
- aaa //tag标签为aaa
- name: addgroup //任务名称
group: name=root system=yes //执行 group模块,创建组
tags: //创建taq标签
- bbb //tag标签为bbb
- hosts: web2 //针对web2( 192.168.8.139 )的操作
remote_user: root //远端执行用户身份为root
tasks: //任务列表
- name: copy file to web //任务名称
copy: src=/etc/passwd dest=/home //执行copy模块,复制文件
tags: //创建tag标签
- ccc //tag标签为ccc
[root@ansible-master ~]# cat /etc/ansible/a.yml
---
- hosts: web1
remote_user: root
tasks:
- name: adduser
user: name=user2 state=present
tags:
- aaa
- name: addgroup
group: name=root system=yes
tags:
- bbb
- hosts: web2
remote_user: root
tasks:
- name: copy file to web
copy: src=/etc/passwd dest=/home
tags:
- ccc
所有的 “-” 和 “:” 后面均有空格,而且要注意缩进和对齐,如上图所示。
playbook的核心元素包含:
- hosts:任务的目标主机,多个主机用冒号分隔,一般调用/etc/ansible/hosts中的分组信息。
- remote_user:远程主机上,运行此任务的身份默认为root。
- tasks:任务,即定义的具体任务,由模块定义的操作列表。
- handlers:触发器,类似tasks,只是在特定的条件下才会触发的任务。某任务的状态在运行后为 changed时,可通过"inotify"通知给相应的 handlers进行触发执行。
- roles:角色,将 hosts剥离出去,由 tasks、handlers等所组成的一种特定的结构集合。
playbook文件定义的任务需要通过 ansible-playbook命令进行调用并执行,ansible-playbook命令用法如下。
ansible-playbook [ option ] /PATH/TO/PLAYBOOK.yaml
其中,[ option]部分的功能包括:
- --syntax-check:检测yaml文件的语法。
- -C( --check ):预测试,不会改变目标主机的任何设置。
- --list-hosts:列出yaml文件影响的主机列表。
- --list-tasks:列出yaml文件的任务列表。
- --list-tags:列出yam文件中的标签。
- -t TAGS( --tags=TAGS ):表示只执行指定标签的任务。
- --skip-tags=SKIP_TAGS:表示除了指定标签的任务,执行其他任务。
- --start-at-task=START_AT:从指定的任务开始往下运行。
执行 playbook的示例如下。
[root@ansible-master ~]# ansible-playbook --syntax-check /etc/ansible/a.yml
playbook: /etc/ansible/a.yml
[root@ansible-master ~]#
[root@ansible-master ~]# ansible-playbook -C /etc/ansible/a.yml
PLAY [web1] ***************************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [192.168.8.136]
TASK [adduser] ************************************************************************
changed: [192.168.8.136]
TASK [addgroup] ***********************************************************************
ok: [192.168.8.136]
PLAY [web2] ***************************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [192.168.8.139]
TASK [copy file to web] ***************************************************************
changed: [192.168.8.139]
PLAY RECAP ****************************************************************************
192.168.8.136 : ok=3 changed=1 unreachable=0 failed=0
192.168.8.139 : ok=2 changed=1 unreachable=0 failed=0
[root@ansible-master ~]#
[root@ansible-master ~]# ansible-playbook --list-hosts /etc/ansible/a.yml
playbook: /etc/ansible/a.yml
play #1 (web1): web1 TAGS: []
pattern: [u'web1']
hosts (1):
192.168.8.136
play #2 (web2): web2 TAGS: []
pattern: [u'web2']
hosts (1):
192.168.8.139
[root@ansible-master ~]# ansible-playbook --list-tasks /etc/ansible/a.yml
playbook: /etc/ansible/a.yml
play #1 (web1): web1 TAGS: []
tasks:
adduser TAGS: [aaa]
addgroup TAGS: [bbb]
play #2 (web2): web2 TAGS: []
tasks:
copy file to web TAGS: [ccc]
[root@ansible-master ~]#
[root@ansible-master ~]# ansible-playbook --list-tags /etc/ansible/a.yml
playbook: /etc/ansible/a.yml
play #1 (web1): web1 TAGS: []
TASK TAGS: [aaa, bbb]
play #2 (web2): web2 TAGS: []
TASK TAGS: [ccc]
[root@ansible-master ~]#
[root@ansible-master ~]# ansible-playbook /etc/ansible/a.yml
PLAY [web1] ***************************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [192.168.8.136]
TASK [adduser] ************************************************************************
changed: [192.168.8.136]
TASK [addgroup] ***********************************************************************
ok: [192.168.8.136]
PLAY [web2] ***************************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [192.168.8.139]
TASK [copy file to web] ***************************************************************
changed: [192.168.8.139]
PLAY RECAP ****************************************************************************
192.168.8.136 : ok=3 changed=1 unreachable=0 failed=0
192.168.8.139 : ok=2 changed=1 unreachable=0 failed=0
[root@ansible-master ~]#
[root@ansible-master ~]# ssh 192.168.8.136 tail -1 /etc/passwd //确认结果
user2:x:1001:1001::/home/user2:/bin/bash
[root@ansible-master ~]# ssh 192.168.8.139 ls -l /home/passwd
-rw-r--r-- 1 root root 3230 12月 5 01:05 /home/passwd
通常情况下先执行 ansible-playbook -C /PATH/TO/PLAYBOOK.yaml命令进行测试,测试没问题后再执行 ansible-playbook /PATH/TO/PLAYBOOK.yml命令。
2.触发器
需要触发才能执行的任务当之前定义在 tasks中的任务执行成功后.若希望在此基础上触发其
他的任务,这时就需要定义 handlers,例如,当通过 ansible的模块对目标主机的配置文件进行修改之后,如果任务执行成功.可以触发一个触发器,在触发器中定义目标主机的服务重启操作,以使配置文件生效, handlers触发器具有以下特点。
- handlers是 Ansible提供的条件机制之一,handlers和task很类似,但是它只在被task通知的时候才会触发执行。
- handlers只会在所有任务执行完后执行,而且即使被通知了多次,它也只会执行一次,handlers
按照定义的顺序依次执行。
handlers触发器的使用示例如下。
[root@ansible-master ~]# ssh 192.168.8.136 netstat -lnupt | grep 80 //正常情况下httpd监听80端口
tcp6 0 0 :::80 :::* LISTEN 95426/httpd
[root@ansible-master ~]# vim /etc/ansible/httpd.yml //创建httpd.yml配置文件
---
- hosts: web1
remote_user: root
tasks:
- name: change port //修改端口
command: sed -i 's/Listen\ 80/Listen\ 8080/g' /etc/httpd/conf/httpd.conf
notify: //配置触发条件
- restart httpd serve //完成该任务后调用名为 ”restart httpd server” 的触发器
handlers: //配置触发器
- name: restart httpd server //指定触发器名字
service: name=httpd state=restarted //触发任务为重启httpd服务
...
[root@ansible-master ~]# cat /etc/ansible/httpd.yml
---
- hosts: web1
remote_user: root
tasks:
- name: change port
command: sed -i 's/Listen\ 80/Listen\ 8080/g' /etc/httpd/conf/httpd.conf
notify:
- restart httpd server //注意格式
handlers:
- name: restart httpd server
service: name=httpd state=restarted
...
[root@ansible-master ~]# ansible-playbook /etc/ansible/httpd.yml //执行yml文件
PLAY [web1] ***************************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [192.168.8.136]
TASK [change port] ********************************************************************
[WARNING]: Consider using template or lineinfile module rather than running sed
changed: [192.168.8.136]
RUNNING HANDLER [restart httpd server] ************************************************
changed: [192.168.8.136]
PLAY RECAP ****************************************************************************
192.168.8.136 : ok=3 changed=2 unreachable=0 failed=0
[root@ansible-master ~]# ssh 192.168.8.136 netstat -lnupt | grep 8080 //远端主机已经运行8080端口
tcp6 0 0 :::8080 :::* LISTEN 99260/httpd
3.角色
将多种不同的tasks的文件集中存储在某个目录下,则该目录就是角色,角色一般存放在 /etc/ansible/roles/目录,可通过 ansible的配置文件来调整默认的角色目录,/etc/ansible/roles/ 目录下有很多子目录。其中每一个子目录对应一个角色,每个角色也有自己的目录结构、如下图所示。
/ect/ansible/roles/为角色集合,该目录下有自定义的各个子目录:
- mariadb:mysql角色。
- Apache:httpd角色。
- nginx:nginx角色。
每个角色的定义,以特定的层级目录结构进行组织。以 Mariadb( msql角色 )为例:
- files:存放由copy或 script等模块调用的文件。
- templates:存放 template 模块查找所需要的模板文件的目录,如mysql配置文件等模板。
- tasks:任务存放的目录。
- handlers:存放相关触发执行器的目录。
- vars:变量存放的目录。
- meta:用于存放此角色元数据。
- default:认变量存放的目录,文件中定义了此角色使用的默认变量。
上述目录中, tasks、handlers、vars、meta、default至少应该包含一个main.yml文件,该目录下也可以有其他 .yml文件,但是需要在main.yml文件中用 include指令将其他 .yml文件包含进来。
有了角色之后,可以直接在yaml文件( playbook配置文件 )中调用角色,示例如下。
- hosts:web
remote_user: root
roles:
- mysql //调用角色名
- httpd //调用角色名
可以只调用一个角色,也可以调用多个角色。当定义了角色后,用 ansible-playbook PLAYBOOK 文件执行即可,此时 ansible会到角色集合的目录( /etc/ansible/roles )去找mysql和httpd目录,然后依次运行mysql目录和httpd目录下的所有代码。
下面通过一个实例配置数据库角色,要求被管理主机上自动安装 Mariadb,安装完成之后上传提前准备好的配置文件至远端主机,重启服务,然后新建testdb数据库,并允许test用户对其拥有所有权限。
1)被管理主机配置yum源
复制提供的 ansiblerepo文件夹至 Linux虚拟机,并配置yum仓库文件,指向该文件夹。
[root@demo ~]# cat /etc/yum.repos.d/cnetos7.repo
[base]
name=good
baseurl=file:///media
enabled=1
gpgcheck=0
[root@demo ~]# umount /dev/cdrom
[root@demo ~]# mount /dev/cdrom /media
mount: /dev/sr0 写保护,将以只读方式挂载
[root@demo ~]# yum clean all
已加载插件:fastestmirror, langpacks
正在清理软件源: base
Cleaning up everything
Cleaning up list of fastest mirrors
[root@os ~]# cat /etc/yum.repos.d/centos7.repo
[base]
name=good
baseurl=file:///media
enabled=1
gpgcheck=0
[root@os ~]# umount /dev/cdrom
[root@os ~]# mount /dev/cdrom /media
mount: /dev/sr0 写保护,将以只读方式挂载
[root@os ~]# yum clean all
已加载插件:fastestmirror, langpacks
正在清理软件源: base
Cleaning up everything
Cleaning up list of fastest mirrors
2)配置数据库角色
[root@ansible-master ~]# mkdir -pv /etc/ansible/roles/mariadb/{files,tasks,handlers}
mkdir: 已创建目录 "/etc/ansible/roles/mariadb"
mkdir: 已创建目录 "/etc/ansible/roles/mariadb/files"
mkdir: 已创建目录 "/etc/ansible/roles/mariadb/tasks"
mkdir: 已创建目录 "/etc/ansible/roles/mariadb/handlers"
[root@ansible mariadb]# pwd
/etc/ansible/roles/mariadb
[root@ansible mariadb]# ls
files good.yml handlers mariadb.yml tasks
[root@ansible mariadb]# cat mariadb.yml //此文件内容是非角色式部署。
---
- hosts: web1
remote_user: root
tasks:
- name: install mariadb mariadb-server
yum: name=mariadb-server state=present
- name: move config file
shell: "[ -e /etc/my.cnf ]&& mv /etc/my.cnf /etc/my.cnf.bak"
- name: provide a new config file
copy: src=/etc/ansible/roles/mariadb/files/my.cnf dest=/etc/my.cnf
- name: reload mariadb
shell: systemctl restart mariadb
- name: create database testdb
shell: mysql -u root -e "CREATE DATABASE testdb;GRANT ALL ON *.* TO 'test'@'192.168.8.%' IDENTIFIED BY 'test123';FLUSH PRIVILEGES;"
notify:
- restart mariadb service
handlers:
- name: restart mariadb service
service: name=mariadb state=restarted
...
[root@ansible mariadb]# cat good.yml
---
- hosts: web1
remote_user: root
roles:
- mariadb
...
[root@ansible mariadb]# cd tasks/
[root@ansible tasks]# cat main.yml
---
- name: install mariadb mariadb-server
yum: name=mariadb-server state=present
- name: move config file
shell: "[ -e /etc/my.cnf ]&& mv /etc/my.cnf /etc/my.cnf.bak"
- name: provide a new config file
copy: src=/etc/ansible/roles/mariadb/files/my.cnf dest=/etc/my.cnf
- name: reload mariadb
shell: systemctl restart mariadb
- name: create database testdb
shell: mysql -u root -e "CREATE DATABASE testdb;GRANT ALL ON *.* TO 'test'@'192.168.8.%' IDENTIFIED BY 'test123';FLUSH PRIVILEGES;"
notify:
- restart mariadb
...
[root@ansible tasks]# cd ../
[root@ansible mariadb]# cd handlers/
[root@ansible handlers]# cat main.yml
---
- name: restart mariadb
service: name=mariadb state=restarted
...
[root@ansible handlers]# cd ../
[root@ansible mariadb]# cd files/
[root@ansible files]# ls
my.cnf
[root@ansible mariadb]# ansible-playbook good.yml
PLAY [web1] ***************************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [192.168.8.136]
TASK [mariadb : install mariadb mariadb-server] ***************************************
changed: [192.168.8.136]
TASK [mariadb : move config file] *****************************************************
changed: [192.168.8.136]
TASK [mariadb : provide a new config file] ********************************************
changed: [192.168.8.136]
TASK [mariadb : reload mariadb] *******************************************************
changed: [192.168.8.136]
TASK [mariadb : create database testdb] ***********************************************
changed: [192.168.8.136]
RUNNING HANDLER [mariadb : restart mariadb] *******************************************
changed: [192.168.8.136]
PLAY RECAP ****************************************************************************
192.168.8.136 : ok=7 changed=6 unreachable=0 failed=0
在OS主机上安装mariadb数据库。
[root@os ~]# yum -y install mariadb-server
测试登录检查是否成功。
[root@os ~]# systemctl start mariadb
[root@os ~]# mysql -u test -h 192.168.8.136 -p //远端测试是否成功。
Enter password: //密码为:test123
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 5.5.52-MariaDB MariaDB Server
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> show databases; //查看数据库
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| testdb | //检测mariadb数据库成功创建。
+--------------------+
5 rows in set (0.00 sec)
MariaDB [(none)]>