该系列的一部分:
常见的 HAProxy 错误
本教程系列介绍了如何对您在使用HAProxy TCP 和 HTTP 代理服务器时可能遇到的一些最常见错误进行故障排除和修复。
本系列中的每个教程都包含对常见 HAProxy 配置、网络、文件系统或权限错误的描述。该系列首先概述了可用于对 HAProxy 进行故障排除的命令和日志文件。后续教程详细检查特定错误。
介绍
HAProxy 代表高可用性代理,是一种广泛使用的基于 TCP 和 HTTP 的代理服务器,可在 Linux、Solaris 和 FreeBSD 上运行。它用于通过在多个服务器之间分发请求来平衡应用程序,并确保应用程序对用户具有高可用性。
默认情况下,在许多 CentOS 8 安装中,HAProxy 未配置为将其日志输出写入文件。本快速入门教程将解释如何通过使用 Unix 域套接字来使用 Rsyslog 配置 HAProxy 日志记录以实现可靠性、速度和安全性。
先决条件
要完成本教程,您需要一台运行 CentOS 8 的服务器。该服务器应具有具有管理权限的非 root 用户。要进行设置,请遵循CentOS 8教程的初始服务器设置指南。
步骤 1 — 安装和启用 HAProxy
要安装 HAProxy,请运行以下dnf
命令:
- sudo dnf install haproxy
当系统提示您Is this ok [y/N]:
输入y
并按下RETURN
以安装软件包时。
安装 HAProxy 后,使用以下systemctl
命令启用并启动它:
- sudo systemctl enable haproxy.service
您应该会收到以下输出:
OutputCreated symlink /etc/systemd/system/multi-user.target.wants/haproxy.service → /usr/lib/systemd/system/haproxy.service.
现在启用 HAProxy 服务后,您可以启动它以确保它在您的服务器上以默认配置运行:
- sudo systemctl start haproxy.service
接下来检查 HAProxy 的状态以确保它正在运行:
- sudo systemctl status haproxy.service
您应该会收到如下输出。请注意active (running)
输出的突出显示部分。如果您的服务器显示相同的突出显示部分,则 HAProxy 在您的服务器上正常运行,您可以继续配置日志记录。
Output● haproxy.service - HAProxy Load Balancer
Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2020-09-09 21:16:39 UTC; 4min 39s ago
Process: 21340 ExecStartPre=/usr/sbin/haproxy -f $CONFIG -c -q (code=exited, status=0/SUCCESS)
Main PID: 21341 (haproxy)
Tasks: 2 (limit: 2881)
Memory: 2.7M
CGroup: /system.slice/haproxy.service
├─21341 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid
. . .
如果您的输出不同,或者状态显示类似Active: failed
,请按照如何对常见 HAProxy 错误进行故障排除教程中的故障排除步骤确定阻止 HAProxy 正确启动的原因。
确认 HAProxy 已启用并正在运行后,您可以继续下一步,即配置 HAProxy 的日志记录指令。
第 2 步 – 配置 HAProxy 日志记录指令
要配置 HAProxy 的日志记录指令,请/etc/haproxy/haproxy.cfg
在vi
或您首选的编辑器中打开:
- sudo vi /etc/haproxy/haproxy.cfg
按i
切换到INSERT
模式,然后找到该行log 127.0.0.1 local2
并通过#
在该行的开头添加一个字符来将其注释掉,如以下示例中突出显示的:
. . .
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
#log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
. . .
现在直接在注释掉的行之后添加一行,内容如下:
log /dev/log local0
/etc/haproxy/haproxy.cfg
您编辑的整个部分应包含以下几行:
. . .
# local2.* /var/log/haproxy.log
#
#log 127.0.0.1 local2
log /dev/log local0
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
. . .
该chroot
行很重要,因为它限制 HAProxy 进程只能访问目录中的/var/lib/haproxy
文件。该log /dev/log local0
行将在该目录中创建一个文件,Rsyslog 将使用该文件从中收集日志条目。
完成对中的log
行的编辑后/etc/haproxy/haproxy.cfg
,通过按ESC
、键入:wq
和按来保存并关闭文件ENTER
。
您需要在本节中完成的最后一步是创建/var/lib/haproxy/dev
目录,因为它默认不存在。
使用mkdir
命令创建目录,然后重新启动 HAProxy:
- sudo mkdir /var/lib/haproxy/dev
- sudo systemctl restart haproxy.service
您现在已将 HAProxy 配置为将其日志发送到驻留在/var/lib/haproxy/dev/log
. 在下一步中,您将配置 Rsyslog 以创建和访问套接字。
第 3 步 – 配置 Rsyslog 以收集 HAProxy 日志
Rsyslog 在 CentOS 8 上的默认配置不处理 HAProxy 日志。要从 HAProxy 服务收集日志,请/etc/rsyslog.d/99-haproxy.conf
使用vi
或您喜欢的编辑器打开一个新文件:
- sudo vi /etc/rsyslog.d/99-haproxy.conf
按i
切换到INSERT
模式,然后将以下行粘贴到文件中:
$AddUnixListenSocket /var/lib/haproxy/dev/log
# Send HAProxy messages to a dedicated logfile
:programname, startswith, "haproxy" {
/var/log/haproxy.log
stop
}
该$AddUnixListenSocket
指令告诉 Rsyslog 在指定位置创建一个 Unix 域套接字,在本例中为/var/lib/haproxy/dev/log
。该:programname, startswith, "haproxy"
部分指定了 Rsyslog 将从套接字收集的日志条目写入的文件。
完成编辑后/etc/rsyslog.d/99-haproxy.conf
,通过按ESC
、键入:wq
和按保存并关闭文件ENTER
。
您现在已将 Rsyslog 配置为从 Unix 域套接字中读取日志条目/var/lib/haproxy/dev/log
并将它们写入/var/log/haproxy.log
.
但是,在重新启动 Rsyslog 之前,您需要确定 SELinux 是否在 CentOS 8 系统上强制执行访问控制。
要检查 SELinux 的当前策略,请运行以下命令:
- getenforce
您将收到一个以下输出:
Enforcing
– 在这种模式下,SELinux 正在对您的系统实施访问控制。您需要完成以下可选的步骤 4 — 配置 SELinux部分。Permissive
– 在这种情况下,SELinux 会记录对其日志文件的所有访问尝试,但不会对您的系统实施访问控制。Disabled
– 如果 SELinux 被禁用,则它不会在您的系统上记录或执行任何访问控制策略。
如果getenforce
命令返回Permissive
或Disabled
,则可以使用以下命令重新启动 Rsyslog:
- sudo systemctl restart rsyslog
重新启动 Rsyslog 后,您将能够查看您在 .config/var/log/haproxy.log
文件中配置的文件中的日志/etc/rsyslog.d/99-haproxy.conf
。继续第 5 步 — 测试 HAProxy 日志记录以确保一切按预期工作。
否则,如果您的系统在Enforcing
模式下运行 SELinux ,那么本教程的下一部分将解释如何添加模块以允许 Rsyslog 和 HAProxy 通过其共享的 Unix 域套接字相互通信。
第 4 步 -(可选)配置 SELinux
如果你的 CentOS 8 系统配置了 SELinuxEnforcing
模式,那么你需要允许 Rsyslog 访问 HAProxy 的chroot
目录。允许此访问将让 Rsyslog 创建 Unix 域套接字,HAproxy 会将其日志发送到该套接字。
如果您不熟悉 SELinux,本教程系列CentOS 7 上的 SELinux 简介将帮助您学习如何管理 SELinux 并与 SELinux 交互。虽然是为 CentOS 7 编写的,但系列中的原理和命令同样适用于 CentOS 8。
要启用 Rsyslog 和 HAProxy 对其共享套接字的访问,第一个任务是创建类型强制策略文件。打开名为一个新的文件rsyslog-haproxy.te
中vi
或你喜欢的编辑器:
- vi rsyslog-haproxy.te
按i
切换到INSERT
模式,然后将以下行粘贴到文件中:
module rsyslog-haproxy 1.0;
require {
type syslogd_t;
type haproxy_var_lib_t;
class dir { add_name remove_name search write };
class sock_file { create setattr unlink };
}
#============= syslogd_t ==============
allow syslogd_t haproxy_var_lib_t:dir { add_name remove_name search write };
allow syslogd_t haproxy_var_lib_t:sock_file { create setattr unlink };
第一行定义模块名称和版本。该require
部分告诉 SELinux 模块加载器有关作为模块加载的策略所需的类型和类。最后两行是允许 Rsyslog 分别访问 HAProxychroot
和套接字文件的规则。
完成文件编辑后,通过按ESC
、键入:wq
和按来保存并关闭它ENTER
。
接下来,运行以下命令来安装checkpolicy
包,其中包含checkmodule
将用于将类型强制文件转换为 SELinux 模块的实用程序。
- sudo dnf install checkpolicy
现在您已经checkmodule
安装了该工具,下一步是编译模块,然后将其加载到 SELinux 中。运行以下命令将 Type Enforcement 文件编译为 SELinux 模块:
- checkmodule -M -m rsyslog-haproxy.te -o rsyslog-haproxy.mod
接下来,运行semodule_package
生成一个完整的策略包,SELinux 可以加载到 Linux 内核中:
- semodule_package -o rsyslog-haproxy.pp -m rsyslog-haproxy.mod
最后一步是使用以下semodule
命令将您生成的包加载到 Linux 内核中:
- sudo semodule -i rsyslog-haproxy.pp
添加模块可能需要几秒钟。命令完成后,您可以通过运行以下semodule
命令确认模块已加载到内核中:
- sudo semodule -l |grep rsyslog-haproxy
您应该收到如下输出:
Outputrsyslog-haproxy
加载模块后,您可以使用以下命令重新启动 Rsyslog:
- sudo systemctl restart rsyslog
您现在已经定义、编译并加载了一个 SELinux 策略,该策略将允许 HAProxy 和 Rsyslog 通过它们的共享套接字进行通信。
在下一步中,您将通过向 HAProxy 发出 HTTP 请求并检查其新日志文件来测试一切是否正常。
步骤 5 — 测试 HAProxy 日志记录
现在您已经配置了 HAProxy、Rsyslog 和可选的 SELinux,您可以测试日志记录/var/log/haproxy.log
是否正常工作。
默认情况下,该haproxy
软件包附带一个配置文件,该文件在端口 5000 上创建一个 HTTP 侦听器套接字。该配置指向一个不存在的后端服务器,因此对该端口的任何请求都将导致 HTTP 503 错误。
要检查/var/log/haproxy.log
文件中的 503 错误,请首先使用curl
如下方式生成 HTTP 请求:
- curl -si http://127.0.0.1:5000
您应该收到如下输出:
OutputHTTP/1.0 503 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html
<html><body><h1>503 Service Unavailable</h1>
No server is available to handle this request.
</body></html>
现在/var/log/haproxy.log
使用以下grep
命令检查任何 HTTP 503 响应:
- sudo grep -E 'NOSRV.+503' /var/log/haproxy.log
注意:NOSRV.+503
命令的部分是正则表达式。这个关于在 Linux 中使用 Grep 和正则表达式搜索文本模式的
教程更深入地使用grep
正则表达式。
您应该收到如下一行(或多行):
OutputSep 9 21:32:22 centos-s-1vcpu-1gb-nyc3-01 haproxy[4451]: 127.0.0.1:56024 [9/Sep/2020:21:32:22.098] main app/<NOSRV> 0/-1/-1/-1/0 503 212 - - SC-- 1/1/0/0/0 0/0 "GET / HTTP/1.1"
此行对应于curl
您提出的请求,这意味着 Rsyslog 和 HAProxy 已配置为正确使用它们的共享套接字。
结论
在本快速入门教程中,您将 HAProxy 配置为登录到 Unix 域套接字。您还设置了 Rsyslog 来创建和读取套接字,以便两个程序可以相互通信,而无需打开系统上的任何 TCP/IP 端口。最后,您可以选择编译、打包和加载 SELinux 策略,以允许 Rsyslog 和 HAProxy 共享访问其套接字。