前言
隨著 Kubernetes 生態系統的不斷演進,傳統的 Ingress API 已逐漸無法滿足現代雲原生應用的複雜需求。Kubernetes Gateway API 作為新一代的流量管理標準,提供了更強大、更靈活且更具表達力的路由能力。本文將深入介紹 Gateway API 的設計理念、核心概念,以及如何在實際環境中部署和使用。
Gateway API 概述與設計理念
什麼是 Gateway API?
Gateway API 是 Kubernetes SIG-Network 社群開發的新一代流量管理 API,旨在取代並超越傳統的 Ingress API。它於 2023 年 10 月正式成為 GA(General Availability)穩定版本,標誌著 Kubernetes 網路層的重大進步。
設計理念
Gateway API 的設計遵循以下核心原則:
- 角色導向(Role-Oriented):明確區分基礎設施管理員、叢集操作員和應用開發者的職責
- 可移植性(Portable):提供跨不同實作的標準化介面
- 表達力(Expressive):支援更豐富的路由規則和流量管理功能
- 可擴展性(Extensible):透過 Policy Attachment 機制支援自訂擴展
角色分離模型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| ┌─────────────────────────────────────────────────────────────────┐
│ 基礎設施提供者 │
│ (Infrastructure Provider) │
│ ↓ │
│ GatewayClass │
│ (定義 Gateway 實作類型) │
├─────────────────────────────────────────────────────────────────┤
│ 叢集操作員 │
│ (Cluster Operator) │
│ ↓ │
│ Gateway │
│ (定義監聽器和入口點) │
├─────────────────────────────────────────────────────────────────┤
│ 應用開發者 │
│ (Application Developer) │
│ ↓ │
│ HTTPRoute / TCPRoute / GRPCRoute │
│ (定義路由規則) │
└─────────────────────────────────────────────────────────────────┘
|
Gateway API vs Ingress 比較
功能對比
| 功能 | Ingress | Gateway API |
|---|
| 角色分離 | 無 | 支援 |
| 跨命名空間路由 | 有限 | 完整支援 |
| Header 匹配 | Annotation | 原生支援 |
| 流量分流 | Annotation | 原生支援 |
| 請求/回應修改 | Annotation | 原生支援 |
| TCP/UDP 路由 | 不支援 | 支援 |
| gRPC 路由 | 不支援 | 原生支援 |
| 可移植性 | 低(依賴 Annotation) | 高(標準化 API) |
Ingress 的限制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| # 傳統 Ingress 需要依賴 Annotation 實現進階功能
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: legacy-ingress
annotations:
# 不同 Controller 有不同的 Annotation
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "20"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: example.com
http:
paths:
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: api-service
port:
number: 80
|
Gateway API 的優勢
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| # Gateway API 提供標準化的原生功能
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: modern-route
spec:
parentRefs:
- name: my-gateway
hostnames:
- "example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-v1
port: 80
weight: 80
- name: api-v2
port: 80
weight: 20
|
核心資源類型
GatewayClass
GatewayClass 定義了 Gateway 的實作類型,類似於 StorageClass 之於 PersistentVolume。它由基礎設施提供者建立和管理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: istio-gateway
spec:
controllerName: istio.io/gateway-controller
description: "Istio Gateway Controller"
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: envoy-gateway
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
description: "Envoy Gateway Controller"
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx-gateway
spec:
controllerName: gateway.nginx.org/nginx-gateway-controller
description: "NGINX Gateway Fabric Controller"
|
Gateway
Gateway 代表一個負載平衡器實例,定義了監聽器(Listener)和入口點。它由叢集操作員建立和管理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: production-gateway
namespace: gateway-system
spec:
gatewayClassName: istio-gateway
listeners:
# HTTP 監聽器
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
# HTTPS 監聽器
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: production-cert
kind: Secret
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway-access: "true"
# 特定主機的監聽器
- name: api-https
protocol: HTTPS
port: 443
hostname: "api.example.com"
tls:
mode: Terminate
certificateRefs:
- name: api-cert
allowedRoutes:
namespaces:
from: Same
|
HTTPRoute
HTTPRoute 定義了 HTTP/HTTPS 流量的路由規則,由應用開發者建立和管理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app-routes
namespace: production
spec:
parentRefs:
- name: production-gateway
namespace: gateway-system
hostnames:
- "app.example.com"
- "www.example.com"
rules:
# API 路由
- matches:
- path:
type: PathPrefix
value: /api/v1
backendRefs:
- name: api-v1-service
port: 8080
# 前端路由
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: frontend-service
port: 3000
|
其他路由類型
Gateway API 還支援其他協定的路由:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| # TCPRoute - TCP 流量路由
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: database-route
spec:
parentRefs:
- name: tcp-gateway
sectionName: mysql
rules:
- backendRefs:
- name: mysql-service
port: 3306
---
# GRPCRoute - gRPC 流量路由
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: grpc-route
spec:
parentRefs:
- name: grpc-gateway
hostnames:
- "grpc.example.com"
rules:
- matches:
- method:
service: myapp.UserService
method: GetUser
backendRefs:
- name: user-service
port: 50051
|
Gateway API 安裝與設定
安裝 Gateway API CRDs
首先需要安裝 Gateway API 的 Custom Resource Definitions:
1
2
3
4
5
| # 安裝標準通道(穩定版功能)
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml
# 或安裝實驗性通道(包含實驗性功能)
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/experimental-install.yaml
|
驗證安裝
1
2
3
4
5
6
7
8
| # 檢查 CRDs 是否安裝成功
kubectl get crd | grep gateway
# 預期輸出:
# gatewayclasses.gateway.networking.k8s.io
# gateways.gateway.networking.k8s.io
# httproutes.gateway.networking.k8s.io
# referencegrants.gateway.networking.k8s.io
|
安裝 Gateway Controller
以下介紹幾個常見的 Gateway Controller 安裝方式:
Istio Gateway
1
2
3
4
5
6
7
8
9
| # 使用 istioctl 安裝
istioctl install --set profile=minimal
# 或使用 Helm
helm repo add istio https://istio-release.storage.googleapis.com/charts
helm repo update
helm install istio-base istio/base -n istio-system --create-namespace
helm install istiod istio/istiod -n istio-system --wait
|
Envoy Gateway
1
2
3
4
5
6
7
8
| # 使用 Helm 安裝 Envoy Gateway
helm install eg oci://docker.io/envoyproxy/gateway-helm \
--version v1.2.0 \
-n envoy-gateway-system \
--create-namespace
# 驗證安裝
kubectl wait --timeout=5m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available
|
NGINX Gateway Fabric
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 使用 Helm 安裝
helm install ngf oci://ghcr.io/nginxinc/charts/nginx-gateway-fabric \
--create-namespace \
-n nginx-gateway
# 建立 GatewayClass
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx
spec:
controllerName: gateway.nginx.org/nginx-gateway-controller
EOF
|
建立基本 Gateway
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| # 建立 Gateway 命名空間
kubectl create namespace gateway-system
# 建立 Gateway
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: main-gateway
namespace: gateway-system
spec:
gatewayClassName: istio # 或 nginx, envoy 等
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
EOF
# 檢查 Gateway 狀態
kubectl get gateway -n gateway-system
kubectl describe gateway main-gateway -n gateway-system
|
HTTPRoute 路由設定
基本路由
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: basic-route
namespace: default
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
hostnames:
- "myapp.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: myapp-service
port: 80
|
路徑匹配類型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: path-matching-route
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
rules:
# 精確匹配
- matches:
- path:
type: Exact
value: /api/health
backendRefs:
- name: health-service
port: 8080
# 前綴匹配
- matches:
- path:
type: PathPrefix
value: /api/v1
backendRefs:
- name: api-v1-service
port: 8080
# 正則表達式匹配(實驗性功能)
- matches:
- path:
type: RegularExpression
value: "/users/[0-9]+"
backendRefs:
- name: user-service
port: 8080
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: header-matching-route
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
hostnames:
- "api.example.com"
rules:
# 根據 Header 路由到不同版本
- matches:
- headers:
- name: X-API-Version
value: v2
backendRefs:
- name: api-v2-service
port: 8080
# 預設路由
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: api-v1-service
port: 8080
|
Query Parameter 匹配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: query-matching-route
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
rules:
- matches:
- queryParams:
- name: version
value: beta
backendRefs:
- name: beta-service
port: 8080
- backendRefs:
- name: stable-service
port: 8080
|
Method 匹配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: method-matching-route
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
hostnames:
- "api.example.com"
rules:
# 只允許 GET 和 POST
- matches:
- method: GET
path:
type: PathPrefix
value: /api/resources
- method: POST
path:
type: PathPrefix
value: /api/resources
backendRefs:
- name: api-service
port: 8080
|
請求修改(Request Modification)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: request-modification-route
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
filters:
# 新增 Header
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Custom-Header
value: "custom-value"
- name: X-Request-ID
value: "generated-id"
set:
- name: Host
value: "backend.internal"
remove:
- X-Deprecated-Header
# URL 重寫
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /v1
backendRefs:
- name: api-service
port: 8080
|
回應修改(Response Modification)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: response-modification-route
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: ResponseHeaderModifier
responseHeaderModifier:
add:
- name: X-Frame-Options
value: "DENY"
- name: X-Content-Type-Options
value: "nosniff"
- name: Strict-Transport-Security
value: "max-age=31536000; includeSubDomains"
backendRefs:
- name: web-service
port: 80
|
重導向(Redirect)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: redirect-route
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
hostnames:
- "old.example.com"
rules:
# HTTP 重導向到 HTTPS
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
# 路徑重導向
- matches:
- path:
type: Exact
value: /old-page
filters:
- type: RequestRedirect
requestRedirect:
path:
type: ReplaceFullPath
replaceFullPath: /new-page
statusCode: 301
|
TLS 終止與設定
建立 TLS Secret
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 使用現有憑證建立 Secret
kubectl create secret tls production-cert \
--cert=./tls.crt \
--key=./tls.key \
-n gateway-system
# 或使用 YAML
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: production-cert
namespace: gateway-system
type: kubernetes.io/tls
data:
tls.crt: $(cat tls.crt | base64 -w0)
tls.key: $(cat tls.key | base64 -w0)
EOF
|
Gateway TLS 設定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: secure-gateway
namespace: gateway-system
spec:
gatewayClassName: istio
listeners:
# HTTP 監聽器(用於重導向到 HTTPS)
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
# HTTPS 監聽器
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: production-cert
kind: Secret
allowedRoutes:
namespaces:
from: All
# 特定域名的 HTTPS 監聽器
- name: api-https
protocol: HTTPS
port: 443
hostname: "api.example.com"
tls:
mode: Terminate
certificateRefs:
- name: api-cert
kind: Secret
allowedRoutes:
namespaces:
from: Same
|
TLS Passthrough
對於需要端到端加密的場景,可以使用 TLS Passthrough:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: passthrough-gateway
namespace: gateway-system
spec:
gatewayClassName: istio
listeners:
- name: tls-passthrough
protocol: TLS
port: 443
hostname: "secure.example.com"
tls:
mode: Passthrough
allowedRoutes:
namespaces:
from: All
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: passthrough-route
spec:
parentRefs:
- name: passthrough-gateway
namespace: gateway-system
hostnames:
- "secure.example.com"
rules:
- backendRefs:
- name: secure-backend
port: 443
|
使用 cert-manager 自動管理憑證
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
| # 安裝 cert-manager
# kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.0/cert-manager.yaml
# 建立 ClusterIssuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
gatewayHTTPRoute:
parentRefs:
- name: main-gateway
namespace: gateway-system
---
# 建立 Certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: app-certificate
namespace: gateway-system
spec:
secretName: app-tls-cert
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- "app.example.com"
- "www.example.com"
---
# 在 Gateway 中使用憑證
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: auto-tls-gateway
namespace: gateway-system
spec:
gatewayClassName: istio
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: app-tls-cert
allowedRoutes:
namespaces:
from: All
|
HTTP 到 HTTPS 重導向
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: https-redirect
namespace: gateway-system
spec:
parentRefs:
- name: secure-gateway
sectionName: http # 指定 HTTP 監聽器
hostnames:
- "app.example.com"
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
|
流量分流與金絲雀部署
基於權重的流量分流
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: canary-route
namespace: production
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
# 80% 流量到穩定版本
- name: app-stable
port: 8080
weight: 80
# 20% 流量到金絲雀版本
- name: app-canary
port: 8080
weight: 20
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: header-based-canary
namespace: production
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
hostnames:
- "app.example.com"
rules:
# 內部測試人員使用金絲雀版本
- matches:
- headers:
- name: X-Canary
value: "true"
backendRefs:
- name: app-canary
port: 8080
# Beta 用戶使用金絲雀版本
- matches:
- headers:
- name: X-User-Group
value: "beta"
backendRefs:
- name: app-canary
port: 8080
# 其他流量到穩定版本
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: app-stable
port: 8080
|
藍綠部署
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| # 藍色環境(目前生產環境)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: blue-green-route
namespace: production
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
# 切換時修改權重
- name: app-blue
port: 8080
weight: 100
- name: app-green
port: 8080
weight: 0
|
漸進式發布腳本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| #!/bin/bash
# canary-rollout.sh - 漸進式金絲雀發布腳本
NAMESPACE="production"
ROUTE_NAME="canary-route"
STABLE_SERVICE="app-stable"
CANARY_SERVICE="app-canary"
# 逐步增加金絲雀流量
for weight in 10 25 50 75 100; do
stable_weight=$((100 - weight))
echo "Setting canary weight to ${weight}%..."
kubectl patch httproute ${ROUTE_NAME} -n ${NAMESPACE} --type=json -p="[
{\"op\": \"replace\", \"path\": \"/spec/rules/0/backendRefs/0/weight\", \"value\": ${stable_weight}},
{\"op\": \"replace\", \"path\": \"/spec/rules/0/backendRefs/1/weight\", \"value\": ${weight}}
]"
echo "Waiting 5 minutes for monitoring..."
sleep 300
# 這裡可以加入健康檢查邏輯
# 如果失敗,回滾到 100% stable
done
echo "Canary rollout completed!"
|
A/B 測試
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: ab-testing-route
namespace: production
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
hostnames:
- "app.example.com"
rules:
# A 版本:新結帳流程
- matches:
- headers:
- name: Cookie
type: RegularExpression
value: ".*ab_test=checkout_v2.*"
path:
type: PathPrefix
value: /checkout
backendRefs:
- name: checkout-v2
port: 8080
# B 版本:原始結帳流程
- matches:
- path:
type: PathPrefix
value: /checkout
backendRefs:
- name: checkout-v1
port: 8080
|
與服務網格整合
Istio 整合
Gateway API 與 Istio 的整合非常緊密。Istio 從 1.15 版本開始完整支援 Gateway API。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| # 使用 Istio 作為 Gateway Controller
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: istio
spec:
controllerName: istio.io/gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: istio-gateway
namespace: istio-system
spec:
gatewayClassName: istio
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
---
# HTTPRoute 搭配 Istio 服務網格功能
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: mesh-route
namespace: production
spec:
parentRefs:
- name: istio-gateway
namespace: istio-system
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: frontend
port: 80
|
搭配 Istio 的流量管理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| # 結合 Gateway API 和 Istio VirtualService
# 用於更複雜的流量管理場景
# Gateway API 負責入口流量
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: entry-route
namespace: production
spec:
parentRefs:
- name: istio-gateway
namespace: istio-system
hostnames:
- "app.example.com"
rules:
- backendRefs:
- name: frontend
port: 80
---
# Istio DestinationRule 負責細粒度流量控制
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: frontend-dr
namespace: production
spec:
host: frontend
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
h2UpgradePolicy: UPGRADE
http1MaxPendingRequests: 100
loadBalancer:
simple: LEAST_REQUEST
outlierDetection:
consecutive5xxErrors: 5
interval: 30s
baseEjectionTime: 30s
|
Linkerd 整合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| # Linkerd 也支援 Gateway API
apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
name: linkerd
spec:
controllerName: linkerd.io/gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: linkerd-gateway
namespace: linkerd
annotations:
linkerd.io/inject: enabled
spec:
gatewayClassName: linkerd
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
|
跨服務網格的流量管理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| # 使用 ReferenceGrant 允許跨命名空間引用
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-gateway-to-backend
namespace: backend-system
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: frontend-system
to:
- group: ""
kind: Service
---
# 跨命名空間的路由
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: cross-namespace-route
namespace: frontend-system
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
namespace: backend-system # 跨命名空間引用
port: 8080
|
最佳實務
1. 命名空間隔離策略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
| # 為不同環境建立獨立的 Gateway
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: production-gateway
namespace: gateway-production
spec:
gatewayClassName: istio
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: prod-cert
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
environment: production
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: staging-gateway
namespace: gateway-staging
spec:
gatewayClassName: istio
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: staging-cert
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
environment: staging
|
2. 使用 ReferenceGrant 控制存取
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 明確授權跨命名空間存取
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-routes-from-apps
namespace: gateway-system
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: app-team-a
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: app-team-b
to:
- group: ""
kind: Secret
name: shared-tls-cert
|
3. 實作健康檢查路由
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: health-routes
namespace: production
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
rules:
# 健康檢查端點不需要認證
- matches:
- path:
type: Exact
value: /health
- path:
type: Exact
value: /ready
backendRefs:
- name: health-service
port: 8080
|
4. 設定適當的超時和重試
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| # 使用 BackendLBPolicy(實驗性功能)
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: BackendLBPolicy
metadata:
name: api-backend-policy
namespace: production
spec:
targetRef:
group: ""
kind: Service
name: api-service
sessionPersistence:
sessionName: session-cookie
type: Cookie
---
# 或使用特定 Controller 的 Policy
# 以 Istio 為例
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: api-timeout
namespace: production
spec:
hosts:
- api-service
http:
- timeout: 30s
retries:
attempts: 3
perTryTimeout: 10s
retryOn: connect-failure,refused-stream,503
route:
- destination:
host: api-service
|
5. 監控與可觀測性
1
2
3
4
5
6
7
8
9
10
11
| # 檢查 Gateway 狀態
kubectl get gateway -A -o wide
# 檢查 HTTPRoute 狀態
kubectl get httproute -A
# 查看詳細狀態
kubectl describe gateway main-gateway -n gateway-system
# 檢查路由是否正確綁定
kubectl get httproute my-route -o jsonpath='{.status.parents}'
|
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 設定 Prometheus 監控
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: gateway-metrics
namespace: monitoring
spec:
selector:
matchLabels:
app: istio-ingressgateway
endpoints:
- port: http-monitoring
path: /stats/prometheus
|
6. GitOps 最佳實務
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # 使用 Kustomize 管理不同環境的設定
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gateway.yaml
- routes/
patches:
- path: patches/gateway-patch.yaml
target:
kind: Gateway
name: main-gateway
configMapGenerator:
- name: gateway-config
literals:
- ENVIRONMENT=production
|
7. 安全性建議
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| # 實作 CORS 和安全 Header
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: secure-route
namespace: production
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: ResponseHeaderModifier
responseHeaderModifier:
add:
- name: X-Frame-Options
value: "DENY"
- name: X-Content-Type-Options
value: "nosniff"
- name: X-XSS-Protection
value: "1; mode=block"
- name: Referrer-Policy
value: "strict-origin-when-cross-origin"
- name: Content-Security-Policy
value: "default-src 'self'"
backendRefs:
- name: web-service
port: 80
|
8. 版本遷移策略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| # 從 Ingress 遷移到 Gateway API 的過渡期設定
# 同時維護兩種路由,逐步切換流量
# 保留原有 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: legacy-ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "50" # 逐步減少
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
---
# 新的 Gateway API 路由
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: new-route
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
hostnames:
- "app.example.com"
rules:
- backendRefs:
- name: app-service
port: 80
|
故障排除
常見問題診斷
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # 檢查 GatewayClass 是否被接受
kubectl get gatewayclass
kubectl describe gatewayclass <name>
# 檢查 Gateway 狀態
kubectl get gateway -n gateway-system
kubectl describe gateway <name> -n gateway-system
# 檢查 HTTPRoute 是否正確綁定到 Gateway
kubectl get httproute -A
kubectl describe httproute <name> -n <namespace>
# 查看 Gateway Controller 日誌
kubectl logs -n istio-system -l app=istiod
kubectl logs -n envoy-gateway-system -l app=envoy-gateway
# 檢查 Gateway Pod 狀態
kubectl get pods -n gateway-system
kubectl describe pod <gateway-pod> -n gateway-system
|
常見錯誤及解決方案
| 錯誤 | 可能原因 | 解決方案 |
|---|
| Gateway 不被接受 | GatewayClass 不存在 | 確認 Controller 已安裝並建立 GatewayClass |
| HTTPRoute 未綁定 | parentRef 設定錯誤 | 檢查 Gateway 名稱和命名空間是否正確 |
| 跨命名空間路由失敗 | 缺少 ReferenceGrant | 建立適當的 ReferenceGrant 資源 |
| TLS 憑證錯誤 | Secret 不存在或格式錯誤 | 確認 Secret 存在且為 kubernetes.io/tls 類型 |
| 503 錯誤 | 後端服務不可用 | 檢查 Service 和 Pod 狀態 |
總結
Kubernetes Gateway API 代表了 Kubernetes 網路層的重大進步。相比傳統的 Ingress API,它提供了:
- 更清晰的角色分離:基礎設施管理員、叢集操作員和應用開發者各司其職
- 更強大的表達能力:原生支援 Header 匹配、流量分流、請求修改等進階功能
- 更好的可移植性:標準化的 API 減少了對特定 Controller 的依賴
- 更靈活的擴展機制:透過 Policy Attachment 支援自訂擴展
隨著 Gateway API 正式成為 GA 版本,越來越多的 Gateway Controller 實作開始支援這個新標準。建議在新專案中優先考慮使用 Gateway API,並逐步將現有的 Ingress 遷移到 Gateway API。
參考資源