主机:
控制节点:
192.168.188.153 ansible
被控制节点:
192.168.188.154 server-1
192.168.188.155 server-2
ansible的部署,一个控制节点,若干被控制节点,首先互相做本地解析“ip hostname”,其次需要将ansible服务器的公钥传送到被控制节点,控制节点需要下载ansible软件(前提需要有epel仓库)通过修改/etc/ansible/hosts配置文件,来控制主机,通过ansible 组名(或者主机,或者ip) -m ping 测试是否连接,
vim /etc/ansible/hosts #注意,设置group名的时候,不可用特俗符号,如“-“, “_”等
[server]
server-1
server-2
[server1]
server-1
[server2]
server-2
保存,利用ansible server -m ping -o测试是否连通

Ansible特性
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:可实现多级指挥
q.png
connection plugins:连接插件,负责和被监控端实现通信,默认使用SSH连接
host inventory:主机清单,是一个配置文件里面定义监控的主机
modules : 模块,核心模块、command模块、自定义模块等
plugins : modules功能的补充,包括连接插件,邮件插件等
playbook:编排,定义 Ansible 多任务配置文件,非必需

Ansible执行流程:
读取ansible.cfg文件
通过规则过滤inventory中定义的主机列表
加载task对应的模块
通过ansible core 将模块或命令打包成python脚本文件
将临时脚本文件传输到远程服务器
对应执行用户家目录的‘ansible/tmp/xx/xxx.py’文件
给文件加执行权限
执行py文件并返回结果
删除临时文件并退出

主配置文件:
/etc/ansible/ansible.cfg
主要设置一些ansible初始化的信息,比如日志存放路径、模块、插件等配置信息
配置文件中常见参数:
inventory = /etc/ansible/hosts
#这个参数表示资源清单inventory文件的位置
library = /usr/share/ansible
#指向存放Ansible模块的目录,支持多个目录方式,只要用冒号(:)隔开就可以
forks = 5
#并发连接数,默认为5
sudo_user = root
#设置默认执行命令的用户
remote_port = 22
#指定连接被管节点的管理端口,默认为22端口,建议修改,能够更加安全
host_key_checking = False
#设置是否检查SSH主机的密钥,值为True/False。关闭后第一次连接不会提示配置实例
timeout = 60
#设置SSH连接的超时时间,单位为秒
log_path = /var/log/ansible.log
#指定一个存储ansible日志的文件(默认不记录日志)
主机配置文件/etc/ansible/hosts中可配置主机,组,和数据库,数据库组。

语法:
ansible -m -a
pattern—主机清单里定义的主机组名,主机名,IP,别名等,all表示所有的主机,支持通配符,正则
“,”或者”:” —多个组,组名之间用冒号隔开
web —组名中含web的
webservers[0] - webservers组中的第一台主机
以~开头,匹配正则
-m module_name: 模块名称,默认为command
-a arguments: 传递给模块的参数

创建一个新的目录,Ad-Hoc(点对点)


ad hoc 临时的,在ansible中是指需要快速执行,并且不需要保存的命令。其实就是执行
简单的命令——一条命令。对于复杂的命令则为 playbook。

帮助文档:
列出ansible支持的模块:
-l:获取列表
-s module_name:获取指定模块的使用信息
获取模块列表
[root@ansible-server ~]# ansible-doc -l
模块使用格式:
[root@ansible-server ~]# ansible-doc -s yum
参数:
-f 2 指定定要使用的并行进程数,默认为5个,临时指定,如果想要永久指定,修改主配置文件。
常用模块:
1.远程复制备份模块:copy
模块参数详解:
src=:指定源文件路径
dest=:目标地址(拷贝到哪里)
owner:指定属主
group:指定属组
mode:指定权限,可以以数字指定比如0644
backup:在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no
在ansible端创建文件,并复制到被控制节点,设置权限
echo 1234 > /root/xiang.txt #在root目录下创建xiang.txt
ansible xiang -m copy -a “src=/root/xiang.txt dest=/root/ mode=644 owner=root group=root “ -o #将xiang.txt复制到xiang组下的所有机器,并设置权限为644,属主及属组均为root,
登录到被控制节点查看

