介绍
定义
Ansible是一款开源的IT自动化(运维)工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
功能
批量完成日常运维的工作。(这里会主讲ansible在linux上运维方面的内容,其他方面类同)日常linux运维工作主要包括:安装软件、启动服务、运行脚本、修改配置、升级软件、备份复制文件等。
目的
提升效率和降低人力成本。
组成
- 核心(ansible)。
- 核心模块(Core Modules):这些都是ansible自带的模块,实现不同功能的程序。
- 扩展模块(Custom Modules):如果核心模块不足以完成某种功能,可以添加扩展模块。
- 插件(Plugins):依附于ansible的一个小软件,实现某个小功能,完成模块功能的补充。
- 剧本(Playbooks):也可以叫做脚本,ansible的任务配置文件,将多个任务定义在剧本中,由ansible自动执行,也就是让主机清单里的主机去批量完成的任务。
- 连接插件(Connectior Plugins):ansible基于连接插件连接到各个主机上,虽然ansible是使用ssh连接到各个主机的,但是它还支持其他的连接方法,所以需要有连接插件。
- 主机清单(Host Inventory):可以控制其他电脑的名单,告诉ansible需要管理哪些server,和server的分类和分组信息。
Ansible官方网站的架构图
简而言之,ansible就是让什么主机使用什么工具做什么事情。
首页 |Ansible 协作 --- Homepage | Ansible Collaborative这是官方网站,可以去里面深层次学习。
组成(详细)
本文中代码的操作环境是centos7.9。
Host Inventory
这一部分主要是写明控制的机器的信息,例如ip地址、ssh端口号、域名、用户名和密码。如果想要查看可按照下面的代码进行操作。(这里的代码操作都是在linux上进行的,前提是已经安装ansible,后面有安装教程)
[root@ansible ~]# cd /etc/ansible
[root@ansible ansible]# ls
ansible.cfg hosts roles
[root@ansible ansible]# vim hosts
如果自己有想要加入管理的主机,可以按照下图中的黑色字体进行操作。(下图是hosts里面的内容)
指定用户名和密码的配置,需要连接一次,获取对方服务器的公钥到know_hosts文件。(获取公钥操作也在后面的安装教程里)
Modules
查询模块使用方法的代码
ansible-doc -s 模块名
常用模块
ping(命令模块)
ansible all -m ping
测试连接可通性,没有参数,连接通过的话返回pong,结果类似下图。
yum(安装模块)
ansible all/被控服务器名 -m yum -a "name=软件安装包名 state=操作"
这里的操作包含installed(安装)、present(默认安装)、latest(安装最新版本或升级)、absent(卸载)、removed(卸载)。
name后面除了直接填已下载在本地的软件包名外,还可以填安装路径。如file://(指定本地安装路径,类似yum localinstall -y)、http://(指定yum仓库)。
运行成功效果图如下(一般情况下输入命令后结果全为黄色即视作成功,红色则代表出错)
copy(拷贝模块)
ansible all/被控服务器名 -m copy -a "src=复制文件在管理主机上的绝对路径或者相对路径 dest=需要复制的远程机器上的绝对路径"
linux上的操作实例如下。
其他附属操作:
1.mode(设置文件权限,执行类似a+x这种方式)
ansible all/被控服务器名 -m copy -a "src=复制文件在管理主机上的绝对路径或者相对路径 dest=需要复制的远程机器上的绝对路径 mode=600"
2.backup(在覆盖源文件之前将其备份,备份文件包含时间信息,如果文件相同则不会备份;这个操作在后面很多模块里也可加入,同理)
ansible all/被控服务器名 -m copy -a "src=复制文件在管理主机上的绝对路径或者相对路径 dest=需要复制的远程机器上的绝对路径 backup=yes"
3.owner(文件复制过去后的所有者)、group(文件复制过去后的所属组)
ansible all/被控服务器名 -m copy -a "src=复制文件在管理主机上的绝对路径或者相对路径 dest=需要复制的远程机器上的绝对路径 owner=nobody group=nobody"
cron(定时模块)
ansible all/被控服务器名 -m cron -a "minute=分(0-59或*或*/数字) hour=时(0-23或*或*/数字) day=日(1-31或*或*/数字) month=月(1-12或*或*/数字) weekday=周(0-6或1-7或*) name='定时任务名' job='执行指定定时任务的命令' state=present(可写可不写,表示添加默认值)"
上面代码中的*/数字是指每隔多少(即写上去的数字)分钟/时/天/月/周执行一次任务。
下面是运行实例。
如果想要删除定时任务就将运行定时任务代码里的state=present改为state=absent,之前没写直接在最后加入即可。
ansible all/被控服务器名 -m cron -a "minute=分(0-59或*或*/数字) hour=时(0-23或*或*/数字) day=日(1-31或*或*/数字) month=月(1-12或*或*/数字) weekday=周(0-6或1-7或*) name='定时任务名' job='执行指定定时任务的命令' state=absent(表示删除)"
注视定时任务使其失效,就在后面加上disabled=yes。
ansible all/被控服务器名 -m cron -a "minute=分(0-59或*或*/数字) hour=时(0-23或*或*/数字) day=日(1-31或*或*/数字) month=月(1-12或*或*/数字) weekday=周(0-6或1-7或*) name='定时任务名' job='执行指定定时任务的命令' disabled=yes"
查看定时任务代码:
ansible 服务器名 -a "crontab -l"
shell(万能模块)
ansible all/被控服务器名 -m shell -a "系统命令"
这里的系统命令包括很多,复杂的和简单的都可以,也支持特殊符号,比如bash /etc/test.sh(执行/etc下的test脚本)、ps aux | grep redis(查看redis进程的信息)等。
command(基础模块)
ansible all/被控服务器名 -m command -a "简单命令"
shell模块的基础版,适合使用简单的命令(例如cat、ls),不支持变量"<"、">"、"|"、"&"、
";"等特殊符号。
由于command属于默认模块,可省略不指定,所以也可以直接这样使用。
ansible all/被控服务器名 -a "简单命令"
service(服务模块)
ansible all/被控服务器 -m service -a "name=服务名 state=操作名 enabled=yes"
这里state的选择有started(启动)、stopped(停止)、restarted(重启)、reloaded(重载),enabled是指是否开机自启动,一般情况下默认为no。
service模块的功能总结就是从远程对服务进行启动停止,重启重载,可以跨平台和系统,与systemd模块作用类似,使用命令也类似。
file(文件属性模块)
ansible all/被控服务器名 -m file -a "path=指定创建的目录或文件 state=操作名 (其他附属操作)"
file模块一般用来创建或删除文件、目录、创建软硬链接、修改文件权限等。
这里的state包括touch(文件不存在就创建一个新文件,已存在就更新修改时间)、directory(如果目录不存在,就创建目录)、absent(删除目录、文件或者取消链接文件)、link(创建软链接)、hard(创建硬链接)。
其他附属操作包括group(定义文件或目录的属组)、owner(定义文件或目录的属主)、mode(定义文件或目录的权限)、recurse(递归设置文件的属性,只对目录有效)等。
fetch(拉取模块)
ansible all/被控服务器名 -m fentch -a "src=指定远程主机上的源文件路径(文件) dest=保存文件的目录"
fetch模块主要用于从远程机器获取文件,并将其本地存储在由主机名组织的文件树中,而非在主机间传输文件。
Group(用户组模块)
ansible all/被控服务器名 -m group -a "name=指定创建的组名 gid=指定创建的组id state=操作名"
这里的state包括absent(删除)、present(创建,这是默认的,可以省略不写)。
User(用户模块)
ansible all/被控服务器名 -m user -a "name=指定的用户名名 uid=指定的用户uid group=指定用户主要属于哪个组 其他附属操作"
注意,这里""内的部分除了name一定要写外,其他后面按照要求添加,还有其他附属操作包括groups(指定用户属于哪个附加组 )、shell(指定是否能够登录)、creat_home(是否创建家目录信息)、home(指定家目录创建的路径,默认/home)等。
在用这个模块给用户创建密码时不能使用明文方式,只能使用密文方式。这里用一种我试过的方法进行举例。
第一步,先生成明文密码,密文,这里是生成SHA-512密码。
python -c 'import crypt; print(crypt.crypt("yourpassword", "$6$Salt$"))'(对于SHA-512密码)
第二步,进行创建。
ansible all/被控服务器名 -m user -a "name=指定的用户名 password='密文密码'"
以上只是我学习时对模块部分的一些总结,不是很全面,还有一些其他模块没有介绍,比如unarchive(压缩解压模块)、mount(挂载模块)、setup(获取主机信息模块)等,大家可以去官网或者其他文档里进行学习。
Index of all Modules — Ansible Community Documentation 这是官方网站里的模块索引合集。
Plugins
分类
Connection类型插件
这类插件代表通信连接,用来和远程主机通信。默认提供诸如Paramiko、Native SSH、Local、Winrm等连接方式。默认情况下通过ansible_connections变量指定连接类型,ansible all -m ping -connections=ssh,或直接在Inventory文件中配置ansible_connection=winrm,默认是系统自动判断连接类型,默认值是smart。将新的Connection插件放在ansible.cfg指定的同级目录下即可生效。
Lookup类型插件
这类插件代表循环体功能类型,实现诸如with_items、with_fileglob等遍历功能的内置插件,Ansible-palybook中的with_items、with_fileglob语法均是通过调用Lookup插件实现的。新的Lookup插件放在ansible.cfg指定的同级目录下即可生效。
Vars类型插件
变量类型插件,这些变量并非来自Inventory、Playbook、命令终端,而是通过host_vars、group_vars产生的,需要留意的是这些变量也可以通过Inventory产生,言外之意是Vars类型的插件绝大多数时候用不到。
Filter类型插件
Filter类型插件其实是Jinja2模板引擎的Filter,Jinja2的常用的Filter实现有to_yaml、to_json,官网实现的Filter Plugins代码全合并在core.py脚本中,新Filter插件需在该脚本的基础上编写。
Callback类型插件
Callback类型插件允许程序捕获响应的事件,并进行一些自定义响应,如前面提到的插入日志到数据库、发送邮件等功能。
安装
这个地方我没有实操过,所以就去整合了其他文章的一些方法。
找到插件的存放目录,以centos的环境为例。
cd /etc/ansible
ls
cd ansible.cfg
进入ansible.cfg文件后往下翻,直到找到如下代码。
以第一个anction_plugins为例,动作插件都存放在/usr/share/ansible/plugins/anction目录下。你自己编写相关插件后就将其存放在该目录下,最后需要创建一个playbook使用这个插件。(可以从Github上下载对应类型的模板到对应目录,在模板上面直接修改即可)
Indexes of all modules and plugins — Ansible Community Documentation 这是官方网站里的插件和模块索引合集。
Playbook
简介
playbooks是一个不同于使用ansible命令行执行方式的模式,其功能更加强大灵活。同样可以说playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已存在的模式,可作为一个适合部署复杂应用程序的基础。(简单来说,playbook是ansible的配置,部署和编排的语言;也是ansible用于配置,部署和管理被节点的剧本)
Playbook可以定制配置,可以按照指定的操作步骤有序执行,支持同步和异步方式。值得注意的是playbook是通过YAML格式来进行描述定义的。
组成部分
Playbook由Hosts(主机组)、Tasks(任务)、Variables(变量)、Templates(模板)、Handles(处理器)、Roles(角色)六个部分组成。
- Hosts:主机组
- Tasks:任务,由模板定义的操作列表
- Variables:变量(四种设置方式)
- Templates:模板,即使用模板语法的文件
- Handlers:处理器,当某条件满足时,触发执行的操作
- Roles:角色
格式(YAML语法)
Playbook由YAML语言编写,而YAML参考了其他多种语言,比如XML、C语言、Python等,它的格式类似JSON的文件格式,只是用法不同,它用于文件的配置编写,JSON多用于开发设计。主要规则如下:
- YAML使用固定的缩进放松表示层级结构,空格和Tab不能混用。
- 元素最少需要有name和task。(一个name只能包括一个task)
- 除结尾冒号,其它冒号后面必须有空格。
- 表示列表项,使用一个短横杠加一个空格;使用同样缩进级别的项视作同一列表。
可参照如下代码格式。
--- #表示开始
- name: #指定play的名称
hosts: #将要执行任务的主机,已经在hosts文件中定义好了,可是单个主机或主机组
remote_user: #指定远程主机的用户身份
grather_facts: ture|fales #指定是否要收集远程主机的facts信息
vars: #自定义变量,只能在当前play有效
- 变量1: 值1 #格式为key: value
- 变量2: 值2
tasks: #定义任务列表,默认从上往下依次执行
- name: #定义任务的名称
模块名: 模块参数
ignore errors: true #忽略任务的失败
- name: #可以定义多个任务
模块名: 模块参数
notify: 任务#如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作
##条件判断##
- name:
模块名: 模块参数
when: #定义条件表达式(== != > < >= <=),条件成立时执行此task任务,否则不执行任务
##循环##
- name:
模块名: 模块参数={{item}}
with_items: #定义循环列表
##tags模块,标签##
- name:
模块名: 模块参数
tags:
- 标签1
- 标签2
handlers: # handlers与tasks是同一级别
- name: 任务名 #和notify中的任务名相同
模块名: 模块参数
service: name=httpd state=restarted
效果图类似下图。
使用方法
ansible-playbook 名称.yml/yaml
一些其他常用命令:
#检查yaml文件的语法是否正确
ansible-playbook 名称.yml/yaml --syntax-check
#检查tasks任务
ansible-playbook 名称.yml/yaml --list-task
#检查生效的主机
ansible-playbook 名称.yml/yaml --list-hosts
#指定从某个task开始运行
ansible-playbook 名称.yml/yaml --start-at-task='Copy Nginx.conf'
#用来交互输入ssh密码
ansible-playbook 名称.yml/yaml -k
#用来交互输入sudo密码
ansible-playbook 名称.yml/yaml -K
#指定用户
ansible-playbook 名称.yml/yaml -u
Ansible playbooks — Ansible Community Documentation 这里只是简单的个人学习笔记,可能不全或者有错误,可以去链接里的官方网站学习。
linux上ansible的安装步骤
第一步 建立免密通道
在server(服务器端)和client(客户端)之间建立单向信任关系,server端产生密钥对,上传公钥到client端。
ssh-keygen
效果图大致如下。
然后进入相关目录下查看生成文件。(下面是代码和效果图)
cd /root/.ssh/
ls
接下来是上传公钥到client端。
ssh-copy-id -i id_rsa.pub root@client端ip地址
回车运行后会出来下面的内容,输入client端root用户密码即可。
最后是测试免密通道是否创建成功。
ssh 'root@client端ip地址'
当你看到主机名改变后就意味着你的免密通道已经创建成功,你已经登陆到client端上了。(类似效果图如下)
第二步 安装Ansible
在管理服务器上先安装ansible。(第一行代码是先安装epel源,才方便之后的ansible安装)
yum install epel-release -y
yum install ansible -y
可以进入安装目录下查看ansible。
cd /etc/ansible
ls
效果图大致如下。
这里面的ansible.cfg是ansible的配置文件,hosts里面可以定义主机清单。(如何定义可以看上面Host Inventory部分的内容)
第三步 用Ansible进行批量操作
最后就是用ansible批量安装epel源到其他服务器。
ansible all -m yum -a "name=epel-release state=installed"
可以再安装htop(这是top的增强版),用来监控和管理进程。
ansible all -m yum -a "name=htop state=installed"