ansible

ansible简介

Ansible目前是运维自动化工具中最简单、容易上手的一款优秀软件,能够用来管理各种资源,用户可以使用Ansible自动部署应用程序,以此实现IT基础架构的全面部署。

Ansible基于SSH远程会话协议,不需要客户端程序,只要知道受管主机的账号密码,就能直接用SSH协议进行远程控制,因此使用起来优势明显。

  Ansible服务专用术语对照表

术语 中文叫法 含义
Control node 控制节点 指的是安装了Ansible服务的主机,也被称为Ansible控制端,主要是用来发布运行任务、调用功能模块,对其他主机进行批量控制。
Managed nodes 受控节点 指的是被Ansible服务所管理的主机,也被称为受控主机或客户端,是模块命令的被执行对象。
Inventory 主机清单 指的是受控节点的列表,可以是IP地址、主机名称或者域名。
Modules 模块 指的是上文提到的特定功能代码,默认自带有上千款功能模块,在Ansible Galaxy有超多可供选择。
Task 任务 指的是Ansible客户端上面要被执行的操作。
Playbook 剧本 指的是通过YAML语言编写的可重复执行的任务列表,把常做的操作写入到剧本文件中,下次可以直接重复执行一遍。
Roles 角色 从Ansible 1.2版本开始引入的新特性,用于结构化的组织Playbook,通过调用角色实现一连串的功能。

安装ansible

RHEL 8系统的镜像文件默认不带有Ansible服务程序,需要从Extra Packages for Enterprise Linux(EPEL)扩展软件包仓库获取。EPEL软件包仓库由红帽公司提供,是一个用于创建、维护和管理企业版Linux的高质量软件扩展仓库,通用于RHEL、CentOS、Oracle Linux等多种红帽系企业版系统,目的是对于默认系统仓库软件包进行扩展。红帽红帽EPEL地址:baseurl=https://dl.fedoraproject.org/pub/epel/8/Everything/x86_64/

1.配置yum仓库添加epel源

[root@linuxprobe ~]# vim /etc/yum.repos.d/rhel.repo
[BaseOS]
name=BaseOS
baseurl=file:///media/cdrom/BaseOS
enabled=1
gpgcheck=0

[AppStream]
name=AppStream
baseurl=file:///media/cdrom/AppStream
enabled=1
gpgcheck=0

[EPEL]
name=EPEL
baseurl=https://dl.fedoraproject.org/pub/epel/8/Everything/x86_64/
enabled=1
gpgcheck=0

2.安装ansible

[root@linuxprobe ~]# dnf install -y ansible
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Last metadata expiration check: 0:01:31 ago on Sun 04 Apr 2021 02:23:32 AM CST.
Dependencies resolved.
===========================================================================================
 Package                          Arch             Version            Repository        Size
===========================================================================================
Installing:
 ansible                          noarch           2.9.18-2.el8       EPEL               17 M
Installing dependencies:
 python3-babel                    noarch           2.5.1-3.el8        AppStream         4.8 M
 python3-jinja2                   noarch           2.10-9.el8         AppStream         537 k
 python3-jmespath                 noarch           0.9.0-11.el8       AppStream          45 k
 python3-markupsafe               x86_64           0.23-19.el8        AppStream          39 k
 python3-pyasn1                   noarch           0.3.7-6.el8        AppStream         126 k
 libsodium                        x86_64           1.0.18-2.el8       EPEL              162 k
 python3-bcrypt                   x86_64           3.1.6-2.el8.1      EPEL               44 k
 python3-pynacl                   x86_64           1.3.0-5.el8        EPEL              100 k
 sshpass                          x86_64           1.06-9.el8         EPEL               27 k
Installing weak dependencies:
 python3-paramiko                 noarch           2.4.3-1.el8        EPEL              289 k

Transaction Summary
===========================================================================================
Install  11 Packages

………………省略部分输出信息…………

Installed:
  ansible-2.9.18-2.el8.noarch            python3-paramiko-2.4.3-1.el8.noarch
  python3-babel-2.5.1-3.el8.noarch       python3-jinja2-2.10-9.el8.noarch
  python3-jmespath-0.9.0-11.el8.noarch   python3-markupsafe-0.23-19.el8.x86_64
  python3-pyasn1-0.3.7-6.el8.noarch      libsodium-1.0.18-2.el8.x86_64                  
  python3-bcrypt-3.1.6-2.el8.1.x86_64    python3-pynacl-1.3.0-5.el8.x86_64
  sshpass-1.06-9.el8.x86_64                         

