ansible部分功能详解

一. 架构: 组成

    ansible core:

    modules:

    Core Module

    Custom Module

  Host Inventory: 主机清单

      File

      CMDB

  Playbooks : 定义对每个主机的操作任务, 定义了host和role的对应关系

    hosts:

    roles: 任务

  Connection plugin: 连接插件

二. 特性

    模块化: 调用特定的模块, 完成特定的任务;

    基于Python语言研发, 由paramiko,pyYAML和jinja2三个核心库实现;

    部署简单: agentless, 无代理;

    支持自定义模块, 使用任意编程语言;

    强大的playbook机制;

    幂等性: 多次执行同一命令, 结果相同;

三. 安装及程序环境

ansible: 主程序

ansible-playbook: 执行脚本文件程序

ansible-doc: 获取帮助文档

配置文件:

/etc/ansible/ansible.cfg

主机清单:

/etc/ansible/hosts

插件目录:

/usr/share/ansible_plugins/: 连接插件

ansible命令:

ansible命令是以ssh通信连接的, 前提要在主机之间建立ssh公钥认证;

ssh-keygen -t rsa -P ''  #生成公钥;
ssh-copy-id -i .ssh/id_rsa.pub root@NODE  #将公钥发送给客户端;

为了手动完成管理功能

前提: 配置/etc/ansible/hosts

[GROUP_NAME]
HOST_IP_1
HOST_IP_2
...

基本语法:

ansible <host-pattern> [options]

host-pattern : 需要管理的主机

options:

-m MOD_NAME : 指明调用的模块;

-a MODULE_ARGS: 指明模块参数;

基本格式:

ansible GRP_NAME -m MOD_NAME -a MOD_ARGS "ARGS"

ansible 模块:

ansible-doc [options] [module…]

-l, –list: 获取模块列表

-s MOD_NAME: 获取模块的简单用法

四. 常用模块 

1. ping : 尝试连接主机, 验证一个可用的python并且成功返回"pong";

ansible GRP_NAME -m ping

2. command : 在远程节点上执行命令;

示例:

ansible websrv -m command -a "ifconfig"

注意: command模块不能接受管道等符号, 若需要使用, 需要调用shell模块;

3. shell : 在节点上启动脚本执行命令, 支持shell的高级功能;

注意: command和shell模块的核心参数直接为命令本身, 而其它模块的参数通常为"key=value"格式;

示例: 

ansible websrv -m command -a "useradd centos"
ansible websrc -m shell -a "echo 'magedu' | passwd --stdin centos"

4. copy : 复制ansible上的文件到远程主机上;

参数:

content: 直接给定内容, 保存在远程主机上;

src= : 要复制到远程服务器的文件的本地路径, 可以是相对路径, 也可以是绝对路径. 所以, 在一般使用中, 会将需要的各种文件, 放置到同一的ansible的目录下进行存放, 方便以后的命令的整体移动使用;

dest= : 指明远程路径, 必须为目录;

mode : 指明目标文件的权限;

group : 指明目标文件的属组;

owner : 指明目标文件的属主;

示例:

ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab.ansible mode=600"
ansible all -m copy -a "content='hello\nworld\n' dest=/tmp/fstab mode=640"

5. file : 设置文件的属性;

参数: 

group : 设置文件的属组;

owner : 设置文件的属主;

path= : 指明要修改哪个文件的属性;

state : 定义目标文件属性; 如果是directory, 不存在, 将被创建; 如果是file, 不存在, 不会创建, 请使用copy或template模块; 如果是link, 将创建或更改符号链接; 硬链接使用hard; state默认为present;

示例:

ansible all -m file -a "path=/tmp/fstab.ans owner=centos" #修改文件属主
ansible all -m file -a "path=/tmp/fstab.ans state=absent" #删除文件, absent表示删除;
ansible all -m file -a "path=/tmp/dir.ansible state=directory" #创建空目录;
ansible all -m file -a "path=/tmp/test.ansible.link src=/tmp/test.ansible state=link" #创建符号链接文件, 其中path指明
#要创建的符号链接文件路径, src指明符号链接的源文件, state指明创建的为符号链接;

6.fetch : 从远程节点获取文件, 通常从远程某一台主机上获取文件, 同时从多台远程主机获取文件, 会发生紊乱;

7. cron : 管理cron.d和crontab任务条目;

