与 Netflix Eureka 集成
Netflix Eureka 是 Netflix 用 Java 编写的开源注册中心服务,是 Netflix 基础设施的重要组成部分。Netflix Eureka 为 服务发现 提供了一个轻量级且可靠的解决方案。它利用客户端-服务器模型,微服务在服务器注册自己,其他服务可以通过服务解析动态定位它们。
本指南 将向你展示如何设置 Netflix Eureka 进行服务发现,并演示如何将其与 APISIX 集成,以动态路由和负载均衡微服务的流量。
如果你在 Kubernetes 中运行 APISIX 和 Ingress Controller,本指南模拟了一个混合环境,其中 APISIX 通过外部 Eureka 注册中心将流量路由到集群外的服务。
在所有服务都已在 Kubernetes 内运行的设置中,你通常不需要 Eureka,因为 Kubernetes 通过 Kubernetes 服务注册表和 DNS 提供了自己的内置服务发现。
前置条件
启 动 Eureka 实例
在与 APISIX 实例相同的网络中启动一个名为 eureka 的 Eureka Docker 实例,并将端口 8761 暴露给主机上的同一端口:
docker run \
--name eureka \
-d -p 8761:8761 \
--network=apisix-quickstart-net \
-e ENVIRONMENT=apisix \
-e spring.application.name=apisix-eureka \
-e server.port=8761 \
-e eureka.instance.ip-address=127.0.0.1 \
-e eureka.client.registerWithEureka=true \
-e eureka.client.fetchRegistry=false \
-e eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8761/eureka/ \
bitinit/eureka
启动示例 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。
在 Eureka 中注册服务
将主机的 IP 地址保存到环境变量:
HOST_IP=192.168.31.89 # 替换为你的主机 IP
在 Eureka 中注册两个服务:
curl "http://127.0.0.1:8761/eureka/apps/web" -X POST \
-H "Content-Type: application/json" \
-d '{
"instance":{
"instanceId": "'"$HOST_IP"':9081",
"hostName": "'"$HOST_IP"'",
"ipAddr": "'"$HOST_IP"'",
"port":{
"$":9081,
"@enabled":true
},
"status": "UP",
"app": "web",
"dataCenterInfo": {
"name": "MyOwn",
"@class":"com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo"
}
}
}'
curl "http://127.0.0.1:8761/eureka/apps/web" -X POST \
-H "Content-Type: application/json" \
-d '{
"instance":{
"instanceId": "'"$HOST_IP"':9082",
"hostName": "'"$HOST_IP"'",
"ipAddr": "'"$HOST_IP"'",
"port":{
"$":9082,
"@enabled":true
},
"status": "UP",
"app": "web",
"dataCenterInfo": {
"name": "MyOwn",
"@class":"com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo"
}
}
}'
验证服务是否注册成功:
curl "http://127.0.0.1:8761/eureka/apps/web"
你应该看到包含服务信息的 XML 响应。
连接 Eureka 到 APISIX
- Docker
- Kubernetes
将 Eureka 服务发现配置添加到 APISIX 的 config.yaml 配置文件:
docker exec apisix-quickstart /bin/sh -c "echo '
discovery:
eureka:
// Annotate 1
host:
- "http://eureka:8761"
// Annotate 2
prefix: /eureka/
fetch_interval: 30
weight: 100
timeout:
connect: 2000
send: 2000
read: 5000
' >> /usr/local/apisix/conf/config.yaml"
❶ host:Eureka 服务器的地址。
❷ prefix:Eureka 服务器用于服务注册和发现请求的基本 API 路径。
重新加载 APISIX 以使配置更改生效:
docker exec apisix-quickstart apisix reload
要更新网关的服务发现配置,首先导出所有值(包括默认值):
helm get values -n ingress-apisix apisix --all > values.yaml
在 values 文件中,更新以下部分值如下:
apisix:
discovery:
enabled: true
registry:
eureka:
// Annotate 1
host:
- "http://host.docker.internal:8761"
// Annotate 2
prefix: /eureka/
fetch_interval: 30
weight: 100
timeout:
connect: 2000
send: 2000
read: 5000
❶ host:Eureka 服务器的地址。
❷ prefix:Eureka 服务器用于服务注册和发现请求的基本 API 路径。
升级发布:
helm upgrade -n ingress-apisix apisix apisix/apisix -f values.yaml
在 APISIX 中创建路由
创建一个路由并配置上游使用 Eureka 进行 WEB 的服务发现:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT -d '
{
"id": "eureka-web-route",
"uri": "/eureka/web/*",
"upstream": {
"service_name": "WEB",
"discovery_type": "eureka",
"type": "roundrobin"
}
}'
HTTP/1.1 200 OK 响应验证了路由已成功创建。
services:
- name: Eureka Service
routes:
- uris:
- /eureka/web/*
name: eureka-web-route
upstream:
service_name: WEB
discovery_type: eureka
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: eureka
namespace: ingress-apisix
spec:
ingressClassName: apisix
loadbalancer:
type: roundrobin
discovery:
type: eureka
serviceName: WEB
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: eureka-web-route
namespace: ingress-apisix
spec:
ingressClassName: apisix
http:
- name: eureka-web-route
match:
paths:
- /eureka/web/*
upstreams:
- name: eureka
将配置应用到你的集群:
kubectl apply -f eureka-upstream-route.yaml
验证
向之前创建的路由生成一些请求:
curl "http://127.0.0.1:9080/eureka/web/"
你应该看到响应在以下内容之间交替:
Application 1 is running%
Application 2 is running%
下一步
除 Eureka 外,APISIX 还支持与 HashiCorp Consul、Nacos 和其他服务发现平台的集成(即将推出)。