Complete!

3.检查安装信息

安装完毕后,Ansible服务便默认已经启动。使用--version参数可以看到Ansible服务的版本及配置信息。

[root@linuxprobe ~]# ansible --version
ansible 2.9.18
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Jan 11 2019, 02:17:16) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]

设置主机清单

Ansible服务的主配置文件存在优先级的顺序关系,默认存放在/etc/ansible目录中的主配置文件优先级最低。如果在当前目录或用户家目录中也存放着一份主配置文件,则以当前目录或用户家目录中的主配置文件为主。同时存在多个Ansible服务主配置文件时,具体优先级顺序如表所示。 

Ansible服务主配置文件优先级顺序 

优先级 文件位置
./ansible.cfg
~/.ansible.cfg
/etc/ansible/ansible.cfg

inventory主机清单的配置文件为/etc/ansible/hosts,将受控主机加入主机清单从而实现集中控制。设置主机清单时可以根据实际环境设置不同的分组,从而实现分组控制。

[root@superwu ~]# vim /etc/ansible/hosts
[dev]              //名称为dev的组
192.168.10.20
[test]
192.168.10.21
[prod]            //名称为prod的组
192.168.10.22
192.168.10.23
[balancers]
192.168.10.24
[all:vars]       //all表示所有主机,vars表示变量(以下设置对所有主机生效),表示使用ansible时默认使用的用户和密码(自动验证)
ansible_user=root     //登录使用的账号
ansible_password=111111   //账号密码
[root@superwu ~]# ansible-inventory --graph  //以结构化的方式显示受管的主机信息
@all:
  |--@balancers:
  |  |--192.168.10.24
  |--@dev:
  |  |--192.168.10.20
  |--@prod:
  |  |--192.168.10.22
  |  |--192.168.10.23
  |--@test:
  |  |--192.168.10.21
  |--@ungrouped:

运行临时命令

Ansible服务的强大之处在于只需要一条命令,便可以操控成千上万台的主机节点,而ansible命令便是最得力的工具之一。

Ansible服务实际上只是一个框架,能够完成工作的是模块化功能代码,ansible-doc命令可以查询模块信息。

ansible是用于执行临时任务的命令,也就在是执行后即结束(与剧本文件的可重复执行不同)。在使用ansible命令时,必须指明受管主机的信息,如果已经设置过主机清单文件(/etc/ansible/hosts),则可以使用all参数来指代全体受管主机,或是用dev、test等主机组名称来指代某一组的主机。

ansible命令常用的语法格式为“ansible 受管主机节点 -m 模块名称 [-a 模块参数]”,其中,-a是要传递给模块的参数,只有功能极其简单的模块才不需要额外参数,所以大多情况下-m与-a参数都会同时出现。

如果想实现某个功能,但是却不知道用什么模块,又或者是知道了模块名称,但不清楚模块具体的作用,则建议使用ansible-doc命令进行查找。

查询模块信息

[root@linuxprobe ~]# ansible-doc -l  //列出所有模块信息
a10_server                                           Manage A10 Networks AX/SoftAX/Thunder/v...
a10_server_axapi3                                    Manage A10 Networks AX/SoftAX/Thunder/v...           
a10_service_group                                    Manage A10 Networks AX/SoftAX/Thunder/v...
a10_virtual_server                                   Manage A10 Networks AX/SoftAX/Thunder/v...
aci_aaa_user                                         Manage AAA users (aaa:User)                                              
aci_aaa_user_certificate                             Manage AAA user certificates (aaa:User...                        
aci_access_port_block_to_access_port                 Manage port blocks of Fabric interface ...
aci_access_port_to_interface_policy_leaf_profile     Manage Fabric interface policy leaf pro...
aci_access_sub_port_block_to_access_port             Manage sub port blocks of Fabric interf...
aci_aep                                              Manage attachable Access Entity Profile...
aci_aep_to_domain                                    Bind AEPs to Physical or Virtual Domain...   
aci_bd_subnet                                        Manage Subnets (fv:Subnet)                 
………………省略部分输出信息………………
[root@linuxprobe ~]# ansible-doc a10_server  //查看模块的具体信息
> A10_SERVER    (/usr/lib/python3.6/site-packages/ansible/modules/network/a10/a10_server.py)

     Manage SLB (Server Load Balancer) server objects on A10 Networks devices via aXAPIv2.

  * This module is maintained by The Ansible Community
………………省略部分输出信息………………
[root@linuxprobe ~]# ansible all -m ping  //对所有主机执行ping模块
192.168.10.20 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
192.168.10.21 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
192.168.10.22 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
192.168.10.23 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}192.168.10.24 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

