搜索内容

12.Ansible和Zabbix应用进阶及协同工作

12.Ansible和Zabbix应用进阶及协同工作

CentOS 8作为云时代的操作系统,特别突出了自动化的管理和运维,2015红帽收购了Ansible后,更是将其与RHEL高度融合,RHEL 8就是收购Ansible后发布的一个重量级版本,让IT管理更加自动化和高效,下面就顺应这一趋势和潮流,突出CentOS 8的这一特点,通过大量实例帮助大家掌握如何应用并切实提高企业的IT管理效率。

当企业规模较小的时候,服务器的数量可能不多,几台或十几台,这种情形,手动部署和配置,辅助以脚本就可以实现,但随着企业规模和业务的发展,企业的服务器成几何级发展,面对越来越多的服务器,自动化部署,管理和运维成为唯一的选择,更何况当下,开发和运维逐步合二为一,自动化部署,管理,CI/CD(持续集成/持续部署)使得敏捷开发成为企业的最佳实践,DevOps变得越来越流行,本章就来掌握CentOS 8的自动化管理,从自动化管理工具Ansible和监控工具Zabbix入手,全面掌握自动化管理的基础。

12.1 Ansible实现批量应用部署和配置

Ansible是由Michael DeHaan开发的,他同时也是著名的Cobbler和FUNC这两个流行的自动化工具的开发者。2012年3月9日发布Ansible的0.0.1版本发布,短短三年时间,在2015年10月17就被红帽公司收购,Ansible的Logo如图12-1所示。

图12-1 Ansible的Logo(图片来源:Ansible官网)

Ansible是一个十分流行的自动化管理工具,基于Python的paramiko开发,可以实现诸如自动化批量部署和配置等操作,通过host inventory指定所操作的一组主机,使用Playbook(剧本)完成一组复杂的操作,利用SSH服务进行认证和管理,Ansible的原理如图12-2所示。

图12-2 Ansible的原理图(图片来源:https://medium.com/)

Ansible的官方网址如下:
https://www.ansible.com/

Ansible官方文档地址:
https://docs.ansible.com/ #Ansible的官方文档范例丰富,十分值得一读

Ansible相应版本的官方文档地址:
https://docs.ansible.com/ansible/2.8/
https://docs.ansible.com/ansible/2.7/
https://docs.ansible.com/ansible/2.6/

本文所涉及的所有内容几乎都可以通过查询官方文档获得。

Ansible的Web解决方案名为Ansible Tower,无论是Ansible还是Ansible Tower,功能强大,但使用起来都十分简单,首先在各个节点部署Ansible,然后管理节点通过SSH创建密钥,并将该密钥分发密钥到各个被管理的节点,一旦密钥分发成功,就可以通过管理节点对被管理节点发号施令了,如批量执行命令或配置,高效便捷。下面就来实现一个管理节点和两个被管理节点的实例,通过三节点实例来掌握Ansible的基本使用方法。需要注意的是,无论采用下列哪种部署方法,管理节点和被管理节点的版本最好一致。

三节点规划如下:
角色 主机名 IP地址
Ansible server centos8 192.168.1.168 #管理节点
Ansible host1 node1 192.168.1.30 #被管理节点
Ansible host2 node2 192.168.1.31 #被管理节点

    12.1.1.准备工作

各个节点套用规划中的主机名并添加到/etc/hosts文件,具体操作如下:
hostnamectl set-hostname centos8
vi /etc/hosts

之后在各个节点,设置静态解析,具体实现如下:
vi /etc/hosts
192.168.1.168 centos8
192.168.1.30 node1
192.168.1.31 node2

   12.1.2. 部署Ansible

所有节点都需要部署Ansible,先要从Python软件仓库安装,Python 2具体安装方法如下:

dnf -y install python2-pip
python2 -m pip install --upgrade pip
pip2 install ansible
Collecting ansible
  Downloading https://files.pythonhosted.org/packages/04/25/48fee5f8048360d9375e01846fcf395dda58242ed1f25a2106b6794452eb/ansible-2.8.5.tar.gz (14.4MB)
     |████████████████████████████████| 14.4MB 690kB/s
Collecting jinja2 (from ansible)
  Downloading https://files.pythonhosted.org/packages/1d/e7/fd8b501e7a6dfe492a433deb7b9d833d39ca74916fa8bc63dd1a4947a671/Jinja2-2.10.1-py2.py3-none-any.whl (124kB)
     |████████████████████████████████| 133kB 933kB/s
Collecting PyYAML (from ansible)
  Downloading https://files.pythonhosted.org/packages/e3/e8/b3212641ee2718d556df0f23f78de8303f068fe29cdaa7a91018849582fe/PyYAML-5.1.2.tar.gz (265kB)
     |████████████████████████████████| 266kB 1.1MB/s
Collecting cryptography (from ansible)
  Downloading https://files.pythonhosted.org/packages/e6/68/50698ce24c61db7d44d93a5043c621a0ca7839d4ef9dff913e6ab465fc92/cryptography-2.7-cp27-cp27mu-manylinux1_x86_64.whl (2.3MB)
     |████████████████████████████████| 2.3MB 684kB/s
Collecting MarkupSafe>=0.23 (from jinja2->ansible)
  Downloading https://files.pythonhosted.org/packages/fb/40/f3adb7cf24a8012813c5edb20329eb22d5d8e2a0ecf73d21d6b85865da11/MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl
Collecting enum34; python_version < "3" (from cryptography->ansible)
  Downloading https://files.pythonhosted.org/packages/c5/db/e56e6b4bbac7c4a06de1c50de6fe1ef3810018ae11732a50f15f62c7d050/enum34-1.1.6-py2-none-any.whl
Collecting asn1crypto>=0.21.0 (from cryptography->ansible)
  Downloading https://files.pythonhosted.org/packages/ea/cd/35485615f45f30a510576f1a56d1e0a7ad7bd8ab5ed7cdc600ef7cd06222/asn1crypto-0.24.0-py2.py3-none-any.whl (101kB)
     |████████████████████████████████| 102kB 1.0MB/s
Collecting cffi!=1.11.3,>=1.8 (from cryptography->ansible)
  Downloading https://files.pythonhosted.org/packages/8d/e9/0c8afd1579e5cf7bc0f06fbcd7cdb954cbc0baadd505973949a99337da1c/cffi-1.12.3-cp27-cp27mu-manylinux1_x86_64.whl (415kB)
     |████████████████████████████████| 419kB 880kB/s
Collecting six>=1.4.1 (from cryptography->ansible)
  Downloading https://files.pythonhosted.org/packages/73/fb/00a976f728d0d1fecfe898238ce23f502a721c0ac0ecfedb80e0d88c64e9/six-1.12.0-py2.py3-none-any.whl
Collecting ipaddress; python_version < "3" (from cryptography->ansible)
  Downloading https://files.pythonhosted.org/packages/fc/d0/7fc3a811e011d4b388be48a0e381db8d990042df54aa4ef4599a31d39853/ipaddress-1.0.22-py2.py3-none-any.whl
Collecting pycparser (from cffi!=1.11.3,>=1.8->cryptography->ansible)
  Downloading https://files.pythonhosted.org/packages/68/9e/49196946aee219aead1290e00d1e7fdeab8567783e83e1b9ab5585e6206a/pycparser-2.19.tar.gz (158kB)
     |████████████████████████████████| 163kB 794kB/s
Installing collected packages: MarkupSafe, jinja2, PyYAML, enum34, asn1crypto, pycparser, cffi, six, ipaddress, cryptography, ansible
  Running setup.py install for PyYAML ... done
  Running setup.py install for pycparser ... done
  Running setup.py install for ansible ... done
Successfully installed MarkupSafe-1.1.1 PyYAML-5.1.2 ansible-2.8.5 asn1crypto-0.24.0 cffi-1.12.3 cryptography-2.7 enum34-1.1.6 ipaddress-1.0.22 jinja2-2.10.1 pycparser-2.19 six-1.12.0

成功安装后,运行如下命令检测:

ansible --version
ansible 2.8.5
  config file = None
  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.15 (default, Jun 22 2019, 03:44:59) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)] 

