• Ansible 自动化运维工具 --- playbook 剧本


    1. Host inventory ---- 主机清单

    在这里插入图片描述

    1.1 简介

    ansible定义了管理主机的策略。

    一般小型环境下我们只需要在host文件中写入主机的ip地址即可。
    但是当中大型环境下,我们可能需要使用静态inventory或者动态主机清单来生成我们需要执行的目标主机。

    1.2 inventory文件

    默认路径为/etc/ansible/hosts

    Ansible Inventory 文件是一个纯文本文件,用于定义 Ansible 执行命令的目标主机和组,以及这些主机和组的变量和属性

    1.3 Inventory 文件的构成

    1.3.1 主机与组

    • 主机:一个主机就是目标机器,可以是 IP 地址、域名或在 SSH 配置中定义的别名,也可以使用 ansible_host 指定。

    • :可以将多个主机划分到同一个组中,并可以对组进行操作。

    在这里插入图片描述
    注:组名不能包含空格,并且主机和组名必须放在方括号中。

    1.3.2 变量

    • 主机变量
      为单个主机指定变量,使用主机名或 IP 地址作为标识符,变量可以设置为一个或多个值。
    #示例
    [ServerA]
    192.168.x.xx http_port=80 https_port=443
    
    [ServerB]
    serverb.example.com ansible_user=admin ansible_password=1234
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 组变量
      在组名之后,使用 vars 关键字设置变量,可以在组间共享变量
    #示例
    #所有主机指定 `ansible_ssh_user` 变量,这意味着每个主机都具有该变量。
    #为每个主机定义唯一的 `name` 变量。
    [WebServer]
    192.168.1.10 name=webserver1
    192.168.1.11 name=webserver2
    192.168.1.12 name=webserver3
    
    [DatabaseServer]
    192.168.1.20 name=dbserver1
    192.168.1.21 name=dbserver2
    
    [all:vars]
    ansible_ssh_user=centos
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 组的嵌套
      将一个组嵌套到另一个组中,在 Inventory 文件中使用 :children 关键字
    #示例
    #将 `WebServer` 和 `DatabaseServer` 组嵌套到 `Production` 组中。
    [WebServer]
    192.168.1.10
    192.168.1.11
    192.168.1.12
    
    [DatabaseServer]
    192.168.1.20
    
    [Production:children]
    WebServer
    DatabaseServer
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 别名
      使用 Alias(别名)来引用 Inventory 中的主机。
    #为 `WebServer` 和 `DatabaseServer` 组定义别名,并将它们作为两个分离的组 `Web` 和 `Db` 的成员
    #创建了一个名为 `Production` 的组,该组由这两个组的别名组成。
    [WebServer]
    192.168.1.10
    192.168.1.11
    192.168.1.12
    
    [DatabaseServer]
    192.168.1.20
    
    [Web:children]
    WebServer
    
    [Db:children]
    DatabaseServer
    
    [Production]
    @Web
    @Db
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    1.4 inventory 中的常用变量

    hosts 文件为主机或组定义变量,在 playbook中可以直接调用变量

    变量名含义
    ansible_hostansible连接节点时的IP地址
    ansible_port连接对方的端口号,ssh连接时默认为22
    ansible_user连接对方主机时使用的用户名。不指定时,将使用执行ansible或ansible-playbook命令的用户
    ansible_password连接时的用户的ssh密码,仅在未使用密钥对验证的情况下有效
    ansible_ssh_private_key_file指定密钥认证ssh连接时的私钥文件
    ansible_ssh_common_args提供给ssh、sftp、scp命令的额外参数
    ansible_become允许进行权限提升
    ansible_become_method指定提升权限的方式,例如可使用sudo/su/runas等方式
    ansible_become_user提升为哪个用户的权限,默认提升为root
    ansible_become_password提升为指定用户权限时的密码

    2. Ansible-playbook剧本

    在这里插入图片描述

    2.1 简介

    playbook 是由一个或多个play组成的列表

    play的主要功能在于将直线归并为一组的主机装扮实现通过ansible中的task定义好的角色
    从根本来讲,所谓的task无非是调用ansible的一个module

    将多个play组织在一个playbook内,即可以让它们联动起来按实现编排的机制唱一台大戏

    playbook采用YAML语言编写

    2.2 Playbook的结构组成

    1. Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行
    2. Variables:变量
    3. Templates:模板
    4. Handlers:处理器,当changed状态条件满足时,(notify)触发执行的操作
    5. Roles:角色

    2.3 编写playbook的基本格式与写法

    2.3.1 基本格式

    xxx.yaml/xxx.yml
    --- #表示开始
    - name:  #指定play的名称
      hosts: #指定主机清单中定义的主机组名
      remote_user: #指定远程主机的执行用户
      grather_facts: ture|fales #指定是否要收集远程主机的facts信息
      vars:   #自定义变量,只能在当前play有效
        - 变量1: 值1  #格式为key: value
        - 变量2: 值2
      tasks: #定义任务列表,默认从上往下依次执行
        - name: #定义任务的名称
          模块名: 模块参数        
          ignore errors: true  #忽略任务的失败
        - name: #可以定义多个任务
          模块名: 模块参数  
          notify: 任务名  #如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作
          ##条件判断##
         - name:
           模块名: 模块参数
           when: #定义条件表达式(== != > < >= <=),条件成立时执行此task任务,否则不执行任务
           ##循环##
         - name:
           模块名: 模块参数={{item}}
           with_items: #定义循环列表
         ##tags模块,标签## 
         - name: 
           模块名: 模块参数 
           tags:
           - 标签1
           - 标签2
            
      handlers: 
        - name: 任务名  #和notify中的任务名相同
          模块名: 模块参数
    
    #无注释版
    ---
    - name: 
      hosts: 
      remote_user:
      grather_facts: ture|fales 
      vars:
        - 变量1: 值1
        - 变量2: 值2
      tasks:
        - name:
          模块名: 模块参数        
          ignore errors: true
        - name:
          模块名:
          notify: 任务名
         - name:
           模块名:
           when:
         - name:
           模块名: 模块参数={{item}}
           with_items:
      handlers: 
        - name: 任务名
          模块名: 模块参数
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    Ansible在执行完某个任务之后并不会立即去执行对应的handler,而是在当前play中所有普通任务都执行完后再去执行handler。

    这样的好处是可以多次触发notify,但最后只执行一次对应的handler,从而避免多次重启

    2.3.2 语句的横向/纵向写法

    • 横向写法一般是数组类型

    • 纵向写法一般是

    task任务的模块语法格式
    横向格式:
    模块名: 参数1=值 参数2={{变量名}} ...
    
    纵向格式:
    模块名:
      参数1: 值
      参数2: "{{变量名}}"
      ...
      
    with_items 和 vars 的语法格式
    横向格式:
    with_items: ["值1", "值2", "值3", ...]
    
    值为对象(键值对字段)时:
    with_items:
    - {key1: "值1", key2: "值2"}
    - {key1: "值3", key2: "值4"}
    ...
    
    纵向格式:
    with_items:
    - 值1
    - 值2
    - 值3
    ...
    
    值为对象(键值对字段)时:
    with_items:
    - key1: "值1"
      key2: "值2"
    - key1: "值3"
      key2: "值4"
    ...
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    3. Playbook剧本编写实例

    3.1 编写yum安装nginx的playbook

    3.1.1 更新主机清单

    vim /etc/ansible/hosts
    
    • 1

    在这里插入图片描述

    3.1.2 编写剧本

    /etc/ansible
    
    • 1
    #编写yaml文件,安装nginx的剧本
    vim test.yaml
    
    ---
     - name: first play
       hosts: webservers  #指定执行脚本的目标
       remote_user: root
       gather_facts: false
       tasks:
         - name: firewalld
           service: name=firewalld state=stopped enabled=no
         - name: selinux
           command: '/usr/sbin/setenforce 0 '
           ignore_errors: true
         - name: mount
           mount: src=/dev/sr0 path=/mnt state=mounted fstype=iso9660
         - name: nginx.repo file
           copy: src=/etc/yum.repos.d/nginx.repo dest=/etc/yum.repos.d/nginx.repo  #需要提前准备好源
         - name: epel.repo
           copy: src=/etc/yum.repos.d/epel.repo dest=/etc/yum.repos.d/
         - name: nginx install
           yum: name=nginx state=latest
         - name: configuration file
           copy: src=/opt/nginx.conf dest=/etc/nginx/nginx.conf            #需要提前准备好配置文件
           notify: "reload nginx"
         - name: start nginx
           service: name=nginx state=started enabled=yes
       handlers:
         - name: reload nginx
           service: name=nginx state=reloaded
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    在这里插入图片描述

    3.1.3 运行剧本

    ansible-playbook test.yaml
    
    • 1

    在这里插入图片描述

    3.1.4 查看web服务器组的主机

    systemctl status firewalld
    getenforce
    
    systemctl status nginx
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    3.2 基本格式与常用参数

    #执行playbook
    ansible-playbook xx.yaml/yml [参数]
    
    • 1
    • 2
    常用参数描述使用场景
    –syntax-check检查yaml文件的语法是否正确
    –list-task检查tasks任务
    –list-hosts检查生效的主机
    –start-at-task=’ name ’指定从某个task开始运行一般用于剧本较长且不想从头重复执行的场景
    -k用来交互输入ssh密码-ask-pass
    -K用来交互输入sudo密码-ask-become-pass
    -u指定用户

    3.2.1 示例

    #检查yaml文件的语法是否正确
    ansible-playbook test.yaml --syntax-check    
    
    • 1
    • 2

    在这里插入图片描述

    #检查tasks任务
    ansible-playbook test.yaml --list-task      
    
    • 1
    • 2

    在这里插入图片描述

    #检查生效的主机
    ansible-playbook test.yaml --list-hosts      
    
    • 1
    • 2

    在这里插入图片描述

    #指定从 nginx install 开始运行
    ansible-playbook test.yaml --start-at-task='nginx install'
    
    • 1
    • 2

    在这里插入图片描述

    3.3 变量的定义和引用

      vars:   #自定义变量,只能在当前play有效
        - 变量1: 值1  #格式为key: value
        - 变量2: 值2
      tasks:  #在任务列表中引用变量
        -name:
         module: {{变量1}}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.3.1 方式一 ---- 在yaml文件中定义和引用

    vim test2.yml
    
    ---
     - name: second play
       hosts: webservers
       remote_user: root
       gather_facts: true
       vars: 
         - groupname: mysql 
         - username: nginx
       tasks:
         - name: create group
           group: name={{groupname}} system=yes gid=306    #使用 {{key}} 引用变量的值
         - name: create user
           user: name={{username}} uid=306 group={{groupname}} 
         - name: copy file
           copy: content="{{ansible_default_ipv4.network}}" dest=/opt/vars.txt    #在setup模块中可以获取facts变量信息
           
    #ansible_default_ipv4为facts变量信息中的字段
    #ansible_default_ipv4.network中的 .network表示只提取信息中network部分
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    ansible-play test2.yml
    
    • 1

    在这里插入图片描述

    3.3.2 方式二 ---- 在命令行定义

    ansible-playbook test1.yml -e "username=nginx"
    #通过 -e 参数传递一个额外的变量 "username=nginx" 给 playbook
    #playbook 将会使用变量 "username" 的值设置为 "nginx"
    
    • 1
    • 2
    • 3

    3.4 指定远程主机sudo切换用户

    使用-k-K参数实现。

    3.4.1 编写剧本

    vim test3.yml
    
    ---
    - hosts: webservers
      remote_user: test           
      become: yes	                 #2.6版本以后的参数,之前是sudo,意思为切换用户运行
      become_user: root              #指定sudo用户为root
      tasks: 
        - name: ts
          command: ls ./
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.4.2 执行剧本

    #执行playbook,加上参数-k和-K
    ansible-playbook test3.yml -k -K 
    
    • 1
    • 2

    3.5 when条件判断

    3.5.1 使用方式

    在Ansible中,提供的唯一一个通用的条件判断是when指令

    当when指令的值为true时,则该任务执行,否则不执行该任务。

    When指令一个比较常见的应用场景是实现跳过某个主机不执行任务 或者 只有满足条件的主机执行任务。

    3.5.2 编写剧本,使用条件判断语句

    vim test4.yaml
    ---
    - name: secend play
      hosts: all
      remote_user: root
      vars:
       - dirname: /var/www/html
      tasks:
       - name: create dir
         file: path={{dirname}} state=directory
         when: ansible_default_ipv4.address == "192.168.67.101"
    
      #when指令中的变量名不需要手动加上 {{}}
    或 
         when: inventory_hostname == "<主机名>"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3.5.3 执行剧本

    ansible-playbook test4.yaml
    
    • 1

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    3.6 迭代 ---- 循环结构

    Ansible提供了很多种循环结构,一般都命名为with_items,作用等同于 loop 循环

    #循环创建文件
    vim test5.yaml
    
    ---
    - name: diedai play
      hosts: dbservers
      remote_user: root
      tasks:
      - name: create file
        file: path={{item}} state=touch
        with_items: ["/opt/a", "/opt/b", "/opt/c", "/opt/d"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    ansible-playbook test5.yml
    
    • 1

    在这里插入图片描述
    在这里插入图片描述

    #循环创建目录与文件
    vim test6.yml
    
    ---
    - name: diedai play
      hosts: webservers
      remote_user: root
      vars:
      - myfiles: ["/opt/a", "/opt/b", "/opt/c", "/opt/d"]
      - mydirs:
        - /opt/aaa
        - /opt/bbb
        - /opt/ccc
        - /opt/ddd
    
      tasks:
      - name: create file
        file: path={{item}} state=touch
        with_items: "{{myfiles}}"
    
      - name: create dir
        file: path={{item}} state=directory
        with_items: "{{mydirs}}"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    ansible-playbook test6.yml
    
    • 1

    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    vue init webpack xxx报错timeout
    Web前端大作业:基于bootstrap响应式页面,家具装修公司网站
    ChatGPT的工作原理是什么?
    LVS-DR集群部署
    防止鱼叉式网络钓鱼的4个步骤
    MFC编辑框控件属性和用法
    【vue3】10.跟着官网学习vue3-表单输入绑定,双向绑定,封装input组件,封装ant-design-vue的input组件
    MapReduce概述及工作流程
    【hadoop3.x】一 搭建集群调优
    【Python-Pandas】删除未命名列Unnamed
  • 原文地址:https://blog.csdn.net/m0_74170357/article/details/134230599