使用gateway api来实现GKE 的pods 从外部访问

传统实现k8s 的集群外访问的方法

当我们部署了一个web app 到k8s的pods里, 如果要实现从外部访问, 除了要创建1个clusterip 作为loadbarlancer 外, 还需要创建1个ingress 实现从外部访问 该clusterip.

但是ingress 的 创建相对繁琐, 以nginx-ingress为例, 首先要安装1个 ingress controller, 再基于此controller setup 1个ingress 对象。。。

体验并不好

什么是k8s 的gateway api?

Kubernetes Gateway API 是一个用于管理集群入口流量的高级 API。它旨在替代 Ingress API,并提供更强大、更灵活、更具扩展性的功能。

Gateway API 由 Kubernetes SIG-NETWORK 社区开发和维护。

最早版本: Gateway API 的第一个版本是 v1alpha1,于 2021 年发布。

较新版本: 目前,Gateway API 的最新版本是 v1beta1 和 v1。v1beta1 版本在 Kubernetes v1.23+ 中可用,而 v1 版本在 Kubernetes v1.28+ 中可用。

gateway api 相比于 ingress 有哪些优缺点?

如何使用 Gateway API:

安装 Gateway API CRD: 首先需要在 Kubernetes 集群中安装 Gateway API 的 Custom Resource Definitions (CRD)。

部署 Gateway Controller: Gateway Controller 负责监听 Gateway 资源,并根据配置进行流量路由。常用的 Gateway Controller 包括 Contour、Istio 和 Kong。

创建 Gateway 资源: 创建 Gateway 资源来定义监听的端口和协议。

创建 Route 资源: 创建 HTTPRoute 或 TCPRoute 等资源来定义流量路由规则。

配置 Backend: 将流量路由到后端服务。

gateway api 相比于 ingress 有哪些优缺点?

gateway api 相比于 ingress 有哪些优缺点?

Gateway API 的优点:

角色分离: Gateway API 允许集群管理员、应用开发者和服务提供商分别管理 Gateway 资源、HTTPRoute/TCPRoute 等路由资源以及后端服务,实现了更清晰的职责划分。

协议支持: 除了 HTTP(S) 之外,Gateway API 还支持 TCP、UDP 和 TLS 等协议,适用范围更广。

高级流量管理: Gateway API 提供了更丰富的流量管理功能,例如流量分割、流量镜像、请求头修改等,可以满足更复杂的业务需求。

可扩展性: Gateway API 允许自定义 GatewayClass 和 Route 类型,可以根据实际需求进行扩展。

更强的表达能力: Gateway API 使用 CRD (Custom Resource Definitions) 扩展了 Kubernetes API,允许更细粒度的配置和更强大的功能。

Gateway API 的缺点:

复杂性: Gateway API 的配置和管理比 Ingress 更加复杂,需要更多的学习成本。

生态系统: 相比于 Ingress,Gateway API 的生态系统还不够完善,支持的 Controller 较少。

成熟度: Gateway API 还是相对较新的 API,可能存在一些未知的 Bug 或问题。

GKE的gateway api

可见gateway api的首次安装甚至更复杂, 但是GKE 已经在平台Level 帮我们完全了所有繁琐的前置工作, 我们只需要直接使用就好

GKE Gateway API 支持

GKE 提供了对 Gateway API 的支持,方便你在 GKE 集群中使用 Gateway API 来管理入口流量。

GKE Gateway Controller

GKE 提供了自己的 Gateway Controller,称为 gke-l7-global-external-managed。你可以在 Gateway 资源中使用 gatewayClassName: gke-l7-global-external-managed 来指定使用 GKE 提供的 Gateway Controller。这个 Controller 实现了 Gateway API 规范,并与 GKE 的负载均衡器集成。

接下我会用1个实际例子部署和使用GKE 的gateway api.

首先我们部署两个python的web app 到GKE

py-api-svc:

https://github.com/nvd11/py-api-svc.git