2.用户管理user模块
添加用户并设置密码:使用命令需要用双引:
[root@ansible ~]# ansible xiang -m user -a “name=liudehua password=echo 1234 | openssl passwd -1 -stdin“ -o
添加用户liudehua,并采用MD5的加密算法设置密码为1234(设置密码必须使用非交互式)
或者 ansible xiang -m shell -a “useradd xiang && echo 1234 | passwd xiang —stdin “的方式来添加用户
删除用户:
[root@ansible ~]# ansible xiang -m user -a “name=liudehua state=absent” -o
adsent #删除用户,但是不会删除家目录
“name= “ #如:指定的用户名,要安装的软件
-1 MD5加密算法
3.软件包管理 yum模块
安装apache
[root@ansible ~]# ansible xiang -m yum -a “name=httpd state=latest” -o
state= #状态是什么,干什么
state=absent 用于remove安装包
state=latest 表示最新的
state=removed 表示卸载
卸载软件:
[root@ansible ~]# ansible xiang -m yum -a “name=httpd state=removed” -o
4.服务管理service模块
[root@ansible ~]# ansible xiang -m service -a “name=httpd state=started” #启动
[root@ansible ~]# ansible xiang -m service -a “name=httpd state=stopped” #停止
[root@ansible ~]# ansible xiang -m service -a “name=httpd state=restarted” #重启
[root@ansible ~]# ansible xiang -m service -a “name=httpd state=started enabled=yes” #开机启动
[root@ansible ~]# ansible xiang -m service -a “name=httpd state=started enabled=no” #开机关闭
5.文件模块file
模块参数详解:
owner:修改属主
group:修改属组
mode:修改权限
path=:要修改文件的路径
recurse:递归的设置文件的属性,只对目录有效
yes:表示使用递归设置
state:
touch:创建一个新的空文件
directory:当目录存在时不会进行修改
[root@ansible ~]# ansible xiang -m file -a ‘path=/tmp/88.txt mode=777 state=touch’ #创建一个文件
[root@ansible ~]# ansible xiang -m file -a ‘path=/tmp/99 mode=777 state=directory’ #创建一个目录
6.收集信息模块setup
[root@ansible ~]# ansible xiang -m setup #收集所有信息
[root@ansible ~]# ansible xiang -m setup -a ‘filter=ansibleall_ipv4_addresses’ #只查询ipv4的地址
filter:过滤
[root@ansible ~]# ansible xiang -m setup -a ‘filter=ansible
*_mb’
[root@ansible ~]# ansible -i /home/ansible/hostlist xiang -m setup -a ‘filter=ansible_processor_cores’
[root@ansible ~]#ansible all -m setup —tree /tmp/facts

playbook剧本介绍

  1. playbookansible用于配置,部署,和管理被控节点的剧本。通过playbook的详细描述,执行其中的tasks,可以让远端主机达到预期的状态。playbook是由一个或多个”play”组成的列表。 当对一台机器做环境初始化的时候往往需要不止做一件事情,这时使用playbook会更加适合。通过playbook你可以一次在多台机器执行多个指令。通过这种预先设计的配置保持了机器的配置统一,并很简单的执行日常任务。<br />playbook格式:<br />playbookYMAL语言编写。YMAL格式是类似于JSON的文件格式,便于人理解和阅读,同时便于书写。<br />核心元素:<br />Playbooks <br />Variables #变量元素,可传递给Tasks/Templates使用; <br />Tasks #任务元素,由模块定义的操作的列表,即调用模块完成任务; <br />Templates #模板元素,使用了模板语法的文本文件,可根据变量动态生成配置文件; <br />Handlers #处理器元素,通常指在某事件满足时触发的操作; <br />Roles #角色元素<br />注意:<br />一个剧本里面可以有多个play,每个play只能有一个tasks,每个tasks可以有多个name <br />playbook的基础组件:<br />name:<br />定义playbook或者task的名称(描述信息),每一个play都可以完成一个任务。<br />hosts: <br />playbook中的每一个paly的目的都是为了让某个或某些以某个指定用户的身份执行任务。hosts用于指定要执行指定任务的主机,其可以是一个或多个由冒号分割主机组。与命令模式下的ansible匹配规则一样<br />user :<br />remote_user则用于指定远程主机上的执行任务的用户,也可以使用user(基本上是root)<br />tasks :<br />任务列表play的主体部分是task list. task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。<br />vars:<br />定义变量(如果不使用内部变量需要提前定义)<br />vars_files:<br />调用定义变量文件<br />notify:<br />任务执行结果如果是发生更改了的则触发定义在handler的任务执行<br />handlers:<br />用于当前关注的资源发生变化时采取一定指定的操作<br />include:<br />能包含的包括task,handler和playbook<br />可以在include的时候传递变量

