跳到主要内容
版本:3.10.x

配置 TCP/UDP 代理

除了 HTTP 流量外,API7 网关还可以代理第 4 层(TCP/UDP)流量。这样,你可以将网关作为 MySQL、Redis、MQTT 和自定义 TCP 服务等非 HTTP 协议的统一入口。

本指南以配置到 MySQL 数据库的 TCP 代理为例。相同方法也适用于任何 TCP 或 UDP 服务。

前提条件

  • API7 企业版实例正在运行。
  • 已创建网关组,并且网关实例正在运行。
  • Dashboard Token
  • 如果你希望使用 mysql 验证示例 TCP 代理,请安装 MySQL 客户端。

启动示例 TCP 上游

启动 API7 企业版 TCP 代理最佳实践指南中使用的同一个示例 MySQL 服务器:

docker run -d \
--name mysql \
--network host \
-e MYSQL_ROOT_PASSWORD=password \
mysql:8.4 \
mysqld --mysql-native-password=ON

以下示例假设网关可以通过 host.docker.internal 访问 Docker 主机。如果你的环境使用其他主机地址,请将 host.docker.internal 替换为该地址。

确保 Stream 代理端口可用

在流量能够到达 Stream 路由之前,网关必须已经在某个 TCP 或 UDP 端口上监听 Stream 流量。

Admin API 和 ADC 可以创建 Stream 服务与 Stream 路由,但它们不会创建或暴露网关监听器本身。如果你的 API7 企业版部署已经提供 L4 监听器,请在 server_port 中复用该端口。如果没有,请在网关运行时配置中添加监听端口,并重新部署或重启网关,使新监听器暴露出来。

如果你直接管理网关运行时,请按如下方式将端口添加到 config.yaml

config.yaml
apisix:
stream_proxy:
only: false
tcp:
- 2000

如果网关运行在 Docker 中,还需要将相同端口从容器发布到主机。例如,使用 -p 2000:2000 重新创建或重新部署网关容器。

对于 Kubernetes 部署,请将 Stream 代理端口添加到 Helm 配置项,确保 Service 暴露这些端口,然后重新部署网关。

创建 Stream 服务

网关上有可用的 Stream 监听器后,创建一个类型为 stream 的服务并配置上游。

curl -k "https://localhost:7443/apisix/admin/services/mysql-service?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "mysql-service",
"type": "stream",
"upstream": {
"scheme": "tcp",
"nodes": [
{
"host": "host.docker.internal",
"port": 3306,
"weight": 100
}
]
}
}'

创建 Stream 路由

创建一个 Stream 路由,用于匹配 Stream 代理端口上的流量并将其转发到上游。

curl -k "https://localhost:7443/apisix/admin/stream_routes/mysql-route?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "mysql-route",
"server_port": 2000,
"service_id": "mysql-service"
}'

server_port 必须匹配 stream_proxy.tcpstream_proxy.udp 下已配置的网关 Stream 监听器。在 Admin API 示例中,service_id 引用包含上游配置的 Stream 服务。

对于 ADC 工作流,请在父级服务下定义 Stream 路由。若要端到端验证这些示例,请确保同一个 Stream 端口已在网关上配置,并且已由你的部署暴露给客户端。

验证配置

网关已在启用并暴露 Stream 监听器后完成重新部署或重启时,可以通过连接到网关的 Stream 代理端口来测试 TCP 代理:

# MySQL 示例
mysql -h 127.0.0.1 -P 2000 -u root -p

如果连接成功,并且你可以与 MySQL 服务器交互,则说明 Stream 路由正常工作。

对于通用 TCP 测试:

# 使用 netcat
nc -zv 127.0.0.1 2000

添加 Stream 插件

Stream 路由支持有限数量的插件。例如,你可以使用 limit-conn 添加连接限流:

curl -k "https://localhost:7443/apisix/admin/stream_routes/mysql-route?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "mysql-route",
"server_port": 2000,
"service_id": "mysql-service",
"plugins": {
"limit-conn": {
"conn": 100,
"burst": 50,
"default_conn_delay": 0.1,
"key": "remote_addr",
"key_type": "var"
}
}
}'

PUT 会替换整个 Stream 路由,因此需要在新的 plugins 配置块之外,一并重新发送现有字段(nameserver_portservice_id)。

为 Stream 路由配置 TLS

若要代理基于 SNI 路由的 TLS 加密 TCP 连接:

  1. 启用 TLS Stream 代理端口:

    config.yaml
     apisix:
    stream_proxy:
    tcp:
    - addr: 9443
    tls: true
  2. 创建带有 sni 字段的 Stream 路由,以根据客户端的 TLS Server Name Indication 进行路由。

后续步骤