91-ansible

一. 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 [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=  "

#从本地主机复制到远程主机

[[email protected] 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:

[[email protected] 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:

[[email protected] ~]# 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对其拥有所有权限;

来自为知笔记(Wiz)

  • 版权声明: 本文源自互联网, 于4个月前,由整理发表,共 8761字。
  • 原文链接:点此查看原文