ansible-playbook使用:
例1、在被控制节点创建/root/playbook.txt文件
[root@ansible ansible]# vim test.yml #创建文件必须以.yml结尾
- hosts: xiang #可以是主机名,也可以是主机组
user: root
tasks:
- name: playbook_test #名字自定义
file: state=touch path=/root/playbook.txt
ansible-playbook —syntax-check test.yml #检测test.yml的语法是否有误,
ansible-playbook test.yml #执行剧本文件
例2、利用handlers,执行shell,echo “abcd” >>/mnt/a.txt
handlers:由特定条件触发的Tasks,在playbook中起到承上启下作用,handlers中的name必须和notify一致,当notify上文中copy执行成功后,shell才会执行。
语法:
tasks:
- name: TASK_NAME
module: arguments #1.上面任务执行成功,然后
notify: HANDLER_NAME #2.通知他
handlers:
- name: HANDLER_NAME #3.一一对应,这里的描述与notify定义的必须一样
module: arguments #4.执行这个命令

[root@ansible-server ansible]# vim handlers.yml
- hosts: xiang
user: root
tasks:
- name: test copy
copy: src=/root/a.txt dest=/mnt
notify: test handlers
handlers:
- name: test handlers
shell: echo “abcd” >> /mnt/a.txt
例3、批量操作
循环:迭代,需要重复执行的任务;
对迭代项的引用,固定变量名为”item”,使用with_items属性给定要迭代的元素;
元素:1.列表 2.字符串 3.字典

基于字符串列表元素实战:
[root@ansible ansible]# vim list.yml
- hosts: xiang
user: root
tasks:
- name: install packages
yum: name={{ item }} state=latest #相当于for循环里面的i
with_items: #取值 。但是不支持通配符
- httpd
- php
- php-mysql
- php-mbstring
- php-gd
基于字典列表给元素示例:
- hosts: all
user: root
tasks:
- name: create groups
group: name={{ item }} state=present
with_items:
- groupx1
- groupx2
- groupx3
- name: create users
user: name={{ item.name }} group={{ item.group }} state=present
with_items: 这里使用的是字典
- {name: ‘userx1’, group: ‘groupx1’}
- {name: ‘userx2’, group: ‘groupx2’}
- {name: ‘userx3’, group: ‘groupx3’}

例4、tags标签
tags使用:
给指定的任务定义一个调用标识,形式如下
只运行指定标记的任务:-t tags
[root@ansible ansible]# ansible-playbook -t 标记名称 test.yml

跳过某一个被标记的任务:—skip-tags=SKIP_TAGS
[root@ansible ansible]# ansible-playbook —skip-tags=标记名称 test.yml

从某一个任务开始往下运行:—start-at-task 任务名称
[root@ansible ansible]# ansible-playbook —start-at-task “start httpd service” test.yml

[root@ansible /]# vim /home/ansible/tag.yml
—-
- hosts: web
user: root
tasks:
- name: touch file
file: path=/root/nihao.txt state=touch
tags: nihao
- name: mkdir file
file: path=/root/xingdian state=directory
tags: xingdian
- name: touch file1
file: path=/root/file1.txt state=touch
tags: file1

安装nginx:
- hosts: xiang
user: root
tasks:
- name: install epel-release
yum: name=epel-release state=latest
tags: install epel
- name: install nginx
yum: name=nginx state=latest
tags: install nginx
- name: mkdir app
file: state=directory path=/app
tags: mkdir app
- name: copy conf
copy: src=/etc/ansible/app.conf dest=/etc/nginx/conf.d/
tags: copy conf
- name: copy index.html
copy: src=/etc/ansible/index.html dest=/app
tags: copy index.html
notify: start nginx
handlers:
- name: start nginx
service: name=nginx state=restarted
tags: start nginx

ansible-playbook中role

roles是在ansible中,playbooks的目录组织结构。
role_name/ 这个是角色的名称
files/:存储由copy或script等模块调用的文件;
tasks/: 专门存储任务的目录 一个角色可以定义多个任务
此目录中至少应该有一个名为main.yml的文件,用于定义各task;其它的文件需要由main.yml进行“包含”调用;
handlers/: 条件 前一个任务执行成功去执行下面的 处理特定事物的文件
此目录中至少应该有一个名为main.yml的文件,用于定义各handler;其它的文件需要由main.yml进行“包含”调用;
vars/: 变量 定义变量的文件
此目录中至少应该有一个名为main.yml的文件,用于定义各variable;其它的文件需要由main.yml进行“包含”调用;
templates/: 模板 使用变量的文件存储由template模块调用的模板文本;
meta/:此目录中至少应该有一个名为main.yml的文件,定义当前角色的特殊设定及其依赖关系;其它的文件需要由main.yml进行“包含”调用;
default/:此目录中至少应该有一个名为main.yml的文件,用于设定默认变量;