13.1.3.密钥的创建和分发
创建密钥
Ansible最大的优点就是配置简单,只需在管理节点使用SSH创建并分发密钥到被管理节点即可,密钥的创建和分发操作如下:

ssh-keygen                                  #此处为了演示而采用最简生成方法,生产环境需要注意
cd ~/.ssh/
ll
total 8
-rw-------. 1 henry henry 1823 Sep 29 10:25 id_rsa
-rw-r--r--. 1 henry henry  395 Sep 29 10:25 id_rsa.pub

分发密钥到各个节点
管理节点运行如下命令分发密钥到每个被管理节点:

ssh-copy-id 192.168.1.30
The authenticity of host '192.168.1.30 (192.168.1.30)' can't be established.
ECDSA key fingerprint is SHA256:SZg74B167pJCh7vmfXZaQUVOjfaHUvVzrV7yhc5e6dI.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '192.168.1.30'"
and check to make sure that only the key(s) you wanted were added.

被管理端可以运行如下命令来验证SSH密钥分发成功:

cd .ssh
total 4
-rw-------. 1 henry henry 395 Sep 29 10:26 authorized_keys

然后运行如下命令查看所分发过来的密钥:

cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9+r1iiLxa/uQVFQxtMZMaWblJgFsMmO64iXOpJIdH8OTEM9C6ZqMuMsVAZ8bAEjv5PW2je6oU9M7CwnOXqDUb3jjjZx0nlwhk/c+C4uJQDNUv4gJQ9pr6R+XLgkZjVX284gKpUP3HLV+Udmt3uHyqjRlqXCkMtV0y+s8Ie6W9JluHGTXz4SxJtf10RjHc1sJJfGxQjUlVV+SMnqGiEsI5FF01OuyBhctk/0uX922sI9W+VAl92phLpPaU5VNVfeazEgFPjJwOtEuhwo1Nor/28lPrA4t7AOrRFu8JylfY27h0vyU2mXkM4/5WA03yyEn7x554up0fLOhAEZTbREqF henry@centos8

看到如上信息,说明密钥分发成功,然后再分发给第二个管理节点,具体操作如下:

ssh-copy-id 192.168.1.31

成功部署和配置好服务端和被管理端的Ansible之后,先来掌握Ansible的两个重要概念:Ad-hoc和Inventory:
◆Ad-Hoc就是Ansible的命令行工具,下面实例中将会用到;
◆Inventory则是被管理服务器的IP列表,可自行定义。

掌握了这两个重要概念,回到Ansible的服务器端,开始自定义Inventory,需要编辑Ansible的hosts配置文件,将被管理节点的相关信息写入,关键操作如下:

cd
vi hosts                        #在henry用户的主目录创建Inventory的文件

文件添加如下被管理主机的配置:
[webservers]                    #为了管理方便,将被管理节点分成若干个组来管理
192.168.1.30                    #如果可以解析便,主机名也可以
192.168.1.31

保存后可使用如下命令检测各个被管理节点的运作是否正常:

ansible -i hosts -m ping all
192.168.1.31 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
192.168.1.30 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