使用ansible安装yum仓库

[root@linuxprobe ~]# ansible all -m yum_repository -a 'name="EX294_BASE" description="EX294 base software" baseurl="file:///media/cdrom/BaseOS" gpgcheck=yes enabled=1 gpgkey="file:///media/cdrom/RPM-GPG-KEY-redhat-release"'

192.168.10.20 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "repo": "EX294_BASE",
    "state": "present"
}

使用-m参数直接指定模块名称,用-a参数将参数传递给模块,让模块的功能更高级。

剧本ansible-playbook

在很多情况下,仅仅执行单个命令或调用某一个模块,根本无法满足复杂工作的需要。Ansible服务允许用户根据需求,在类似于Shell脚本的模式下编写自动化运维脚本,然后由程序自动、重复地执行,从而大大提高了工作效率。

Ansible服务的剧本(playbook)文件采用YAML语言编写,具有强制性的格式规范,它通过空格将不同信息分组,因此有时会因一两个空格错位而导致报错。

YAML文件的开头需要先写3个减号(---),多个分组的信息需要间隔一致才能执行,而且上下也要对齐,后缀名一般为.yml。剧本文件在执行后,会在屏幕上输出运行界面,内容会根据工作的不同而变化。在运行界面中,绿色表示成功,黄色表示执行成功并进行了修改,而红色则表示执行失败

YAML语言编写的Ansible剧本文件会按照从上到下的顺序自动运行,其形式类似于Shell脚本,但格式有严格的要求。

剧本文件的结构由4部分组成,分别是target、variable、task、handler,其各自的作用如下。 

target:用于定义要执行剧本的主机范围。

variable:用于定义剧本执行时要用到的变量。

task:用于定义将在远程主机上执行的任务列表。

handler:用于定义执行完成后需要调用的后续任务。

示例1

创建一个名为packages.yml的剧本,让dev、test和prod组的主机可以自动安装数据库软件,并且将dev组主机的软件更新至最新。

查看模块帮助信息

安装和更新软件需要使用yum模块。先看一下帮助信息中的示例吧:

[root@linuxprobe ~]# ansible-doc yum
> YUM    (/usr/lib/python3.6/site-packages/ansible/modules/packaging/os/yum.py)

        Installs, upgrade, downgrades, removes, and lists packages and
        groups with the `yum' package manager. This module only works
        on Python 2. If you require Python 3 support see the [dnf]
        module.

  * This module is maintained by The Ansible Core Team
  * note: This module has a corresponding action plugin.

………………省略部分输出信息………………

EXAMPLES:

- name: install the latest version of Apache
  yum:
    name: httpd
    state: latest

编辑剧本

[root@linuxprobe ~]# vim packages.yml
---
- name: 安装软件包
  hosts: dev,test,prod
  tasks:
          - name: one
            yum:
                    name: mariadb
                    state: latest
[root@linuxprobe ~]#

其中,name字段表示此项play(动作)的名字,用于在执行过程中提示用户执行到了哪一步,以及帮助管理员在日后阅读时能想起这段代码的作用。大家可以在name字段自行命名,没有任何限制。hosts字段表示要在哪些主机上执行该剧本,多个主机组之间用逗号间隔;如果需要对全部主机进行操作,则使用all参数。tasks字段用于定义要执行的任务,每个任务都要有一个独立的name字段进行命名,并且每个任务的name字段和模块名称都要严格上下对齐,参数要单独缩进。

执行剧本

ansible-playbook命令用于执行剧本。

[root@linuxprobe ~]# ansible-playbook packages.yml 

PLAY [安装软件包] *******************************************************************

TASK [Gathering Facts] **************************************************************
ok: [192.168.10.20]
ok: [192.168.10.21]
ok: [192.168.10.22]
ok: [192.168.10.23]

TASK [one] **************************************************************************
changed: [192.168.10.20]
changed: [192.168.10.21]
changed: [192.168.10.22]
changed: [192.168.10.23]

PLAY RECAP **************************************************************************
192.168.10.20  : ok=2   changed=1  unreachable=0   failed=0   skipped=0   rescued=0   ignored=0   
192.168.10.21  : ok=2   changed=1  unreachable=0   failed=0   skipped=0   rescued=0   ignored=0   
192.168.10.22  : ok=2   changed=1  unreachable=0   failed=0   skipped=0   rescued=0   ignored=0   
192.168.10.23  : ok=2   changed=1  unreachable=0   failed=0   skipped=0   rescued=0   ignored=0   

其中,ok和changed表示执行及修改成功。如遇到unreachable或failed大于0的情况,建议手动检查剧本是否在所有主机中都正确运行了,以及有无安装失败的情况。  

创建及使用角色

在日常编写剧本时,会存在剧本越来越长的情况,这不利于进行阅读和维护,而且还无法让其他剧本灵活地调用其中的功能代码。角色(role)这一功能则是自Ansible 1.2版本开始引入的新特性,用于层次性、结构化地组织剧本。角色功能分别把变量、文件、任务、模块及处理器配置放在各个独立的目录中,然后对其进行便捷加载。简单来说,角色功能是把常用的一些功能“类模块化”,然后在用的时候加载即可。

角色的获取有3种方法,分别是加载系统内置角色、从外部环境获取角色以及自行创建角色。 

系统内置角色 

系统内置角色是由系统镜像自带的角色,它们在日常的工作中能派上大用场。

安装系统内置角色

[root@linuxprobe ~]# dnf install -y rhel-system-roles
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Last metadata expiration check: 1:06:26 ago on Tue 13 Apr 2021 07:22:03 AM CST.
Dependencies resolved.
================================================================================
 Package                  Arch          Version          Repository        Size
================================================================================
Installing:
 rhel-system-roles        noarch        1.0-5.el8        AppStream        127 k

Transaction Summary
================================================================================
Install  1 Package

………………省略部分输出信息………………  

Installed:
  rhel-system-roles-1.0-5.el8.noarch                                            

Complete!

查看系统内置角色

ansible-galaxy list命令查看系统中有哪些自带的角色可用。

[root@linuxprobe ~]# ansible-galaxy list
# /usr/share/ansible/roles
- linux-system-roles.kdump, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.timesync, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)
- rhel-system-roles.selinux, (unknown version)
- rhel-system-roles.timesync, (unknown version)
# /etc/ansible/roles
[WARNING]: - the configured path /root/.ansible/roles does not exist.

示例1

以rhel-system-roles.timesync角色为例,它用于设置系统的时间和NTP服务,让主机能够同步准确的时间信息。剧本模板文件存放在/usr/share/doc/rhel-system-roles/目录中,可以复制过来修改使用:

[root@linuxprobe ~]# cp /usr/share/doc/rhel-system-roles/timesync/example-timesync-playbook.yml timesync.yml

  

[root@linuxprobe ~]# vim timesync.yml 
---
- hosts: all
  vars:
    timesync_ntp_servers:
      - hostname: pool.ntp.org
        iburst: yes
  roles:
    - rhel-system-roles.timesync

从外部获取角色 

Ansible Galaxy(https://galaxy.ansible.com)是Ansible的一个官方社区,用于共享角色和功能代码,用户可以在网站自由地共享和下载Ansible角色。

1.从ansible官方社区下载角色

从网站查询要下载的角色,然后使用命令“ansible-galaxy install 角色名称”下载,需要能访问互联网。

[root@linuxprobe ~]# ansible-galaxy install nginxinc.nginx  //安装ngixn角色
- downloading role 'nginx', owned by nginxinc
- downloading role from https://github.com/nginxinc/ansible-role-nginx/archive/0.19.1.tar.gz
- extracting nginxinc.nginx to /etc/ansible/roles/nginxinc.nginx
- nginxinc.nginx (0.19.1) was installed successfully

  

[root@linuxprobe ~]# ansible-galaxy list
# /etc/ansible/roles
- nginxinc.nginx, 0.19.1      //已经安装了nginx角色
# /usr/share/ansible/roles
- linux-system-roles.kdump, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.timesync, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)
- rhel-system-roles.selinux, (unknown version)
- rhel-system-roles.timesync, (unknown version)

2.从ansible官方社区外下载角色

在这种情况下,就不能再用“ansible-galaxy install角色名称”的命令直接加载了,而是需要手动先编写一个YAML语言格式的文件,指明网址链接和角色名称,然后再用-r参数进行加载。  

1.编辑yml文件

[root@linuxprobe ~]# vim nginx.yml
---
- src: https://www.linuxprobe.com/Software/nginxinc-nginx_core-0.3.0.tar.gz    //获取角色的地址
  name: nginx-core

2.使用ansible-galaxy命令的-r参数加载这个文件

[root@linuxprobe ~]# ansible-galaxy install -r nginx.yml  //-r参数一定要加
- downloading role from https://www.linuxprobe.com/nginxinc-nginx_core-0.3.0.tar.gz
- extracting nginx to /etc/ansible/roles/nginx
- nginx was installed successfully
[root@linuxprobe ~]# ansible-galaxy list
# /etc/ansible/roles
- nginx-core, (unknown version)
- nginxinc.nginx, 0.19.1
# /usr/share/ansible/roles
- linux-system-roles.kdump, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.timesync, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)
- rhel-system-roles.selinux, (unknown version)
- rhel-system-roles.timesync, (unknown version)

自建角色

在Ansible的主配置文件中,第68行(#roles_path)定义的是角色保存路径。如果用户新建的角色信息不在规定的目录内,则无法使用ansible-galaxy list命令找到。因此需要手动填写新角色的目录路径,或是进入/etc/ansible/roles目录内再进行创建。为了避免后期角色信息过于分散导致不好管理,建议在默认目录下进行创建。 

[root@linuxprobe roles]# cat -n /etc/ansible/ansible.cfg
 66 
 67 # additional paths to search for roles in, colon separated
 68 #roles_path    = /etc/ansible/roles
 69 

示例1:自建apache角色  

自建角色需要使用ansible-galaxy命令的init参数,格式为“ansible-galaxy init 角色名称”。

第1步:创建自建角色名称及目录结构

[root@linuxprobe ~]# cd /etc/ansible/roles   //切换到角色默认路径下进行创建
[root@linuxprobe roles]# ansible-galaxy init apache   //需要使用init参数
- Role apache was created successfully
[root@linuxprobe roles]# ls   //会生成一个以角色名称命名的目录
apache nginx nginxinc.nginx

 

[root@linuxprobe roles]# cd apache   //进入自建的角色目录
[root@linuxprobe apache]# ls         //自建角色目录下有若干文件
defaults  files  handlers  meta  README.md  tasks  templates  tests  vars

Ansible角色目录结构及含义  

目录 含义
defaults 包含角色变量的默认值(优先级低)。
files 包含角色执行tasks任务时做引用的静态文件。
handlers 包含角色的处理程序定义。
meta 包含角色的作者、许可证、频台和依赖关系等信息。
tasks 包含角色所执行的任务。
templates 包含角色任务所使用的Jinja2模板。
tests 包含用于测试角色的剧本文件。
vars 包含角色变量的默认值(优先级高)。

第2步:编辑用于定义角色任务的tasks/main.yml文件。

在该文件中不需要定义要执行的主机组列表,因为后面会单独编写剧本进行调用,此时应先对apache角色能做的事情(任务)有一个明确的思路,在调用角色后yml文件会按照从上到下的顺序自动执行。即向main.yml文件写入若干任务。

任务1:安装httpd网站服务。

任务2:运行httpd网站服务,并加入到开机启动项中。

任务3:配置防火墙,使其放行HTTP协议。

任务4:根据每台主机的变量值,生成不同的主页文件。

写第一个任务。

使用yum模块安装httpd网站服务程序(注意格式):

[root@linuxprobe apache]# vim tasks/main.yml
---
- name: one
  yum:
          name: httpd
          state: latest

写第二个任务。

使用service模块启动httpd网站服务程序,并加入开机自启动。

[root@linuxprobe apache]# ansible-doc service  //查询service模块信息及使用格式
> SERVICE    (/usr/lib/python3.6/site-packages/ansible/modules/system/service.py)

        Controls services on remote hosts. Supported init systems
        include BSD init, OpenRC, SysV, Solaris SMF, systemd, upstart.
        For Windows targets, use the [win_service] module instead.

  * This module is maintained by The Ansible Core Team
  * note: This module has a corresponding action plugin.

………………省略部分输出信息………………

EXAMPLES:

- name: Start service httpd, if not started
  service:
    name: httpd
    state: started

- name: Enable service httpd, and not touch the state
  service:
    name: httpd
    enabled: yes

  

[root@linuxprobe apache]# vim tasks/main.yml
---
- name: one
  yum:
          name: httpd
          state: latest
- name: two
  service:
          name: httpd
          state: started
          enabled: yes

写第三个任务。

配置防火墙的允许策略,让其他主机可以正常访问。在配置防火墙时,需要使用firewalld模块。

[root@linuxprobe defaults]# ansible-doc firewalld  //查看firewalld模块信息及使用格式
> FIREWALLD    (/usr/lib/python3.6/site-packages/ansible/modules/system/firewalld.py)

        This module allows for addition or deletion of services and
        ports (either TCP or UDP) in either running or permanent
        firewalld rules.

  * This module is maintained by The Ansible Community
OPTIONS (= is mandatory):
EXAMPLES:

- firewalld:
    service: https
    permanent: yes
    state: enabled

- firewalld:
    port: 8081/tcp
    permanent: yes
    state: disabled
    immediate: yes

 

[root@linuxprobe apache]# vim tasks/main.yml
---
- name: one
  yum:
          name: httpd
          state: latest
- name: two
  service:
          name: httpd
          state: started
          enabled: yes
- name: three
  firewalld:
          service: http
          permanent: yes
          state: enabled
          immediate: yes

写第四个任务。

根据每台主机的变量值,生成不同的主页文件,让每台主机显示的主页文件均不相同。

让每台主机上运行的httpd网站服务都能显示不同的内容,要用到template模块及Jinja2技术。

[root@linuxprobe apache]# ansible-doc template  //查询template模块及使用格式
> TEMPLATE    (/usr/lib/python3.6/site-packages/ansible/modules/files/template.>

        Templates are processed by the L(Jinja2 templating
        language,http://jinja.pocoo.org/docs/). Documentation on the
        template formatting can be found in the L(Template Designer
        Documentation,http://jinja.pocoo.org/docs/templates/).
        Additional variables listed below can be used in templates.
        `ansible_managed' (configurable via the `defaults' section of
        `ansible.cfg') contains a string which can be used to describe
        the template name, host, modification time of the template
        file and the owner uid. `template_host' contains the node name
        of the template's machine. `template_uid' is the numeric user
        id of the owner. `template_path' is the path of the template.
        `template_fullpath' is the absolute path of the template.
        `template_destpath' is the path of the template on the remote
        system (added in 2.8). `template_run_date' is the date that
        the template was rendered.

  * This module is maintained by The Ansible Core Team
  * note: This module has a corresponding action plugin.

