Haproxy + confd + etcd搭建负载均衡框架
Haproxy + confd + etcd搭建负载均衡框架
前言
=> 最近工作上接触到了haproxy与confd、etcd搭配起来的负载均衡架构的项目。由于以前只接触过nginx,从没接触过haproxy等技术栈,对其流程运转比较迷茫,因此在本地搭建了一套单机版本的,便于理解和熟悉业务流程。
本地环境
| 序号 | 资源 | 版本 |
|---|---|---|
| 1. | 电脑 | Mac16 M1 |
| 2. | VM操作系统 | CentOS8 arm64 (VMware Fusion) |
| 3. | Haproxy | 2.3.13 |
| 4. | confd | 0.16.0 |
| 5. | etcd | V3.5.10 |
一、流程关系
三者的关系图谱暂时先不画了,有时间的话补上,累了。
二、搭建
2.1 Haproxy
HAProxy 是一款高性能的开源负载均衡软件,主要用于分布式系统中处理流量分发、高可用性管理和代理服务。
它支持HTTP、TCP、WebSocket 等多种协议,既能作为七层(应用层)负载均衡器(处理 HTTP 头部、URI 路由等),
也能作为四层(传输层)负载均衡器(基于 IP 和端口转发流量),广泛应用于 Web 服务器、数据库集群、消息队列等场景。
2.1.1 安装包及解码安装
**官网:https://www.haproxy.org/ **
下载地址:https://www.haproxy.org/#down
不过可以从这里(https://src.fedoraproject.org/repo/pkgs/haproxy/ )选择一个版本进行下载,这里我用的是haproxy-2.3.13.tar.gz版本。通过 Transmit 工具将其上传到虚拟机中(这里我的路径是: My_WorkSpace/My_project)

或者可以通过wget进行下载
# 安装wget
yum -y install wget
# 下载haproxy
wget http://fossies.org/linux/misc/haproxy-2.3.13.tar.gz
2.1.2 解压编码安装
解压到/usr/local/src
tar -zxvf haproxy-2.3.13.tar.gz -C /usr/local/src
2.1.3 切换到/usr/local/src/haproxy-2.3.13/,查看linux内核版本
cd /usr/local/src/haproxy-2.3.13/
uname -r

2.1.4 安装gcc、编译-make、安装
#第一步:安装gcc
sudo yum -y install gcc gcc-c++ libstdc++-devel
#安装好之后查看版本
gcc -v
# 第二步:编译-make
# PREFIX=/usr/local/haproxy为haprpxy安装路径。
# CentOS 8默认内核为4.18.x,因此使用 linux418
make TARGET=linux418 PREFIX=/usr/local/haproxy ARCH=aarch64
# 第三步:安装
make install PREFIX=/usr/local/haproxy
# 第四步:创建数据目录放pid文件(等到启动的时候,会自动生成)
mkdir -p /usr/data/haproxy/
2.1.5 编写cfg配置文件
#全局配置
global
log 127.0.0.1 local0
#log 127.0.0.1 local1 notice
#log loghost local0 info
maxconn 4096
#程序的目录
chroot /usr/local/haproxy
#指定进程pid的文件
pidfile /usr/data/haproxy/haproxy.pid
uid 99
gid 99
daemon
#debug
#quiet
defaults
log global
mode http
option httplog
option dontlognull
retries 3
maxconn 2000
timeout connect 5s
timeout client 30s
timeout server 30s
timeout http-request 10s
# frontend结合backend配置:
frontend http_80
bind *:80
mode http
# 调用的后端服务器组名称
default_backend proxy_servers
#监听
backend proxy_servers
mode http
#需要负均衡的服务
balance roundrobin
#后台管理的配置
listen admin_stats
#后台管理端口7777
bind :7777
mode http
stats enable
option httplog
maxconn 10
stats refresh 30s
#地址ip:端口/admin
stats uri /admin
#用户名:admin 密码:123456
stats auth admin:123456
stats auth Frank:Frank
stats realm XingCloud\ Hello-Haproxy
stats hide-version
stats admin if TRUE
frontend 监听 80端口,使用http 模式,默认调用proxy_servers 模块,backend proxy_servers模块下是将来后端服务注册信息的地方。
admin_stats 是haproxy的监控(登录)页面,我们可以通过 http://192.16.10.128:7777/admin 地址登录该页面(不过必须将7777端口暴露出来),访问账号和密码是:admin/123456 和 Frank/Frank。
记住该配置文件的地址是:/usr/local/haproxy/haproxy.cfg
2.1.6 启动haproxy
我们使用刚刚配置的haproxy.cfg配置文件启动haproxy.
/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/haproxy.cfg
我们可以通过ps -ef | grep haproxy 查看haproxy是否正常启动。

此时我们在访问http://192.16.10.128:7777/admin 前需要开启7777端口暴露。
firewall-cmd --zone=public --add-port=7777/tcp
成功的页面如下:


2.1.7 测试haproxy负载均衡
我们可以通过本地编写一个简单的springboot项目,然后打包部署在服务器上,启动并暴露对应端口之后,在`haproxy.cfg`文件中配置服务信息。
2.1.7.1 代码

2.1.7.2 打包部署在服务器上
# 创建log目录文件
mkdir /root/My_WorkSpace/My_project/haproxy-springboot/haproxy-springboot-log/
# springboot包名称叫:springboot-haproxy-demo,
# 产生的日志在/root/My_WorkSpace/My_project/haproxy-springboot/haproxy-springboot-log/app1.log
nohup java -jar -Dserver.port=8081 springboot-haproxy-demo.jar > /root/My_WorkSpace/My_project/haproxy-springboot/haproxy-springboot-log/app1.log 2>&1 &
# springboot包名称叫:springboot-haproxy-demo,
# 产生的日志在/root/My_WorkSpace/My_project/haproxy-springboot/haproxy-springboot-log/app1.log
nohup java -jar -Dserver.port=8082 springboot-haproxy-demo.jar > /root/My_WorkSpace/My_project/haproxy-springboot/haproxy-springboot-log/app2.log 2>&1 &
# 暴露端口8081和8082
firewall-cmd --zone=public --add-port=8081/tcp
firewall-cmd --zone=public --add-port=8082/tcp
# 我们可以通过下面地址查看springboot项目是否正常启动
http://172.16.10.128:8081/health
http://172.16.10.128:8082/health
2.1.7.3 haproxy.cfg文件修改
调整haproxy.cfg文件中backend部分,将8081端口的服务和8082端口的服务信息以下面方式配置:
server springboot-server1 172.16.10.128:8081 check inter 10s rise 2 fall 5
server springboot-server2 172.16.10.128:8082 check inter 10s rise 2 fall 5
2.1.7.4 重启haproxy
先使用 ps -ef | grep haproxy 查看haproxy的进程端口号,然后使用kill -9 端口号 杀死进程,再重新启动。
# 查看haproxy进程
`ps -ef | grep haproxy`
# kill -9 端口
# 启动
/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/haproxy.cfg


2.1.7.5 测试负载均衡
先使用firewall-cmd --zone=public --add-port=80/tcp暴露80端口,然后多次调用:http://172.16.10.128/health ,能够看到返回的结果端口不同。


这就说明haproxy的基本负载均衡功能是可以正常转发的。
下面confd和etcd要做的,其实就是通过
haproxy.toml模板动态生成haproxy.cfg配置文件中的backend下的servers列表,并且无感重启haproxy,将对应的服务挂载到haproxy上。
2.2 confd
2.2.1 下载安装
confd的下载地址:https://github.com/kelseyhightower/confd/releases/tag/v0.16.0

下载下来的是一个不需要任何操作的文件包,我们唯一的操作就是将其移动到/usr/local/bin/confd目录下
# 移动
mv confd-0.16.0-linux-arm64 /usr/local/bin/confd
# 加权限
chmod +x /usr/local/bin/confd
# 进入目录
cd /usr/local/bin/
# 执行命令
./confd

从打印日志中可以看出,confd未找到模板资源进行加载。
2.2.2 创建配置文件
confd的配置文件,主要包含配置的生成逻辑,例如模板源,后端存储对应的keys,命令执行等。
templates:配置模板Template,即基于不同组件的配置,修改为go语言的模板文件。
其实下面的命令就是在confd文件夹下创建两个conf.d和templates两个文件夹
mkdir -p /etc/confd/{conf.d,templates}
2.2.3 /etc/confd/conf.d/目录下创建haproxy.toml模板文件
[template]
#模板文件名(对应templates目录下的文件)
src = "haproxy.tmpl"
#生成的目标配置文件路径
dest = "/usr/local/haproxy/haproxy.cfg"
#监听的存储键
keys = [
"/haproxy/backends", #监听的etcd存储键(如etcd中的路径)
"/haproxy/frontends" # 另一个键值,目前没什么用
]
# 配置更新后重载hparoxy的命令($(cat /usr/data/haproxy/haproxy.pid)命令时获取旧的进程号,意思就是删除旧进程,添加新进程.)
reload_cmd = "sudo /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/haproxy.cfg -p /usr/data/haproxy/haproxy.pid -sf $(cat /usr/data/haproxy/haproxy.pid)"
2.2.4 /etc/confd/templates/目录下创建haproxy.tmpl
#全局配置
global
log 127.0.0.1 local0
#log 127.0.0.1 local1 notice
#log loghost local0 info
maxconn 4096
#程序的目录
chroot /usr/local/haproxy
#指定进程pid的文件
pidfile /usr/data/haproxy/haproxy.pid
uid 99
gid 99
daemon
#debug
#quiet
defaults
log global
mode http
option httplog
option dontlognull
retries 3
maxconn 2000
timeout connect 5s
timeout client 30s
timeout server 30s
timeout http-request 10s
# frontend结合backend配置:
frontend http_80
bind *:80
mode http
# 调用的后端服务器组名称
default_backend proxy_servers
#监听
backend proxy_servers
mode http
#需要负均衡的服务
balance roundrobin
# 这段我把它隐藏了,下面动态生成的其实就是这种配置.
#server springboot-server1 172.16.10.129:8081 check inter 10s rise 2 fall 5
#server springboot-server2 172.16.10.129:8082 check inter 10s rise 2 fall 5
#从etcd存储中读取key为/haproxy/backends/*的数据,并动态渲染生成server配置
{{range gets "/haproxy/backends/*"}}
server {{base .Key}} {{.Value}} check inter 10s rise 2 fall 5
{{end}}
#后台管理的配置
listen admin_stats
#后台管理端口7777
bind :7777
mode http
stats enable
option httplog
maxconn 10
stats refresh 30s
#地址ip:端口/admin
stats uri /admin
#用户名:admin 密码:123456
stats auth admin:123456
stats auth Frank:Frank
stats realm XingCloud\ Hello-Haproxy
stats hide-version
stats admin if TRUE
此时再次启动confd(cd /usr/local/bin)后,我们发现confd未找到etcd,所以我们还需要安装etcd.

2.3 etcd
2.3.1 安装
首先,从官方的 GitHub 仓库下载 ETCD 二进制文件
# 下载最新版本的 ETCD
wget https://github.com/etcd-io/etcd/releases/download/v3.5.0/etcd-v3.5.0-linux-arm64.tar.gz
# 解压缩
tar -xvf etcd-v3.5.0-linux-arm64.tar.gz
# 移动到 /usr/local/bin
sudo mv etcd-v3.5.0-linux-arm64/etcd /usr/local/bin/
sudo mv etcd-v3.5.0-linux-arm64/etcdctl /usr/local/bin/
2.3.2安装验证
etcd --version
etcdctl version

2.3.3 /etc/etcd.conf配置文件
# ETCD 数据存储目录
data-dir: "/var/lib/etcd"
# 节点名称
name: "etcd-node-1"
# 启动时绑定的 IP 和端口
listen-peer-urls: "http://0.0.0.0:2380"
listen-client-urls: "http://0.0.0.0:2379"
# 集群配置
initial-advertise-peer-urls: "http://127.0.0.1:2380"
advertise-client-urls: "http://127.0.0.1:2379"
# 集群状态
initial-cluster-state: "new"
initial-cluster-token: "etcd-cluster-1"
# 集群节点(单节点启动时只包含自己)
initial-cluster: "etcd-node-1=http://127.0.0.1:2380"
2.3.4 启动
/usr/local/bin/etcd --config-file=/etc/etcd.conf &
2.3.5 添加数据测试
新开一个连接窗口(V2),添加一个键值对试试,如果返回success就表示成功。
etcdctl put /dzb/name "DZV-VALUE"
2.3.6 confd 监听 etcd 中的/haproxy/backends/*的所有键值
进入cd /usr/local/bin ,执行下面命令:
cd /usr/local/bin
./confd -watch -backend etcdv3 -node http://172.16.10.129:2379

此时不是守护线程,不要关闭这个窗口。
2.3.6 etcdctl 插入/haproxy/backend/*键值,并观察http://172.16.10.128:7777/admin页面中backend的配置
此时haproxy页面是没有挂载任何服务的

在刚刚新开的窗口V2处,添加server8081和8082,观察confd左侧的监听情况。

然后再看一下haproxy页面的刷新情况.

confd监听到值变化之后,就会读取/haproxy/backends/*下的所有值,并且动态渲染模板,生成新的haproxy.cfg文件。
/usr/local/haproxy
vim haproxy.cfg

动态生成之后,haproxy经过脚本重启,服务就能实时挂载到haproxy上
三、总结
先不总结了,累了…😭 😭
更多推荐
所有评论(0)