Java教程

Ansible浅析

本文主要是介绍Ansible浅析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

安装

配置yum源

[root@test yum.repos.d]# cat aliBase.repo 
[aliBase]
name=aliBase
baseurl=https://mirrors.aliyun.com/centos/$releasever/os/$basearch/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/centos/$releasever/os/$basearch/RPM-GPG-KEY-CentOS-$releasever

[root@test yum.repos.d]# cat aliEpel.repo 
[aliEpel]
name=aliEpel
baseurl=https://mirrors.aliyun.com/epel/$releasever\Server/$basearch/
enabled=1
gpgcheck=0
[root@test yum.repos.d]# yum –y install ansible

ansible模块

添加ansible要管理的主机到/etc/ansible/hosts中

[root@test ansible]# cat /etc/ansible/hosts
[test] #组名
test1 ansible_ssh_host=10.0.0.6 ansible_port=22 ansible_user=root ansible_ssh_pass='redhat'

ping模块

示列:测试所有主机的连通性

[root@test ansible]# ansible all -m ping
test1 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

command模块

示例1:让所有主机同步时间
此处没有给出指定的-m command命令,是因为ansible的模块默认就是command

[root@test ansible]# ansible all -a 'ntpdate cn.pool.ntp.org'
test1 | SUCCESS | rc=0 >>
    1 Mar 15:47:27 ntpdate[10058]: step time server 108.59.2.24 offset 3323066.601752 sec

示例2:让每一台主机都执行uname -r命令

[root@test ansible]# ansible all -m command -a 'uname -r'
test1 | SUCCESS | rc=0 >>
2.6.32-431.el6.x86_64

注意:ansible的command模块并不支持管道等输出,要用shell模块

shell模块

示例1: 批量修改其他主机的特定用户的密码

[root@test ansible]# ansible test -m shell -a "echo centos|passwd --stdin master"
test1 | SUCCESS | rc=0 >>
Changing password for user master.
passwd: all authentication tokens updated successfully.

copy模块

用法:
    (1) 复制文件
        -a "src=\'#\'"  "
    (2) 给定内容生成文件
        -a "content=  dest=  "

示例1:

创建测试的文件
[root@test ansible]# ll testfile 
-rw-r--r-- 1 root root 240 Mar  1 16:02 testfile
[root@test ansible]# cat  testfile 
test
test
[root@test ansible]# ansible test -m copy -a "src=/etc/ansible/testfile dest=/tmp/testfile mode=600"
test1 | SUCCESS => {
    "changed": true, 
    "checksum": "9463dc689c8c1f60e325bdec041f7e990fea3aa1", 
    "dest": "/tmp/testfile", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "698176fd8145406a9a5da91249eeb8b8", 
    "mode": "0600", 
    "owner": "root", 
    "size": 240, 
    "src": "/root/.ansible/tmp/ansible-tmp-1519891581.76-215500947985572/source", 
    "state": "file", 
    "uid": 0
}

file模块

file模块作用:设置文件属性

用法:
    (1) 创建目录:
        -a "path=  state=directory"
    (2) 创建链接文件:
        -a "path=  src=\'#\'" /p>
    (3) 删除文件:
        -a "path=  state=absent“

示例1:修改文件的属主

[root@test ansible]# ansible test -m file -a "path=/tmp/testfile mode=777 owner=master"
test1 | SUCCESS => {
    "changed": true, 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "master", 
    "path": "/tmp/testfile", 
    "size": 240, 
    "state": "file", 
    "uid": 502
}

示例2:创建文件的软连接

[root@test ansible]# ansible test -m file -a "src=/tmp/testfile path=/tmp/testfile.link state=link"
test1 | SUCCESS => {
    "changed": true, 
    "dest": "/tmp/testfile.link", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "size": 13, 
    "src": "/tmp/testfile", 
    "state": "link", 
    "uid": 0
}

示例3: 删除文件

[root@test ansible]# ansible test -m file -a " path=/tmp/testfile.link state=absent"
test1 | SUCCESS => {
    "changed": true, 
    "path": "/tmp/testfile.link", 
    "state": "absent"
}