………………省略部分输出信息………………

EXAMPLES:

- name: Template a file to /etc/files.conf
  template:
    src: /mytemplates/foo.j2
    dest: /etc/file.conf
    owner: bin
    group: wheel
    mode: '0644'

从template模块的输出信息中可得知,这是一个用于复制文件模板的模块,能够把文件从Ansible服务器复制到受管主机上。其中,src参数用于定义本地文件的路径,dest参数用于定义复制到受管主机的文件路径,而owner、group、mode参数可选择性地设置文件归属及权限信息。

正常来说,我们可以直接复制文件的操作,受管主机上会获取到一个与Ansible服务器上的文件一模一样的文件。但有时候,我们想让每台客户端根据自身系统的情况产生不同的文件信息,这就需要用到Jinja2技术了,Jinja2格式的模板文件后缀是.j2。

[root@linuxprobe apache]# vim tasks/main.yml
---
- name: one
  yum:
          name: httpd
          state: latest
- name: two
  service:
          name: httpd
          state: started
          enabled: yes
- name: three
  firewalld:
          service: http
          permanent: yes
          state: enabled
          immediate: yes
- name: four
  template:
          src: index.html.j2    //本地文件路径
          dest: /var/www/html/index.html   //受管主机路径

Jinja2是Python语言中一个被广泛使用的模板引擎,能够让受管主机根据自身变量产生出不同的文件内容。换句话说,正常情况下的复制操作会让新旧文件一模一样,但在使用Jinja2技术时,不是在原始文件中直接写入文件内容,而是写入一系列的变量名称。在使用template模块进行复制的过程中,由Ansible服务负责在受管主机上收集这些变量名称所对应的值,然后再逐一填写到目标文件中,从而让每台主机的文件都根据自身系统的情况独立生成。 