参数: 

    name= : crontab条目的描述, 如果设置了env,则为环境变量的名称. 如果state=absent, 则为必须;

    job : 要执行的命令, 或者如果设置了env, 则为环境变量的值; 如果state=present, 则为必须;

    state : whether to ensure the job or environment variable is present or absent;

示例: 

ansible all -m cron -a "minute='*/5' job='/usr/sbin/ntpdate 10.1.0.1 &> /dev/null name='sync time'" 
#每5分钟与服务器同步一次时间; 其中, name必须指定, 不能省略;
ansible all -m cron -a "name='sync time' state=absent" #删除name指定的计划任务;

crontab -l : 查看本机的计划任务;

8. hostname :设定主机名称;

参数:

name= : 指明要设置的主机名称, 属于必须给的选项;

9. yum : 使用yum管理软件包;

参数:

state={present|installed|latest|absent|removed} : 

安装 : present或installed或latest;

删除 : absent或removed;

disable_gpg_check={true|false} : 安装过程中禁止gpg密钥检查;

disablerepo= : 安装过程中临时禁用某个repo;

enablerepo= : 安装过程中, 临时启用某个repositories;

示例:

ansible all -m yum -a "name=httpd" #安装httpd;
ansible all -m yum -a "name=httpd state=absent" #删除httpd;

10. service : 管理服务;

参数:

name= : 指明要管理的服务;

state={started|stopped|restarted|reloaded} : 指明服务的动作; 'started'/'stopped'是幂等动作,除非必要,否则不会运行命令; 'restarted'将始终退回服务; 'reloaded'将总是重新加载; *至少一个状态和启用.

enabled={true|false} : 是否开机自动启动;

arguments= : 传递其他参数;

示例:

chkconfig –list httpd

ansible all -m service -a "name=httpd state=started enable=true" # 启动httpd服务, 并且开机启动;
systemctl is-enabled *.service #查看服务是否开机启动;

11. group : 添加或删除用户组;

参数:

gid= : 指明组的gid

name= : 指明创建的组名

state={present|absent} : 添加或删除组;

system=[yes] : 如果指明为yes则创建系统组;

12. user : 管理用户账户;

参数:

name= : 指明要创建的用户名;

groups= : 指明要添加到的组;

shell= : 指明默认shell;

uid= : 指明id号;

system= : 创建用户是, 如果为'yes', 则会创建系统用户;

createhome= : 如果指明为no, 则不创建家目录;

comment= : 指明用户的注释信息;

expires= : 指明用户的过期时间;

13. setup : 收集远程主机的系统景况;

当需要用到一些系统的信息的时候, 需要首先收集主机的信息, 将其报告为ansible, 然后才能使用;

示例:

ansible 10.1.52.2 -m setup #此处的IP地址必须是/etc/ansible/hosts中定义了的主机IP地址; 未定义无法获取;

部分获取的主机信息参数:

ansible_distribution : 系统的发行版本;

ansible_distribution_major_version : 系统的主版本号;

ansible_hostname : 主机名;

ansible_processor_core : 每颗CPU的核心数;

ansible_processor_count : 共有几颗CPU;

ansible_processor_vcpus: 虚拟CPU数量;

ansible_processor_threads_per_code : 每个CPU核心的线程数量;

YAML格式的存储文件 : python常用的模板语言;

yum info PyYAML

序列化格式

数据格式:

键值对  key:value

列表 : 有序数组

– item1

– item2

字典 : 关联数组

{name:jerry,age:21}

playbook :

语法结构:

tasks : 任务, 由模块定义的操作列表;

variables : 变量

templates : 模板, 即使用模板语法的文本文件;

handlers : 由特定条件触发的task;

roles : 角色;

五. playbook的基础组件

  Hosts :       运行指定任务的目标主机;

  remote_user : 在远程主机上以哪个用户的身份执行; 建议使用root用户; 非root账户, 要使用sudo_user

  tasks : 任务列表;

  模块, 模块参数

格式:

(1) action:module arguments

(2) module:arguments

1. tasks 基本语法格式 – 如何定义 tasks

示例一:

- name: deploy web server
  user: foouser
  sudo: true
  hosts: all

  tasks: 
  - name: install apache
    apt: pkg=apache2-mpm-prefork state=latest
   (其中apt指明使用的模块)

示例二:

在hosts中的用户上创建组, 创建用户并指定组

首先创建的playbook脚本要以".yaml"结尾