root path 是/pyapi

py-webhook-svc:

https://github.com/nvd11/py-webhook-svc.git

root path 是/webhook

我们还要配置两个clusterip 作为 它们的Load balancer

部署过程省略。。。

检查部署后的资源
bash 复制代码
gateman@MoreFine-S500: github$ kubectl get pods -o wide
NAME                              READY   STATUS    RESTARTS   AGE   IP              NODE                                       NOMINATED NODE   READINESS GATES
dns-test                          1/1     Running   0          86m   192.171.18.9    gke-my-cluster2-node-pool1-01eff82c-1r5b   <none>           <none>
py-api-svc-77585759d7-6dcfs       1/1     Running   0          76m   192.171.17.13   gke-my-cluster2-node-pool1-8bb426f2-3nqn   <none>           1/1
py-api-svc-77585759d7-9mdt7       1/1     Running   0          76m   192.171.16.13   gke-my-cluster2-node-pool1-6a83612b-mj40   <none>           1/1
py-api-svc-77585759d7-lf9wh       1/1     Running   0          76m   192.171.18.11   gke-my-cluster2-node-pool1-01eff82c-1r5b   <none>           1/1
py-webhook-svc-78bd8646bd-9mnqv   1/1     Running   0          48s   192.171.16.15   gke-my-cluster2-node-pool1-6a83612b-mj40   <none>           1/1
py-webhook-svc-78bd8646bd-chwh9   1/1     Running   0          40s   192.171.17.15   gke-my-cluster2-node-pool1-8bb426f2-3nqn   <none>           1/1
py-webhook-svc-78bd8646bd-p77k9   1/1     Running   0          54s   192.171.18.13   gke-my-cluster2-node-pool1-01eff82c-1r5b   <none>           1/1
gateman@MoreFine-S500: github$ kubectl get svc -o wide
NAME                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE   SELECTOR
clusterip-py-api-svc       ClusterIP   192.172.26.174   <none>        8000/TCP   10h   app=py-api-svc
clusterip-py-webhook-svc   ClusterIP   192.172.21.174   <none>        8000/TCP   72m   app=py-webhook-svc
kubernetes                 ClusterIP   192.172.16.1     <none>        443/TCP    47h   <none>
在dns-test 容器里测试两个clusterip
bash 复制代码
gateman@MoreFine-S500: github$ kubectl exec -it dns-test -- /bin/sh
/home # curl clusterip-py-api-svc:8000/pyapi/
{"message":"Hello, py-api-svc!"}/home # 
/home # curl clusterip-py-webhook-svc:8000/webhook/
{"message":"Hello, webhook service!"}/home # 

两个web svc 都部署好了, 接下来配置gateway

为GKE cluster enable gateway api

默认下是没有enabled的。

命令

bash 复制代码
gcloud container clusters update my-cluster2 --region europe-west2 --gateway-api=standard

确认结果:

bash 复制代码
(.venv) gateman@MoreFine-S500: py-webhook-svc$ kubectl get crds | grep gateway.networking.k8s.io
gatewayclasses.gateway.networking.k8s.io           2025-10-04T10:34:22Z
gateways.gateway.networking.k8s.io                 2025-10-04T10:34:21Z
httproutes.gateway.networking.k8s.io               2025-10-04T10:34:22Z
referencegrants.gateway.networking.k8s.io          2025-10-04T10:34:24Z

编写一个gateway 的yaml

gateway.yaml

yaml 复制代码
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
  name: py-api-gateway
spec:
  gatewayClassName: gke-l7-global-external-managed
  listeners:
    - name: http
      protocol: HTTP
      port: 80
      allowedRoutes:
        namespaces:
          from: Same