例如让每个网站的输出信息值为“Welcome to 主机名 on 主机地址”,也就是用每个主机自己独有的名称和IP地址来替换文本中的内容。

可以用setup模块进行查询对应的变量名称、主机名及地址所对应的值保存在哪里。setup模块的作用是自动收集受管主机上的变量信息,使用-a参数外加filter命令可以对收集来的信息进行二次过滤。相应的语法格式为ansible all -m setup -a 'filter="*关键词*",其中*号是通配符,用于进行关键词查询。

[root@linuxprobe apache]# ansible-doc setup
> SETUP    (/usr/lib/python3.6/site-packages/ansible/modules/system/setup.py)

        This module is automatically called by playbooks to gather
        useful variables about remote hosts that can be used in
        playbooks. It can also be executed directly by
        `/usr/bin/ansible' to check what variables are available to a
        host. Ansible provides many `facts' about the system,
        automatically. This module is also supported for Windows
        targets.

FQDN(Fully Qualified Domain Name,完全限定域名)用于在逻辑上准确表示出主机的位置。fqdn常常被作为主机名的完全表达形式,比/etc/hostname文件中定义的主机名更加严谨和准确。

[root@linuxprobe ~]# ansible all -m setup -a 'filter="*fqdn*"'
192.168.10.20 | SUCCESS => {
    "ansible_facts": {
        "ansible_fqdn": "linuxprobe.com",
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false
}
………………省略部分输出信息………………

过滤IP

[root@linuxprobe ~]# ansible all -m setup -a 'filter="*ip*"'
192.168.10.20 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.10.20",
            "192.168.122.1"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::d0bb:17c8:880d:e719"
        ],
        "ansible_default_ipv4": {},
        "ansible_default_ipv6": {},
        "ansible_fips": false,
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false
}
………………省略部分输出信息………………

