• 18.自动运维工具ansible


    1 Ansible 介绍和架构

    1.1 Ansible介绍

    ansible 的名称来自科幻小说《安德的游戏》中跨越时空的即时通信工具,使用它可以在相距数光年的 距离,远程实时控制前线的舰队战斗。在计算机中ansible则作为一个运维工具,可以实现批量管理主机、使用模块化方式自动安装复杂软件如K8s等功能。与ansible类似还有以下工具:

    • Saltstack:python,一般需部署agent,执行效率更高
    • Puppet:ruby, 功能强大,配置复杂,重型,适合大型环境
    • Fabric:python,agentless
    • Chef:ruby,国内应用少
    • Cfengine
    • func

    ansible工作方式

    在实现主机间基于key验证之后,ansible执行playbook时会自动连接至被管理主机,并将ansible模块推送到被管理主机上,之后ansible会在被管理主机上执行这些模块,并在执行完毕之后移除这些模块。

    官方文档:https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html

    1.2 Ansible 特性

    • 模块化:调用特定的模块完成特定任务,支持自定义模块,可使用任何编程语言写模块
    • Paramiko(python对ssh的实现),PyYAML,Jinja2(模板语言)三个关键模块
    • 基于Python语言实现
    • 部署简单,基于python和SSH(默认已安装),agentless,无需代理不依赖PKI(无需ssl)
    • 安全,基于OpenSSH
    • 幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
    • 支持playbook编排任务,YAML格式,编排任务,支持丰富的数据结构
    • 较强大的多层解决方案 role

    1.3 Ansible相关概念介绍

    控制节点(Control node)

    安装了Ansible的主机,调用命令来管理需要被管理的主机。控制节点不能安装在Windows上

    被管理节点(Managed nodes)

    使用Ansible来管理的设备,被管理节点无需安装Ansible

    清单(Inventory)

    被管理节点的列表

    模块(Modules)

    用于实现Ansible功能,类似于命令行中的各种命令,如ls等

    任务(TASK)

    用于PLAYBOOK中,指定要执行的模块

    剧本(PLAYBOOK)

    包含了多个顺序执行的TASK,还可以在其中定义变量等

    2 Ansible 安装和入门

    2.1 Ansible安装

    ansible的安装方法有多种

    2.1.1 EPEL源的安装方式

    #推荐使用该方式安装
    [root@ansible ~]#yum install ansible
    

    2.1.2 pip安装

    #pip默认安装最新版本
    yum install python-pip python-devel
    yum install gcc glibc-devel zibl-devel rpm-bulid openssl-devel
    /usr/bin/python -m pip install --upgrade pip
    pip install ansible --upgrade
    

    2.1.3 git安装

    git clone git://github.com/ansible/ansible.git --recursive
    cd ./ansible
    source ./hacking/env-setup
    

    还有很多其他安装方式,详细可以参考官方文档:https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html

    2.1.4 确认ansible版本

    [root@server1 ~]# ansible --version
    ansible 2.9.21
      config file = /etc/ansible/ansible.cfg
      configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
      ansible python module location = /usr/lib/python2.7/site-packages/ansible
      executable location = /usr/bin/ansible
      python version = 2.7.5 (default, Nov 16 2020, 22:23:17) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
    

    2.1.5 windows主机配置

    参考文档:https://docs.ansible.com/ansible/latest/user_guide/windows_setup.html

    管理节点
    #安装pywinrm用于连接被管理主机
    [root@centos8 Python-3.8.11]# pip3.6 install -i https://pypi.tuna.tsinghua.edu.cn/simple pywinrm
    #配置主机列表
    [root@centos8 Python-3.8.11]# cat /etc/ansible/hosts 
    [windows]
    172.16.60.90
    [windows:vars]
    ansible_user="administratorHsykt"
    ansible_password="Hlhthsykt@60.90"
    ansible_connection="winrm"
    ansible_winrm_transport="basic"
    ansible_port=5985
    ansible_winrm_scheme=http
    ansible_winrm_server_cert_validation=ignore
    
    被管理节点
    Windows机器上的powershell版本5.0,Framework4.0
    #查看winrm服务状态
    winrm enumerate winrm/config/listener
    #配置winrm服务
    winrm quickconfig
    winrm set winrm/config/service/auth '@{Basic="true"}'
    winrm set winrm/config/service '@{AllowUnencrypted="true"}'
    
    注意事项
    1.powershell和Framework版本要满足官方要求
    2.管理节点要安装pywinrm
    

    2.2 Ansible主要文件

    2.2.1 配置文件

    Ansible 的配置文件 /etc/ansible/ansible.cfg

    [defaults]
    #inventory     = /etc/ansible/hosts # 主机列表配置文件
    #library = /usr/share/my_modules/ # 库文件存放目录
    #remote_tmp = $HOME/.ansible/tmp #临时py命令文件存放在远程主机目录
    #local_tmp     = $HOME/.ansible/tmp # 本机的临时命令执行目录
    #forks         = 5   # 默认并发数
    #sudo_user     = root # 默认sudo 用户
    #ask_sudo_pass = True #每次执行ansible命令是否询问ssh密码
    #ask_pass     = True  
    #remote_port   = 22
    #host_key_checking = False # 检查对应服务器的host_key,建议取消注释
    #log_path=/var/log/ansible.log #日志文件,建议启用
    #module_name = command   #默认模块,可以修改为shell模块
    

    2.2.2 Inventory设备清单文件

    默认的inventory file为 /etc/ansible/hosts,主要用于指定要执行Ansible模块的主机

    范例:

    #如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明
    [webservers]
    www1.123.com:2222
    www2.321.com
    
    [websrvs]
    www[1:100].example.com
    
    [appsrvs]
    10.0.0.[1:100]
    

    2.2.3 roles

    默认位于/etc/ansible/roles/ ,主要用来存放角色

    [root@server1 ~]# ll /etc/ansible/roles/ -d
    drwxr-xr-x 2 root root 6 5月   5 04:39 /etc/ansible/roles/
    

    2.3 Ansible的常用工具

    • /usr/bin/ansible 主程序,临时命令执行工具

    • /usr/bin/ansible-doc 查看配置文档,模块功能查看工具,相当于man

    • /usr/bin/ansible-playbook 定制自动化任务,编排剧本工具,相当于脚本

    • /usr/bin/ansible-pull 远程执行命令的工具

    • /usr/bin/ansible-vault 文件加密工具

    • /usr/bin/ansible-console 基于Console界面与用户交互的执行工具

    • /usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台

    利用ansible实现管理的主要方式:

    • Ad-Hoc 即利用ansible命令,主要用于临时命令使用场景
    • Ansible-playbook 主要用于长期规划好的,大型项目的场景,需要有前期的规划过程

    2.3.1 ansible-doc

    显示模块的帮助信息

    格式:

    ansible-doc [options] [module...]
    -l, --list       #列出可用模块
    -s, --snippet #显示指定模块的playbook片段
    

    2.3.2 ansible

    针对设置的主机执行单个任务playbook

    格式:

    ansible <host-pattern> [-m module_name] [-a "<module options>"]
    

    选项:

    • --version #显示版本
    • -m module #指定模块,默认为command
    • -v #详细过程 –vv -vvv更详细
    • --list-hosts #显示主机列表,可简写 --list
    • -k, --ask-pass #提示输入ssh连接密码,默认Key验证
    • -C, --check #检查,并不执行
    • -T, --timeout=TIMEOUT #执行命令的超时时间,默认10s
    • -u, --user=REMOTE_USER #执行远程执行的用户
    • -b, --become #代替旧版的sudo 切换
    • --become-user=USERNAME #指定sudo的runas用户,默认为root
    • -K, --ask-become-pass #提示输入sudo时的口令

    pattern的用法

    表格中列出了常用的pattern

    Description Pattern(s) Targets
    All hosts all (or *)
    One host host1
    Multiple hosts host1:host2 (or host1,host2)
    One group webservers
    Multiple groups webservers:dbservers all hosts in webservers plus all hosts in dbservers
    Excluding groups webservers:!atlanta all hosts in webservers except those in atlanta
    Intersection of groups webservers:&staging any hosts in webservers that are also in staging

    同时还支持通配符和正则表达式

    #通配符
    ansible "*" -m ping
    ansible 192.168.1.* -m ping
    ansible "srvs" -m ping
    
    #正则表达式
    ansible "websrvs:dbsrvs" –m ping
    ansible "~(web|db).*.magedu.com" –m ping
    

    这里值得说明的是执行完成后会有不同颜色的返回结果,下面简单进行一个说明

    • 绿色:执行成功并且不需要做改变的操作
    • 黄色:执行成功并且对目标主机做变更
    • 红色:执行失败

    在配置文件中可以进行自定义

    [root@server1 ~]# grep -A 14 '[colors]' /etc/ansible/ansible.cfg
    [colors]
    #highlight = white
    #verbose = blue
    #warn = bright purple
    #error = red
    #debug = dark gray
    #deprecate = purple
    #skip = cyan
    #unreachable = red
    #ok = green
    #changed = yellow
    #diff_add = green
    #diff_remove = red
    #diff_lines = cyan
    

    2.4 Ansible常用模块

    Ansible虽然模块众多,但最常用的模块也就2,30个而已,针对特定业务只用10几个模块。

    官方文档:https://docs.ansible.com/ansible/latest/collections/index.html

    2.4.1 Command 模块

    功能:在远程主机执行命令,此为默认模块,所以可忽略-m选项

    注意:variables like $HOSTNAME and operations like "*", "<", ">", "|", ";" and "&" will not work,所以一般会使用shell模块来代替Command 模块

    范例:

    [root@server1 ~]# ansible lvyou -a 'ls /data'
    172.16.60.218 | CHANGED | rc=0 >>
    123.txt
    

    2.4.2 shell 模块

    功能:和command相似,用shell执行命令(推荐)

    范例:

    [root@centos8 .ssh]# ansible innet -m shell -a 'ls /root'
    172.16.222.101 | CHANGED | rc=0 >>
    anaconda-ks.cfg
    172.16.111.100 | CHANGED | rc=0 >>
    anaconda-ks.cfg
    
    [root@centos8 .ssh]# ansible innet -m shell -a 'echo $HOSTNAME'
    172.16.222.101 | CHANGED | rc=0 >>
    centos8
    172.16.111.100 | CHANGED | rc=0 >>
    centos8.1
    

    将shell设置为默认模块

    [root@ansible ~]#vim /etc/ansible/ansible.cfg
    #修改下面一行
    module_name = shell
    

    2.4.3 Script 模块

    功能:在远程主机上运行ansible服务器上的脚本(无需执行权限)

    范例:

    ansible inint -m script -a /data/test.sh
    

    2.4.4 Copy 模块

    功能:从ansible服务器主控端复制文件到远程主机

    范例:

    #如目标存在,默认覆盖,此处指定先备份,注意文件内容不一致时才会产生备份文件
    [root@centos8 .ssh]# ansible innet -m copy -a "src=/root/123.txt dest=/data backup=yes"
    
    #将指定内容,直接生成目标文件
    [root@centos8 .ssh]# ansible innet -m copy -a "content='123
    ab' dest=/data/test.txt"
    
    #复制/etc目录自身,注意/etc/后面没有/,此时会将/etc整个目录拷贝过去,dest目录如果没有会自动创建
    [root@centos8 .ssh]# ansible innet -m copy -a "src=/etc dest=/backup"
    

    2.4.5 File模块

    功能:创建文件指定文件属性

    范例:

    #创建空文件
    [root@centos8 .ssh]# ansible innet -m file  -a 'path=/data/test1.txt state=touch'
    
    #删除文件
    [root@centos8 .ssh]# ansible innet -m file  -a 'path=/data/test1.txt state=absent'
    
    #创建目录
    ansible all -m file -a "path=/data/mysql state=directory owner=mysql group=mysql"
    
    #创建软链接
    ansible all -m file -a 'src=/data/testfile dest=/data/testfile-link state=link'
    

    2.4.6 unarchive 模块

    功能:解包解压缩

    常见参数:

    • copy:默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上,如果设置为 copy=no,会在远程主机上寻找src源文件
    • remote_src:和copy功能一样且互斥,yes表示在远程主机,不在ansible主机,no表示文件在 ansible主机上
    • src:源路径,可以是ansible主机上的路径,也可以是远程主机(被管理端或者第三方主机)上的路 径,如果是远程主机上的路径,则需要设置copy=no
    • dest:远程主机上的目标路径
    • mode:设置解压缩后的文件权限

    范例:

    ansible all -m unarchive -a 'src=/data/foo.tgz dest=/var/lib/foo'
    ansible all -m unarchive -a 'src=https://example.com/example.zip dest=/data copy=no'
    

    2.4.7 Archive 模块

    功能:管理主机名

    范例:

    ansible websrvs -m archive  -a 'path=/var/log/ dest=/data/log.tar.bz2 format=bz2'
    

    2.4.8 Cron 模块

    功能:实现计划任务

    范例:

    #创建计划任务
    ansible 10.0.0.8 -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql"
    job=/root/mysql_backup.sh'
    
    #禁用计划任务
    ansible websrvs   -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.20.0.1
    &>/dev/null' name=Synctime disabled=yes"
    
    #启用计划任务
    ansible websrvs   -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.20.0.1
    &>/dev/null' name=Synctime disabled=no"
    
    #删除计划任务
    ansible websrvs -m cron -a "name='backup mysql' state=absent"
    ansible websrvs -m cron -a 'state=absent name=Synctime'
    

    2.4.9 Yum 模块

    功能:管理软件包,只支持RHEL,CentOS,fedora,不支持Ubuntu其它版本

    范例:

    ansible innet -m yum -a 'name=httpd state=present'  #安装
    ansible innet -m yum -a 'name=httpd state=absent'   #删除
    

    2.4.10 Setup 模块

    功能: setup 模块来收集主机的系统信息,这些 facts 信息可以直接以变量的形式使用,但是如果主机 较多,会影响执行速度,可以使用 gather_facts: no 来禁止 Ansible 收集 facts 信息

    范例:

    #收集全部信息
    [root@centos8 .ssh]# ansible innet -m setup
    
    #收集指定主机信息
    [root@centos8 .ssh]# ansible innet -m setup -a 'filter=ansible_python_version'
    

    3 Playbook

    3.1 Plyabook介绍

    playbook 剧本是由一个或多个"play"组成

    play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。Task实际是 调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作,从而完成复杂的主机管理功能

    3.2 YAML

    3.2.1 YAML简介

    由于Playbook 文件是采用YAML语言编写的,所以下面对YAML进行简单的介绍

    YAML是一种和XML、JSON类似的语言,JSON主要用于进行网络中数据交换,YAML则通常用来配置。XML既可以用于数据交换也能配置,不过语法比前两种繁琐。

    可以用工具互相转换

    https://www.json2yaml.com/

    http://www.bejson.com/json/json2yaml/

    3.2.2 YAML特点

    • 易读性较强
    • 交互性较好
    • 易于实现
    • 表达能力强,扩展好
    • 有一个一致的信息模型

    3.2.3 YAML语法简介

    • 在单一文件第一行,用连续三个连字号"-" 开始(也可以省略),还有选择性的连续三个点号( ... )用来表示文件的结尾
    • 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
    • 使用#号注释代码
    • 缩进必须统一,TAB和空格不能混用
    • 缩进的级别也必须一致
    • key/value可同行也可换行写,同行使用,进行分隔
    • 一般YAML文件扩展名为yml或yaml

    List列表

    列表由多个元素组成,每个元素放在不同行,且元素前均使用"-"打头,并且 - 后有一个空格, 或者将所 有元素用 [ ] 括起来放在同一行

    范例:

    #不同行,行以-开头,后面有一个空格
    # A list of tasty fruits
    - Apple
    - Orange
    - Strawberry
    - Mango
    
    #同一行
    [Apple,Orange,Strawberry,Mango]
    

    Dictionary字典

    字典由多个key与value构成,key和value之间用 :分隔, 并且 : 后面有一个空格,所有k/v可以放在一 行,或者每个 k/v 分别放在不同行

    范例:

    #不同行
    # An employee record
    name: Example Developer
    job: Developer
    skill: Elite
    
    #同一行,也可以将ke
    y:value放置于{}中进行表示,用,分隔多个key:value
    # An employee record
    {name: "Example Developer", job: "Developer", skill: "Elite"}
    

    3.3 Playbook 核心组件

    常见组件类型如下:

    • Hosts 执行的远程主机列表
    • Tasks 任务集,由多个task的元素组成的列表实现,每个task是一个字典
    • Variables 内置变量或自定义变量在playbook中调用
    • Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
    • Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
    • tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此 会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地 长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
    • 一个完整的代码块功能需最少元素需包括 name 和 task,一个name只能包括一个task

    更多组件和详细的组件说明可以参看官方文档:https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.html

    下面分别用shell和palybook实现httpd安装

    范例:

    #SHELL脚本实现
    #!/bin/bash
    # 安装Apache
    yum install --quiet -y httpd
    # 复制配置文件
    cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
    cp/tmp/vhosts.conf /etc/httpd/conf.d/
    # 启动Apache,并设置开机启动
    systemctl enable --now httpd
    
    #Playbook实现
    ---
    - hosts: websrvs
     remote_user: root
     tasks:
       - name: "安装Apache"
         yum: name=httpd
       - name: "复制配置文件"
         copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
       - name: "复制配置文件"
         copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
       - name: "启动Apache,并设置开机启动"
         service: name=httpd state=started enabled=yes
    

    3.4 playbook命令

    格式:

    ansible-playbook <filename.yml> ... [options]
    

    常用选项:

    • -C --check #只检测可能会发生的改变,但不真正执行操作
    • --list-hosts #列出运行任务的主机
    • --list-tags #列出tag
    • --list-tasks #列出task
    • --limit 主机列表 #只针对主机列表中的特定主机执行
    • -v -vv -vvv #显示过程

    范例:

    [root@centos8 data]# cat hello.yml 
    ---
    - hosts: innet
      tasks:
        - name: hello
          command: echo "hello ansible"
          
    [root@centos8 data]# ansible-playbook -C hello.yml
    [root@centos8 data]# ansible-playbook hello.yml
    

    3.5 Playbook初步

    3.5.1 Playbook使用handlers和notify

    Handlers本质是task list,其作用类似一个动作,当task执行完毕时使用notify触发才会执行。

    范例:当配置文件发生改变,对服务进行重启操作

    ---
    - hosts: websrvs
     remote_user: root
     gather_facts: no
     tasks:
        - name: Install httpd
         yum: name=httpd state=present
        - name: Install configure file
         copy: src=files/httpd.conf dest=/etc/httpd/conf/
         notify: restart httpd
        - name: ensure apache is running
          service: name=httpd state=started enabled=yes
      
     handlers:
        - name: restart httpd
          service: name=httpd state=restarted
    

    3.5.2 Playbook中使用tags组件

    在playbook文件中,可以利用tags组件,为特定 task 指定标签,当在执行playbook时,可以只执行特 定tags的task,而非整个playbook文件

    范例:

    # tags example
    - hosts: websrvs
     remote_user: root
     gather_facts: no
      
     tasks:
        - name: Install httpd
         yum: name=httpd state=present
        - name: Install configure file
         copy: src=files/httpd.conf dest=/etc/httpd/conf/
         tags: conf
        - name: start httpd service
         tags: service
          service: name=httpd state=started enabled=yes
          
    [root@centos8 data]#ansible-playbook –t conf,service httpd.yml
    

    3.6 Playbook中变量的使用

    变量的调用:

    通过{{ variable_name }} 调用变量,且变量名前后建议加空格,有时用"{{ variable_name }}"才生效

    调用较为简单,这里主要介绍几种定义变量的方式

    3.6.1 使用setup模块中的变量

    本模块自动在playbook调用,不要用ansible命令调用

    范例:

    [root@centos8 data]# cat var1.yml 
    ---
    #var1.yml
    - hosts: innet
      
      tasks:
        - name: create log file
          file: name=/data/{{ ansible_nodename }}.log state=touch 
    

    3.6.2 在命令行中定义变量

    范例:

    [root@centos8 data]# cat var2.yml 
    ---
    - hosts: innet
    
      tasks:
        - name: touch file
          file: name=/data/{{ file }}.log state=touch
    
    [root@centos8 data]# ansible-playbook -e file=test var2.yml
    

    3.6.3 在playbook文件中定义变量

    范例:

    [root@centos8 data]# cat va3.yml 
    ---
    - hosts: innet
      remote_user: root
      vars:
        collect_info: "/data/{{ansible_nodename}}/"
      tasks:
        - name: create IP directory
          file: name="{{collect_info}}" state=directory
           
    [root@centos8 data]# ansible-playbook -e file=test var3.yml
    

    3.6.4 使用变量文件

    可以在一个独立的playbook文件中定义变量,在另一个playbook文件中引用变量文件中的变量,比 playbook中定义的变量优化级高

    范例:

    vim vars.yml
    ---
    # variables file
    package_name: mariadb-server
    service_name: mariadb
    vim var5.yml
    ---
    #install package and start service
    - hosts: dbsrvs
     remote_user: root
     vars_files:
        - vars.yml
     tasks:
        - name: install package
         yum: name={{ package_name }}
         tags: install
        - name: start service
          service: name={{ service_name }} state=started enabled=yes
    

    3.6.5 主机清单文件中定义变量

    主机变量

    为指定的主机定义变量

    范例:

    [websrvs]
    www1.hello.com http_port=80 maxRequestsPerChild=808
    www2.hello.com http_port=8080 maxRequestsPerChild=909
    

    组(公共)变量

    给指定组内所有主机上的在playbook中可用的变量,如果和主机变是 同名,优先级低于主机变量

    范例:

    [websrvs]
    www1.hello.com http_port=8080
    www2.hello.com
    [websrvs:vars]
    http_port=80
    ntp_server=ntp.magedu.com
    nfs_server=nfs.magedu.com
    

    3.7 template 模板

    模板是一个文本文件,可以做为生成文件的模版,并且模板文件中还可嵌套jinja语法

    3.7.1 jinja2语言

    官方文档:https://jinja.palletsprojects.com/en/3.0.x/

    中文版本:http://docs.jinkan.org/docs/jinja2/#

    3.7.2 template

    官方介绍:https://docs.ansible.com/ansible/latest/collections/ansible/builtin/template_module.html

    范例:

    使用 if条件判断,决定是否生成相关的配置信息
    #yml文件
    [root@centos8 data]# cat temp5.yml 
    ---
    - hosts: innet
      vars:
        nginx_vhosts:
         - web1:
           listen: 8080
           root: "/var/www/nginx/web1/"
         - web2:
           listen: 8080
           server_name: "web2.magedu.com"
           root: "/var/www/nginx/web2/"
         - web3:
           listen: 8080
           server_name: "web3.magedu.com"
           root: "/var/www/nginx/web3/"
      tasks:
         - name: template config to
           template: src=nginx.conf5.j2 dest=/data/nginx5.conf #也可以写绝对路径,使用此处写法将模板文件放在同级目录也可以执行
    
    #模板文件位置
    [root@centos8 data]# cat ./templates/nginx.conf5.j2 
    {% for vhost in nginx_vhosts %}
    server {
       listen {{ vhost.listen }}
       {% if vhost.server_name is defined %}
    server_name {{ vhost.server_name }}
       {% endif %}
    root  {{ vhost.root }}
    }
    {% endfor %}
    
    #生成的文件
    [root@centos8 data]# cat nginx5.conf 
    server {
       listen 8080
       root  /var/www/nginx/web1/
    }
    server {
       listen 8080
       server_name web2.magedu.com
       root  /var/www/nginx/web2/
    }
    server {
       listen 8080
       server_name web3.magedu.com
       root  /var/www/nginx/web3/
    }
    

    4 roles角色

    roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便 捷地include它们的一种机制。将任务拆分成多个模块,适用于较为复杂的场景,提高代码复用性。

    官方文档:https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html

    4.1 roles结构

    roles目录结构如下

    # playbooks
    site.yml
    webservers.yml
    fooservers.yml
    roles/
        common/
            tasks/
            handlers/
            library/
            files/
            templates/
            vars/
            defaults/
            meta/
        webservers/
            tasks/
            defaults/
            meta/
    

    默认情况Ansible会去查找角色每个目录下的main.yml文件中内容

    • tasks/main.yml - the main list of tasks that the role executes.
    • handlers/main.yml - handlers, which may be used within or outside this role.
    • library/my_module.py - modules, which may be used within this role
    • defaults/main.yml - 设定默认变量时使用此目录中的main.yml文件,比vars的优先级低
    • vars/main.yml - other variables for the role.
    • files/main.yml - 存放由copy或script模块等调用的文件
    • templates/main.yml - templates that the role deploys.
    • meta/main.yml - metadata for the role, including role dependencies.

    4.2 role使用

    调用role步骤

    1 创建以roles命名的目录
    2 在roles目录中分别创建以各角色名称命名的目录,如webservers等
    3 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用不到
    的目录可以创建为空目录,也可以不创建
    4 在playbook文件中,调用各角色
    

    在playbook中调用role方法

    范例:

    ---
    - hosts: websrvs
     remote_user: root
     roles:
     - mysql
     - memcached
     - nginx 
     
    #键role用于指定角色名称,后续的k/v用于传递变量给角色
    ---
    - hosts: all
     remote_user: root
     roles:
        - mysql
        - { role: nginx, username: nginx }
        
    #还可基于条件测试实现角色调用
    ---
    - hosts: all
     remote_user: root
     roles:
       - { role: nginx, username: nginx, when: ansible_distribution_major_version
    == '7' }
    

    roles 中使用 tags

    #nginx-role.yml
    ---
    - hosts: websrvs
     remote_user: root
     roles:
        - { role: nginx ,tags: [ 'nginx', 'web' ] ,when:
    ansible_distribution_major_version == "6" }
        - { role: httpd ,tags: [ 'httpd', 'web' ] }
        - { role: mysql ,tags: [ 'mysql', 'db' ] }
        - { role: mariadb ,tags: [ 'mariadb', 'db' ] }
    ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml
    

    4.3 实战案例

    4.3.1 roles实现zabbix-agent批量部署

    [root@centos8 data]# tree roles/
    roles/
    └── zabbix
        ├── tasks
        │   ├── main.yml
        │   └── zabbixconf.yml
        └── templates
            └── zabbix.conf.j2
    
    [root@centos8 data]# cat roles/zabbix/tasks/main.yml 
    - include: zabbixconf.yml
    [root@centos8 data]# cat roles/zabbix/tasks/zabbixconf.yml 
    ---
    - name: zabbix host set
      template: src=zabbix.conf.j2 dest=/data/zabbix.conf
    
    [root@centos8 data]# cat roles/zabbix/templates/zabbix.conf.j2 
    hostname {{ ansible_nodename }};
    

    5 ansible相关链接

    ansible模块共享社区:https://galaxy.ansible.com/home

  • 相关阅读:
    Html 表单表格 form table
    JavaWeb -- 服务器传递给Servlet的对象 -- ServletConfig, ServletContext,Request, Response
    JavaWeb -- Servlet运行过程 和 细节
    调用DLL中的过程和函数
    调用DLL中的过程和函数
    动态载入 DLL
    动态载入 DLL
    静态载入 DLL
    DLL的加载和调用
    静态载入 DLL
  • 原文地址:https://www.cnblogs.com/bestvae/p/14988243.html
Copyright © 2020-2023  润新知