Proxy TCP Traffic by Port
Route TCP connections to a MySQL Service based on the incoming gateway port using either a Gateway API TCPRoute or an APISIX CRD stream route.
Prerequisites
- Complete Set Up Ingress Controller and Gateway.
- Install MySQL Shell to initiate connections with MySQL server.
Start an Example Upstream Service
Create a Kubernetes manifest file for an example MySQL upstream service with the root password my-secret-pw:
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
Apply the configuration to your cluster:
kubectl apply -f mysql.yaml
Enable Gateway Stream Proxy
Upgrade your gateway to enable stream mode and set TCP port 9100:
- APISIX Gateway
- API7 Gateway
helm upgrade -n aic apisix apisix/apisix \
--set ... \ # add other parameters
--set "service.stream.enabled=true" \
--set "service.stream.tcp[0]=9100"
helm upgrade -n aic api7-ee-3-gateway api7/gateway \
--set ... \ # add other parameters
--set "gateway.stream.enabled=true" \
--set "gateway.stream.only=false" \
--set "gateway.stream.tcp[0]=9100"
Configure TCP Routing
In this section, you will configure a route that listens for TCP traffic on port 9100.
- Gateway API
- APISIX CRD
Update your Gateway manifest file to define a listener for TCP traffic:
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
Create a Kubernetes manifest for a TCPRoute:
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
When listener_port_match_mode is explicit or auto, the sectionName: tcp reference adds a server_port match for 9100. The Gateway listener port must equal the physical APISIX stream listener port. The default off mode does not add this match.
Apply the configuration to your cluster:
kubectl apply -f gateway.yaml -f tcp-route.yaml
Create a Kubernetes manifest file for a stream route:
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: stream-route-mysql
namespace: aic
spec:
ingressClassName: apisix
stream:
- name: stream-route-mysql
protocol: TCP
match:
ingressPort: 9100
backend:
serviceName: mysql
servicePort: 3306
Apply the configuration to your cluster:
kubectl apply -f tcp-route.yaml
Set the Upstream Transport
Use tcp for a plain TCP backend or tls when the gateway must establish TLS to the backend. The L4 schemes apply only to stream routes.
- Gateway API
- APISIX CRD
Attach a BackendTrafficPolicy to the backend Service:
apiVersion: apisix.apache.org/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: mysql-transport
namespace: aic
spec:
targetRefs:
- group: ""
kind: Service
name: mysql
sectionName: mysql
scheme: tcp
Apply the policy:
kubectl apply -f mysql-upstream-policy.yaml
Create an ApisixUpstream with the same name as the backend Service:
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
name: mysql
namespace: aic
spec:
ingressClassName: apisix
scheme: tcp
Apply the upstream configuration:
kubectl apply -f mysql-upstream.yaml
To attach stream plugins to the TCPRoute, see Apply Plugins to L4 Routes.
Verify
Expose the gateway’s service port to your local machine:
# replace with your gateway’s service name
kubectl port-forward svc/<gateway-service-name> 9100:9100 &
Connect with the MySQL server as root and key in the password my-secret-pw once prompted:
mysqlsh --sqlc --host=127.0.0.1 --port=9100 --user=root --password
If successful, MySQL Shell opens a classic protocol session and displays output similar to the following:
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