一. Ansible
Configuration、Command and Control
SSH-based configuration management, deployment, and task execution system
运维工具的分类:
agent:基于专用的agent程序完成管理功能,puppet, func, zabbix,salkstack
agentless:基于ssh服务完成管理,ansible, fabric, …
1. 架构:
Ansible Core
Modules:
Core Modules
Customed Modules #自定义模块,可二次开发导入使用
Host Iventory #受控主机列表
Files
CMDB :client managment database
PlayBooks
Hosts
roles
Connection Plugins: #连接插件
2. 特性:
模块化:调用特定的模块,完成特定的任务;
基于Python语言研发,由Paramiko, PyYAML和Jinja2三个核心库实现;
部署简单:agentless;
支持自定义模块,使用任意编程语言;
强大的playbook机制;
幂等性; 即一个命令,即使执行一次或多次, 其结果也一样
3. 安装及程序环境:
注意: ansible 依赖python环境,因此介意使用yum 来安装
程序:
ansible
ansible-playbook
ansible-doc #帮助文档
(CentOS 6 中,只需安装ansible 一个包即可)
配置文件:
/etc/ansible/ansible.cfg
主机清单:
/etc/ansible/hosts
插件目录:
/usr/share/ansible_plugins/
4. ssh连接支持
建议私钥连接:
创建监控端公钥
ssh-keygen -t rsa -P ''
复制公钥到制定被控主机:
ssh-copy-id ip /root/.ssh/id_rsa.pub
============================================================
二. 基本使用入门
1.ansible命令:
Usage: ansible <host-pattern> [options]
常用选项:
-m MOD_NAME(模块) -a "MOD_ARGS" (传递参数,需要加引号)
ansible 使用帮助:
ansible -h
2. 配置Host Inventory: #主机清单; 若不用主机清单,则需要直接使用IP地址
/etc/ansible/hosts
#直接添加主机
#添加主机范围:
## www[001:006].example.com
#即用001–006号主机
#创建群组
[group_id]
HOST_PATTERN1
HOST_PATTERN2
eg:
[websrvs]
10.1.252.4
10.1.232.2
补充:
ansible all …. 代表全部主机
3. 模块使用:
获取模块列表:ansible-doc -l
获取指定模块的使用帮助:ansible-doc -s MOD_NAME
注意: -a 选项后的参数,涉及空格的项,注意要用引号引起:
eg:
ansible all -m cron -a "minu='*/5 ' job='/usr/sbin/ntpdate 10.1.0.1' "
常用模块:
1) ping:探测目标主机是否存活;
eg:
ansible all -m ping
2) command:在远程主机执行命令;:(注意,此命令无法识别管道命令)
eg:
ansible all -m command -a "useradd centos"
3) shell:在远程主机上调用shell解释器运行命令,支持shell的各种功能,例如管道等 ;
注意:command和shell模块的核心参数直接为命令本身;而其它模块的参数通常
为“key=value”格式;
4). copy: C o p i e s f i l e s t o r e m o t e l o c a t i o n s .
用法:
(1) 复制文件
-a "src= dest= "
#从本地主机复制到远程主机
[root@localhost test]# ansible webs -m copy -a "src=/test/1111 dest=/test/"
(2) 给定内容生成文件
-a "content= dest= "
#在远程主机上生成制定内容的文件
其它参数:mode, owner, group, …
eg:
ansible webs -m copy -a "content=1ddfd111 dest=/test/2222"
5) . file:S e t s a t t r i b u t e s o f f i l e s
用法:
(1) 创建目录:
-a "path= state=directory"
(2) 创建链接文件:
-a "path= src= state=link"
(3) 删除文件:
-a "path= state=absent“
4) 另还有额外配置项: owner ,group 等,可以指定文件属性
eg:
ansible all -m file -a "path=/test/2222 owner=centos"
6) fetch:F e t c h e s a f i l e f r o m r e m o t e n o d e s
#从远程主机上复制文件到本地
格式示例:
ansible all -m fetch -a "dest=/###/@@@ src=/test/"
7) .cron:M a n a g e c r o n . d a n d c r o n t a b e n t r i e s .
#周期性任务管理
-a "":
minute=
hour=
day=
month=
weekday=
job=
name=
user=
state={present|absent}
eg:
ansible all -m cron -a "minu='*/5 ' job='/usr/sbin/ntpdate 10.1.0.1' "
8). hostname:M a n a g e h o s t n a m e
-a "name=host_name"
eg:
[root@localhost test]# ansible 10.1.252.59 -m hostname -a
"name=node1111"
10.1.252.59 | SUCCESS => {
"ansible_facts": {
"ansible_domain": "",
"ansible_fqdn": "node1111",
"ansible_hostname": "node1111",
"ansible_nodename": "node1111"
},
"changed": true,
"name": "node1111"
}
9). yum:M a n a g e s p a c k a g e s w i t h t h e I ( y u m ) p a c k a g e
m a n a g e r
备注: 另有其他选项,请自行查看帮助
注意: client 上的yum源需要先配置好
-a " ":
(1) name=soft_name state={present|latest} #安装
(2) name=soft_name state=absent #卸载
eg:
ansible webs -m yum -a "name=httpd state=latest"
#安装httpd 程序
10) service:M a n a g e s e r v i c e s .
-a ""
name= #程序名
state=
started
stopped
restarted
enabled= true | false
#开机启动
runlevel=# # 设置启动级别
eg:
ansible webs -m service -a "name=httpd state=restarted enabled"
11 ) group: A d d o r r e m o v e g r o u p s
-a ""
name=
state=present | absent
system=yes|no # 设置为系统组
gid=##
12) user:M a n a g e u s e r a c c o u n t s
-a ""
name=
group= #同名组(基本组)
groups= #将用户加入多个组(附加组)
comment= #用户注释信息
uid=
system= yes|no (true|false) #设置为系统用户
shell=
expires= #指定用于过期时间
home= #指定用户家目录
13) setup:G a t h e r s f a c t s a b o u t r e m o t e h o s t s
#用于获取client的各种属性信息
eg:
[root@localhost ~]# ansible webs -m setup
10.1.252.218 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.122.1",
"10.1.48.2",
"10.1.252.218"
],
"ansible_all_ipv6_addresses": [
"fe80::20c:29ff:fe41:1e55"
],
"ansible_architecture": "x86_64",
"ansible_bios_date": "07/02/2015",
"ansible_bios_version": "6.00",
"ansible_cmdline": {
"BOOT_IMAGE": "/vmlinuz-3.10.0-327.el7.x86_64",
"LANG": "en_US.UTF-8",
"quiet": true,
"rhgb": true,
"ro": true,
"root": "UUID=795056d7-a4e5-43eb-b4df-4681d61acbfe"
},
"ansible_date_time": {
"date": "2016-11-04",
"day": "04",
"epoch": "1478262632",
"hour": "20",
"iso8601": "2016-11-04T12:30:32Z",
"iso8601_basic": "20161104T203032309415",
"iso8601_basic_short": "20161104T203032",
"iso8601_micro": "2016-11-04T12:30:32.309575Z",
"minute": "30",
"month": "11",
"second": "32",
"time": "20:30:32",
"tz": "CST",
"tz_offset": "+0800",
"weekday": "Friday",
"weekday_number": "5",
"weeknumber": "44",
"year": "2016"
},
…………
===========================================================
三.playbook
#用于实现将client 配置同一写入文件,并一键运行
1. YAML:(ansible client配置文件的格式,python中常使用的模板语言)
YAML is a data serialization format designed for human readability and
interaction with scripting languages.
数据结构:
键值对:
key:value
列表:(以"-"为开头引导的)
– item1
– item2
– item3
字典:
{name:jerry, age:21}
2. PlayBook:
1) 文件格式:
file_name.yaml 或者 file_name.yml
2) 帮助:
ansible-playbook -h
3) 核心元素:
Tasks:任务,由模块定义的操作的列表;
Variables:变量
Templates:模板,即使用了模板语法的文本文件;
Handlers:由特定条件notify触发的Tasks;
Roles:角色;
notify: 触发条件, 放于tasks 中,用于当指定任务发生时促发handlers
4) playbook的基础组件:
Hosts:运行指定任务的目标主机;
remote_user:在远程主机以哪个用户身份执行;
sudo_user:非管理员需要拥有sudo权限;
tasks:任务列表
模块,模块参数:
格式:
(1) action: module arguments
(2) module: arguments
5) 常用格式:
注意:yaml内容格式有严格固定,缩进只能用一个空格
格式示例:
– hosts: #"-"需顶格,后接一个空格
remote_user: ## #首部为两个空格,remote与hosts对齐
tasks: #tasks 与remote对齐
– name: task_name1 #任务1 #"-"需要与name与tasks对齐
mod_name : name= ## …
– name: task_name2 #任务2
mod_name: name=###
语法以及格式测试:
ansible-playbook –syntax-check /path/to/playbook.yaml
———————————————————————
示例1:
vim group.yml:
– hosts: all #对all 主机执行的task
remote_user: root
tasks:
– name: install a group #任务1
group: name=mygrp system=true
#调用group 模块
– name: install a user #任务2
user: name=user1 group=mygrp system=true
#调用user模块
– hosts: websrvs #对 websrvs 组主机需要执行的task
remote_user: root
tasks:
– name: install httpd package
yum: name=httpd
– name: start httpd service
service: name=httpd state=started
– ———————————————————————————–
6) 运行playbook,使用ansible-playbook命令
(1) 检测语法(仅做语法检测,不测试运行)
ansible-playbook –syntax-check /path/to/playbook.yaml
(2) 测试运行
ansible-playbook /path/to/playbook.yaml
-C ,–check 测试运行
–check
–list-hosts
–list-tasks
–list-tags
注意:–check时候,有些报错不一定是真实错误,部分操作需要真实执行后才
能进行的任务,在测试执行时候也会报错
eg:
ansible-playbook -C | –check /test.yaml
(3) 运行
ansible-playbook /path/to/playbook.yaml
-t TAGS, –tags=TAGS #指定需要运行的标签对应的任务
–skip-tags=SKIP_TAGS #跳过对应标签的的任务
–start-at-task=START_AT
7) handlers:由特定条件触发的Tasks;
调用及定义方式:
tasks:
– name: TASK_NAME
module: arguments
notify: HANDLER_NAME #触发条件
#只有在对应的tasks中添加了notify ,才能触发后续对应的handlers
handlers:
– name: HANDLER_NAME
module: arguments
示例:
– hosts: websrvs
remote_user: root
tasks:
– name: install httpd package
yum: name=httpd state=latest
– name: install conf file
copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart httpd service
– name: start httpd service
service: name=httpd state=started
handlers:
– name: restart httpd service
service: name=httpd state=restarted
# 当执行了name: install conf file 此名称的任务时,会触发handlers的任务
8) tags:给指定的任务定义一个调用标识;
– name: NAME
module: arguments
tags: TAG_ID
eg:
– name: install httpd package
yum: name=httpd state=latest
tags: install
– name: restart httpd service
service: name=httpd state=restarted
tags: restart
执行时:
ansible-playbook -t install,restart web.yaml
9) Variables:
变量调用:
{{ var_name }}
类型:
内建:
(1) facts
自定义:
(1) 命令行传递;
-e VAR=VALUE
#直接在yaml文件中定义变量,并在执行时,在命令行直接传递变量
eg:
vim test.yaml:
– hosts: all
remote_name: root
tasks:
– name: install a package
yum: name= {{ pkgname }} state=present
执行并传递变量值:
ansible-playbook -e pkgname=httpd test.yaml
(2) 在hosts Inventory中为每个主机定义专用变量值;
# 在/etc/ansible/hosts中,直接给对应主机赋予变量
(a) 向不同的主机传递不同的变量 ;
IP/HOSTNAME variable_name=value
eg:
[websrvs]
10.1.252,.1 pkgname=httpd
10.1.252.2 pkgname=nginx
(b) 向组内的所有主机传递相同的变量 ;
[groupname:vars]
variable_name=value
eg:
[srvs]
10.1.1.1
10.1.1.2
[srvs:vars]
pkgname=httpd
(3) 在playbook中定义
vars:
– var_name: value
– var_name: value
注意: 如果此时命令行也用-e 给出指定变量的值,则-e 的优先级高,变量
引用-e 的值
eg:
vim test.yaml:
– hosts: all
remote_name: root
vars:
– pkgname: httpd
– pkgname2: vsftpd
tasks:
– name: install a package
yum: name= {{ pkgname }} state=present
– name: uninstall a package
yum: name= {{ pkgname2 }} state=absent
(4) Inventory还可以使用参数:
(直接在/ets/ansible/hosts中传递)
用于定义ansible远程连接目标主机时使用的属性,而非传递给
playbook的变量 ;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass
…
eg:
[websrvs]
10.1.0.1 ansible_ssh_port=2222
10.1.0.2 ansible_ssh_user=centos ……
(5) 在角色调用时传递
roles:
– { role: ROLE_NAME, var: value, …}
eg:
某个执行调用roles 的.yaml文件,对某个指定的角色传递指定变量
– hosts: all
remote_user: root
roules:
– { role: nginx, nginx_port: 8080 }
10) Templates:模板 (使用jinja2语言编写) (仅能在playbook中使用)
文本文件,内部嵌套有模板语言脚本(使用模板语言编写)
Jinja2 is a template engine written in pure Python. It provides a Django inspired
non-XML syntax but supports inline expressions and an optional sandboxed
environment.
(1)作 用: 执行模板文件中的脚本,并生成结果数据流,需要使用template模块;
即,作用类似于copy, 但是可以将文件中包含的变量等,转化为对应值,
查看可以使用的 内建的键 可以使用ansilbe host_name -m setup 来查看含有的键
eg:
修改nginx.conf 中的
work_processes {{ ansible_processor_vcpus }}
只有使用template模块传递nginx.conf 文件时候,才会将 ansible_processor_vcpus
解析为对应主机上硬件的值
详细使用,见下方示例处
(2)template:
-a ”“
src=
dest=
mode=
onwer=
group=
注意:此模板不能在命令行使用,而只能用于playbook;
(3)语法:
文件后缀: .j2
字面量:
字符串:使用单引号或双引号;
数字:整数、浮点数;
列表:[item1, item2, …]
元组:(item1, item2, …)
字典:{key1:value1, key2:value2, …}
布尔型:true/false
算术运算:
+, -, *, /, //, %, **
比较操作:
==, !=, >, <, >=, <=
逻辑运算:and, or, not
————————————————————————————-
(4)示例:
vim nginx.yaml:
– hosts: ngxsrvs
remote_user: root
tasks:
– name: install nginx package
yum: name=nginx state=latest
– name: install conf file
template: src=/root/nginx.conf.j2 dest=/etc/nginx/nginx.conf
tags: ngxconf
notify: reload nginx service
– name: start nginx service
service: name=nginx state=started enabled=true
handlers:
– name: reload nginx service
shell: "/usr/sbin/nginx -s reload"
————————————————————————–
(5)条件测试:
when语句:在tasks中使用,Jinja2的语法格式;
可以直接使用内置变量(即 -m setup 中显示的)
– hosts: all
remote_user: root
tasks:
– name: install nginx package
yum: name=nginx state=latest
– name: start nginx service on CentOS6
shell: "service nginx start"
when: ansible_distribution == "CentOS" and
ansible_distribution_major_version == "6"
– name: start nginx service
shell: "systemctl start nginx.service"
when: ansible_distribution == "CentOS" and
ansible_distribution_major_version == "7"
(6)循环:迭代,需要重复执行的任务;
对迭代项的引用,固定变量名为"item”,使用with_items属性给定要迭代的元素;
元素:列表
字符串
字典
基于字符串列表给出元素示例:
– hosts: websrvs
remote_user: root
tasks:
– name: install packages
yum: name={{ item }} state=latest
with_items:
– httpd
– php
– php-mysql
– php-mbstring
– php-gd
基于字典列表给元素示例:
– hosts: all
remote_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'}
==========================================================
11) 角色:roles
以特定的层级目录结构进行组织的tasks、variables、handlers、templates、files等;
即将原本一个yaml文件中定义的各项内容,拆分到至指定的位置,调用时再组合起来,
此方式对调用更为灵活
#各文件一般位于/etc/ansible/roles 目录, ansible-playbook会自行前往该目录查找
若需要重新定义,则在ansible的配置文件修改即可
( role_name 即为指定角色的名字,如nginx ,与nginx 相关的配置均放于此文件夹中)
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的文件,用于设定默认变
量;
在playbook中调用角色的方法:
– hosts: HOSTS
remote_user: USERNAME
roles:
– ROLE1
– ROLE2
– { role: ROLE3, VARIABLE: VALUE, …}
– { role: ROLE4, when: CONDITION }
示例:
1. mkdir -pv /etc/ansible/roles/ngixn/{files,template,vars,handlers,meta,default,tasks}
2. vim …./nginx/tasks/main.yaml:
– name: install nginx
yum: name=nginx state=present
– name: install conf file
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
#指定文件放于对应模块的文件夹后,就不需要使用绝对路径
tags: ngxconf
notify: reload conf
– name: start nginx service
service: name=nginx state=started enabled=true
3. vim …./nginx/handlers/main.yaml
#补充定义tasks中notify: reload conf 指定的handlers
– name: reload nginx service
service: name=nginx state=restarted
4. cp /etc/nginx/nginx.conf /etc/ansible/roles/nginx/template/nginx.conf.j2
同时,修改nginx.conf.j2 中的:
Listen 80 —–> Listen {{ nginx_port }}
work_processes auto ; ——> work_processes {{ ansible_processor_vcpus }};
5. vim …./nginx/vars/main.yaml
– nginx_port: '8080'
6. #role调用:
vim /etc/ansible/nginx.yaml
– hosts: webs
remote_user: root
roles:
– nginx #此名称需要与/etc/ansible/roles下定义的文件夹名称一致
7. 执行:
ansible-playbook xxxx.yaml 即可
==========================================================
博客作业:以上所有内容;
实战作业:
(1) 主/备模型的keepalived+nginx;
(2) httpd+php+php-mysql;
(3) mysql-server或mariadb-server;
拥有testdb库,并允许testuser对其拥有所有权限;
原创文章,作者:ldt195175108,如若转载,请注明出处:http://www.178linux.com/60033