跳到主要内容

按端口代理 TCP 流量

使用 Gateway API TCPRoute 或 APISIX CRD stream route,按网关入站端口将 TCP 连接路由到 MySQL Service。

前置条件

  1. 完成设置 Ingress Controller 和网关
  2. 安装 MySQL Shell,用于连接 MySQL 服务器。

启动示例上游服务

创建 Kubernetes manifest 文件,部署一个 root 密码为 my-secret-pw 的示例 MySQL 上游服务:

mysql.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
namespace: aic
labels:
app: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:9.4
env:
- name: MYSQL_ROOT_PASSWORD
value: "my-secret-pw"
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumes:
- name: mysql-data
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: aic
spec:
selector:
app: mysql
ports:
- name: mysql
port: 3306
targetPort: 3306

将配置应用到集群:

kubectl apply -f mysql.yaml

启用网关 Stream 代理

升级网关,启用 stream 模式并设置 TCP 端口 9100。下列命令使用 --reuse-values 保留当前 Helm release 的其他值:

helm upgrade -n aic apisix apisix/apisix \
--reuse-values \
--set "service.stream.enabled=true" \
--set "service.stream.tcp[0]=9100"

配置 TCP 路由

本节将配置一条监听 9100 端口 TCP 流量的路由。

更新 Gateway manifest 文件,为 TCP 流量定义监听器:

gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: aic
name: apisix
spec:
gatewayClassName: apisix
listeners:
- name: http
protocol: HTTP
port: 80
- name: tcp
protocol: TCP
port: 9100
allowedRoutes:
kinds:
- kind: TCPRoute
infrastructure:
parametersRef:
group: apisix.apache.org
kind: GatewayProxy
name: apisix-config

创建 TCPRoute 的 Kubernetes manifest:

tcp-route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: TCPRoute
metadata:
name: stream-route-mysql
namespace: aic
spec:
parentRefs:
- name: apisix
sectionName: tcp
rules:
- backendRefs:
- name: mysql
port: 3306

listener_port_match_modeexplicitauto 时,sectionName: tcp 引用会为 9100 添加 server_port 匹配。Gateway 监听器端口必须等于 APISIX 实际的 stream 监听端口。默认的 off 模式不会添加该匹配。

将配置应用到集群:

kubectl apply -f gateway.yaml -f tcp-route.yaml

设置上游传输协议

普通 TCP 后端使用 tcp;需要由网关向后端建立 TLS 时使用 tls。这些 L4 scheme 仅适用于 stream route。

BackendTrafficPolicy 挂载到后端 Service:

mysql-upstream-policy.yaml
apiVersion: apisix.apache.org/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: mysql-transport
namespace: aic
spec:
targetRefs:
- group: ""
kind: Service
name: mysql
sectionName: mysql
scheme: tcp

应用策略:

kubectl apply -f mysql-upstream-policy.yaml

如需将 stream 插件挂载到 TCPRoute,请参阅将插件应用到 L4 路由

验证

将网关 Service 端口暴露到本地机器:

# 替换为你的网关 Service 名称
kubectl port-forward svc/<gateway-service-name> 9100:9100 &

以 root 用户连接 MySQL 服务器,并在提示时输入密码 my-secret-pw

mysqlsh --sqlc --host=127.0.0.1 --port=9100 --user=root --password

如果连接成功,MySQL Shell 会打开 classic protocol 会话,并显示类似以下内容:

Creating a Classic session to 'root@127.0.0.1:9100'
Your MySQL connection id is 9
Server version: 9.4.0 MySQL Community Server - GPL