获得如上结果,说明Ansible安装配置正确。需要说明的是,通过i参数指定Inventory的文件hosts。

Tips:Ansible高频命令参数
Ansible的高频命令和参数如下:
ansible -h:获得Ansible全面的帮助信息
ansible-doc -l:列出所有Ansible有效模块
ansible-doc -s:显示指定插件的playbook代码段
ansible-playbook:执行Playbook

12.2.Ansible实现批量部署和配置

Ansible实现批量部署和配置的方法有两种,一种是较为简单的,批量执行命令进行部署或配置,另外一种较为复杂,通过Playbook(剧本)文件实现较为复杂的批量部署和配置,先来掌握批量执行命令进行部署和配置。

   12.2.1.批量执行命令进行部署或配置

批量执行命令进行部署或配置是Ansible最为基本的使用方法,具体方法如下:

ansible -i hosts webservers -m shell -a "hostname"
192.168.1.30 | CHANGED | rc=0 >>
node2

192.168.1.31 | CHANGED | rc=0 >>
node1

ansible -i hosts webservers -m shell -a "timedatectl"
192.168.1.31 | CHANGED | rc=0 >>
               Local time: Sun 2019-09-29 10:42:26 EDT
           Universal time: Sun 2019-09-29 14:42:26 UTC
                 RTC time: Sun 2019-09-29 14:42:25
                Time zone: America/New_York (EDT, -0400)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

192.168.1.30 | CHANGED | rc=0 >>
               Local time: Sun 2019-09-29 10:42:26 EDT
           Universal time: Sun 2019-09-29 14:42:26 UTC
                 RTC time: Sun 2019-09-29 14:42:26
                Time zone: America/New_York (EDT, -0400)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

ansible -i hosts webservers -m shell -a "w"
192.168.1.31 | CHANGED | rc=0 >>
 10:43:18 up 36 min,  2 users,  load average: 0.03, 0.01, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
henry    tty2     tty2             10:11   36:40  10.91s  0.01s /usr/libexec/gsd-disk-utility-notify
henry    pts/1    192.168.1.168    10:43    1.00s  0.18s  0.03s w

192.168.1.30 | CHANGED | rc=0 >>
 10:43:18 up 39 min,  2 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
henry    tty2     tty2             10:05   39:27  15.16s  0.00s /usr/libexec/gsd-disk-utility-notify
henry    pts/1    192.168.1.168    10:43    1.00s  0.17s  0.02s w

获得被管理端的内核版本,具体操作如下:

ansible -i hosts webservers -m shell -a "uname -r"
192.168.1.30 | CHANGED | rc=0 >>
4.18.0-80.el8.x86_64

192.168.1.31 | CHANGED | rc=0 >>
4.18.0-80.el8.x86_64

获得内核版本后,发现不是最新内核,使用如下命令进行内核的升级:

ansible -i hosts -i hosts webservers -m command -a "dnf update kernel -y"

192.168.1.30 | CHANGED | rc=0 >>
Updating Subscription Management repositories.
Red Hat Enterprise Linux 8 for x86_64 - AppStre 625 kB/s | 9.2 MB     00:15
Red Hat Enterprise Linux 8 for x86_64 - BaseOS  608 kB/s | 8.1 MB     00:13
Last metadata expiration check: 0:00:05 ago on Mon 30 Sep 2019 10:13:09 AM EDT.
Dependencies resolved.
================================================================================
 Package        Arch   Version              Repository                     Size
================================================================================
Installing:
 kernel         x86_64 4.18.0-80.11.2.el8_0 rhel-8-for-x86_64-baseos-rpms 424 k
Installing dependencies:
 kernel-core    x86_64 4.18.0-80.11.2.el8_0 rhel-8-for-x86_64-baseos-rpms  24 M
 kernel-modules x86_64 4.18.0-80.11.2.el8_0 rhel-8-for-x86_64-baseos-rpms  20 M

Transaction Summary
================================================================================
Install  3 Packages

Total download size: 44 M
Installed size: 76 M
Downloading Packages:
(1/3): kernel-4.18.0-80.11.2.el8_0.x86_64.rpm    97 kB/s | 424 kB     00:04
(2/3): kernel-core-4.18.0-80.11.2.el8_0.x86_64. 578 kB/s |  24 MB     00:41
(3/3): kernel-modules-4.18.0-80.11.2.el8_0.x86_ 331 kB/s |  20 MB     01:01
--------------------------------------------------------------------------------
Total                                           730 kB/s |  44 MB     01:01
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                        1/1
  Installing       : kernel-core-4.18.0-80.11.2.el8_0.x86_64                1/3
  Running scriptlet: kernel-core-4.18.0-80.11.2.el8_0.x86_64                1/3
  Installing       : kernel-modules-4.18.0-80.11.2.el8_0.x86_64             2/3
  Running scriptlet: kernel-modules-4.18.0-80.11.2.el8_0.x86_64             2/3
  Installing       : kernel-4.18.0-80.11.2.el8_0.x86_64                     3/3
  Running scriptlet: kernel-core-4.18.0-80.11.2.el8_0.x86_64                3/3
  Running scriptlet: kernel-4.18.0-80.11.2.el8_0.x86_64                     3/3
  Verifying        : kernel-core-4.18.0-80.11.2.el8_0.x86_64                1/3
  Verifying        : kernel-4.18.0-80.11.2.el8_0.x86_64                     2/3
  Verifying        : kernel-modules-4.18.0-80.11.2.el8_0.x86_64             3/3
Installed products updated.