- hosts: all
  remote_user: root
  tasks:
  - name: install a group
    group: name=mygrp system=true
  - name: install a user
    user: name=user1 group=mygrp system=true

- hosts:
  remote_user: root
  tasks:
  - name: install httpd
    yum: name=httpd
  - name: start httpd.service
    service: name=httpd state=started

ansible-playbook命令 – 运行.yml或.yaml脚本

语法:

ansible-playbook [options] PLAYBOOK.yml

options:

-C, –check: 测试模式, 不做任何更改, 而是尝试运行, 进行检查;

–list-hosts: 输出匹配的主机列表, 不执行其他操作;

–list-tags : 列出所有可用的标签

–list-tasks: 列出所有将要执行的任务;

-t TAGS, –tags=TAGS : 只运行tags标识的任务

–skip-tags=SKIP-TAGS : 只运行tags没有标记的任务;

–syntax-check: 对剧本执行语法检查, 但是不执行;

示例三:

要求: 在远程主机上安装httpd服务, 并且能够监听8080端口.

方法: 

(1) 安装httpd;

(2) 提供配置文件;

(3) 启动httpd服务;

playbook文件

- hosts: dbsrv
  remote_user: root
  tasks:
  - name: install httpd
    yum: name=httpd state=latest
  - name: install conf file
    copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
  - name: start httpd.service 
    service: name=httpd state=started

2. handlers : 

playbook文件 :

- hosts: dbsrv
  remote_user: root
  tasks:
  - name: install httpd
    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

handlers: 由特定条件触发的Tasks; 

在某个tasks中触发, 当notify存在位置的上一个动作如果发生改变, 就会触发handlers定义的动作; 使用notify来调用, 调用的为handlers中name定义的名字; 

此方法在服务类程序中使用较多, 当可以reload生效时, 可以使用command和shell进行定义;

handlers:

– name: reload httpd

 shell: systemctl reload httpd.service 

3. tags : 给指定的任务定义一个调用标识;

ansible-playbook -t TAGS PLAYBOOK.yaml

ansible-playbook –skip-tags TAGS PLAYBOOK.yaml

在 tasks 或 handlers 中定义, 必须放置在 – name: 段当中, 对存在 tags 的程序段进行操作; 其他全部不进行操作;

4. variables : 

类型 : 

内建 : 可直接调用

(1) facts : 可以使用 setup模块获取的变量

用户自定义 : 

(1) 通过命令行传递

-e VAR1=VALUE1 -e VAR2=VALUE2 …

(2) 在hosts Inventory中为每个主机定义专用变量值;

(a) 向不同的主机传递不同的变量;

IPhone/HOSTNAME variable_name=value

(b) 向组内的所有主机传递相同的变量;

[group_name:VARS]

variable_name=value

调用 :

{{ var_name }}

示例:

- hosts: dbsrv
  remote_user: root
  vars:
  - pkgname: httpd
  tasks:
  - name: install a packet
    yum: name={{ pkgname }} state=present

使用vars记性变量的定义, 格式如下

vars:

– VAR_NAME1: VALUE1

– VAR_NAME2: VALUE2

若没指定, 可以使用 -e 选项, 并且命令行中给定的 -e VAR_VALUE 的优先级更高;

ansible-playbook -e VAR_VALUE PLAYBOOK.yaml

组变量 :

可以在/etc/ansible/hosts中单独向主机传递变量

方式一:

[websrv]
10.1.52.2 pkgname=naginx
10.1.52.3 pkgname=httpd

方式二:

[websrv]
10.1.52.2
10.1.52.3
[websrv:vars]
pkgname=memcached

Inventory还可以使用参数

用于定义ansible远程连接目标主机时使用的属性, 而非传递给playbook;

[websrv]

10.1.52.2 ansible_ssh_user=USER ansible_shh_pass=PASSWORD ansible_sudo_pass=SUDO_PASSWD

ansible_ssh_host

ansible_ssh_port

ansible_ssh_user

ansible_ssh_pass

ansible_sudo_pass

5. templates : 模板

文本文件, 内部嵌套有模板语言脚本(使用模板编程语言)

语法 :

字面量:

字符串 : 使用单引号或双引号;

数字 : 整数, 浮点数

列表 : [item1, item2,…]

元组 : (item1,item2,…)

字典 : {key1:value1,key2:valuse2,…}

布尔值 : true/false

算数运算 :

+, -, * , /, //, %, **

比较操作 :

逻辑运算 : and, or, not

