Gateway API高级功能
文章目录
- [Gateway API高级功能](#Gateway API高级功能)
-
- 一、HTTP查询参数匹配
- 二、基于HTTP方法匹配请求
- 三、TCP路由
-
- [3.1、安装TCPRoute CRD资源](#3.1、安装TCPRoute CRD资源)
- [3.2、部署MySQL Redis](#3.2、部署MySQL Redis)
- 3.3、部署Gateway
- 3.4、测试
一、HTTP查询参数匹配
HTTPRoute资源可用于根据查询参数匹配请求。
1.1、根据单个查询参数匹配请求
-
以下
HTTPRoute配置根据查询参数animal的值,将流量分流到两个不同的后端: -
先部署一下环境
bash
# ==========================================
# 实例 1: nginx-1 资源
# ==========================================
# 1.1 ConfigMap 1
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-1-config
data:
nginx.conf: |
user nginx;
worker_processes auto;
events { worker_connections 1024; }
http {
include /etc/nginx/mime.types;
server {
listen 80;
location / {
return 200 "This is NGINX-1\n";
}
}
}
---
# 1.2 Deployment 1
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-1-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx-1
template:
metadata:
labels:
app: nginx-1
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: config-vol
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: config-vol
configMap:
name: nginx-1-config
---
# 1.3 Service 1
apiVersion: v1
kind: Service
metadata:
name: nginx-1-service
spec:
type: ClusterIP
selector:
app: nginx-1
ports:
- protocol: TCP
port: 80
targetPort: 80
---
# ==========================================
# 实例 2: nginx-2 资源
# ==========================================
# 2.1 ConfigMap 2
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-2-config
data:
nginx.conf: |
user nginx;
worker_processes auto;
events { worker_connections 1024; }
http {
include /etc/nginx/mime.types;
server {
listen 80;
location / {
return 200 "This is NGINX-2\n";
}
}
}
---
# 2.2 Deployment 2
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-2-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx-2
template:
metadata:
labels:
app: nginx-2
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: config-vol
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: config-vol
configMap:
name: nginx-2-config
---
# 2.3 Service 2
apiVersion: v1
kind: Service
metadata:
name: nginx-2-service
spec:
type: ClusterIP
selector:
app: nginx-2
ports:
- protocol: TCP
port: 80
targetPort: 80
# apply 一下
[root@master ~]# kubectl apply -f nginx-stack.yaml
configmap/nginx-1-config created
deployment.apps/nginx-1-deployment created
service/nginx-1-service created
configmap/nginx-2-config created
deployment.apps/nginx-2-deployment created
service/nginx-2-service created
- 部署
HTTPRoute资源
bash
[root@master ~]# cat httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: query-param-matching
spec:
parentRefs:
- name: example-gateway # 使用的 Gateway
rules: # 规则
- matches: # 匹配规则, 如果访问路径当中带有 animal=whale 的查询参数, 流量将会打到 nginx-1-service 的 80 端口
- queryParams:
- name: animal
value: whale
backendRefs:
- name: nginx-1-service
port: 80
- matches: # 匹配规则, 如果访问路径当中带有 animal=dolphin 的查询参数, 流量将会打到 nginx-2-service 的 80 端口
- queryParams:
- name: animal
value: dolphin
backendRefs:
- name: nginx-2-service
port: 80
# apply 一下
[root@master ~]# kubectl apply -f httproute.yaml
httproute.gateway.networking.k8s.io/query-param-matching created
- 访问
bash
# 通过 lb 地址进行访问测试
[root@master ~]# kubectl get gateway
NAME CLASS ADDRESS PROGRAMMED AGE
example-gateway istio 192.168.93.11 True 24d
[root@master ~]# curl 192.168.93.11/?animal=whale
This is NGINX-1
[root@master ~]# curl 192.168.93.11/?animal=dolphin
This is NGINX-2
1.2、基于多个查询参数匹配请求
bash
[root@master ~]# cat httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: query-param-matching
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- queryParams: # 再次访问的时候需要两个查询参数了, 也就是animal=whale&color=blue
- name: animal
value: whale
- name: color
value: blue
backendRefs:
- name: nginx-1-service
port: 80
- matches:
- queryParams:
- name: animal
value: dolphin
backendRefs:
- name: nginx-2-service
port: 80
[root@master ~]# kubectl apply -f httproute.yaml
httproute.gateway.networking.k8s.io/query-param-matching configured
bash
[root@master ~]# curl "192.168.93.11/?animal=whale&color=blue"
This is NGINX-1
1.3、与其他匹配类型结合使用
- 查询参数匹配,可以与其他匹配类型(如路径匹配和请求头匹配)结合使用。
bash
[root@master ~]# cat httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: query-param-matching
spec:
parentRefs:
- name: example-gateway
rules:
- matches: # 基于 匹配路径、头部访问、查询参数结合使用
- path:
type: PathPrefix
value: /path1
- headers:
- name: version
value: one
- queryParams:
- name: animal
value: whale
backendRefs:
- name: nginx-1-service
port: 80
- matches:
- queryParams:
- name: animal
value: dolphin
backendRefs:
- name: nginx-2-service
port: 80
# apply 一下
[root@master ~]# kubectl apply -f httproute.yaml
httproute.gateway.networking.k8s.io/query-param-matching configured
bash
# 还需要更改一下nginx-1的cm,是否会造成404
[root@master ~]# kubectl edit cm nginx-1-config
server {
listen 80;
# 添加一个对应的路径 location
location /path1 {
return 200 "结合使用\n";
}
location / {
return 200 "This is NGINX-1\n";
}
}
# 重启一下 nginx-1 的 deployment
[root@master ~]# kubectl rollout restart deployment nginx-1-deployment
deployment.apps/nginx-1-deployment restarted
bash
[root@master ~]# curl -H "version: one" http://192.168.93.11/path1?animal=whale
结合使用
二、基于HTTP方法匹配请求
- 以下
HTTPRoute根据请求的HTTP方法(如GET、POST等)将流量分发到两个不同的后端:
bash
[root@master ~]# cat httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: method-matching
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /mepost
- method: POST
backendRefs:
- name: nginx-1-service
port: 80
- matches:
- method: GET
backendRefs:
- name: infra-backend-v2
port: 8080
# apply 一下
[root@master ~]# kubectl apply -f httproute.yaml
httproute.gateway.networking.k8s.io/method-matching created
bash
# 我们自己写一个 post 协议, 然后用 nginx 代理一下
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.POST("/mepost", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "POST method",
})
})
r.Run(":8080")
}
# 我直接在物理机运行了, 所以我等一下代理物理的网络
server {
listen 80;
# 代理内容
location = /mepost {
proxy_pass http://192.168.93.1:8080;
}
location / {
return 200 "This is NGINX-1\n";
}
}
bash
[root@master ~]# curl -X POST http://192.168.93.11/mepost
{"message":"POST method"}
# 看一下程序的日志
[GIN] 2026/01/17 - 15:25:00 | 200 | 0s | 10.244.219.64 | POST "/mepost"
三、TCP路由
- Gateway API皆在支持多种协议,而
TCPRoute正是其中一种允许管理TCP流量的路由资源。 - 在下面的示例中,我们拥有一个Gateway资源和两个TCPRoute资源,它们按照以下规则分发流量:
- Gateway端口8080上所有TCP流量都将被转发至
mysql-svcKubernettes服务的3306端口。 - Gateway端口8090上的所有TCP流量都将被转发至
redis-svcKubernetes的6379端口。 - 在此示例中,Gateway将应用两个TCP监听器,以便将流量路由到两个独立的后端TCPRoute。请注意,Gateway监听器上设置的协议为TCP。
- Gateway端口8080上所有TCP流量都将被转发至
3.1、安装TCPRoute CRD资源
TCPRoute目前就处于实验版频道,Kubernetes官方不希望在默认安装中包含这些可能会发生的"破坏性变更"的API,所以需要用户根据需求主动安装,
bash
# 安装资源
[root@master ~]# kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/experimental-install.yaml
# 开启 istio 的实验性资源支持
[root@master ~]# kubectl patch deployment istiod -n istio-system --type=json -p='[{"op":"add","path":"/spec/template/spec/containers/0/env/-","value":{"name":"PILOT_ENABLE_ALPHA_GATEWAY_API","value":"true"}}]'
deployment.apps/istiod patche
bash
# 查看 tcproute 资源
[root@master ~]# kubectl api-resources | grep tcp
tcproutes gateway.networking.k8s.io/v1alpha2 true TCPRoute
3.2、部署MySQL Redis
bash
[root@master ~]# cat mysql-redis.yaml
# ==========================================
# 1. MySQL 最小化部署
# ==========================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deploy
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
nodeName: node1
containers:
- name: mysql
image: mysql:5.7 # 5.7 版本启动比 8.0 更轻量
env:
- name: MYSQL_ROOT_PASSWORD
value: "root123" # 必须设置初始密码
ports:
- containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
type: ClusterIP # 仅集群内访问
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
---
# ==========================================
# 2. Redis 最小化部署
# ==========================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-deploy
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
nodeName: node2
containers:
- name: redis
image: redis:alpine # 使用 alpine 镜像体积最小
ports:
- containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: redis-service
spec:
type: ClusterIP # 仅集群内访问
selector:
app: redis
ports:
- port: 6379
targetPort: 6379
bash
[root@master ~]# kubectl apply -f mysql-redis.yaml
deployment.apps/mysql-deploy created
service/mysql-service created
deployment.apps/redis-deploy created
service/redis-service created
3.3、部署Gateway
bash
[root@master ~]# cat gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-tcp-gateway
spec:
gatewayClassName: istio
listeners:
- name: foo
protocol: TCP
port: 8080
allowedRoutes:
kinds:
- kind: TCPRoute
- name: bar
protocol: TCP
port: 8090
allowedRoutes:
kinds:
- kind: TCPRoute
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: tcp-mysql
spec:
parentRefs:
- name: my-tcp-gateway
sectionName: foo # 使用 my-tcp-gateway 的 foo 监听器
rules:
- backendRefs:
- name: mysql-service
port: 3306
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: tcp-redis
spec:
parentRefs:
- name: my-tcp-gateway
sectionName: bar # 使用 my-tcp-gateway 的 bar 监听器
rules:
- backendRefs:
- name: redis-service
port: 6379
bash
[root@master ~]# kubectl apply -f gateway.yaml
gateway.gateway.networking.k8s.io/my-tcp-gateway created
tcproute.gateway.networking.k8s.io/tcp-mysql created
tcproute.gateway.networking.k8s.io/tcp-redis created
bash
[root@master ~]# kubectl get gateway
NAME CLASS ADDRESS PROGRAMMED AGE
my-tcp-gateway istio 192.168.93.12 True 18s
3.4、测试
bash
# 安装 mysql redis 命令行工具
[root@master ~]# yum -y install mysql redis
[root@master ~]# mysql -h 192.168.93.12 -u root -proot123 -P 8080
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.44 MySQL Community Server (GPL)
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
[root@master ~]# redis-cli -h 192.168.93.12 -p 8090
192.168.93.12:8090> ping
PONG