Installed:
  kernel-4.18.0-80.11.2.el8_0.x86_64
  kernel-core-4.18.0-80.11.2.el8_0.x86_64
  kernel-modules-4.18.0-80.11.2.el8_0.x86_64

192.168.1.30 | CHANGED | rc=0 >>
...

关于内核升级的更多操作,请复习第5章内核管理等内容。

   12.2.2.Ansible Playbook的创建和使用

Ansible还可以通过Playbook进行更为复杂的部署和配置,只需将部署及配置命令按照YAML格式编写出来即可,下面照例以一个简单的Hello world Playbook为例,管中窥豹,体验一下Playbook,Playbook内容如下:

cat helloworld.playbook
---                                                     #YAML文件的固定格式,三个西文横杠
- hosts: all                                    #所有被管理节点,横杠和冒号后必须留有一个空格,否则报错
  tasks:                                         #定义所执行的任务,注意缩进
    - name:  hello world                              #任务名称,横杠和冒号后必须留有一个空格,否则报错
      shell: echo hello world!                  #任务内容,横杠和冒号后必须留有一个空格,否则报错

随后执行如下命令运行Playbook,具体操作如下:

ansible-playbook -i hosts helloworld.playbook

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

TASK [Gathering Facts] *********************************************************************************************************************************************
ok: [192.168.1.30]
ok: [192.168.1.31]

TASK [hello world] *************************************************************************************************************************************************
changed: [192.168.1.31]
changed: [192.168.1.30]

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

如不小心遗漏了横杠或冒号后的空格,将会报如下的错误:

ERROR! Syntax Error while loading YAML.
  mapping values are not allowed in this context

The error appears to have been in '/home/henry/helloworld.playbook': line 3, column 8, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

- hosts:all
  tasks:
       ^ here
There appears to be a tab character at the start of the line.

YAML does not use tabs for formatting. Tabs should be replaced with spaces.

For example:
    - name: update tooling
      vars:
        version: 1.2.3
#    ^--- there is a tab there.

Should be written as:
    - name: update tooling
      vars:
        version: 1.2.3
# ^--- all spaces here.

为了防止执行时发生错误,最好先用如下命令检测一下:

ansible-playbook -i hosts helloworld.playbook --syntax-check

此外还需注意行中多余的Tab空格,也是引起报错的主要原因之一,最好只用空格,不用乱用Tab键。

成功执行了Playbook,但却无从验证,下面修改一下Playbook,让操作结果看的见,具体修改如下:

cat helloworld.playbook                                         #playbook配置文件的扩展名为yml也可以
---
- hosts: all                                                    #所有被管理节点
  tasks:                                        
    - name:  hello world
      shell: echo hello world! > ~/helloworld.ansible           #输出重定向到家目录下helloworld.ansible文件

再次运行如下命令执行Playbook,具体操作如下:
ansible-playbook helloworld.playbook  --syntax-check
ansible-playbook helloworld.playbook

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

TASK [Gathering Facts] *********************************************************************************************************************************************
ok: [192.168.1.31]
ok: [192.168.1.30]

TASK [hello world] *************************************************************************************************************************************************
changed: [192.168.1.31]
changed: [192.168.1.30]

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

这样,Playbook的操作就可以验证了,在管理节点浏览家目录,具体方法如下:

ll
total 8
-rw-------. 1 root root 1321 Jun 29 20:09 anaconda-ks.cfg
-rw-r--r--. 1 root root   13 Aug  5 17:40 helloworld.ansible

cat helloworld.ansible
hello world!

从上述结果可以验证,Ansible的Playbook执行成功,Playbook的编写规范可以参考其官方文档和范例,通过实例,结合Playbook的语法,可以快速入门。下面再循序渐进地掌握几个稍微复杂的Playbook,帮助大家巩固所学,学以致用,先从初始化系统的Playbook讲起,具体内容如下:

cat centos8_init.playbook                                           #或centos8_init.yml
---
- hosts: all
  user: root

  tasks:
    - name: disable selinux temporarily
      selinux:
        state: disabled
    - name: disable selinux permanently
      command: sed -i s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
    - name: stop firewalld server and disable it on reboot
      service:
        name: firewalld
        state: stopped
        enabled: false
    - name: Install a list of applications
      dnf:
        name:
           - wget
           - curl
           - unzip
           - lsof
           - net-tools
           - vim
           - git
        state: present

这个Playbook是用来初始化刚刚上线的服务器系统的,假设服务器系统都是安装的是CentOS 8,主要功能是关闭SELinux,禁止防火墙,安装高频工具等工具,当然大家可以自行增删脚本的内容,需要注意的还是缩进格式不能错,由于这个Playbook要比Helloworld复杂了不少,所以创建完此Playbook后,最好在运行前通过如下网站进行检测:
http://www.yamllint.com/ #在线检测YAML格式文件的错误

或:
https://onlineyamltools.com/validate-yaml

或通过Ansible命令检查:

ansible-playbook -i hosts centos8_init.playbook --syntax-check

通过检测后在运行如下命令执行Playbook:

ansible-playbook -i hosts centos8_init.playbook

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

TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.1.30]
ok: [192.168.1.31]

TASK [disable selinux temporarily] ******************************************************************************************************
 [WARNING]: SELinux state change will take effect next reboot

ok: [192.168.1.30]
ok: [192.168.1.31]

TASK [disable selinux permanently] ******************************************************************************************************
 [WARNING]: Consider using the replace, lineinfile or template module rather than running 'sed'.  If you need to use command because
replace, lineinfile or template is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.

changed: [192.168.1.30]
changed: [192.168.1.31]

TASK [stop firewalld server and disable it on reboot] ***********************************************************************************
ok: [192.168.1.30]
ok: [192.168.1.31]

