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 server的IP地址,此外,还需配置如下选项:
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-10和12-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