掘金 后端 ( ) • 2024-04-23 10:42

APISIX是一款基于Nginx和OpenResty的云原生API网关,由lua语言编写。它提供了一个可扩展的、低延迟、高性能的API网关解决方案,支持常见的API管理功能,如流量控制、认证、转发等,并提供了灵活的插件机制,可支持自定义插件的开发和集成。最近的项目架构调整中,就使用apisix替换掉了nginx,既然在实际生产项目中使用,那么高可用的问题必不可少。不过Apisix是一个无状态的服务,自然也就没有主从一说了。所以高可用需要依赖于其他组件,如etcd,nginx,keepalived。但是apisix本身就支持了反向代理,负载均衡,可以直接将其挡在最前面,所以nginx就不再考虑。那最终的架构如下图所示。

image.png

搭建etcd集群,部署多个apisix服务,apisix依赖etcd集群进行数据存储,keepalived做主备切换高可用。

etcd集群

apisix自身属于无状态服务,但运行时需要依赖于etcd,etcd用于存储apisix运行过程中所需要的数据。所以,etcd集群是高可用环境中不可或缺的一部分,其集群模式搭建起来也比较容易,只需要在启动时带上指定参数即可。下面是etcd提供的部分配置参数,在启动时将会使用到。

  • --name:节点名称,用于在集群中唯一标识一个节点。
  • --data-dir:数据目录,用于存储Etcd的数据。
  • --listen-client-urls:客户端监听地址,用于监听来自客户端的连接请求。
  • --listen-peer-urls:对等体监听地址,用于监听来自对等体的连接请求。
  • --initial-cluster:初始集群配置,用于定义集群中的所有节点。
  • --initial-cluster-state:初始集群状态,用于指示当前节点是新的节点还是已有的节点。
  • --initial-cluster-token:初始集群标记,用于标识一个特定的Etcd集群。

上面几个参数有点多,也有点长,不好记。为了简化启动方式,可以编写shell启动脚本,将这些参数写进脚本里即可。需要注意的是etcd会将--initial-cluster中的第一个节点作为leader节点,所以在启动时,需要先启动这个leader节点,然后在依次启动从节点。

#!/bin/bash
#是否存在etcd进程,如果存在则kill掉
etcd_id=`ps -ef | grep etcd | grep -v "grep" | grep -v "etcd-start" | awk '{print $2}'`
echo $etcd_id

for id in $etcd_id
do
    kill -15 $id
    echo "killed $id"
done

# 启动etcd集群
nohup etcd \
 --name etcdMaster \
 --data-dir /data/default.etcd \
 --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://0.0.0.0:2379 \
 --listen-peer-urls http://192.168.xxx.xxx:2380 \
 --initial-advertise-peer-urls http://192.168.xxx.xxx:2380 \
 --initial-cluster-token etcd-cluster-0 \
 --initial-cluster-state new \
 --initial-cluster etcdMaster=http://192.168.xxx.xxx:2380,etcdSalve=http://192.168.xxx.xxx:2380 >/data/etcd.log 2>&1 &
etcd_id=`ps -ef | grep etcd | grep -v "grep" | grep -v "etcd-start" | awk '{print $2}'`
echo "start etcd $etcd_id"

exit 0

编写完成后,各节点依次执行该脚本。执行后,可以使用etcdctl命令查看集群状态。资源有限,先搞两个节点,实际场景建议最少三个节点。

ETCDCTL_API=3 etcdctl \
  --endpoints=http://192.168.xxx.xxx:2379, http://192.168.xxx.xxx:2379 \   #各节点etcd服务
  --write-out=table \
  endpoint status

执行该命令后,会以表格的形式展示各节点信息,包括版本,leader状态,数据量大小等。

image.png

Apisix

etcd集群搞定后,现在开始搞apisix。apisix可以选择Docker安装(推荐),也可以选择安装包安装。安装就直接跟着官网的步骤操作好了,这里不做赘述。

官网 https://apisix.apache.org/docs/apisix/installation-guide/

安装完成后,会有一个默认的配置文件config-default.yaml(如果是Docker安装,推荐将该文件挂载到本地磁盘上)。在配置文件中,找到etcd的配置信息,将上述的etcd集群配置到该处。配置完成后,使用systemctl restart apisix命令来启动apisix。 image.png

Keepalived主备配置

Keepalived是一个用于负载均衡和高可用性的开源软件,旨在为基于Linux的基础架构提供简单而强大的解决方案,它通过实现负载均衡和VRRP(Virtual Router Redundancy Protocol)协议来提供高可用性。这里我们使用Keepalived的VIP(Virtual IP 虚拟IP)功能来实现多个节点共用一个虚拟IP来实现高可用。VIP会当在Master节点宕机之后,漂移到备节点上。默认情况下,如果Master节点恢复后,并不会切回到主节点,但是可以使用vrrp_script来检查主节点状态,如果主节点正常便切回。这个虚拟IP可以自定义,但是需要和节点处在同一网段。下面是主节点的keepalived.conf的配置信息,备节点的配置大径相同。

global_defs {
#   notification_email {
#     [email protected]
#     [email protected]
#    [email protected]
#   }
#   notification_email_from [email protected]
#   smtp_server 192.168.200.1
#   smtp_connect_timeout 30
   router_id LVS_DEVEL
#   vrrp_skip_check_adv_addr
#   vrrp_strict
#   vrrp_garp_interval 0
#   vrrp_gna_interval 0
}

#检查服务状态脚本 配节点可不需要
vrrp_script chk_http_port {      
    # 检查服务状态的脚本
    script "/data/keepalive-check.sh"
    interval 2                  
    weight -6                    
}

vrrp_instance VI_1 {
    # 节点状态,配节点需要更改
    state MASTER
    # 网卡名
    interface eth0
    virtual_router_id 55
    # 优先级 主节点要高于备节点
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    # 设置虚拟IP
    virtual_ipaddress {
        192.168.xxx.239
    }
    track_script {                      
      chk_http_port                    
    }
}

服务的健康检查脚本,只需要检查apisix是否正在运行即可。如果发现apisix的进程不存在或者端口号不存在时,可以断定服务不健康,那么这时可以将keepalived停止,主节点被停掉后,VIP便自动飘到备上面。

#!/bin/bash
#serverHealth=$(curl -XGET --connect-timeout 1 -s http://127.0.0.1:9080)
#result=$(echo ${serverHealth} | grep "Route")
result=$(lsof -i:9080)
echo $result
if [[ "$result" != "" ]]
then
  exit 0
else
  cd /etc/keepalived
  systemctl stop keepalived 
  exit 1
fi

健康检查脚本搞定后,可以使用systemctl start keepalived来启动服务。如果配置无误,启动成功后,可以查看keepalived的状态,这个时候可以看到我们配置的虚拟IP地址信息。 image.png

可以通过Ping命令或者直接使用curl命令请求apisix来测试虚拟IP可用状态。 image.png

image.png

apisix-dashboard

与nginx相比,apisix提供了一个管理平台,可以在这个管理平台配置路由,配置负载均衡,配置限流等等,而且不需要手动重启,修改即生效,非常好用,非常方便。安装也很容易,直接使用docker安装即可,不过需要注意的是,管理平台的数据源是依赖etcd的,所以需要修改平台的配置文件将etcd数据源更改为etcd集群即可。

docker pull apache/apisix-dashboard
docker run -d --name dashboard \
           -p 9000:9000        \
           -v /data/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml \
           apache/apisix-dashboard

image.png

image.png