Gateway API是Kubernetes中用于对服务网络流量进行建模的一系列资源。它的目标是建立一套表现力强、易扩展、面向角色的服务网络模型。本文介绍如何使用Gateway API访问服务。
前提条件
- 确保集群为1.24及以上版本。
- 已安装Gateway API组件。具体操作,请参见管理组件。
说明 1.24及以上版本的集群已默认安装Gateway API组件。
背景信息
ACK 1.24及以上版本集群默认安装Gateway API组件相关的CRD资源。您可以通过安装支持Gateway API的网关来使用Gateway API的相关特性。关于Gateway API的更多说明,请参见Gateway API。使用流程

准备工作
- 通过kubectl工具连接集群。
- 创建测试应用go-httpbin。
- 使用以下内容,创建httpbin.yaml。
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-httpbin
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: go-httpbin
template:
metadata:
labels:
app: go-httpbin
version: v1
spec:
containers:
- image: specialyang/go-httpbin:v3
args:
- "--port=8090"
- "--version=v1"
imagePullPolicy: Always
name: go-httpbin
ports:
- containerPort: 8090
---
apiVersion: v1
kind: Service
metadata:
name: go-httpbin
namespace: default
spec:
ports:
- port: 80
targetPort: 8090
protocol: TCP
selector:
app: go-httpbin
- 执行以下命令,创建go-httpbin应用。
kubectl apply -f httpbin.yaml
- 安装Kong Kubernetes Ingress Controller。
- 执行以下命令,安装Kong Kubernetes Ingress Controller。
说明 Kong Kubernetes Ingress Controller会使用LoadBalancer类型的kong-proxy Service向外暴露服务,创建的CLB实例会产生额外的费用。关于CLB实例的计费说明,请参见
计费概述。
kubectl create -f https://raw.githubusercontent.com/Kong/kubernetes-ingress-controller/v2.8.0/deploy/single/all-in-one-dbless.yaml
创建完成的资源将会放置在kong命名空间下。
- 验证Kong Kubernetes Ingress Controller是否安装成功。
- 执行以下命令,查看Service的LoadBalancer IP。
kubectl get svc -n kong kong-proxy
预期输出:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kong-proxy LoadBalancer 172.16.19.238 47.14.**.** 80:31611/TCP,443:30936/TCP 10s
在返回结果中获取EXTERNAL IP
。
- 执行以下命令,访问Kong Kubernetes Ingress Controller。
curl http://<EXTERNAL-IP>
预期输出:
{"message":"no Route matched with those values"}
访问Kong Kubernetes Ingress Controller时,返回{"message":"no Route matched with those values"}
,表明安装Kong Kubernetes Ingress Controller成功。
- 创建GatewayClass和Gateway。
- 使用以下内容,创建gateway.yaml。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
name: kong
annotations:
konghq.com/gatewayclass-unmanaged: 'true'
spec:
controllerName: konghq.com/kic-gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: kong
spec:
gatewayClassName: kong
listeners:
- name: proxy
port: 80
protocol: HTTP
- name: proxy-ssl
port: 443
protocol: HTTPS
- 执行以下命令,创建GatewayClass和Gateway。
kubectl apply -f gateway.yaml
- 执行以下命令,查看Gateway外部端点。
kubectl get gateway kong
预期输出:
NAME CLASS ADDRESS PROGRAMMED AGE
kong kong 47.14.**.** 68s
返回以上结果,表明创建GatewayClass和Gateway成功。
使用HTTPRoute
以下介绍如何使用HTTPRoute,
功能一:创建前缀匹配路由
使用HTTPRoute的前缀匹配路由能力,使仅前缀正确的请求路由到应用。
- 使用以下内容,创建demo-route.yaml。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: demo-route
spec:
parentRefs: # 引用Gateway资源。
- group: gateway.networking.k8s.io
kind: Gateway
name: kong
hostnames:
- example.com # host设置为example.com
rules:
- matches: # 匹配规则为前缀匹配路径。
- path:
type: PathPrefix
value: /
backendRefs: # 后端为类型为Service,名称go-httpbin,端口80。
- kind: Service
name: go-httpbin
port: 80
- 执行以下命令,创建HTTPRoute资源。
kubectl apply -f demo-route.yaml
- 执行以下命令,访问go-httpbin应用。
curl http://example.com/version --resolve example.com:80:<EXTERNAL-IP>
预期输出:
version:v1
返回以上结果,表明访问go-httpbin应用成功,创建前缀匹配路由成功。
功能二:创建权重路由
使用HTTPRoute的权重路由能力,使流量按照权重比例路由到应用。
- 创建测试应用new-nginx和old-nginx。
- 使用以下内容,创建nginx.yaml。
apiVersion: apps/v1
kind: Deployment
metadata:
name: old-nginx
spec:
replicas: 1
selector:
matchLabels:
run: old-nginx
template:
metadata:
labels:
run: old-nginx
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/acs-sample/old-nginx
imagePullPolicy: Always
name: old-nginx
ports:
- containerPort: 80
protocol: TCP
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: old-nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: old-nginx
sessionAffinity: None
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: new-nginx
spec:
replicas: 1
selector:
matchLabels:
run: new-nginx
template:
metadata:
labels:
run: new-nginx
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx
imagePullPolicy: Always
name: new-nginx
ports:
- containerPort: 80
protocol: TCP
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: new-nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: new-nginx
sessionAffinity: None
type: NodePort
- 执行以下命令,创建new-nginx和old-nginx。
kubectl apply -f nginx.yaml
- 创建HTTPRoute资源。
- 执行以下命令,创建demo-weight.yaml。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: demo-weight
spec:
parentRefs: # 引用Gateway资源。
- group: gateway.networking.k8s.io
kind: Gateway
name: kong
hostnames:
- weight.example.com # host设置为weight.example.com
rules:
- matches: # 匹配规则为前缀匹配路径。
- path:
type: PathPrefix
value: /
backendRefs:
# 设置后端以及对应权重,权重不为百分比形式,无需等于100。
- kind: Service
name: old-nginx
port: 80
weight: 1 # 设置old-nginx的权重为1。
- kind: Service
name: new-nginx
port: 80
weight: 1 # 设置new-nginx的权重为1。
weight:权重比例,例如本文设置old-nginx的weight为1,new-nginx的weight为1,表明流量按照1∶1的比例路由到old-nginx和new-nginx。
- 执行以下命令,创建HTTPRoute资源。
kubectl apply -f demo-weight.yaml
- 多次执行以下命令,访问new-nginx和old-nginx应用。
curl http://weight.example.com/ --resolve weight.example.com:80:<EXTERNAL-IP>
预期输出:
old
new
old
new
old
new
可以看到流量按照1∶1的比例路由到new-nginx和old-nginx两个应用中,表明创建权重路由成功。
功能三:修改请求头
使用HTTPRoute的filter能力,可以在请求或者回复阶段对请求头进行额外处理。本文以给发送到后端的请求添加请求头为例。关于filter能力的更多介绍,请参见HTTPRoute。
- 创建HTTPRoute资源。
- 执行以下命令,创建demo-filter.yaml。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: demo-filter
spec:
parentRefs: # 引用Gateway资源。
- group: gateway.networking.k8s.io
kind: Gateway
name: kong
hostnames:
- filter.example.com # host设置为filter.example.com。
rules:
- matches: # 匹配规则为前缀匹配路径。
- path:
type: PathPrefix
value: /
filters:
- type: RequestHeaderModifier # 添加请求头my-header: foo。
requestHeaderModifier:
add:
- name: my-header
value: foo
backendRefs: # 后端为类型为Service,名称go-httpbin,端口80。
- kind: Service
name: go-httpbin
port: 80
- 执行以下命令,创建HTTPRoute资源。
kubectl apply -f demo-filter.yaml
- 执行以下命令,访问go-httpbin应用。
curl http://filter.example.com/ --resolve filter.example.com:80:<EXTERNAL-IP>
预期输出:
headers: {
// ...
"My-Header": [
"foo"
],
// ...
}
可以看到访问go-httpbin应用时,返回结果中包含My-Header:foo
请求头,表明修改请求头成功。
配置TLS证书
- 执行以下命令,通过OpenSSL创建自签名证书。
openssl req -subj '/CN=example.com' -new -newkey rsa:2048 -sha256 \
-days 365 -nodes -x509 -keyout server.key -out server.crt \
-addext "subjectAltName = DNS:example.com" \
-addext "keyUsage = digitalSignature" \
-addext "extendedKeyUsage = serverAuth" 2> /dev/null;
openssl x509 -in server.crt -subject -noout
生成的证书和私钥位于当前目录的server.crt和server.key文件中。
- 执行以下命令,使用server.crt和server.key文件创建TLS Secret。
kubectl create secret tls example.com --key server.key --cert server.crt
预期输出:
secret/example.com created
- 将证书配置到Gateway。
- 执行以下命令,创建gateway1.yaml。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: kong
spec:
gatewayClassName: kong
listeners:
- name: proxy
port: 80
protocol: HTTP
- name: proxy-ssl
port: 443
protocol: HTTPS
tls: # 配置TLS。
mode: Terminate
certificateRefs: # 引用所创建的secret。
- kind: Secret
name: example.com
- 执行以下命令,将证书配置到Gateway。
kubectl apply -f gateway1.yaml
- 执行以下命令,验证配置TLS证书是否成功。
openssl s_client -servername example.com -connect <EXTERNAL-IP>:443
返回结果中包含CN = example.com
,表明配置TLS证书成功。