与 HashiCorp Consul 集成
HashiCorp Consul 是一个多云服务网络平台,用于连接和保护来自各种云和运行时环境的服务。它通过使服务能够快速注册和查找其他服务,简化了 服务发现 过程。
本指南将向你展示如何设置 HashiCorp Consul 进行服务发现,并演示如何将其与 APISIX 集成,以动态路由和负 载均衡微服务的流量。
如果你在 Kubernetes 中运行 APISIX 和 Ingress Controller,本指南模拟了一个混合环境,其中 APISIX 通过外部 Consul 注册中心将流量路由到集群外的服务。
在所有服务都已在 Kubernetes 内运行的设置中,你通常不需要 Consul,因为 Kubernetes 通过 Kubernetes 服务注册表和 DNS 提供了自己的内置服务发现。

前置条件
启动 Consul 实例
在与 APISIX 实例相同的网络中启动一个名为 consul 的 Consul Docker 实例,并将端口 8500 暴露给主机上的同一端口:
docker run \
--name consul \
-d -p 8500:8500 \
--network=apisix-quickstart-net \
consul:1.15.1 \
consul agent \
-server \
-bootstrap-expect=1 \
-node=agent-one \
-client 0.0.0.0 \
-log-level info \
-data-dir=/consul/data \
-enable-script-checks
启动示例 Web 服务
在本节中,你将启动两个基于 NGINX 的示例 Web 服务。
创建两个配置文件 web1.conf 和 web2.conf,指示 NGINX 在根目录提供静态文本响应:
echo 'worker_processes 1;
error_log stderr notice;
events {
worker_connections 1024;
}
http {
variables_hash_max_size 1024;
access_log off;
real_ip_header X-Real-IP;
charset utf-8;
server {
listen 80;
location / {
return 200 "Application 1 is running";
}
location /static/ {
alias static/;
}
}
}' > web1.conf
echo 'worker_processes 1;
error_log stderr notice;
events {
worker_connections 1024;
}
http {
variables_hash_max_size 1024;
access_log off;
real_ip_header X-Real-IP;
charset utf-8;
server {
listen 80;
location / {
return 200 "Application 2 is running";
}
location /static/ {
alias static/;
}
}
}' > web2.conf
启动 Web 服务 web1 和 web2:
docker run -d \
--name web1 \
--restart always \
// Annotate 1
-v $(pwd)/web1.conf:/etc/nginx/nginx.conf \
// Annotate 2
-p 9081:80 \
--network=apisix-quickstart-net \
nginx:1.25-alpine
docker run -d \
--name web2 \
--restart always \
// Annotate 1
-v $(pwd)/web2.conf:/etc/nginx/nginx.conf \
// Annotate 2
-p 9082:80 \
--network=apisix-quickstart-net \
nginx:1.25-alpine
❶ 将主机上的 web1.conf 和 web2.conf 挂载到容器内的 /etc/nginx/nginx.conf。
❷ 将容器的端口 80 映射到主机的端口 9081 和 9082。
在 Consul 中注册服务
将主机的 IP 地址保存到环境变量:
HOST_IP=192.168.42.145 # 替换为你的主机 IP
在 Consul 中注册两个服务:
curl "http://127.0.0.1:8500/v1/agent/service/register" -X PUT \
-H "Content-Type: application/json" \
-d '{
"ID": "svc-a1",
"Name": "svc-a",
// Annotate 1
"Tags": ["sample_web_svc", "v1"],
// Annotate 2
"Address": "'"$HOST_IP"'",
// Annotate 3
"Port": 9081,
"Weights": {
"Passing": 10,
"Warning": 1
}
}'
curl "http://127.0.0.1:8500/v1/agent/service/register" -X PUT \
-H "Content-Type: application/json" \
-d '{
"ID": "svc-a2",
"Name": "svc-a",
// Annotate 1
"Tags": ["sample_web_svc", "v1"],
// Annotate 2
"Address": "'"$HOST_IP"'",
// Annotate 3
"Port": 9082,
"Weights": {
"Passing": 10,
"Warning": 1
}
}'
❶ Tags:与服务关联的标签或元数据数组。
❷ Address:服务所在的 IP 地址或主机名。
❸ Port:服务监听的端口号。
验证服务是否注册成功:
curl "http://127.0.0.1:8500/v1/catalog/service/svc-a"
你应该看到包含服务信息的 JSON 响应。
连接 Consul 到 APISIX
- Docker
- Kubernetes
将 Consul 服务发现配置添加到 APISIX 的 config.yaml 配置文件:
docker exec apisix-quickstart /bin/sh -c "echo '
discovery:
consul:
// Annotate 1
servers:
- "http://consul:8500"
dump:
// Annotate 2
path: "logs/consul.dump"
expire: 2592000
' >> /usr/local/apisix/conf/config.yaml"
❶ servers:Consul 服务器的地 址。
❷ logs/consul.dump:保存数据转储的文件路径。
重新加载 APISIX 以使配置更改生效:
docker exec apisix-quickstart apisix reload
要更新网关的服务发现配置,首先导出所有值(包括默认值):
helm get values -n ingress-apisix apisix --all > values.yaml
在 values 文件中,更新以下部分值如下:
apisix:
discovery:
enabled: true
registry:
consul:
// Annotate 1
servers:
- "http://host.docker.internal:8500"
dump:
// Annotate 2
path: "logs/consul.dump"
expire: 2592000
❶ servers:Consul 服务器的地址。
❷ logs/consul.dump:保存数据转储的文件路径。
升级发布:
helm upgrade -n ingress-apisix apisix apisix/apisix -f values.yaml
在 APISIX 中创建路由
创建一个路由并配置上游使用 Consul 进行 svc-a 的服务发现:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT -d '
{
"id": "consul-web-route",
"uri": "/consul/web/*",
"upstream": {
"service_name": "svc-a",
"discovery_type": "consul",
"type": "roundrobin"
}
}'
HTTP/1.1 200 OK 响应验证了路由已成功创建。
services:
- name: Consul Service
routes:
- uris:
- /consul/web/*
name: consul-web-route
upstream:
service_name: svc-a
discovery_type: consul
type: roundrobin
将配置同步到 APISIX:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
APISIX Ingress Controller 目前不支持使用 Gateway API 配置服务发现。
为使用服务发现的路由和上游创建一个 Kubernetes 清单文件:
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
name: consul
namespace: ingress-apisix
spec:
ingressClassName: apisix
loadbalancer:
type: roundrobin
discovery:
type: consul
serviceName: svc-a
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: consul-web-route
namespace: ingress-apisix
spec:
ingressClassName: apisix
http:
- name: consul-web-route
match:
paths:
- /consul/web/*
upstreams:
- name: consul
将配置应用到你的集群:
kubectl apply -f consul-upstream-route.yaml
验证
向之前创建的路由生成一些请求:
curl "http://127.0.0.1:9080/consul/web/"
你应该看到响应在以下内容之间交替:
Application 1 is running%
Application 2 is running%
下一步
APISIX 中的服务发现创建了一些用于检查和故障排除的 Control API 端点。有关更多信息,请参阅 Control API 参考。
除 Consul 外,APISIX 还支持与 Eureka、Nacos 和其他服务发现平台的集成(即将推出)。