fetch模块

fetch模块:从远程主机拿文件

示例: 从主机test1拿文件

[root@test ansible]# ansible test1 -m fetch -a "src=/tmp/testfile dest=/tmp"
test1 | SUCCESS => {
    "changed": true, 
    "checksum": "9463dc689c8c1f60e325bdec041f7e990fea3aa1", 
    "dest": "/tmp/test1/tmp/testfile", 
    "md5sum": "698176fd8145406a9a5da91249eeb8b8", 
    "remote_checksum": "9463dc689c8c1f60e325bdec041f7e990fea3aa1", 
    "remote_md5sum": null
}

cron模块

cron模块:管理计划任务条目

用法:    
    -a ""
        minute=
        hour=
        day=
        month=
        weekday=
        job=
        name=
        user=

示例1:创建一个同步时间的计划任务,每五分钟执行一次

[root@test tmp]# ansible test -m cron -a "minute='*/5' job='/usr/sbin/ntpdate cn.pool.ntp.org &>/dev/null' name='sync time'"
test1 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "sync time"
    ]
}

示例2:删除计划任务

[root@test tmp]# ansible test -m cron -a "name='sync time' state=absent"
test1 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}

hostname模块

hostname模块:管理主机名

示例:修改主机名

[root@test tmp]# ansible test -a "hostname" 
test1 | SUCCESS | rc=0 >>
centos

[root@test tmp]# ansible test -m hostname -a "name=centos_test2" 
test1 | SUCCESS => {
    "ansible_facts": {
        "ansible_domain": "", 
        "ansible_fqdn": "centos_test2", 
        "ansible_hostname": "centos_test2", 
        "ansible_nodename": "centos_test2"
    }, 
    "changed": true, 
    "name": "centos_test2"
}

yum模块

yum模块:使用yum命令完成程序包管理

用法:
    -a ""
        (1) name=  state={present|latest}
        (2) name=  state=absent

示例1:安装指定包