执行模板文件中的脚本, 并生成结果数据流, 需要使用template模块;

template :

-a ""

src=

dest=

mode=

owner=

group=

注意 : 此模块不能在命令行中使用, 只能在playbook中使用, 别模板语言一般为了表示使用 .j2 结尾;

示例:

- hosts: all
  remote_user: root
  tasks:
 - name: install nginx.conf
   template: src=/root/nginx.conf.j2 dest=/tmp/nginx.conf

并且要在需要使用template解析的文件中, 添加引用的参数, 例如: nginx.conf中添加

worker_processes {{ ansible_processor_vcpus }}

可以调用setup模块中的变量名, 使用template将其解析为 value的值

完整安装nginx并提供配置文件, 示例:

- hosts: ngxsrvs
  remote_user: root
  tasks:
  - name: install nginx
    yum: name=nginx state=latest
  - name: install nginx.conf
    template: src=/root/nginx.conf.j2 dext=/tmp/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"

6. 条件测试

when语句 : 在tasks中使用, jinja2的语法格式;

可以调用 setup 模块的变量, 判断后面的值是否符合条件;

示例 :

- hosts: all
  remote_user: root
  tasks:
  - name: install nginx 
    yum: name=nginx state=latest
  - name: service nginx.service restart
    service: name=nginx state=started
  when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "6" 
  - name: systemctl start nginx
    shell: systemctl start nginx.service 
    when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
  - name: install nginx.conf
    template: src=/root/nginx.conf.j2 dest=/tmp/nginx.conf
    tags: ngxconf
    notify: reload nginx
  handlers:
  - name: relaod nginx
    shell: "/usr/sbin/nginx -s reload"

7. 循环 : 迭代, 需要重复执行的任务;

对迭代项的引用, 固定变量名 "item", 使用with_items属性给定要迭代的元素, 通过遍历元素, 完成所有执行;

元素 : 列表, 字典

示例一:  基于字符串列表给出元素

- hosts: websrv
  remote_user: root
  tasks:
  - name: install packages
    yum: name={{ item }} state=latest
    with_items:
    - httpd
    - php
    - mariadb-server
    - php-mysql
    - sariadb-devel
    - php-devel
    - php-gd
    - php-mbstring

示例二:  基于字典列表给出元素

- hosts: websrv
  remote_user: root
  tasks:
  - name: create groups
    group: name={{ item }} state=present
    with_items:
    - group1
    - group2
    - group3
  - name: create users
    user: name={{ item.name }} group={{ item.group }} state=present
    with_items:
    - { name: user1, group: group1 }
    - { name: user2, group: group2 }
    - { name: user3, group: group3 }

示例三: 在CentOS6 和CentOS 7上分别安装lamp;

- hosts: websrv
  remote_user: root
  tasks:
  - name: install lamp on CentOS 7
    when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
    yum: name={{ item }} state=latest
    with_items:
    - httpd
    - mariadb-server
    - php
    - php-mysql
    - php-gd
    - php-mbstring
  - name: install lamp on CentOS 6
    when: ansible_distribution == "CnetOS" and ansible_distribution_major_version == "6"
    yum: name={{ item }} state=latest
    with_items:
    - httpd
    - mysql-server
    - php
    - php-mysql
    - php-gd
    - php-mbstring

8. 角色 : roles

以特定的层级目录结构进行组织的tasks, variables, handlers, templates, files等;

role_NAME/

    files/ : 存放于copy或script等模块调用的文件;

    tasks/ : 此目录中至少应该有一个名为main.yml的文件, 用于定义各tasks; 其他的文件需要由main.uml进行"包含(include)"调用;

    handlers/ : 此目录中至少应该有一个名为main.yml的文件, 用于定义各handlers; 其他的文件需要由main.uml进行"包含(include)"调用;

    vars/ : 此目录中至少应该有一个名为main.yml的文件, 用于定义各variables; 其他的文件需要由main.uml进行"包含(include)"调用;

    templates/ : 存储由templates模块调用的模板文件;

    meta/ : 此目录中至少应该有一个名为main.yml的文件, 定义当前角色特殊设定及其依赖关系; 其他的文件需要由main.uml进行"包含(include)"调用;

    default/ :  此目录中至少应该有一个名为main.yml的文件, 用于定义默认变量;

路径按照结构, 进行自包含, 不需要指定路径, 程序会自动根据相对路径进行查找文件;

示例:

(1) 在/etc/ansible/roles目录下创建httpd, nginx, mariadb目录, 在目录下创建 files, tasks, handlers, vars, templates, meta, default目录

mkdir -pv /etc/ansible/roles/{httpd,nginx,mariadb}/{files,tasks,handlers,vars,templates,meta,default}

(2) 在tasks目录下创建任务文件

- name: copy nginx package
  copy: src=nginx.rpm dest=/tmp/nginx.rpm
  tags: cppkg
- name: install nginx
  yum: name=nginx.rpm state=latest
- name: install conf file
  templates: src={{ item.ngxconfj2 }} dest={{ item.ngxconf }}
  with_items:
  - { ngxconfj2: nginx.conf.j2, ngxconf: /etc/nginx/nginx.conf }
  - { ngxconfj2: default.conf.j2, ngxconf: /etc/nginx/conf.d/default.conf }
  tags: ngxconf
  notify: reload nginx service
- name: start nginx service
  shell: /usr/bin/systemctl start nginx

(3) 在files文件下存放nginx.rpm文件

(4) 在templates目录下放置nginx.conf.j2和default.conf.j2文件

(5) 在vars目录下新建main.yml文件, 存放templates目录下放置配置文件中的变量和值

(6) 在/etc/ansible目录下新建nginx.yml的playbook文件

- hosts: websrv
  remote_user: root
  roles: 
  - nginx

(7) 检查语法和试运行

ansible-playbook –syntax-check nginx.yml

ansible-playbook –check nginx.yml

ansible-playbook nginx.yml

原创文章,作者:black_fish,如若转载,请注明出处:http://www.178linux.com/57470

(0)
black_fishblack_fish
上一篇 2016-11-11
下一篇 2016-11-11

相关推荐

  • 心清冷其若冰,志皎洁其若云

    第一篇,当做测试也做开始。 心清冷其若冰,志皎洁其若云。 这闹哄哄的人间啊,仿佛是一堆杂货。无奇不有,无所不能。情感,城市,人际。每天走在这杂乱里,需要有一颗清澈而安静的心,来面对。 会累的。就算是拥有了许多,也是会累的。偶尔,我们也会在深夜里泪流满面吧。偶尔,我们也会心烦意乱的不知所措吧。 太多欲望的人间,热闹的上演着各种剧本。太多空洞的灵魂,喧嚣着各种声…

    Linux干货 2016-11-28
  • 三剑客之sed

    sed命令:Stream EDitor 流编辑器 sed命令的工作流程:     sed会复制原文件中的一行或者多行,逐行进行操作。首先会将该行的内容放入到模式空间内,在模式空间内进行定界或者正则表达式匹配操作。     a.如果该行内容不符合正则表达式或定界,该内容则被判断为No,进行标准输出。 &nbsp…

    Linux干货 2016-08-08
  • 前三天基础-Linux文件系统概论

    Linux之我见     在2016农历丙申年2016年猴年,对于小白的我来说接触到了江湖流传的武功秘籍之-Linux心法,第一次接触到命令行,知道在键盘上随便敲击命令就可以满屏跑数据,就像看过的美国大片里黑客帝国里面的画面,感觉学会好后可以装逼了,废话不多说了,允许在下斗胆介绍Linux文件系统。     &nbsp…

    Linux干货 2016-03-24
  • 子网掩码快速划分-心算

    问题状况: 不管作为一名网络工程师还是一名运维工程师,快速心算划分出网络掩码是必备得技能,      为什么要进行子网掩码划分? 纯二层环境不能隔离广播 有安全 管理方面的问题 解决办法:在二层环境下增加三层设备 将原本的一个主类网络号划分成多个子网     掩码基础知识:     注意:此步没记住不要往下进行     死记硬背1:     2^0=1   …

    Linux干货 2017-03-26
  • 马哥教育网络21期+第五周练习博客

    1、显示/boot/grub/grub.conf中以至少一个空白字符开头的行; [root@localhost ~]#  grep '[^[:space:]]\+' /boot/grub2/grub.cfg 2、显示/etc/rc.d/rc.sysinit文件中以#开头,后面跟至少一个空白字符…

    Linux干货 2016-08-08
  • ​Bash2

    字串比较时变量最好使用"" 这样就不会报错了,只是退出码不为0 组合条件:     与:[ condition1 -a condition2 ]或condition1 && condition2     或:[ condition1 -o co…

    Linux干货 2016-09-25