Haproxy + confd + etcd搭建负载均衡框架

前言

​ => 最近工作上接触到了haproxy与confd、etcd搭配起来的负载均衡架构的项目。由于以前只接触过nginx,从没接触过haproxy等技术栈,对其流程运转比较迷茫,因此在本地搭建了一套单机版本的,便于理解和熟悉业务流程。

本地环境

序号资源版本
1.电脑Mac16 M1
2.VM操作系统CentOS8 arm64 (VMware Fusion)
3.Haproxy2.3.13
4.confd0.16.0
5.etcdV3.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_statshaproxy的监控(登录)页面,我们可以通过 http://192.16.10.128:7777/admin 地址登录该页面(不过必须将7777端口暴露出来),访问账号和密码是:admin/123456Frank/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.dtemplates两个文件夹

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上

三、总结

​ 先不总结了,累了…😭 😭

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