[root@test tmp]# ansible test -m yum -a "name=samba"
test1 | SUCCESS => {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base: mirrors.163.com\n * epel: mirrors.ustc.e
……

在ansible管理的机器上查看是否安装samba
    [root@centos shell]# yum info samba
    Loaded plugins: fastestmirror
    Loading mirror speeds from cached hostfile
        * base: mirrors.163.com
        * epel: mirrors.ustc.edu.cn
        * extras: mirrors.aliyun.com
        * updates: mirrors.aliyun.com
    Installed Packages
    Name        : samba
    Arch        : x86_64
    Version     : 3.6.23
    Release     : 46el6_9
    Size        : 18 M
    Repo        : installed
    From repo   : updates

示例2:删除samba安装包

[root@test tmp]# ansible test -m yum -a "name=samba state=absent"
test1 | SUCCESS => {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror\nSetting up Remove Process\nResolving Dependencies\n--> Running transaction check\n---> Package samba.x86_64 0:3.6.23-46el6_9 will be erased\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n
……

查看被管理的主机
    [root@centos shell]# yum info samba
    Loaded plugins: fastestmirror
    Loading mirror speeds from cached hostfile
        * base: mirrors.163.com
        * epel: mirrors.ustc.edu.cn
        * extras: mirrors.aliyun.com
        * updates: mirrors.aliyun.com
    Available Packages
    Name        : samba
    Arch        : x86_64
    Version     : 3.6.23
    Release     : 46el6_9
    Size        : 5.1 M
    Repo        : updates

service模块

service模块:服务管理

用法:  
-a ""
    name=
    state=
        started
        stopped
        restarted
    enabled=
    runlevel=

示例:开启主机的httpd服务,并设置为开机启动

首先确定被管理机器的httpd服务是关闭的
[root@test tmp]# ansible test -m service -a "name=httpd state=started enabled=true"
test1 | SUCCESS => {
    "changed": true, 
    "enabled": true, 
    "name": "httpd", 
    "state": "started"
}

group模块

group模块:增加或删除组

用法:
    -a ""
        name=
        state=
        system=
        gid=

示例1:创建组

[root@test tmp]# ansible test -m group -a "name=suixin system=true"
test1 | SUCCESS => {
    "changed": true, 
    "gid": 499, 
    "name": "suixin", 
    "state": "present", 
    "system": true
}
被管理主机验证:
    [root@centos shell]# getent group suixin
    suixin:x:499:

示例2:删除组

[root@test tmp]# ansible test -m group -a "name=suixin state=absent"
test1 | SUCCESS => {
    "changed": true, 
    "name": "suixin", 
    "state": "absent"
}

user模块

user模块:用户管理

使用格式:
    name= : 创建的用户名
    state= : present新增,absent删除
    force= : 删除用户的时候删除家目录
    system= : 创建系统用户
    uid= : 指定UID
    shell= : 指定shell
    home= : 指定用户家目录

示例1:增加一个系统用户

[root@test tmp]# ansible test -m user -a "name=suixin system=true"
test1 | SUCCESS => {
    "changed": true, 
    "comment": "", 
    "createhome": true, 
    "group": 498, 
    "home": "/home/suixin", 
    "name": "suixin", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": true, 
    "uid": 498
}
[root@test tmp]# ansible test -a "id suixin"
test1 | SUCCESS | rc=0 >>
uid=498(suixin) gid=498(suixin) groups=498(suixin)

示例2:删除用户

[root@test tmp]# ansible test -m user -a "name=suixin state=absent"
test1 | SUCCESS => {
    "changed": true, 
    "force": false, 
    "name": "suixin", 
    "remove": false, 
    "state": "absent"
}
[root@test tmp]# ansible test -a "id suixin"
test1 | FAILED | rc=1 >>
id: suixin: No such usernon-zero return code

setup模块

setup模块:手机主机里面的各种信息

示例:收集主机所有信息

[root@test tmp]# ansible test -m setup
test1 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "10.0.0.6"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::20c:29ff:feb8:5059"
        ], 
        "ansible_apparmor": {
            "status": "disabled"
        }, 
……

ansible命令参数

ansible命令:
	-i PATH ,--inventory=PATH:指定invento信息,默认/etc/ansible/hosts
	-f NUM, --forks=NUM:并发线程数,默认为5
	--private-key: 指定密钥文件
	-m NAME, --module-name=NAME: 指定执行使用的模块
	-M DIRECTORY, --module-path=DIRECTORY: 指定模块存放路径,默认/usr/share/ansible
	-a: 模块参数
	-k: 认证密码
	-K: 用户的密码(--sudo时使用)
	-s: 相当于linux的sudo命令
	-T: 指定链接远程主机的最大超时,单位是s
	-u: 指定用户执行命令
	-l: 指定运行主机
	--list-hosts: 列出复合条件的主机列表

playbook

1.playbook语法:

---                       #表示文档开始
- hosts: 受管机1           #用hosts关键字指定受管机对象
  remote_user: 用户名       #用remote_user关键字指定登录受管机用的账户名
  task:                  #用tasks关键字指定要对受管机进行的操作任务
  - name: 任务名1          #用name关键字指定操作任务名称
    模块名:
      参数1: 值
      参数2: 值

注意:

1. 所有手动键入的空白字符都必须是空格,不能是tab
2. "-" 表示一个数组,后面必须紧接空格,":"表示一个键值对,后面必须紧接空格。
3. playbook有严格的缩进关系,同级别的数组和键值对要对齐,下一级的数组或键值对要使用空格缩进(一个或两个空格都可以)

2.playbook文件常用命令

(1) 检测语法

ansible-playbook  --syntax-check  /path/to/playbook.yaml

(2) 测试运行

ansible-playbook -C /path/to/playbook.yaml
        --list-hosts
        --list-tasks
        --list-tags

(3) 运行

ansible-playbook  /path/to/playbook.yaml
        -t TAGS, --tags=TAGS
        --skip-tags=SKIP_TAGS
        --start-at-task=START_AT

示例1: 定义一个playbook任务来新增用户和组

(1)、定义yaml模版
[root@test ansible]# cat group.yml 
- hosts: all
    remote_user: root
    tasks:
    - name: add a group
    group: name=suixin_group system=true
    - name: add a user
    user: name=suixin 
          group=suixin_group 
          system=true
#有时候参数太多,放在一行不容易观看,可以换行写

(2)、检查语法:
[root@test ansible]# ansible-playbook --syntax-check group.yml 

playbook: group.yml

(3)、测试运行看看,,不会实际操作
[root@test ansible]# ansible-playbook -C group.yml 

PLAY [all] ******************************************************************************

TASK [Gathering Facts]   #收集要操作机器的信息
******************************************************************
ok: [test1]

TASK [add a group] **********************************************************************
changed: [test1]

TASK [add a user] ***********************************************************************
changed: [test1]

PLAY RECAP ******************************************************************************
test1                      : ok=3    changed=2    unreachable=0    failed=0

(4)、单独测试某些特定的选项
#查看仅影响的主机
[root@test ansible]# ansible-playbook -C group.yml --list-hosts

playbook: group.yml

    play #1 (all): all	TAGS: []
    pattern: [u'all']
    hosts (1):
        test1

#查看运行哪些任务
[root@test ansible]# ansible-playbook -C group.yml --list-tasks

playbook: group.yml

    play #1 (all): all	TAGS: []
    tasks:
        add a group	TAGS: []
        add a user	TAGS: []

#查看哪个任务打标记了--这里没有打标记
[root@test ansible]# ansible-playbook -C group.yml --list-tags

playbook: group.yml

    play #1 (all): all	TAGS: []
        TASK TAGS: [

(5)、以上没有任何问题,开始运行该任务
[root@test ansible]# ansible-playbook group.yml 

PLAY [all] ******************************************************************************

TASK [Gathering Facts] ******************************************************************
ok: [test1]

TASK [add a group] **********************************************************************
changed: [test1]

TASK [add a user] ***********************************************************************
changed: [test1]

PLAY RECAP ******************************************************************************
test1                      : ok=3    changed=2    unreachable=0    failed=0 

Handlers

Handlers的使用:由特定条件触发的Tasks

#格式
---
- hosts: pro
  remote_user: root
  tasks:
  - name: touch file ww1
    file: path=/test/ww1 state=touch
    notify: handler1       #notify关键字用来调用handler的任务
  - meta: flush_handlers   #meta关键字用来立即执行前面的所有notify
  - name: touch file ww2
    file: path=/test/ww2 state=touch
    notify: group1      #这里调用的是group1组(即handler2+handler3)
  handlers:
  - name: handler1
    file: path=/test/handler1 state=touch
  - name: handler2
    listen: group1    #listen关键字用来将handler2加入group1组
    file: path=/test/handler2 state=touch
  - name: handler3
    listen: group1    #listen关键字用来将handler3加入group1组
    file: path=/test/handler3 state=touch

注意:

(1) handlers是与tasks同级。与tasks对齐
(2) 只有当tasks执行成功后才会通过notify调用handlers,否则不调用
(3) handlers默认是在所有tasks执行完之后才执行,如果某个task执行完成之后需要立即调用handlers处理,则使用meta关键字进行强制调用
(4) 上述执行顺序为:touch file ww1 --> handler1 --> touch file ww2 --> handler2,handler3

tags

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

(1)tag语法格式:

tasks: 
- name: NAME
  module: arguments
  tags: TAG_ID,TAG_ID...

(2) tag示列

~]# cat testhttpd.yml
---
- hosts: pro
  remote_user: root
  tags: httpd
  tasks:
  - name: install httpd package
    tags: ['package']
    yum:
      name=httpd
      state=latest
 
  - name: start up httpd service
    tags:
      - service
    service:
      name: httpd
      state: started

(3) tag调用

#查看plsybook有哪些标签
~}# ansible-playbook --list-tags testhttpd.yml