就是ansible-playbook的分解,将对应的操作写入到对应的{tasks、templates、vars、handlers}的main.yml文件中
files:要copy的文件
tasks:main.yml要执行的任务命令,及模板
templates:要拷贝到被控制节点的模板文件
vars:main.yml中要修改的变量内容
handlers:main.yml文件中要写入notify下面的执行命令

playbook的变量

Variables:
类型:
内建变量
自定义变量

变量调用:
{{ var_name }}
内建变量:
由facts组件提供,可以使用setup模块查询
[root@ansible ansible]# ansible web1 -m setup

案例一:
[root@xingdian /]# ansible ansible-web1 -m setup | grep “mem”
“ansible_memfree_mb”: 8037,
“ansible_memory_mb”: {
“ansible_memtotal_mb”: 15823,
[root@xingdian /]# vim /home/ansible/vars.yml
[root@xingdian /]# ansible-playbook —syntax-check /home/ansible/vars.yml

playbook: /home/ansible/vars.yml
[root@xingdian /]# ansible-playbook /home/ansible/vars.yml
自定义变量:
1.用命令行传递参数
为了使Playbook更灵活、通用性更强,允许用户在执行的时候传入变量的值,这个时候就需要用到“额外变量”。**定义命令行变量
在release.yml文件里,hosts和user都定义为变量,需要从命令行传递变量值。

案例二:
—-
- hosts: ‘{{ hosts }}’
user: ‘{{ user }}’
tasks:
- name: new file
file: path=/root/var1.txt state=touch

使用命令行变量
在命令行里面传值的方法:
ansible-playbook e33_var_in_command.yml —extra-vars “hosts=web user=root”

还可以用json格式传递参数:
ansible-playbook e33_var_in_command.yml —extra-vars “{‘hosts’:’vm-rhel7-1’, ‘user’:’root’}”

set_fact自定义facts变量:
set_fact模块可以自定义facts,这些自定义的facts可以通过template或者变量的方式在playbook中使用。如果你想要获取一 个进程使用的内存的百分比,则必须通过set_fact来进行计算之后得出其值,并将其值在playbook中引用。
下面是一个配置mysql innodb buffer size的示例:
案例三:变量的传递
- name: Configure MySQL
hosts: web
tasks:
- name: Calculate InnoDB buffer pool size
set_fact: innodb_buffer_pool_size_mb=”{{ ansible_swapfree_mb / 2 }}”
- name: nihao
template: src=/my.cnf dest=/etc/my.cnf owner=root group=root mode=0644

set_fact: innodb_buffer_pool_size_mb=”{{ ansible_memtotal_mb / 2 }}”
通过sey_fact去定义,而不是直接执行
template: src=templates/my.cnf dest=/etc/my.cnf owner=root group=root mode=0644
template:这个是一个模板 可以传变量**
my.cnf的配置示例:
# {{ ansible_managed }}
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted
security risks
symbolic-links=0

Configure the buffer pool
innodb_buffer_pool_size = {{ innodb_buffer_pool_size_mb|int }}M
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid**

利用ansible批量部署lnmp架构
主配置:lnmp.yml
- hosts: xiang
user: root
roles:
- lnmp

tasks目录下:main.yml
- name: mysql repo
copy: src=mysql-community.repo dest=/etc/yum.repos.d/
- name: copy Discuz
copy: src=upload/ dest=/app/
- name: install
yum: name={{ item }} state=latest
with_items:
- php
- php-fpm
- php-mysql
- php-gd
- gd
- mysql
- mysql-server
- nginx
- name: copy dir
template: src=nginx.conf dest=/etc/nginx/
- name: start
service: name={{ item }} state=started
with_items:
- nginx
- php-fpm
- mysqld
- name: copy my.cnf
copy: src=my.cnf dest=/etc/my.cnf
- name: copy bash
copy: src=password.sh dest=/root/
- name: bash
shell: bash /root/password.sh
notify: restart mysqld

templates目录下:nginx.conf

vars目录下:main.yml
模板中定义的名字:nginx.conf中定义的默认发布目录

handles目录下:main.yml
- name: restart mysqld
service: name=mysqld state=restarted
files目录下:存放要copy的配置文件及脚本文件
password.sh:内容如下
systemctl restart mysqld
word=grep password /var/log/mysqld.log |awk 'NR==1{print $NF}'
mysqladmin -u root -p$word password 123
修改过的 mysql-community.repo和网站内容