TASK [Install a list of applications] ***************************************************************************************************
ok: [192.168.1.30]
ok: [192.168.1.31]

PLAY RECAP ******************************************************************************************************************************
192.168.1.30           : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
192.168.1.31           : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

如果这个Playbook顺利应用,再来一个关于网络服务安装和管理的Playbook,自动安装和启动Nginx,并令其随系统一起启动的Playbook,关键内容如下:

cat nginx_deploy.playbook                               #或nginx_deploy.yml
---                                                     #一定不能忽略
- hosts: all                                            #实际应用中可指定主机或分组
  user: root

  tasks:
  - name: copy nginx repo. file                         #每行的缩进一定要注意,缩进错了就会报错,很烦人
    copy:
      src: ~/nginx.repo                                 #将本地nginx.repo复制到远端被管理的服务器
      dest: /etc/yum.repos.d/nginx.repo
      owner: root
      group: root
      mode: '0644'
  - name: deploy nginx
    dnf:
      name: nginx
      state: installed
  - name: start and enable nginx service
    systemd: 
      name: nginx
      state: started
      enabled: true

查看另外一个文件:

cat ~/nginx.repo

文件内容如下:
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/rhel/8/$basearch/
gpgcheck=0
enabled=1

或直接安装Nginx的软件仓库:
cat nginx_deploy.playbook
---                                                     #一定不能忽略
- hosts: all                                            #实际应用中可指定主机或分组
  user: root

  tasks:                                                #从官方安装Nginx的软件仓库软件包
  - name: deploy nginx
    dnf:
      name: http://nginx.org/packages/mainline/rhel/8/x86_64/RPMS/nginx-1.17.4-1.el8.ngx.x86_64.rpm 
      state: installed
  - name: start and enable nginx service
    systemd: 
      name: nginx
      state: started
      enabled: true

最后则是一个自动化部署LAMP stack的Playbook,部署Zabbix时将会用到,需要注意的是,应该先将Nginx卸载,免得冲突,卸载Nginx的Playbook内容如下:

cat nginx_purge.playbook
---
- hosts: all                                            
  user: root

  tasks:
  - name: remove the nginx package
    dnf:
      name: nginx
      state: absent

该Playbook等价于如下命令:

ansible -i hosts -i hosts webservers -m command -a "dnf remove nginx -y"

然后再部署LAMP stack,LAMP stack的Playbook内容如下:

vi lamp_stack.playbook                                  #或lamp_stack.yml

内容如下:

---                                                     #一定不能忽略
- hosts: all                                            #实际应用中可指定主机或分组
  user: root

  tasks:                                                #每行的缩进一定要注意,缩进错了就会报错,很烦人
    - name: install mariadb database
      dnf: name={{item}} state=installed
      with_items:
      - mariadb-server
      - mariadb
    - name: start mariadb server and enable it on reboot
      service:
        name: mariadb
        state: started
        enabled: true
    - name: install Apache Web service
      dnf:
        name: httpd
        state: installed
    - name: start Apache Web server and enable it on reboot
      service:
        name: httpd
        state: started
        enabled: true
    - name: install php
      dnf: name={{item}} state=installed
      with_items:
      - php-mysqlnd
      - php-fpm
    - name: lamp testing file
      shell: echo "<?php phpinfo (); ?>" > /var/www/html/info.php
    - name: restart httpd
      service:
        name: httpd
        state: restarted
    - name: stop firewalld server and disable it on reboot
      service:
        name: firewalld
        state: stopped
        enabled: false

保存退出后,先运行如下脚本检测是否有语法问题:

ansible-playbook -i hosts lamp_stack.playbook --syntax-check    #检查PlayBook语法

如果没有报错,即可运行如下命令自动化部署LAMP stack:

ansible-playbook -i hosts lamp_stack.playbook

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

TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.1.30]
ok: [192.168.1.31]

TASK [install mariadb database] *********************************************************************************************************
[DEPRECATION WARNING]: Invoking "dnf" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items and
specifying `name: "{{item}}"`, please use `name: ['mariadb-server', 'mariadb']` and remove the loop. This feature will be removed in version 2.11. Deprecation
warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: Invoking "dnf" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items and
specifying `name: "{{item}}"`, please use `name: ['mariadb-server', 'mariadb']` and remove the loop. This feature will be removed in version 2.11. Deprecation
warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
changed: [192.168.1.31] => (item=[u'mariadb-server', u'mariadb'])
changed: [192.168.1.30] => (item=[u'mariadb-server', u'mariadb'])

TASK [start mariadb server and enable it on reboot] *************************************************************************************
ok: [192.168.1.30]
ok: [192.168.1.31]

TASK [install Apache Web service] *******************************************************************************************************
ok: [192.168.1.30]
ok: [192.168.1.31]

TASK [start Apache Web server and enable it on reboot] **********************************************************************************
ok: [192.168.1.30]
ok: [192.168.1.31]

TASK [install php] **********************************************************************************************************************
[DEPRECATION WARNING]: Invoking "dnf" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items and
specifying `name: "{{item}}"`, please use `name: ['php-mysqlnd', 'php-fpm']` and remove the loop. This feature will be removed in version 2.11. Deprecation
warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: Invoking "dnf" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items and
specifying `name: "{{item}}"`, please use `name: ['php-mysqlnd', 'php-fpm']` and remove the loop. This feature will be removed in version 2.11. Deprecation
warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
changed: [192.168.1.31] => (item=[u'php-mysqlnd', u'php-fpm'])
changed: [192.168.1.30] => (item=[u'php-mysqlnd', u'php-fpm'])