#调用标签package,service
~]# ansible-playbook --tags package,service testhttpd.yml

#不调用哪些标签
~]# ansible-playbook --skip-tags='t2' testtag.yml

(4) tag内置标签

always :当我们把tags的值指定为always ,那么这个任务总是会被执行,除非你使用"--skip-tags"选项指定不执行对应的任务

never:跟always标签意思相反,不明确指定则不执行。

示列:

~]# cat testtag.yml 
---
- hosts: test70
  remote_user: root
  tasks:
  - name: task1
    file:
      path: /testdir/t1
      state: touch
    tags:
      - t1
  - name: task2
    file: path=/testdir/t2
          state=touch
    tags: ['t2']
  - name: task3
    file: path=/testdir/t3
          state=touch
    tags: t3,always
   
#会执行t1和t3标签的任务
~] # ansible-playbook --tags t1 testtag.yml   
#不执行t3标签的任务,要明确指定
~]# ansible-playbook --skip-tags t3 testtag.yml

拓展:以下三个标签在调用的时候使用,不用作为标签值存在

tagged:示列如下

只执行有标签任务的,没有标签不执行
~]# ansible-playbook --tags tagged testtag.yml

执行没有标签的任务,always标签也会跳过
~]# ansible-playbook --skip-tags tagged testtag.yml

