一、 Ansible 介绍
Ansible 是一种 IT 自动化工具。它可以配置管理,部署软件以及协调更高级的 IT 任务, 例如持续部署,滚动更新。 Ansible 适用于管理企业 IT 基础设施,从 几十台到上百台的服务器环境。Ansible 也是一种简单的自动化语言,可以完美 地描述 IT 应用程序基础结构。
二、特点
简单 -- 减少学习成本
• 易读的描述语言
• 无需特殊编码技能
• 任务按顺序执行
强大 -- 协调应用程序生命周期
• 应用部署
• 配置管理
• 工作流程编排
无代理 -- 可预测,可靠和安全
• 无代理架构
• 使用 OpenSSH 通信
• 没有代理维护成本
架构:
核心组件:
• Inventory:Ansible 管理的主机信息,包括 IP 地址、 SSH 端口、账号、密码 等;
• Modules:任务均有模块完成,也可以自定义模块,例如经常用的脚本;
• Plugins:使用插件增加Ansible 核心功能,自身提供了很多插件, 也可以自定义插件。例如 connection 插件, 用于连接目标主机。 callback 插件可以将 结果输出到其他地方。vars 插件将定义的比变量注入到Ansible 中运行。
• Playbooks:"剧本",模块化定义一系列任务,供外部统一调用。Ansible 核心功能。
三、 Ansible 安装与配置
1)ansible环境搭建
实验准备:三台机器,一台管理,两台被管理
master 192.168.115.3
hd1 192.168.115.4
hd2 192.168.115.5
配置/etc/hosts文件
master
hd1
hd2
2)master安装ansible
1、确认和配置yum源(需要epel源)
2、安装ansible
3、实现master对agent的免密登录,只在master上做。(如果这一步不做,则在后面操作agent时都要加-k参数传密码;或者在主机清单里传密码)
4、在master上定义主机组,并测试连接性
vim /etc/ansible/hosts
ansible -m ping group1
四、ansible模块
ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。
查看所有支持的模块
ansible-doc -l
(一)hostname模块
hostname模块用于修改主机名(**注意**: 它不能修改/etc/hosts文件)
将其中一远程机器主机名修改为agent1.cluster.com
ansible 192.168.115.4 -m hostname -a 'name=agent1.cluster.com'
192.168.115.4查看
(二)file模块
file模块用于对文件相关的操作(创建, 删除, 软硬链接等)
创建一个目录
ansible group1 -m file -a 'path=/test state=directory'
192.168.115.4查看
192.168.115.5查看
创建一个文件
ansible group1 -m file -a 'path=/test/111 state=touch'
192.168.115.4查看
192.168.115.5查看
删除目录 absent 缺席的(连同目录里的所有文件)
ansible group1 -m file -a 'path=/test state=absent'
192.168.115.4查看
192.168.115.5查看
删除文件
ansible group1 -m file -a 'path=/test/111 state=absent'
192.168.115.4查看
192.168.115.5查看
(三)stat模块
stat模块类似linux的stat命令,用于获取文件的状态信息
获取/etc/fstab文件的状态信息
ansible group1 -m stat -a 'path=/etc/fstab'
192.168.115.4查看
192.168.115.5查看
(四)copy模块
copy模块用于对文件的远程拷贝操作(如把本地的文件拷贝到远程的机器上)
在master上准备一个文件,拷贝此文件到group1的所有机器上
echo master > /tmp/222
ansible group1 -m copy -a 'src=/tmp/222 dest=/tmp/333'
192.168.115.4查看
192.168.115.5查看
使用content参数直接往远程文件里写内容(会覆盖原内容)
ansible group1 -m copy -a 'content="ha ha\n" dest=/tmp/333'
192.168.115.4查看
192.168.115.5查看
使用force参数控制是否强制覆盖
如果目标文件已经存在,则不覆盖
ansible group1 -m copy -a 'src=/tmp/222 dest=/tmp/333 force=no'
192.168.115.4查看
192.168.115.5查看
如果目标文件已经存在,则会强制覆盖
ansible group1 -m copy -a 'src=/tmp/222 dest=/tmp/333 force=yes'
192.168.115.4查看
192.168.115.5查看
使用backup参数控制是否备份文件
ansible group1 -m copy -a 'src=/etc/fstab dest=/tmp/333 backup=yes owner=daemon group=daemon mode=1777'
192.168.115.4查看
192.168.115.5查看
(五)fetch模块
fetch模块与copy模块类似,但作用相反。用于把远程机器的文件拷贝到本地。
第1步: 在两台被管理机上分别创建一个同名文件(但内容不同)
hd1#echo agent1 > /tmp/1.txt
hd2#echo agent2 > /tmp/1.txt
第2步: 从master上fecth文件(因为group1里有2台机器,为了避免同名文件文件冲突,它使用了不同的目录)
ansible group1 -m fetch -a 'src=/tmp/1.txt dest=/tmp/'
查看
第3步: 先删除上面fetch过来的, 然后尝试只fetch其中一台机器的,也会使用名称来做子目录区分
rm /tmp/192.168.115.* -rf
ansible 192.168.115.4 -m fetch -a 'src=/tmp/1.txt dest=/tmp/'
查看
**注意**: fetch模块不能从远程拷贝目录到本地
(六)user模块
user模块用于管理用户账号和用户属性。
创建aaa用户,默认为普通用户,创建家目录
ansible group1 -m user -a'name=aaa state=present'
192.168.115.4查看
192.168.115.5查看
创建bbb系统用户,并且登录shell环境为/sbin/nologin
ansible group1 -m user -a'name=bbb state=present system=yes shell="/sbin/nologin"'
192.168.115.4查看
192.168.115.5查看
创建ccc用户, 使用uid参数指定uid, 使用password参数传密码
echo 123456 | openssl passwd -1 -stdin
$19vW7qhvpa93DgktaPTqmIsSMFZjQH/
下一句命令注意一下格式,密码要用双引号引起来,单引号的话验证时会密码不正确
ansible group1 -m user -a ' name=ccc uid=2000 state=present password=" $1$9vW7qhvp$a93DgktaPTqmIsSMFZjQH/"'
192.168.115.4查看
192.168.115.5查看
删除aaa用户,但家目录默认没有删除
ansible group1 -m user -a 'name=aaa state=absent'
192.168.115.4查看
192.168.115.5查看
删除bbb用户,使用remove=yes参数让其删除用户的同时也删除家目录
ansible group1 -m user -a 'name=bbb state=absent remove=yes'
192.168.115.4查看
192.168.115.5查看
(七)group模块
group模块用于管理用户组和用户组属性。
创建组
ansible group1 -m group -a 'name=groupa gid=3000 state=present'
192.168.115.4查看
192.168.115.5查看
删除组(如果有用户的gid为此组,则删除不了)
ansible group1 -m group -a 'name=groupa state=absent'
192.168.115.4查看
192.168.115.5查看
(八)cron模块
cron模块用于管理周期性时间任务
创建一个cron任务,不指定user的话,默认就是root(因为我这里是用root操作的)。 如果minute,hour,day,month,week不指定的话,默认都为*
ansible group1 -m cron -a 'name="test cron1" user=root job="touch /tmp/111" minute=*/2'
192.168.115.4查看
192.168.115.5查看
删除cron任务
ansible group1 -m cron -a 'name="test cron1" state=absent'
192.168.115.4查看
192.168.115.5查看
(九)yum模块
yum模块用于使用yum命令来实现软件包的安装与卸载。
使用yum安装一个软件(前提:group1的机器上的yum配置都已经OK)
ansible group1 -m yum -a 'name=vsftpd state=present'
192.168.115.4查看
192.168.115.5查看
使用yum安装httpd,httpd-devel软件,state=latest表示安装最新版本
ansible group1 -m yum -a 'name=httpd,httpd-devel state=latest'
192.168.115.4查看
192.168.115.5查看
使用yum卸载httpd,httpd-devel软件
ansible group1 -m yum -a 'name=httpd,httpd-devel state=absent'
192.168.115.4查看
192.168.115.5查看
(十)service模块
service模块用于控制服务的启动,关闭,开机自启动等。
启动vsftpd服务,并设为开机自动启动
ansible group1 -m service -a 'name=vsftpd state=started enabled=on'
192.168.115.4查看
192.168.115.5查看
关闭vsftpd服务,并设为开机不自动启动
ansible group1 -m service -a 'name=vsftpd state=stopped enabled=false'
192.168.115.4查看
192.168.115.5查看
(十一)script模块
script模块用于在远程机器上执行本地脚本。
在master上准备一个脚本
vim /root/1.sh
#!/bin/bash
mkdir /tmp/haha
touch /tmp/haha/{1..10}
在group1的远程机器里都执行master上的/tmp/1.sh脚本(此脚本不用给执行权限)
ansible group1 -m script -a '/root/1.sh'
192.168.115.4查看
192.168.115.5查看
(十二)command与shell模块
两个模块都是用于执行linux命令的,这对于命令熟悉的工程师来说,用起来非常high。
shell模块与command模块差不多(command模块不能执行一些类似$HOME,>,<,|等符号,但shell可以)
注意: shell模块并不是百分之百任何命令都可以,比如vim或ll别名就不可以。不建议大家去记忆哪些命令不可以,大家只要养成任何在生产环境里的命令都要先在测试环境里测试一下的习惯就好。
ansible -m command group1 -a "useradd user2"
192.168.115.4查看
192.168.115.5查看
ansible -m command group1 -a "id user2"
五、playbook
playbook(剧本): 是ansible用于配置,部署,和管理被控节点的剧本。用于ansible操作的编排。
使用的格式为yaml格式(saltstack,elk,docker,docker-compose,kubernetes等也都会用到yaml格式)
(一)YAML格式
- 以.yaml或.yml结尾
-
文件的第一行以 "---"开始,表明YMAL文件的开始(可选的)
-
以#号开头为注释
-
列表中的所有成员都开始于相同的缩进级别, 并且使用一个
"- "
作为开头(一个横杠和一个空格) -
一个字典是由一个简单的
键: 值
的形式组成(这个冒号后面必须是一个空格) -
==注意: 写这种文件不要使用tab键,都使用空格==
(二)playbook实例
第1步: 创建一个存放playbook的目录(路径自定义)
mkdir /etc/ansible/playbook
第2步: 准备httpd配置文件,并修改成你想要的配置
yum install httpd -y
按需要修改你想要的配置(为了测试可以随意改动标记一下)
vim /etc/httpd/conf/httpd.conf
第3步: 写一个playbook文件(后缀为.yml或.yaml)
vim /etc/ansible/playbook/example.yaml
---
- hosts: group1
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: name=httpd,httpd-devel state=latest
- name: write the apache config file
copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
- restart apache
- name: ensure apache is running (and enable it at boot)
service: name=httpd state=started enabled=yes
handlers:
- name: restart apache
service: name=httpd state=restarted
第4步: 执行写好的palybook
-
会显示出执行的过程,并且执行的每一步都有ok,changed,failed等标识
-
执行如果有错误(failed)会回滚,解决问题后,直接再执行这条命令即可,并会把failed改为changed(幂等性)
ansible-playbook /etc/ansible/playbook/example.yaml
192.168.115.4查看
192.168.115.5查看
(三)Playbook常见语法
hosts: 用于指定要执行任务的主机,其可以是一个或多个由冒号分隔主机组.
remote_user: 用于指定远程主机上的执行任务的用户.
tasks: 任务列表, 按顺序执行任务.
- 如果一个host执行task失败, 整个tasks都会回滚, 修正playbook 中的错误, 然后重新执行即可.
handlers: 类似task,但需要使用notify通知调用。
-
不管有多少个通知者进行了notify,等到play中的所有task执行完成之后,handlers也只会被执行一次.
-
handlers最佳的应用场景是用来重启服务,或者触发系统重启操作.除此以外很少用到了.
六、role
(一)roles介绍
roles(角色): 就是通过分别将variables, tasks及handlers等放置于单独的目录中,并可以便捷地调用它们的一种机制。
假设我们要写一个playbook来安装管理lamp环境,那么这个playbook就会写很长。所以我们希望把这个很大的文件分成多个功能拆分, 分成apache管理,php管理,mysql管理,然后在需要使用的时候直接调用就可以了,以免重复写。就类似编程里的模块化的概念,以达到代码复用的效果。
(二)创建roles的目录结构
files:用来存放由copy模块或script模块调用的文件。
tasks:至少有一个main.yml文件,定义各tasks。
handlers:有一个main.yml文件,定义各handlers。
templates:用来存放jinjia2模板。
vars:有一个main.yml文件,定义变量。
meta:有一个main.yml文件,定义此角色的特殊设定及其依赖关系。
注意: 在每个角色的目录中分别创建files, tasks,handlers,templates,vars和meta目录,用不到的目录可以创建为空目录.
(三)案例:通过roles实现lamp
需定制三个角色: httpd,mysql,php
第1步: 创建roles目录及文件,并确认目录结构
cd /etc/ansible/roles/
mkdir -p {httpd,mysql,php}/{files,tasks,handlers,templates,vars,meta}
touch {httpd,mysql,php}/{tasks,handlers,vars,meta}/main.yml
yum install -y tree
tree /etc/ansible/roles/
第2步: 准备httpd服务器的主页文件,php测试页和配置文件等
echo "test main page" > /etc/ansible/roles/httpd/files/index.html
echo -e "<?php\n\tphpinfo();\n?>" > /etc/ansible/roles/httpd/files/test.php
yum install httpd -y
按需求修改配置文件后,拷贝到httpd角色目录里的files子目录
vim /etc/httpd/conf/httpd.conf
cp /etc/httpd/conf/httpd.conf /etc/ansible/roles/httpd/files/
第3步: 编写httpd角色的main.yml文件
vim /etc/ansible/roles/httpd/tasks/main.yml
---
- name: 安装httpd
yum: name=httpd,httpd-devel state=present
- name: 同步httpd配置文件
copy: src=/etc/ansible/roles/httpd/files/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart httpd
- name: 同步主页文件
copy: src=/etc/ansible/roles/httpd/files/index.html dest=/var/www/html/index.html
- name: 同步php测试页
copy: src=/etc/ansible/roles/httpd/files/test.php dest=/var/www/html/test.php
- name: 启动httpd并开机自启动
service: name=httpd state=started enabled=yes
第4步: 编写httpd角色里的handler
vim /etc/ansible/roles/httpd/handlers/main.yml
---
- name: restart httpd
service: name=httpd state=restarted
第5步: 编写mysql角色的main.yml文件
vim /etc/ansible/roles/mysql/tasks/main.yml
---
- name: 安装mysql
yum: name=mariadb,mariadb-server,mariadb-devel state=present
- name: 启动mysql并开机自启动
service: name=mariadb state=started enabled=yes
第6步: 编写php角色的main.yml文件
vim /etc/ansible/roles/php/tasks/main.yml
---
- name: 安装php及依赖包
yum: name=php,php-gd,php-ldap,php-odbc,php-pear,php-xml,php-xmlrpc,php-mbstring,php-snmp,php-soap,curl,curl-devel,php-bcmath,php-mysql state=present
notify: restart httpd
第7步:编写lamp的playbook文件调用前面定义好的三个角色
vim /etc/ansible/playbook/lamp.yaml
---
- hosts: group1
remote_user: root
roles:
- httpd
- mysql
- php
第8步: 执行lamp的playbook文件
ansible-playbook /etc/ansible/playbook/lamp.yaml