TASK [lamp testing file] ****************************************************************************************************************
changed: [192.168.1.30]
changed: [192.168.1.31]

TASK [restart httpd] ********************************************************************************************************************
changed: [192.168.1.30]
changed: [192.168.1.31]

TASK [stop firewalld server and disable it on reboot] ***********************************************************************************
changed: [192.168.1.30]
changed: [192.168.1.31]

PLAY RECAP ******************************************************************************************************************************
192.168.1.30            : ok=9    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
192.168.1.31            : ok=9    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

成功部署后,浏览器直接访问服务器IP/info.php,应该可以看到PHP的相关信息了,一个Fast-CGI的LAMP stack很快就搭建好了,效率提升极大。通过上述几个Playbook实例,帮助大家学以致用,熟练掌握后应该可以创建自己的Playbook了,最后,留个作业,上述Playbook还有很大的优化空间,请大家规范并优化上述Playbook并创建几个自己常用服务的剧本试试手。

Playbooks的官方文档:
http://docs.ansible.com/playbooks.html

Playbooks官方范例:
https://github.com/ansible/ansible-examples

12.3 Zabbix监控企业服务器

有道是无监控,不运维,对于企业的大量服务器而言,服务器状态主要是通过监控软件获得,开源的监控软件很多,如MRTG,Catic,Nagios等,不过最为流行的,还是后起之秀Zabbix。

Zabbix是由PHP开发,基于LAMP的开源监控项目,具有漂亮实用的Web界面,可对各种网络服务进行监控,为企业服务器稳定运行提供了数据依据。Zabbix主要由2部分构成,即zabbix server和zabbix agent(支持代理zabbix proxy),服务器端主要通过Client/Server架构采集数据,而用户端则采用Browser/Server架构,通过简捷易用的WEb界面进行配置和管理, 还支持从多种数据采集通道获得数据,除了最为基本的Zabbix Agnet所搜集的数据之外,还支持通过IPMI和SNMP等协议获取数据,并保存到MySQl或PostgreSQL数据库中,还面向用户提供了触发器和消息反馈机制。Zabbix的Logo如图12-3所示。

图12-3 Zabbix的Logo(图片来源:Zabbix官网)

Zabbix的官方地址为:
https://www.zabbix.com/

下面就以部署一个管理节点Zabbix server和两个Zabbix agent被管理节点为例来介绍Zabbix的手动部署,规划如下:
角色 主机名 IP地址
Zabbix server zabbix.example.com 192.168.1.168
Zabbix agnet node1 192.168.1.30
Zabbix agent node2 192.168.1.31

   12.3.1 准备部署Zabbix

1.修改Zabbix server主机名
根据规划,首先运行如下命令修改主机名和静态解析:
hostnamectl set-hostname zabbix.example.com #被监控的两个节点方法相同
vi /etc/hosts

添加如下配置:
192.168.1.168 zabbix.example.com

之后还需关闭各个节点的SELinux和防火墙,具体操作如下:
◆关闭防火墙
systemctl stop firewalld.service #暂时关闭防火墙
systemctl disable firewalld.service #永久关闭防火墙

◆关闭SELinux
setenforce 0 #将SELinux设置为宽容模式
sed -i '/SELINUX/s/enforcing/Disabled/' /etc/selinux/config #永久关闭SELinux

   12.3.2.部署和配置Zabbix server

安装LAMP,请参阅前面章节的内容,此处不做赘述,还需创建测试页检测,具体操作如下:

vim  /var/www/html/info.php

代码如下:
<?php
phpinfo();
?>

创建代码后,使用浏览器打开info.php,可以看到PHP的测试页,说明LAMP部署成功,如通过上述Playbook部署LAMP stack则无需创建,Playbook将会自动创建。

◆修改Apache主机名称
通过编辑器编辑Apache虚拟主机的默认配置文件,具体操作如下:

vi /etc/httpd/conf/httpd.conf

定位到ServerName,并将其值修改为如下内容:

ServerName zabbix.example.com

◆修改PHP相关配置
PHP相关配置对于Zabbix十分重要,相关配置的具体操作如下:

vi /etc/php.ini
date.timezone = America/Toronto                 #大家可能就实际情况修改,如Asia/Shanghai
post_max_size = 16M
max_execution_time = 300                              #这些值都是Zabbix所要求的
max_input_time = 300

管理lamp-server服务
成功安装和配置后,运行如下命令重启lamp-server服务:

systemctl restart httpd mysql           #或mariadb,视具体情况而定
systemctl enable httpd mysql            #或mariadb,视具体情况而定

3.部署Zabbix Server

rpm -ivh http://repo.zabbix.com/zabbix/4.2/rhel/8/x86_64/zabbix-release-4.2-2.el8.noarch.rpm                    #下载Zabbix软件仓库包
dnf install zabbix-server-mysql zabbix-proxy-mysql zabbix-web-mysql -y

4.配置Zabbix时区

修改Apache的时区,具体方法如下:

vi /etc/httpd/conf.d/zabbix.conf

配置如下:
php_value date.timezone America/Toronto

5.创建Zabbix数据库

由于Zabbix将从Agent搜集来的数据保存到数据库,所以需要执行如下命令创建zabbix数据库:

mysql -uroot -p                             #默认密码为空
mysql> CREATE DATABASE zabbix;
mysql> GRANT ALL PRIVILEGES ON zabbix.* TO zabbix@localhost IDENTIFIED BY 'zabbix';         #此处为了简单,故密码设置比较简单,工作环境请设置安全密码
mysql> FLUSH PRIVILEGES;
mysql> QUIT;