untagged:示列如下

只执行没有标签的任务,包含always标签的任务会执行
~]# ansible-playbook --tags untagged testtag.yml
跳过没有标签的任务
~]# ansible-playbook --skip-tags untagged testtag.yml

all:表示所有任务都会被执行,不用指定,默认就是使用这个标签

Variables

Variables:变量

    类型:
        内建:
            (1) facts
        自定义:
            (1) 命令行传递;
                -e VAR=VALUE
            (2) 在hosts Inventory中为每个主机定义专用变量值;
                (a) 向不同的主机传递不同的变量 ;
                    IP/HOSTNAME variable_name=value
                (b) 向组内的所有主机传递相同的变量 ;
                    [groupname:vars]
                    variable_name=value
            (3) 在playbook中定义
                vars:
                    - var_name: value
                    - var_name: value
            (4) Inventory还可以使用参数:
                用于定义ansible远程连接目标主机时使用的属性,而非传递给playbook的变量;
                    ansible_ssh_host
                    ansible_ssh_port
                    ansible_ssh_user
                    ansible_ssh_pass
                    ansible_sudo_pass
                    ...
            (5) 在角色调用时传递
                roles:
                    - { role: ROLE_NAME, var: value, ...}
 
                    变量调用:
                    {{ var_name }}

示例1:利用命令行传递变量来安装不同的包