---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: py-api-route
spec:
  parentRefs:
    - name: py-api-gateway
  hostnames:
    - "jpgcp.shop"
  rules:
    - matches:
      - path:
          type: PathPrefix
          value: /pyapi
      filters:
      - type: URLRewrite
        urlRewrite:
          path:
            type: ReplacePrefixMatch
            replacePrefixMatch: /
      backendRefs:
        - name: clusterip-py-api-svc
          port: 8000
    - matches:
      - path:
          type: PathPrefix
          value: /webhook
      filters:
      - type: URLRewrite
        urlRewrite:
          path:
            type: ReplacePrefixMatch
            replacePrefixMatch: /
      backendRefs:
        - name: clusterip-py-webhook-svc
          port: 8000

注意这里定义了两个资源, 一个是gateway本身,另一个是其http route。

其中httproute 中根据不同的url path 转发到不同的后端svc, 这也是gateway的核心功能。

值得注意是hostname , 如果不只是为了内部测试, 建议先从go爸爸买一个dns.

部署后检查gateway资源

当执行kubectl apply 后

我们检查下创建出来的Gateway对象, 正常需要大概一分钟才会被完全初始化和分配ip

bash 复制代码
gateman@MoreFine-S500: github$ kubectl describe gateway py-api-gateway
Name:         py-api-gateway
Namespace:    default
Labels:       <none>
Annotations:  networking.gke.io/addresses: /projects/912156613264/global/addresses/gkegw1-bu0s-default-py-api-gateway-jfly4jdo622c
              networking.gke.io/backend-services:
                /projects/912156613264/global/backendServices/gkegw1-bu0s-default-clusterip-py-api-svc-8000-iwtsiatbjn23, /projects/912156613264/global/ba...
              networking.gke.io/firewalls: /projects/912156613264/global/firewalls/gkegw1-bu0s-l7-tf-vpc0-global
              networking.gke.io/forwarding-rules: /projects/912156613264/global/forwardingRules/gkegw1-bu0s-default-py-api-gateway-e6c3tpani22a
              networking.gke.io/health-checks:
                /projects/912156613264/global/healthChecks/gkegw1-bu0s-default-clusterip-py-api-svc-8000-iwtsiatbjn23, /projects/912156613264/global/healt...
              networking.gke.io/last-reconcile-time: 2025-10-04T16:03:47Z
              networking.gke.io/lb-route-extensions: 
              networking.gke.io/lb-traffic-extensions: 
              networking.gke.io/ssl-certificates: 
              networking.gke.io/target-http-proxies: /projects/912156613264/global/targetHttpProxies/gkegw1-bu0s-default-py-api-gateway-rrnx141i3brm
              networking.gke.io/target-https-proxies: 
              networking.gke.io/url-maps: /projects/912156613264/global/urlMaps/gkegw1-bu0s-default-py-api-gateway-rrnx141i3brm
              networking.gke.io/wasm-plugin-versions: 
              networking.gke.io/wasm-plugins: 
API Version:  gateway.networking.k8s.io/v1
Kind:         Gateway
Metadata:
  Creation Timestamp:  2025-10-04T10:45:50Z
  Finalizers:
    gateway.finalizer.networking.gke.io
  Generation:        1
  Resource Version:  1759593827931391023
  UID:               4567f1b0-0c3c-414e-b407-28b9d29c06fa
Spec:
  Gateway Class Name:  gke-l7-global-external-managed
  Listeners:
    Allowed Routes:
      Namespaces:
        From:  Same
    Name:      http
    Port:      80
    Protocol:  HTTP