创建了zabbix数据库之后,就可以将预定义好的scheme导入,具体操作如下:
 zcat /usr/share/doc/zabbix-server-mysql/create.sql.gz | mysql -uzabbix -pzabbix -D zabbix                                          #导入zabbix数据库的schema

之后配置Zabbix数据库用户及密码

vi /etc/zabbix/zabbix_server.conf

关键配置如下:
...
DBHost=localhost
DBName=zabbix
DBUser=zabbix
DBPassword=zabbix
...

6.Zabbix server的管理

运行如下命令启动,重启及停止zabbix及相关服务:

systemctl start zabbix-server httpd php-fpm mariadb         
systemctl restart zabbix-server httpd php-fpm mariadb   
systemctl stop zabbix-server httpd php-fpm mariadb  

如设置为随系统一同启动,命令如下:

systemctl enable zabbix-server zabbix-agent httpd mariadb

下面就来学以致用一下,使用Ansible部署Zabbix服务器,具体思路为,由于Zabbix是基于LAMP stack架构的,故先使用相应的Playbook自动实现,并手动配置PHP参数并创建Zabbix数据库,然后再创建Zabbix server的部署Playbook,Zabbix server的自动化部署脚本代码如下:

vi zabbix_server.playbook               #或zabbix_server.yml

内容如下:
---
- hosts: zabbix_server                  #测试时可用all
  user: root
  vars:
     mysql_root_password: hhhhhhhh
  tasks:
  - name: install zabbix repo.
      dnf:
        name: http://repo.zabbix.com/zabbix/4.2/rhel/8/x86_64/zabbix-release-4.2-2.el8.noarch.rpm
        state: installed
  - name: install centos zabbix server
    dnf:
      name: "{{ item }}"
      state: installed
    with_items:
      - zabbix-server-mysql
      - zabbix-server
      - zabbix-proxy-mysql
      - zabbix-web-mysql
  - name: modify zabbix config
    replace:
      path:  /etc/zabbix/zabbix_server.conf 
      regexp: DBUser=zabbix
      replace: DBUser=root
  - name: Install the Python2 MySQL Support Libraries
      dnf: pkg=python2-PyMySQL state=latest
  - name: Install the Python3 MySQL Support Libraries
      dnf: pkg=python3-PyMySQL state=latest
  - name: update mysql root password for all root accounts
      mysql_user:
        name: root
        password: "{{ mysql_root_password }}"
        login_user: root
        login_password: "{{ mysql_root_password }}"
        check_implicit_admin: yes
        priv: "*.*:ALL,GRANT"
  - name: import zabbix database and tables
      mysql_db: name=zabbix state=import target=/usr/share/doc/zabbix-server-mysql/create.sql.gz login_user=root login_password={{ mysql_root_password }}
  - name: start zabbix-server
    systemd:
      name: zabbix-server
      state: started

保存退出后,先运行如下脚本检测是否有语法问题:
ansible-playbook zabbix_server.playbook --syntax-check      #检查PlayBook语法

如果没有报错,说明语法没有问题,再运行如下命令完成部署:
ansible-playbook zabbix_server.playbook

随后的playbook可能更为实用,因为Zabbix客户端可能需要部署好多,这样一条命令就全部自动化安装,关键操作如下:

vi zabbix_clients.playbook

内容如下:
---
- hosts: zabbix_clients
  tasks:
    - name: install zabbix repo.
      dnf:
        name: http://repo.zabbix.com/zabbix/4.2/rhel/8/x86_64/zabbix-release-4.2-2.el8.noarch.rpm
        state: installed
    - name: install centos zabbix server
      dnf:
        name: "{{ item }}"
        state: installed
      with_items:
        - zabbix-get
        - zabbix-agent
        - zabbix-sender

保存退出后,先运行如下脚本检测是否有语法问题:
ansible-playbook zabbix_clients.playbook --syntax-check #检查PlayBook语法

最后,运行如下命令完成自动批量部署:
ansible-playbook zabbix_clients.playbook

上述Zabbix Ansible playbook其实就是Zabbix server通过Ansible所进行的自动化部署,以后不要手动安装了。这样,再也不用为安装数量繁多的Zabbix客户端而头痛了。尽管如此,上述几个Playbook还有很大的改进空间,希望大家通过它们掌握了Ansible的Playbook后,在更进一步,对它们进行优化和完善,并根据实际情况创建出自己的Playbook,学以致用。

7.Web安装界面安装Zabbix

Web安装界面安装Zabbix,相对直观和简单,只需再浏览器中访问如下地址:
http://zabbix.example.com/zabbix/setup.php

根据提示进行安装,关键是数据库设置,只需将上述设定好的数据库参数正确输入即可,具体配置如图12-4所示。

图12-4 配置数据库

成功安装后使用默认账号密码登录:
用户名:Admin
密码:zabbix

登录到Zabbix的Web控制界面,说明安装成功,成功登录后效果如图12-5所示。

图12-5 使用默认用户和密码登录Zabbix

随后就看到Zabbix 4.2的真面目了,简洁,美观,大方,Zabbix主界面如图12-6所示。

图12-6 Zabbix主界面

8.Zabbix Agent部署和配置
先别急着使用Zabbix,鉴于Zabbix的数据主要来自Zabbix Agent,故需要在所有被监控的服务器端安装zabbix-agent服务,具体方法如下:
rpm -ivh http://repo.zabbix.com/zabbix/4.2/rhel/8/x86_64/zabbix-release-4.2-2.el8.noarch.rpm #下载Zabbix软件仓库包
dnf install zabbix-get zabbix-agent zabbix-sender -y


成功安装后,还需修改Agent默认的配置,具体方法如下:

vi /etc/zabbix/zabbix_agentd.conf