此处{{ pkgname }表示变量
[root@test ansible]# cat pkg.
cat: pkg.: No such file or directory
[root@test ansible]# cat pkg.yml 
- hosts: test
    remote_user: root
    tasks:
    - name: install a package
    yum: name={{ pkgname }} state=present

用命令行给变量赋值
[root@test ansible]# ansible-playbook -C -e pkgname=samba pkg.yml 

PLAY [test] *****************************************************************************

TASK [Gathering Facts] ******************************************************************
ok: [test1]

TASK [install a package] ****************************************************************
changed: [test1]

PLAY RECAP ******************************************************************************
test1                      : ok=2    changed=1    unreachable=0    failed=0

示例2:在playbook中定义变量

[root@test ansible]# cat pkg.yml 
- hosts: test
    remote_user: root
    vars:
    - pkgname: samba
    tasks:
    - name: install a package
    yum: name={{ pkgname }} state=present

示例3:在hosts Inventory中为每个主机定义专用变量值

[root@test ansible]# cat /etc/ansible/hosts
[test]
10.0.0.6 pkgname=samba
删掉文档原有的变量,测试没问题

示例4:在hosts Inventory中为每个主机定义专用变量值的第二种方法

[root@test ansible]# cat /etc/ansible/hosts
[test]
10.0.0.6
[test:vars]
pkgname=samba
测试没问题

Template

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

执行模板文件中的脚本,并生成结果数据流,需要使用template模块;
  template:
   -a " "
   src=
   dest=
   mode=
   onwer=
   group=
 
注意:此模板不能在命令行使用,而只能用于playbook;

示例:利用templates模板来设置nginx的定义cpu的数量

1.首先利用ansible命令获取当前系统系统的cpu数量
[root@test ansible]# ansible test -m setup|grep vcpus
        "ansible_processor_vcpus": 2,

2.找一份nginx.conf配置文件修改(变量名修改为上面获取的名字)
[root@test tmp]# head -2 nginx.conf 
user  nginx nginx;
worker_processes  {{ ansible_processor_vcpus }};

3.重命名该文件为Jinja2格式后缀的文件
[root@test tmp]# mv nginx.conf nginx.conf.j2
[root@test tmp]# ll nginx.conf.j2
-rw-r--r-- 1 root root 1451 Mar  1 20:36 nginx.conf.j2

4.新建nginx.yml文档
[root@test ansible]# cat nginx.yml 
- hosts: test
    remote_user: root
    tasks:
    - name: install nginx package
    yum: name=nginx state=latest
    tags: ngxinstall
    - name: install cong file
    template: src=/tmp/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.检查语法,测试执行
[root@test ansible]# ansible-playbook --syntax-check nginx.yml 

playbook: nginx.yml

[root@test ansible]# ansible-playbook -C  nginx.yml 

[root@test ansible]# ansible-playbook nginx.yml 

PLAY [test] *****************************************************************************

TASK [Gathering Facts] ******************************************************************
ok: [test1]

TASK [install nginx package] ************************************************************
ok: [test1]

TASK [install cong file] ****************************************************************
ok: [test1]

TASK [start nginx service] **************************************************************
changed: [test1]

PLAY RECAP ******************************************************************************
test1                      : ok=4    changed=1    unreachable=0    failed=0


6.重点检查一下cpu的变量是否有改变,这里可以看到,跟我们ansible_processor_vcpus的值是一样
[root@centos nginx]# head -2 nginx.conf
user  nginx nginx;
worker_processes  2;
	

条件测试

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

示例:

执行下面命令,在cento6上面可以找到下面该行
[root@test ~]# ansible test -m setup|less
        "ansible_distribution": "CentOS", 
    "ansible_distribution_major_version": "6", 
    "ansible_distribution_release": "Final", 
    "ansible_distribution_version": "6.5"

在centos7机器可以找到下面该行
[root@test ~]# ansible test -m setup|less
        "ansible_distribution": "CentOS", 
    "ansible_distribution_major_version": "7", 
    "ansible_distribution_release": "Core", 
    "ansible_distribution_version": "7.1"

根据以上信息,我们可以创建一个基于条件判断的playbook文件test.yml
[root@test ansible]# cat test.yml 
- hosts: test
    remote_user: root
    tasks:
    - name: install nginx package
    yum: name=nginx state=present
    - name: start nginx service on centos6
    shell: service nginx start
    when: ansible_distribution": "CentOS" and ansible_distribution_major_version == "6"
    - name: start nginx service on centos7
    shell: systemctl start nginx
    when: ansible_distribution": "CentOS" and ansible_distribution_major_version == "7"

循环

循环:迭代,需要重复执行的任务;
  对迭代项的引用,固定变量名为"item”,使用with_item属性给定要迭代的元素;
   元素:列表
      字符串
      字典

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

示例:基于列表的方式安装多个安装包

[root@test ansible]# cat websrv.yml 
- hosts: test
    remote_user: root
    tasks:
    - name: install web package
    yum: name={{ item }} state=latest
    with_items:
    - httpd
    - php
    - vsftp


[root@test ansible]# ansible-playbook --syntax-check websrv.yml 

playbook: websrv.yml

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

示例:常见指定的用户,属于指定的组

[root@test ansible]# cat usrs.yml 
- hosts: all
    remote_user: root
    tasks:
    - name: create groups
    group: name={{ item }} state=present
    with_items:
    - groupx1
    - groupx2
    - name: create users
    user: name={{ item.name }} group={{ item.group }} state=present
    with_items:
    - {name: 'userx1', group: 'groupx1'}
    - {name: 'userx2', group: 'groupx2'}

[root@test ansible]# ansible-playbook --syntax-check usrs.yml 

playbook: usrs.yml

[root@test ansible]# ansible-playbook -C usrs.yml

[root@test ansible]# ansible-playbook usrs.yml 

PLAY [all] ******************************************************************************

TASK [Gathering Facts] ******************************************************************
ok: [test1]

TASK [create groups] ********************************************************************
changed: [test1] => (item=groupx1)
changed: [test1] => (item=groupx2)

TASK [create users] *********************************************************************
changed: [test1] => (item={u'group': u'groupx1', u'name': u'userx1'})
changed: [test1] => (item={u'group': u'groupx2', u'name': u'userx2'})

PLAY RECAP ******************************************************************************
test1                      : ok=3    changed=2    unreachable=0    failed=0 

roles

角色:roles

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

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的文件,用于设定默认变量;

示例1:创建对应的服务目录下面的模版

1. 创建对应的目录
[root@test roles]# cd /etc/ansible/roles/
[root@test roles]# mkdir -p ./{nginx,mysql}/{files,templates,vars,handlers,meta,default,tasks}
首先准备一个安装包,放到nginx/file/目录下面
[root@test files]# ll /etc/ansible/roles/nginx/files/
total 8
-rw-r--r-- 1 root root 4311 Mar  2 10:51 nginx-release-centos-6-0.el6.ngx.noarch.rpm

2. 创建一个nginx的tasks模版
[root@test roles]# cat nginx/tasks/main.yml
- name: copy nginx package to remote host
    copy: src=nginx-release-centos-6-0.el6.ngx.noarch.rpm dest=/tmp/nginx-release-centos-6-0.el6.ngx.noarch.rpm
- name: install nginx package
    yum: name=/tmp/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present
- name: install cong file
    template: src=nginx.conf.j2 dest=/etc/nginx.conf
    tags: ngxconf
    notify: reload nginx service
- name: start nginx service
    service: name=nginx enabled=true state=started
注释:
此处的task会自行查找/etc/ansible/roles/nginx/task/main.yml的任务(此处文件本身也是在task目录下面)。
再比如说,该处指定的copy命令的src=FILENAME也是相对路径,其绝对路径为/etc/ansible/roles/nginx/file/FILENAME。
又比如说定义了notify但是这里并没有handlers,是因为此处定义了的notify的名字会自行去查看该目录下面,即/etc/ansible/roles/nginx/handlers/main.yml里面的handlers。
还有template那里,大家有没发现也是用的相对路径,此处绝对路径为在/etc/ansible/roles/nginx/template/nginx.conf.j2

3. 定义/etc/ansible/roles/nginx/handlers/main.yml,此处的文件就是承接上面notify没有定义handlers的原因

[root@test roles]# cat nginx/handlers/main.yml
- name: reload nginx service
    service: name=nginx state=restarted

4. 复制nginx.conf文件到templates目录下面为nginx.cong.j2
[root@test tmp]# mv nginx.conf /etc/ansible/roles/nginx/templates/nginx.conf.j2

编辑里面cpu数量,此处利用算术表达式控制cpu数量,到时候看到的cpu数量为1
[root@test roles]# grep vcpu nginx/templates/nginx.conf.j2 
worker_processes {{ ansible_processor_vcpus - 1 }};

5. 再复制/etc/nginx/conf.d/default.conf到nginx/templates/default.conf.j2
[root@test conf.d]# cp -p default.conf /etc/ansible/roles/nginx/templates/default.conf.j2

编辑原来的文件端口号为变量ngxport
[root@test roles]# vi nginx/templates/default.conf.j2 
[root@test roles]# grep listen nginx/templates/default.conf.j2 
    listen       {{ ngxport }};

6. 重新编辑task/main.yml文件,添加以下文件
[root@test roles]# cat nginx/tasks/main.yml 
- name: copy nginx package to remote host
    copy: src=nginx-release-centos-6-0.el6.ngx.noarch.rpm dest=/tmp/nginx-release-centos-6-0.el6.ngx.noarch.rpm
- name: install nginx package
    yum: name=/tmp/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present
- name: install cong file
    template: src=nginx.conf.j2 dest=/etc/nginx.conf
    tags: ngxconf
    notify: reload nginx service
- name: install conf file default.conf
    template: src=default.conf.j2 dest=/etc/nginx/conf.d/default.conf
    tags: ngxconf
    notify: reload nginx service
- name: start nginx service
    service: name=nginx enabled=true state=started

7. 定义变量文件
[root@test roles]# cat nginx/vars/main.yml
ngxport: "8888"

8. 此时,所有元素暂时都够了,然后在/etc/ansible/目录下面创建一个nginx.yml的文件
[root@test ansible]# cat /etc/ansible/nginx.yml 
- hosts: test
    remote_user: root
    roles:
    - nginx

9. 编辑查看ansible.cfg配置文件
[root@test ansible]# grep roles_path /etc/ansible/ansible.cfg 
roles_path    = /etc/ansible/roles

10. 检查语法,测试运行,执行
[root@test ansible]# ansible-playbook nginx.yml 

PLAY [test] *********************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************
ok: [test1]

TASK [nginx : copy nginx package to remote host] ********************************************************************************************
changed: [test1]

TASK [nginx : install nginx package] ********************************************************************************************************
changed: [test1]

TASK [nginx : install cong file] ************************************************************************************************************
changed: [test1]

TASK [nginx : install conf file default.conf] ***********************************************************************************************
changed: [test1]

TASK [nginx : start nginx service] **********************************************************************************************************
changed: [test1]

RUNNING HANDLER [nginx : reload nginx service] **********************************************************************************************
changed: [test1]

PLAY RECAP **********************************************************************************************************************************
test1                      : ok=7    changed=6    unreachable=0    failed=0

示例2:根据以上内容,修改端口号

方法1:
[root@test ansible]# cat nginx.yml 
- hosts: test
    remote_user: root
    roles:
    - { role: nginx, ngxport: 8080 }
[root@test ansible]# ansible-playbook nginx.yml

方法2:
[root@test ansible]# ansible-playbook --list-tags nginx.yml 

playbook: nginx.yml

    play #1 (test): test	TAGS: []
        TASK TAGS: [ngxconf]
[root@test ansible]# 
[root@test ansible]# ansible-playbook -C -t ngxconf -e ngxport=8099 nginx.yml 

[root@test ansible]# ansible-playbook -t ngxconf -e ngxport=8099 nginx.yml 

PLAY [test] *********************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************
ok: [test1]

TASK [nginx : install cong file] ************************************************************************************************************
ok: [test1]

TASK [nginx : install conf file default.conf] ***********************************************************************************************
changed: [test1]

RUNNING HANDLER [nginx : reload nginx service] **********************************************************************************************
changed: [test1]

PLAY RECAP **********************************************************************************************************************************
test1                      : ok=4    changed=2    unreachable=0    failed=0  

示例3:实现httpd不同主机不同端口号

先把定义的端口号屏蔽掉
[root@test ansible]# cat roles/nginx/vars/main.yml 
#ngxport: "8888"

定义端口号
[root@test ansible]# cat hosts 
[test]
10.0.0.6 ngxport=8068
10.0.0.7 ngxport=8069

[root@test ansible]# cat nginx.yml 
- hosts: test
    remote_user: root
    roles:
    - nginx

测试执行
[root@test ansible]# ansible-playbook -C -t ngxconf -e ngxport=8099 nginx.yml 

[root@test ansible]# ansible-playbook -t ngxconf -e ngxport=8099 nginx.yml 

示例4:在同一个yml配置文件运行两个服务模版程序

[root@test ansible]# cat nginx.yml 
- hosts: test
    remote_user: root
    roles:
    - nginx
    - memcached
然后配置roles/memcached/

ansible控制主机数量

ansible的能最多控制几台主机
此处是在配置文件里面定义的,默认是5台主机,如果把主机的控制的主机调大,估计也要相对应性能的主机当ansible服务器

[root@test ansible]# cat /etc/ansible/ansible.cfg 
[defaults]

# some basic default values...

#inventory      = /etc/ansible/hosts
#library        = /usr/share/my_modules/
#module_utils   = /usr/share/my_module_utils/
#remote_tmp     = ~/.ansible/tmp
#local_tmp      = ~/.ansible/tmp
forks          = 5
#poll_interval  = 15
这篇关于Ansible浅析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!