Ansible05-Ansible进阶(流程控制、Roles角色、加密优化调优等)

目录

  • 写在前面
  • [7 Ansible 进阶](#7 Ansible 进阶)
    • [7.1 流程控制](#7.1 流程控制)
      • [7.1.1 handlers触发器与notify](#7.1.1 handlers触发器与notify)
        • [7.1.1.1 未使用handlers](#7.1.1.1 未使用handlers)
        • [7.1.1.2 使用handlers](#7.1.1.2 使用handlers)
      • [7.1.2 when判断](#7.1.2 when判断)
        • [7.1.2.1 when的语法](#7.1.2.1 when的语法)
        • [7.1.2.2 when判断主机名选择模块输出](#7.1.2.2 when判断主机名选择模块输出)
        • [7.1.2.3 when结合register变量](#7.1.2.3 when结合register变量)
      • [7.1.3 loop/with_items循环](#7.1.3 loop/with_items循环)
        • [7.1.3.1 with_items案例](#7.1.3.1 with_items案例)
        • [7.1.3.1 loop案例](#7.1.3.1 loop案例)
          • [7.1.3.1.1 单变量的情况](#7.1.3.1.1 单变量的情况)
          • [7.1.3.1.2 多变量的情况](#7.1.3.1.2 多变量的情况)
    • [7.2 剧本调试](#7.2 剧本调试)
      • [7.2.1 检查语法&单步执行](#7.2.1 检查语法&单步执行)
      • [7.2.2 tag标签](#7.2.2 tag标签)
      • [7.2.3 忽略错误](#7.2.3 忽略错误)
    • [7.3 Jinja2模板(template模块)](#7.3 Jinja2模板(template模块))
      • [7.3.1 template和copy的区别](#7.3.1 template和copy的区别)
      • [7.3.2 motd案例(同facts变量部分案例)](#7.3.2 motd案例(同facts变量部分案例))
      • [7.3.3 判断案例](#7.3.3 判断案例)
      • [7.3.4 循环案例](#7.3.4 循环案例)
    • [7.4 include 文件包含](#7.4 include 文件包含)
    • [7.5 Roles角色(重点)](#7.5 Roles角色(重点))
      • [7.5.1 Roles概述](#7.5.1 Roles概述)
      • [7.5.2 Roles 案例](#7.5.2 Roles 案例)
        • [7.5.2.1 创建目录结构](#7.5.2.1 创建目录结构)
        • [7.5.2.2 创建hosts文件](#7.5.2.2 创建hosts文件)
        • [7.5.2.3 书写任务tasks/main.yanl](#7.5.2.3 书写任务tasks/main.yanl)
        • [7.5.2.4 书写模板templates/exports.j2](#7.5.2.4 书写模板templates/exports.j2)
        • [7.5.2.5 书写变量group_vars/all/main.yaml](#7.5.2.5 书写变量group_vars/all/main.yaml)
        • [7.5.2.6 编写触发器handlers/main.yaml](#7.5.2.6 编写触发器handlers/main.yaml)
        • [7.5.2.7 编写top.yaml](#7.5.2.7 编写top.yaml)
        • [7.5.2.8 再次查看完善后的目录结构](#7.5.2.8 再次查看完善后的目录结构)
        • [7.5.2.9 测试](#7.5.2.9 测试)
        • [7.5.2.10 运行并测试](#7.5.2.10 运行并测试)
    • [7.6 Vault](#7.6 Vault)
    • [7.7 Galaxy](#7.7 Galaxy)
    • [7.8 Ansible优化](#7.8 Ansible优化)

写在前面

这是Ansible系列第五篇,内容为Ansible进阶,包含了流程控制、Roles角色、加密优化调优等。

序号连续上篇笔记 Ansible04-Ansible Vars变量详解
回顾一下Ansible架构:

7 Ansible 进阶

7.1 流程控制

7.1.1 handlers触发器与notify

  • 定义一个handlers触发点,进行检测,若检测到变化(一般是配置文件),则执行notify定义的操作。
  • 一般用于检测服务状态的变化,如重启。
  • handler实际上就是一个tasks列表,只是关注于资源的变化。
  • 格式注意:写在playbook的最后,不然handlers下所有内容都会被识别为handlers

notify中的action仅在play最后被触发。

notify中调用handlers定义的操作。

7.1.1.1 未使用handlers
shell 复制代码
# 编写playbook,未使用handlers
[root@manager playbook]# cat 11.handlers.yaml
- hosts: storage
  gather_facts: no
  tasks:
    - name: 分发配置文件
      copy:
        src: exports
        dest: /etc/exports
        backup: yes
    - name: 重启服务
      systemd:
        name: nfs-server
        state: reloaded

# 测试-第一次
[root@manager playbook]# ansible-playbook 11.handler.yaml

PLAY [storage] ********************************************************************************************

TASK [分发配置文件] ***************************************************************************************
changed: [192.168.100.150]

TASK [重启服务] *******************************************************************************************
changed: [192.168.100.150]

PLAY RECAP ************************************************************************************************
192.168.100.150            : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

# 测试-第二次
[root@manager playbook]# ansible-playbook 11.handler.yaml

PLAY [storage] ********************************************************************************************

TASK [分发配置文件] ***************************************************************************************
ok: [192.168.100.150]

TASK [重启服务] *******************************************************************************************
changed: [192.168.100.150]

PLAY RECAP ************************************************************************************************
192.168.100.150            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

以上的例子可以发现,copy模块在未检测到文件变化后,不会再发送,即不changed

而systemd模块的重启服务却是每次执行playbook都会执行一次nfs-server的重启

7.1.1.2 使用handlers
  1. 使用方法:
  • 在需要检测的模块下,并列的添加上notify
  • 在playbook的最下方添加handlers模块,其中namenotify设置的value。
yaml 复制代码
.....
      notify:
        - value
    handlers:
      - name: value
        <Module操作>
        .....
  1. 示例:
shell 复制代码
# 编写playbook
[root@manager playbook]# cat 11.handlers.yaml
- hosts: storage
  gather_facts: no
  tasks:
    - name: 分发配置文件
      copy:
        src: exports
        dest: /etc/exports
        backup: yes
      notify:
        - needrestart
  handlers:
    - name: needrestart
      systemd:
        name: nfs-server
        state: reloaded

# 测试1-配置文件没修改时
[root@manager playbook]# ansible-playbook 11.handlers.yaml

PLAY [storage] ********************************************************************************************

TASK [分发配置文件] ***************************************************************************************
ok: [192.168.100.150]

PLAY RECAP ************************************************************************************************
192.168.100.150            : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

# 测试2-文件发生变化时
[root@manager playbook]# ansible-playbook 11.handlers.yaml

PLAY [storage] ********************************************************************************************

TASK [分发配置文件] ***************************************************************************************
changed: [192.168.100.150]

RUNNING HANDLER [needrestart] *****************************************************************************
changed: [192.168.100.150]

PLAY RECAP ************************************************************************************************
192.168.100.150            : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

以上可以发现,在notify检测的模块不是changed时,不会触发handlers的内容;

若检测到changed,则执行handlers中对应notify- name匹配的模块内容。

7.1.2 when判断

  • 用于给运行的tasks设置条件
  • when进行判断,满足/不满足条件就执行相应的模块
  • 一般与变量一起用,尤其是facts变量和register变量
  • 可以使用的判断的符号:
    • ==: 等于
    • !=:不等于
    • is match:匹配
    • is not match:不匹配

ansible_hostname is match ("front|backup") 类似grep的正则

ansible_hostname is not match ("front|backup") 排除,取反

7.1.2.1 when的语法
yaml 复制代码
- hosts: xxx
  tasks:
    - name: yyy
      <Module>
      when:  # 多条件判断
        - 条件1
        - 条件2
    - name: zzz
      <Module>
      when: 条件 # 单条件判断
  • 多条件相当于and
  • 如果多条件需要orwhen: 条件1 or 条件2
7.1.2.2 when判断主机名选择模块输出
shell 复制代码
# 编写playbook
[root@manager playbook]# cat 12.when.yaml
- hosts: manager,front
  tasks:
          - name: manager call manager
            debug:
                    msg: manager
            when: ansible_hostname == "manager"
          - name: front call front
            debug:
                    msg: front
            when: ansible_hostname == "front"

# 测试
[root@manager playbook]# ansible-playbook 12.when.yaml

PLAY [manager,front] **************************************************************************************

TASK [Gathering Facts] ************************************************************************************
ok: [192.168.100.151]
ok: [192.168.100.148]

TASK [manager call manager] *******************************************************************************
ok: [192.168.100.151] => {
    "msg": "manager"
}
skipping: [192.168.100.148]

TASK [front call front] ***********************************************************************************
skipping: [192.168.100.151]
ok: [192.168.100.148] => {
    "msg": "front"
}

PLAY RECAP ************************************************************************************************
192.168.100.148            : ok=2    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
192.168.100.151            : ok=2    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
# 可以发现,只有对应主机才输出debug模块的值
7.1.2.3 when结合register变量

register变量是将shell或command模块的结果保存为变量。

shell 复制代码
- name: echo date  #执行了一个 date 命令,register 关键字将 date 命令的输出存储到 date_output 变量名
  command: date 
  register: date_output 

 - name: echo date_output   #用 when 对关键字对分析后的进行判断,如果匹配,则执行这个 task,不匹配就不执行
   command: echo "30"
   when: date_output.stdout.split(' ')[2] == "30"
  • 第 1 个 task 执行了 date 命令,register 关键字将 date 命令的输出存储到 date_output 变量名。
  • 第 2 个 task 对输出进行分析,并使用 when 对关键字对分析后的进行判断
    • 如果匹配,则执行这个 task,不匹配就不执行。
    • 因为 register 获取到的输出内容都是字符串,而 ansible 又是 python 写的,可以使用 python 字符串的方法对其做处理,比如使用的 split,还可以使用 find 方法。

7.1.3 loop/with_items循环

  • ansible内有两种循环:
    • with_*: with_items
      迭代项的引用,固定变量名为"item",使用with_item属性给定要迭代的元素。
    • loop:
      等价于with_list,遍历数组(列表)。loop中,每个元素都以列表的方式去定义;
      列表有多少个元素,就循环执行Module多少次。
      每轮循环中,都会将本次迭代的列表元素保存在控制变量 item中。
  • 用于批量创建、添加、启动、重启
7.1.3.1 with_items案例

标准循环关键字:"with_items"

对迭代项的引用,固定变量名为"item",使用with_item属性给定要迭代的元素

分发nfs配置文件并循环重启rpcbind和nfs-server服务:

shell 复制代码
# 编写playbook
[root@manager playbook]# cat 13.with_items.yaml
- hosts: storage
  gather_facts: no
  tasks:
    - name: 分发配置文件
      copy:
        src: exports
        dest: /etc/exports
        backup: yes
    - name: 重启rpcbind和nfs-server
      systemd:
        name: "{{ item }}"
        state: restarted
      with_items:
        - rpcbind
        - nfs-server

# 测试
[root@manager playbook]# ansible-playbook  13.with_items.yaml

PLAY [storage] ********************************************************************************************

TASK [分发配置文件] ***************************************************************************************
ok: [192.168.100.150]

TASK [重启rpcbind和nfs-server] ****************************************************************************
changed: [192.168.100.150] => (item=rpcbind)
changed: [192.168.100.150] => (item=nfs-server)

PLAY RECAP ************************************************************************************************
192.168.100.150            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
7.1.3.1 loop案例
7.1.3.1.1 单变量的情况

这种情况,loop和with_items相同

分发nfs配置文件并循环重启rpcbind和nfs-server服务:

shell 复制代码
[root@manager playbook]# cat 13.loop.yaml
- hosts: storage
  gather_facts: no
  tasks:
    - name: 分发配置文件
      copy:
        src: exports
        dest: /etc/exports
        backup: yes
    - name: 重启rpcbind和nfs-server
      systemd:
        name: "{{ item }}"
        state: restarted
      loop: #仅将with_items修改为了loop
        - rpcbind
        - nfs-server

# 测试
[root@manager playbook]# ansible-playbook 13.loop.yaml

PLAY [storage] ********************************************************************************************

TASK [分发配置文件] ***************************************************************************************
ok: [192.168.100.150]

TASK [重启rpcbind和nfs-server] ****************************************************************************
changed: [192.168.100.150] => (item=rpcbind)
changed: [192.168.100.150] => (item=nfs-server)

PLAY RECAP ************************************************************************************************
192.168.100.150            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
7.1.3.1.2 多变量的情况

循环新建用户和uuid

shell 复制代码
# 创建playbook
[root@manager playbook]# cat 14.loop2.yaml
- hosts: front
  gather_facts: false
  tasks:
    - name: add user
      user:
        name: "{{ item.name }}"
        uid: "{{ item.uid }}"
        shell: /bin/bash
        state: present
      loop:
        - { name: "loop1" , uid: 53101}
        - { name: "loop2" , uid: 53102}
        - { name: "loop3" , uid: 53103}


# 测试:
[root@manager playbook]# ansible-playbook 14.loop2.yaml

PLAY [front] **********************************************************************************************

TASK [add user] *******************************************************************************************
changed: [192.168.100.148] => (item={'name': 'loop1', 'uid': 53101})
changed: [192.168.100.148] => (item={'name': 'loop2', 'uid': 53102})
changed: [192.168.100.148] => (item={'name': 'loop3', 'uid': 53103})

PLAY RECAP ************************************************************************************************
192.168.100.148            : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

7.2 剧本调试

7.2.1 检查语法&单步执行

  • -C/--check 模拟运行,不作出改变,一些变量可能会提示报错,因为-C没有真正运行剧本.
  • --syntax-check 只做语法检查,不运行.
  • --step 单步运行. y执行这个task,n忽略这个task,c自动运行

7.2.2 tag标签

为tasks中的不同任务定一个tag,这样可以在执行剧本的时候-t指定执行哪个tag部分的任务

shell 复制代码
# 编写playbook
[root@manager playbook]# cat 15.tag.yaml
- hosts: storage
  gather_facts: no
  tasks:
    - name: 4. 启动服务rpcbind
      systemd:
        name: rpcbind
        enabled: yes
        state: restarted
      tags: #添加tags
        - rpcrestart
    - name: 5. 启动服务nfs
      systemd:
        name: nfs-server
        enabled: yes
        state: reloaded
      tags:  #添加tags
        - nfsreload

# 测试
[root@manager playbook]# ansible-playbook -t nfsreload 15.tag.yaml

PLAY [storage] ********************************************************************************************

TASK [5. 启动服务nfs] *************************************************************************************
changed: [192.168.100.150]

PLAY RECAP ************************************************************************************************
192.168.100.150            : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

7.2.3 忽略错误

运行剧本的时候,因为重复运行导致的错误提示,并发是真的错误.

比如:目录已经存在,用户已经存在.

在这种情况下,我们可以通过ignore_errors忽略错误,让剧本可以继续运行.

shell 复制代码
# 在需要忽略错误的模块下加
- hosts: xxx
  tasks:
    - name: yyy
    <Module>
    ignore_errors: true #yes/no也可以

7.3 Jinja2模板(template模块)

如果需要在分发文件时使用变量,就需要用到template模块。根据模板文件动态生成配置文件
templates文件必须存放在templates目录中,以.j2结尾。

若需要直接使用templates文件而不指定路径,就需要使playbook文件和templates目录同级
template模块会自动在playbook同级的templates目录中找对应的模板文件。

7.3.1 template和copy的区别

template模块传输时,会将变量解析成对应的值,类似shell脚本的双引号功能。

copy模块传输时,直接传送文件内容,类似shell脚本的单引号功能。

7.3.2 motd案例(同facts变量部分案例)

  • 批量修改系统/etc/motd文件(登陆时自动显示的文件)
    • 输出主机名
    • 内存大小
    • ip
    • 发行版本
    • cpu数量
    • 核心数量
shell 复制代码
#playbook编写
[root@manager playbook]# cat 10.change_moted.yaml
- hosts: front
  tasks:
    - name: template分发motd
      template:
        src: templates/motd.j2
        dest: /etc/motd
        backup: yes
#    - name: cp分发motd
#      copy:
#        src: templates/motd.j2
#        dest: /etc/motd
#        backup: yes

# motd.j2模板编写
[root@manager templates]# cat motd.j2
welcome to Linux-{{ ansible_hostname }}
--------------------------------------------
主机名: {{ ansible_hostname }}
ip地址: {{ ansible_default_ipv4.address }}
内存大小: {{ ansible_memtotal_mb }}
CPU数量: {{ ansible_processor_vcpus }}
核心总数: {{ ansible_processor_cores }}
发行版本: {{ ansible_distribution }}


#运行
[root@manager playbook]# ansible-playbook 10.change_moted.yaml

PLAY [front] **********************************************************************************************

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

TASK [template分发motd] ***********************************************************************************
changed: [192.168.100.148]

PLAY RECAP ************************************************************************************************
192.168.100.148            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0


# 测试
[root@manager playbook]# ssh root@front
welcome to Linux-front
--------------------------------------------
主机名: front
ip地址: 192.168.100.148
内存大小: 3640
CPU数量: 2
核心总数: 2
发行版本: CentOS

### copy模块推送的文件的测试
[root@manager playbook]# ssh root@front
welcome to Linux-{{ ansible_hostname }}
--------------------------------------------
主机名: {{ ansible_hostname }}
ip地址: {{ ansible_default_ipv4.address }}
内存大小: {{ ansible_memtotal_mb }}
CPU数量: {{ ansible_processor_vcpus }}
核心总数: {{ ansible_processor_cores }}
发行版本: {{ ansible_distribution }}

template和copy模块的区别:

copy仅仅传输数据,复制文件;

template 传输数据,复制文件的时候,文件中的变量会被解析和运行.

7.3.3 判断案例

在模板文件中,也可以用到if判断。

  • 格式:
shell 复制代码
{% if vhost.port is undefined %} # 单分支
    http_port=80
{% elif vhost.port == 81 %} # 多分支
    http_port=81
{% else %}
    http_port = 83
{% endif %}

根据主机名,生成不同的文件

shell 复制代码
# 编写模板文件
[root@manager playbook]# cat templates/template-if.j2
{% if ansible_hostname == "front" %}
        state front
{% elif ansible_hostname == "storage" %}
        state storage
{% endif %}

# 编写playbook
[root@manager playbook]# cat 16.template-if.yaml
- hosts: front,storage
  tasks:
    - name: if的template
      template:
        src: templates/template-if.j2
        dest: /tmp/template-if.conf

# 结构
templates/
└── template-if.j2
16.template-if.yaml 

# 运行
[root@manager playbook]# ansible-playbook 16.template-if.yaml

PLAY [front,storage] **************************************************************************

TASK [Gathering Facts] ************************************************************************
ok: [192.168.100.148]
ok: [192.168.100.150]

TASK [if的template] ***************************************************************************
changed: [192.168.100.150]
changed: [192.168.100.148]

PLAY RECAP ************************************************************************************
192.168.100.148            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
192.168.100.150            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

# 测试
[root@manager playbook]# ansible front -m shell -a "cat /tmp/template-if.conf"
192.168.100.148 | CHANGED | rc=0 >>
        state front

[root@manager playbook]# ansible storage -m shell -a "cat /tmp/template-if.conf"
192.168.100.150 | CHANGED | rc=0 >>
        state storage

7.3.4 循环案例

模板文件中同样有循环

  • 格式:
shell 复制代码
{% for xxx in yyy %}  #类似python
server {
listen {{ xxx.listen }} 
}
{% endfor %}

配置server.conf 到front /tmp目录

shell 复制代码
{% for ip in [1,2,3,4,5,6] %}
  10.0.0.{{ ip }}
{% endfor %}

# 也可以
{% for ip in range(2,11) %}
  10.0.0.{{ ip }}
{%endfor%}

# 总之是python的语法

7.4 include 文件包含

1个ansible剧本内容过多,涉及到多个play(- host:web),可读性变弱,不方便调试.

于是人们想出把单个大的剧本拆分为多个,小的剧本.

多个小的剧本可以通过include功能合并使用.

这时候可以通过include_tasks的功能把多个剧本文件合并在一起,让剧本变成多个方便阅读与维护.

shell 复制代码
# 小playbook
- name: xxx
  <Module>
- name: yyy
  <Module>
...

#汇总的playbook
- hosts: xxx
  tasks:
    - include_tasks: yyy.yaml

7.5 Roles角色(重点)

  • ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。
  • 是一套剧本目录结构的要求与标准,让我们书写剧本的时候,把剧本的内容和需要的文件,按照目录要求,分门别类存储.
  • roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。
  • roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷的include它们的一种机制。
  • roles的本质是规定了1套目录结构,用于书写剧本

官网链接:https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_reuse_roles.html

7.5.1 Roles概述

  • Roles目录结构:

  • 目录解释:

shell 复制代码
roles:          <--所有的角色必须放在roles目录下,这个目录可以自定义位置,默认的位置在/etc/ansible/roles
  project:      <--具体的角色项目名称,比如nginx、nfs
    files:     <--无需个性化的文件,copy或script模块可以直接调用。
    templates: <--用来存放jinjia2模板,template模块会自动在此目录中寻找jinjia2模板文件。
    tasks:     <--playbook中tasks部分。此文件可以使用include包含其它的位于此目录的task文件。必须有main.yml
      main.yml
    handlers:  <--playbook中handlers部分,当前角色中触发条件时执行的动作。必须有main.yml
      main.yml
    vars(group_vars):  <--playbook中vats部分,当前角色用到的变量。必须有main.yml。(group_vars是所有roles都可用)
      main.yml
    defaults:  <--当前角色设定默认变量。必须有main.yml
      main.yml
    meta:      <--此角色的特殊设定及其依赖关系。必须有main.yml
      main.yml
 

# roles/example_role/files/             所有文件,都将可存放在这里
# roles/example_role/templates/         所有模板都存放在这里
# roles/example_role/tasks/main.yml:   主函数,包括在其中的所有任务将被执行
# roles/example_role/handlers/main.yml:所有包括其中的 handlers 将被执行
# roles/example_role/vars/main.yml:    所有包括在其中的变量将在roles中生效
# roles/example_role/meta/main.yml:    roles所有依赖将被正常登入

7.5.2 Roles 案例

修改之前的nfs配置playbook,符合roles的要求

  • 分析:
  1. 设置roles对应的目录名。
  2. 根据原始的playbook,拆分成taskstemplatesvarshandlerstop.yaml
7.5.2.1 创建目录结构
shell 复制代码
[root@manager playbook]# mkdir roles-all
[root@manager playbook]# cd roles-all/
[root@manager roles-all]# mkdir roles01
[root@manager roles-all]# cd roles01/
[root@manager roles01]# touch top.yaml
[root@manager roles01]# touch hosts
[root@manager roles01]# mkdir -p nfs-server/{files,templates,tasks,handlers} group_vars
[root@manager roles01]# mkdir group_vars/all

[root@manager roles01]# cd ..
[root@manager roles-all]# tree -F
.
└── roles01/
    ├── group_vars/
    │   └── all/
    ├── hosts
    ├── nfs-server/
    │   ├── files/
    │   ├── handlers/
    │   ├── tasks/
    │   └── templates/
    └── top.yaml
7.5.2.2 创建hosts文件
shell 复制代码
[root@manager roles01]# cp /etc/ansible/hosts .
cp: overwrite './hosts'? y
[root@manager roles01]# cat hosts
[front]
192.168.100.148 ansible_user=root ansible_password=Huawei@123 ansible_port=22

[storage]
192.168.100.150  ansible_user=root ansible_password=Huawei@123 ansible_port=22

[backup]
192.168.100.149 ansible_user=root ansible_password=Huawei@123 ansible_port=22

[data:children]
storage
backup

[docker]
192.168.100.141 ansible_user=root ansible_password=Huawei@123 ansible_port=22

[manager]
192.168.100.151
7.5.2.3 书写任务tasks/main.yanl
shell 复制代码
[root@manager roles01]# cat nfs-server/tasks/main.yaml
- name: 1. 部署nfs-utils,rpcbind
  yum:
    name: nfs-utils,rpcbind
    state: present
  tags:
    - 01.install
- name: 2. 修改配置文件
  template:
    src: exports.j2 #不需要写路径,role根据j2自动在templates目录下寻找对应的文件
    dest: /etc/exports
    backup: yes
  notify:
    - restart_nfs-server
  tags:
    - 02.conf
- name: 3. 创建共享目录并修改所有者
  file:
    path: "{{nfs_server_dir}}"
    state: directory
    owner: "{{nfs_user}}"
    group: "{{nfs_user}}"
  tags:
    - 03.dir
- name: 4. 启动服务rpcbind
  systemd:
    name: "{{item}}"
    enabled: yes
    state: started
  loop:
    - rpcbind
  tags:
    - 04.start_srv
7.5.2.4 书写模板templates/exports.j2
shell 复制代码
cat nfs-server/templates/exports.j2
#author: {{author}}  
#/nfsupload 192.168.100.0/24(rw,all_squash)
{{ nfs_server_dir }} 192.168.100.0/24(rw,all_squash)
7.5.2.5 书写变量group_vars/all/main.yaml
shell 复制代码
[root@manager roles01]# cat group_vars/all/main.yaml
author: tassel
nfs_server_dir: /nfsupload
nfs_user: nobody
7.5.2.6 编写触发器handlers/main.yaml
shell 复制代码
[root@manager roles01]# cat nfs-server/handlers/main.yaml
- name: restart_nfs-server
  systemd:
    name: nfs-server
    enabled: yes
    state: restarted
7.5.2.7 编写top.yaml
shell 复制代码
[root@manager roles01]# cat top.yaml
- hosts: storage
  roles:
    - role: nfs-server
#- hosts: yyy
#  roles:
#    - role: zzz
7.5.2.8 再次查看完善后的目录结构
shell 复制代码
[root@manager roles01]# tree -F
.
├── group_vars/
│   └── all/
│       └── main.yaml
├── hosts
├── nfs-server/
│   ├── files/
│   ├── handlers/
│   │   └── main.yaml
│   ├── tasks/
│   │   └── main.yaml
│   └── templates/
│       └── exports.j2
└── top.yaml

7 directories, 6 files
7.5.2.9 测试
shell 复制代码
[root@manager roles01]# ansible-playbook -i hosts -C top.yaml

PLAY [storage] ********************************************************************************************

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

TASK [nfs-server : 1. 部署nfs-utils,rpcbind] *************************************************************
ok: [192.168.100.150]

TASK [nfs-server : 2. 修改配置文件] ***********************************************************************
changed: [192.168.100.150]

TASK [nfs-server : 3. 创建共享目录并修改所有者] ***********************************************************
ok: [192.168.100.150]

TASK [nfs-server : 4. 启动服务rpcbind] ********************************************************************
ok: [192.168.100.150] => (item=rpcbind)

RUNNING HANDLER [nfs-server : restart_nfs-server] *********************************************************
changed: [192.168.100.150]

PLAY RECAP ************************************************************************************************
192.168.100.150            : ok=6    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
7.5.2.10 运行并测试
shell 复制代码
[root@manager roles01]# ansible-playbook -i hosts  top.yaml

PLAY [storage] ********************************************************************************************

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

TASK [nfs-server : 1. 部署nfs-utils,rpcbind] *************************************************************
ok: [192.168.100.150]

TASK [nfs-server : 2. 修改配置文件] ***********************************************************************
changed: [192.168.100.150]

TASK [nfs-server : 3. 创建共享目录并修改所有者] ***********************************************************
ok: [192.168.100.150]

TASK [nfs-server : 4. 启动服务rpcbind] ********************************************************************
ok: [192.168.100.150] => (item=rpcbind)

RUNNING HANDLER [nfs-server : restart_nfs-server] *********************************************************
changed: [192.168.100.150]

PLAY RECAP ************************************************************************************************
192.168.100.150            : ok=6    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

################

[root@manager roles01]# ansible storage -m shell -a "cat /etc/exports"
192.168.100.150 | CHANGED | rc=0 >>
#author: tassel
#/nfsupload 192.168.100.0/24(rw,all_squash)
/nfsupload 192.168.100.0/24(rw,all_squash)

[root@manager roles01]# ansible storage -m shell -a "showmount -e"
192.168.100.150 | CHANGED | rc=0 >>
Export list for storage:
/nfsupload 192.168.100.0/24

7.6 Vault

ansible-vault用于加密敏感信息

  • hosts文件
  • 变量文件
shell 复制代码
#进行加密
ansible-vault encrypt <文件>
###
[root@manager roles01]# ansible-vault encrypt hosts.cyp
New Vault password:
Confirm New Vault password:
Encryption successful
[root@manager roles01]# cat hosts.cyp
$ANSIBLE_VAULT;1.1;AES256
62623831396464393263383030343163336535383830643337313339356661366537383035643933
6135666137613233636438343364336632346564646362650a336331383263613836363537663666
61656634383233653462393138633566633363383334636231353737366131663361353762303565
3666636530616338660a353034666463666139643136323263353835393863613062666165336263
32356538633930326266393938613864333033636635333761663538383035313337656537376465
32396533353766396633343566396463613264643534393764303733633833616362643737386262
63376233363630623230343339313637356432333535363132303236383831623736306461656164
66376139633365323931353665346136643939353233663733373530336536633537333238666430
36336138393335393834663232313030346661353161333262356432323631643336303964363339
37613662326339326532376665626462386566616463643632663930393837393031633334393939
38363538396435303834616436303736333032623036303536313737666263313331623766343134
36383730663366363465313833373930623865643932306235346436663331663966373432373566
37633935656432353462633438356232376535663231626662376466333836383932343234336261
65303835663437396662306238616435396535653734333234646562333361333337343633393533
33383965643465386162306135363630326566643637643037666635303963623639656164663061
66373938366463336632356134316265383234663130333162343636353933383933306132633436
38666438633763656231316532333065343366303230326136333836303136303965363833343234
63333865643864363439313462313262326566643139346635346663386163613663386631386263
34613630313935373233633466353430616564376334303636356435393230376561663162626234
64383138666531303932623434323936613939613636346130646135306531326161633161633865
33653439306637343362376364653433363962303838366165306264313439613535316330376263
33353864656539356235353331633762626565356366636133326530343636656464396637633337
32653030326631373731346230633064306333623732623934306230383231383361393236353362
65363434613937616539386664326635333862393666316666633036396132613566653264633162
6135

#进行使用
ansible或ansible-playbook   --ask-vault-pass <正常即可>
###
[root@manager roles01]# ansible --ask-vault-pass -i hosts.cyp  storage -m ping
Vault password:
192.168.100.150 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}


#彻底解密
ansible-vault decrypt <文件名>
###
[root@manager roles01]# ansible-vault decrypt hosts.cyp
Vault password:
Decryption successful

7.7 Galaxy

实际上就是别人写好的roles

网址:galaxy.ansible.com

shell 复制代码
[root@manager roles-all]# ansible-galaxy collection install nginxinc.nginx_core
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Downloading https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/nginxinc-nginx_core-0.8.0.tar.gz to /root/.ansible/tmp/ansible-local-276848dtjz1k/tmpt7vv8eud/nginxinc-nginx_core-0.8.0-ipinsxaa
Installing 'nginxinc.nginx_core:0.8.0' to '/root/.ansible/collections/ansible_collections/nginxinc/nginx_core'
nginxinc.nginx_core:0.8.0 was installed successfully
'ansible.posix:1.5.4' is already installed, skipping.
'community.crypto:2.15.0' is already installed, skipping.
'community.general:7.3.0' is already installed, skipping.

[root@manager roles-all]# cp -r /root/.ansible/collections/ansible_collections/nginxinc/* .
[root@manager roles-all]# ls
nginx_core  roles01
[root@manager roles-all]# tree -F nginx_core/
...

7.8 Ansible优化

  • 性能 :

    • ssh连接速度优化,关闭UseDNS,GSSAPIAuthcation ...
    • 不要让ansible运行交互式的命令,非要用使用命令的非交互模式.
    • 需要使用ans,yum安装软件,可以自建本地yum仓库,然后ans安装.(自建yum源,自己制作 - 的rpm包)
    • 调整ansible并发数量( -f 调整并发数量 默认是5 ansible.cfg forks=5 ,实际调整 - 根据负载情况.)
    • 给ansible配置缓存(redis),队列.缓存facts.
    • 给主机进行分组操作与管理.
    • 关闭gather_facts,如果不用facts变量可以关闭, 剧本中: gather_facts: false 配置文件: gathering = explicit
    • 关闭host,key,check 一般使用密码认证的时候需要关闭,如果不关闭 ansible配置文件 host_key_checking = False
  • 安全 :

    • 配置sudo用户ans ALL=(ALL) NOPASSWD: ALL密码是1,ssh端口是 22
    • 配合堡垒机一起使用
    • 用户--->堡垒机---->ansible
    • 用户的密码,进行加密( hash, ansible-vault)
  • sudo配置:

shell 复制代码
# Ansible-Client
## 修改配置文件
[root@manager roles-all]# visudo 
[root@manager roles-all]# tail -1 /etc/sudoers
ans ALL=(ALL) NOPASSWD: ALL
## 创建用户
[root@manager roles-all]# useradd ans
[root@manager roles-all]# passwd ans

# Ansible-Server
## /etc/ansible/ansible.cfg
[defaults]
sudo_user = ans
sudo_user      = ans  #被管理端上具有sudo权限的用户nopasswd: ALL
remote_user    = ans  #被管理端使用的用户,不指定默认是当前用户/root
remote_port    = 22   #被管理端ssh端口号
host_key_checking = False
host_key_checking = False
log_path = /var/log/ansible.log
[privilege_escalation]
become=True           #开启sudo功能
become_method=sudo    #使用sudo命令
become_user=root      #普通用户切换为root
相关推荐
摸鱼也很难18 分钟前
Docker 镜像加速和配置的分享 && 云服务器搭建beef-xss
运维·docker·容器
watermelonoops20 分钟前
Deepin和Windows传文件(Xftp,WinSCP)
linux·ssh·deepin·winscp·xftp
woshilys1 小时前
sql server 查询对象的修改时间
运维·数据库·sqlserver
疯狂飙车的蜗牛1 小时前
从零玩转CanMV-K230(4)-小核Linux驱动开发参考
linux·运维·驱动开发
恩爸编程2 小时前
探索 Nginx:Web 世界的幕后英雄
运维·nginx·nginx反向代理·nginx是什么·nginx静态资源服务器·nginx服务器·nginx解决哪些问题
Michaelwubo3 小时前
Docker dockerfile镜像编码 centos7
运维·docker·容器
远游客07133 小时前
centos stream 8下载安装遇到的坑
linux·服务器·centos
马甲是掉不了一点的<.<3 小时前
本地电脑使用命令行上传文件至远程服务器
linux·scp·cmd·远程文件上传
jingyu飞鸟4 小时前
centos-stream9系统安装docker
linux·docker·centos
好像是个likun4 小时前
使用docker拉取镜像很慢或者总是超时的问题
运维·docker·容器