定位到Server关键字,将其值由127.0.0.1修改为Zabbix serverIP地址,此外,还需配置如下选项:

ServerActive=Zabbix server IP地址
Hostname=Zabbix server主机名称

保存退出后运行如下命令重启客户端:

systemctl restart zabbix-agent


Zabbix客户端部署好了之后,便可在服务的进行连通性测试了,在Zabbix serrver上运行如下命令进行安装所需软件包,测试,获取被监控服务器的处理器负载:

zabbix_get -s 192.168.1.30 -p 10050 -k "system.cpu.load[all,avg15]" #-s指定监控主机的IP地址,-p指定Zabbix的端口号,默认为10050,-k指定监控项目的关键字
0.050000

如需获得连续的状态信息,可以运行如下命令:
watch -n 1 zabbix_get -s 192.168.1.30 -p 10050 -k "system.cpu.load[all,avg15]" #watch命令可以每间隔秒运行一次指定命令

还可以获取被监控主机各种信息:
zabbix_get -s 192.168.1.30 -p 10050 -k "system.hostname"
node1 #主机名

zabbix_get -s 192.168.1.30 -p 10050 -k "system.uptime"
25084 #服务器开机秒数

zabbix_get -s 192.168.1.30 -p 10050 -k "system.boottime"
1553179925 #系统启动的时间点,数值是时间戳,即从1970年1月1日开始所经过的秒数

zabbix_get -s 192.168.1.30 -p 10050 -k "system.localtime"
1553205259 #系统时间,从1970年1月1日开始所经过的秒数

zabbix_get -s 192.168.1.30 -p 10050 -k "system.uname"
Linux centos8 4.18.0-80.el8.x86_64 #1 SMP Tue Jun 4 09:19:46 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux #Linux服务器信息,相当于执行uname -a

zabbix_get -s 192.168.1.30 -p 10050 -k "vm.memory.size[total]" #物理内存总量,单位是byte
8339935232

zabbix_get -s 192.168.1.30 -p 10050 -k "system.swap.size[,total]" #交换分区容量
2147479552

如测试Web服务器,则可以运行如下命令:
zabbix_get -s 192.168.1.30 -p 10050 -k "net.tcp.port[,80]"
1

如果返回0,则表示连接失败。

如测试MySQL服务器,则可以运行如下命令:
zabbix_get -s 192.168.1.30 -p 10050 -k "net.tcp.port[,3306]"
1

如果返回0,则表示连接失败。

9.Web管理和使用Zabbix server
Zabbix server成功部署,Zabbix客户端也工作正常,来看看Zabbix Web界面如何的基本操作吧。

◆监控Zabbix server
要监控Zabbix server,首先Zabbix server需要安装Agent软件包,然后选择主菜单Monitor-Screens-Zabbix server选项,可以看到Zabbix server的处理器使用详情,具体情况如图12-7所示。

12-7 Zabbix server的处理器信息

如果嫌上述信息太笼统,还可以单项查看,具体方法为,选择主菜单Monitor-Graphs选项,从右上角的Group下拉列表框中选择Zabbix server,Host下拉列表框中选择Zabbix server,从Graph下拉列表框中的Zabbix所提供的众多监控选项选择一项,这里就选择CPU Jump(CPU上下文切换),具体情况如图12-8所示。

12-8 Zabbix server的上下文切换

◆监控所有节点
除了查看,还需要创建一台监控主机,即Zabbix server,方法也很简单,选择主菜单Configration-Hosts选项,单击右上角Create Host按钮,根据图12-9添加Zabbix server。

12-9 添加Zabbix server

然后如法炮制,将Node1和Node2也添加到Zabbix server,如图12-1012-11所示。

12-10 添加Node2

12-11 将三个节点全部添加

成功添加主机后,如果不显示所添加主机可以尝试单击Reset键,此外,还需要根据企业实际情况定制监控配置,更多的配置方法请参阅Zabbix的官方文档,Zabbix(4.2)官方文档地址如下:
https://www.zabbix.com/documentation/current/manual

此外,推荐大家一个很有价值的网站-Zabbix share,该网站有大量模板,模块等有价值的共享,常去逛逛总有收获,地址如下:
https://share.zabbix.com/

小结
本章主要介绍了自动化批量部署系统,应用和配置的工具,帮助大家掌握它们的基本使用,并通过它们确确实实地提高企业的IT管理的自动化水平,提高效率,此外,实时监控对于企业的IT管理极为重要,是获得反馈的重要来源,本章帮助大家掌握最为流行的监控项目Zabbix最新版本的基本使用和配置,内容都较为基础和实用,进一步的使用,如YAML的语法和实现及Zabbix监控的各种配置等,都已经超出了CentOS 8系统本身的范畴,需要大家通过官方文档,并结合实际去探索和钻研。

EOF

参考文献
https://stackoverflow.com/questions/44583740/no-module-named-packaging-version-for-ansible-vm-provisioning-in-azure
https://linuxconfig.org/ansible-installation-on-centos-7-linux
https://gist.github.com/vovanmix/0a2ea225692645ef770e
https://maas.io/how-it-works
https://en.wikipedia.org/wiki/Preboot_Execution_Environment
https://en.wikipedia.org/wiki/Cobbler_(software)
https://wiki.debian.org/DebianInstaller/Preseed

引用图片
12-1:https://i.stack.imgur.com/JQHjw.png
12-3:https://cdn-images-1.medium.com/max/1600/1*qykIU2PUoEnkdoPuYvIlOg.png

版权声明:
作者:WaterBear
链接:https://l-t.top/2620.html
来源:雷霆运维
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录