Status:
  Addresses:
    Type:   IPAddress
    Value:  34.111.35.228
  Conditions:
    Last Transition Time:  2025-10-04T10:46:40Z
    Message:               The OSS Gateway API has deprecated this condition, do not depend on it.
    Observed Generation:   1
    Reason:                Scheduled
    Status:                True
    Type:                  Scheduled
    Last Transition Time:  2025-10-04T10:46:40Z
    Message:               
    Observed Generation:   1
    Reason:                Accepted
    Status:                True
    Type:                  Accepted
    Last Transition Time:  2025-10-04T16:03:47Z
    Message:               
    Observed Generation:   1
    Reason:                Programmed
    Status:                True
    Type:                  Programmed
    Last Transition Time:  2025-10-04T16:03:47Z
    Message:               The OSS Gateway API has altered the "Ready" condition semantics and reserved it for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
    Observed Generation:   1
    Reason:                Ready
    Status:                True
    Type:                  Ready
    Last Transition Time:  2025-10-04T16:03:47Z
    Message:               
    Observed Generation:   1
    Reason:                Healthy
    Status:                True
    Type:                  networking.gke.io/GatewayHealthy
  Listeners:
    Attached Routes:  1
    Conditions:
      Last Transition Time:  2025-10-04T10:46:40Z
      Message:               
      Observed Generation:   1
      Reason:                ResolvedRefs
      Status:                True
      Type:                  ResolvedRefs
      Last Transition Time:  2025-10-04T10:46:40Z
      Message:               
      Observed Generation:   1
      Reason:                Accepted
      Status:                True
      Type:                  Accepted
      Last Transition Time:  2025-10-04T16:03:47Z
      Message:               
      Observed Generation:   1
      Reason:                Programmed
      Status:                True
      Type:                  Programmed
      Last Transition Time:  2025-10-04T16:03:47Z
      Message:               The OSS Gateway API has altered the "Ready" condition semantics and reserved it for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
      Observed Generation:   1
      Reason:                Ready
      Status:                True
      Type:                  Ready
    Name:                    http
    Supported Kinds:
      Group:  gateway.networking.k8s.io
      Kind:   HTTPRoute
Events:
  Type    Reason  Age                    From                   Message
  ----    ------  ----                   ----                   -------
  Normal  SYNC    41m (x118 over 5h18m)  sc-gateway-controller  default/py-api-gateway
  Normal  SYNC    3s (x114 over 5h15m)   sc-gateway-controller  SYNC on default/py-api-gateway was a success

获得ip地址34.111.35.228 后, 直至使用ip地址访问是无效的,

yaml 复制代码
  hostnames:
    - "jpgcp.shop"

httproute的hostname配置指定了只能通过hostname 访问

所以我们还需要在域名提供商那里把jpgcp.shop 跟ip 34.111.35.228 map上

测试gateway

bash 复制代码
gateman@MoreFine-S500: github$ curl http://jpgcp.shop/pyapi/
{"message":"Hello, py-api-svc!"}gateman@MoreFine-S500: github$ 
gateman@MoreFine-S500: github$ curl http://jpgcp.shop/webhook/
{"message":"Hello, webhook service!"}gateman@MoreFine-S500: github$ 

完美

相关推荐
罗不俷4 小时前
【Kubernetes】(二十)Gateway
容器·kubernetes·gateway
月夕·花晨2 天前
Gateway-过滤器
java·分布式·spring·spring cloud·微服务·gateway·sentinel
Ytadpole3 天前
性能革命的底层逻辑:深入理解 Spring Cloud Gateway 的 Reactor 核心
java·spring·gateway·reactor·响应式编程·cloud
柳贯一(逆流河版)5 天前
Gateway 集成 JWT 身份认证:微服务统一认证的实战指南
微服务·架构·gateway
码界奇点5 天前
Nginx 502 Bad Gateway从 upstream 日志到 FastCGI 超时深度复盘
运维·nginx·阿里云·性能优化·gateway
半夏知半秋5 天前
基于skynet框架业务中的gateway实现分析
服务器·开发语言·后端·学习·gateway
耳东哇6 天前
sentinel docker gateway k8s 集群 主从
docker·gateway·sentinel
龙茶清欢7 天前
2、Nginx 与 Spring Cloud Gateway 详细对比:定位、场景与分工
java·运维·spring boot·nginx·spring cloud·gateway
龙茶清欢7 天前
在 Spring Cloud Gateway 中实现跨域(CORS)的两种主要方式
java·spring boot·spring cloud·微服务·gateway