在角色所对应的templates目录内新建一个与上面的template模块参数相同的文件名称(index.html.j2)。Jinja2在调用变量值时,格式为在变量名称的两侧格加两个大括号,且大括号内两侧均有一个空格。

[root@linuxprobe apache]# vim templates/index.html.j2
Welcome to {{ ansible_fqdn }} on {{ ansible_all_ipv4_addresses }}  //大括号内两侧均有一个空格

第3步:编写一个用于调用角色的yml文件,以及执行这个文件

[root@linuxprobe apache]# cd ~
[root@linuxprobe ~]# vim roles.yml
---
- name: 调用自建角色
  hosts: all
  roles:
          - apache
[root@linuxprobe ~]# ansible-playbook roles.yml 
PLAY [调用自建角色] **************************************************************************

TASK [Gathering Facts] **********************************************************************
ok: [192.168.10.20]
ok: [192.168.10.21]
ok: [192.168.10.22]
ok: [192.168.10.23]
ok: [192.168.10.24]

TASK [apache : one] *************************************************************************
changed: [192.168.10.20]
changed: [192.168.10.21]
changed: [192.168.10.22]
changed: [192.168.10.23]
changed: [192.168.10.24]

TASK [apache : two] *************************************************************************
changed: [192.168.10.20]
changed: [192.168.10.21]
changed: [192.168.10.22]
changed: [192.168.10.23]
changed: [192.168.10.24]

TASK [apache : three] ***********************************************************************
changed: [192.168.10.20]
changed: [192.168.10.21]
changed: [192.168.10.22]
changed: [192.168.10.23]
changed: [192.168.10.24]

TASK [apache : four] ***********************************************************************
changed: [192.168.10.20]
changed: [192.168.10.21]
changed: [192.168.10.22]
changed: [192.168.10.23] 
changed: [192.168.10.24]

PLAY RECAP **********************************************************************************
192.168.10.20   : ok=5   changed=4  unreachable=0   failed=0   skipped=0   rescued=0   ignored=0   
192.168.10.21   : ok=5   changed=4  unreachable=0   failed=0   skipped=0   rescued=0   ignored=0   
192.168.10.22   : ok=5   changed=4  unreachable=0   failed=0   skipped=0   rescued=0   ignored=0   
192.168.10.23   : ok=5   changed=4  unreachable=0   failed=0   skipped=0   rescued=0   ignored=0   
192.168.10.24   : ok=4   changed=4  unreachable=0   failed=0   skipped=0   rescued=0   ignored=0

执行完毕后,在浏览器中随机输入几台主机的IP地址,即可访问到包含主机FQDN和IP地址的网页了。

 

posted @ 2022-02-17 12:07  小蟋帅  阅读(254)  评论(0编辑  收藏  举报