当前位置: 首页 > 科技观察

再见KubernetesIngress,是时候拥抱更强大的后继者GatewayAPI

时间:2023-03-15 11:01:08 科技观察

GatewayAPI(原名ServiceAPI)是由SIG-NETWORK社区管理的开源项目,项目地址:https://gateway-api.sigs.k8s.io/。主要原因是Ingress资源对象不能很好的满足网络要求。在很多场景下,Ingresscontroller需要通过定义annotations或者crds来扩展其功能,这对于标准的使用和支持是非常不利的。新推出的GatewayAPI旨在通过可扩展的面向角色的接口增强服务网络。GatewayAPI是Kubernetes中API资源的集合,包括GatewayClass、Gateway、HTTPRoute、TCPRoute、Service等。这些资源协同工作,为各种网络用例构建模型。GatewayAPI的价值和定位提供了一个跨Namespace的Ingress机制:允许多个跨Namespace的服务共享一个L7LoadBalancer一个可以实现多租户的Ingress机制:提供了一个分离HttpRoute和Gateway的抽象组件,允许设计路由(HttpRoute)人们可以共享一个L7LoadBalancer。蓝绿部署金丝雀部署在同一个命名空间下。您可以简单地在HttpRoute中根据Hostname、Header或Subpath定义服务,并使用AB测试等。GatewayAPI介绍GatewayAPI主要分为以下几个角色:GatewayClass(Cloud或K8s提供商提供)、Gateway(网管平台公司搭建的GatewayClass)、HTTPRoute(开发团队服务部署者选择对应的网关对接)目前GKE提供四个网关类,它们是:gke-l7-rilb构建在内部HTTP(S)负载均衡上区域内部HTTP(S)负载均衡器(单集群内部LoadBalancer)gke-l7-gxlb构建在全局外部HTTP(S)负载上BalancerontopofExternalHTTP(S)LoadBalancing(SingleClusterExternalLoadBalancer)gke-l7-rilb-mc基于InternalHTTP(S)LoadBalancing的Multi-clusterRegionalLoadBalancer(Multi-ClusterInternalLoadBalancer)gke-l7-gxlb-mc是基于ExternalHTTP(S)LoadBalancing多集群全局负载均衡器(multi-clusterExternalLoadBalancer)网关部署当前GKEGatewayAPIK8S版本1.20以上,如果使用GKE发布通道,需要to支持Oil,现在需要使用RAPIDregion,只提供以下公测:us-west1us-east1us-central1europe-west4europe-west3europe-west2europe-west1asia-southeast1以下测试,我们选择先测试Interal-LoadBalancer,尝试如下拓扑图:部署私有GKE我们先开发一个私有GKE集群,可以参考我提供的Terraform脚本,请直接修改shawn.tfvars以匹配你集群的参数,并且因为我使用的是远程GCS请同时保存tfstate并修改config.tf中的bucket名称。其他常用设置与私有GKE类似,只需要使用内部LB并添加一个proxy-only子网供Envoy使用。部署网关根据上面第三阶段,我们先部署GatewayAPI的CRD文件:kubectlkustomize"github.com/kubernetes-sigs/gateway-api/config/crd?ref=v0.3.0"\|kubectlapply-f-#部署成功后可以使用如下命令查看单个集群internal/externalGatewayClassprivate-gke-tf%kubectlgetgatewayclassNAMECONTROLLERAGEgke-l7-gxlbnetworking.gke.io/gateway23hgke-l7-rilbnetworking.gke.io/gateway23h接下来我们要部署网关,使用kubectlapply-f部署底层YAML:kind:GatewayapiVersion:networking.x-k8s.io/v1alpha1metadata:name:internal-httpspec:gatewayClassName:gke-l7-rilblisteners:-protocol:HTTPport:80routes:kind:HTTPRouteselector:matchLabels:gateway:internal-httpnamespaces:from:"All"因为网关可以接受三种关联模式,基于种类、选择器和命名空间。kind:可以选择以下任意一种Routes:HTTPRoute、TCPRoute或customRouteLabel:通过选择或选择对应的标签namespaces:通过namespaces.from选择Route所在的命名空间。默认是和Gateway在同一个命名空间的Route,因为我们要创建一个跨命名空间的共享网关,所以我们将namespaces.from改为All。部署成功后可以通过以下命令查看:private-gke-tf%kubectldescribegatewayinternal-httpEvents:TypeReasonAgeFromMessage-------------------------NormalSYNC4m59s(x396over23h)sc-gateway-controllerSYNCondefault/internal-httpwasasuccess部署服务+HTTPRoute接下来我们快速部署测试的两个服务,其中store服务部署在default命名空间,site服务部署在site命名空间。部署相应的HTTPRoute,其中http-route.yaml适用于store服务:kind:HTTPRouteapiVersion:networking.x-k8s.io/v1alpha1metadata:name:storelabels:gateway:internal-httpspec:hostnames:-》store.example。com“规则:-forwardTo:-serviceName:store-v1port:8080weight:50-serviceName:store-v2port:8080weight:50-matches:-headers:type:Exactvalues:env:canaryforwardTo:-serviceName:store-v2port:8080-matches:-path:type:Prefixvalue:/deforwardTo:-serviceName:store-germanport:8080对于store服务,我们特意开发了三个不同的后端服务来测试HTTPRoute的不同能力(1)主机名匹配:通过不同的主机名(如store.example.com或site.example.com)将用户连接路由到指定的后台服务(2.1)header匹配:如果请求头中包含env:canary等信息,则路由到store-v2服务(2.2)前缀匹配:如果请求路径前缀为/de,则路由到store-germanservice(3)defaultroute:根据权重,自动均衡到指定的store-v1和store-v2后台服务,使用http-service.yaml配置该服务。由于HTTPRoute和Gateway的命名空间不同,所以必须引入一个gatewayRefs参数:kind:HTTPRouteapiVersion:networking.x-k8s.io/v1alpha1metadata:name:sitenamespace:sitelabels:gateway:internal-httpspec:gateways:allow:FromListgatewayRefs:-name:internal-httpnamespace:defaulthostnames:-"site.example.com"rules:-forwardTo:-serviceName:site-v1port:8080由于我们使用的是InternalLoadBalancer,因此我们需要打开一个GCEVM为了测试,因为我们使用的是私有集群,请记住GCEVM和私有GKE集群在同一个VPC中在K8S客户端上,获取InternalLoadBalancer的IP地址:kubectlgetgatewayinternal-http-ojsonpath='{.status.addresses[0].value}'10.81.68.140在GCEVM上,让我们测试一下我们上面定义的HttpRoute:(1)根据Hostname路由服务:通过定义hostname为site.example.com路由到另一个命名空间的K8S服务:shawnho@jumper2:~$curl-H"host:site.example.com"10.81.68.140{"cluster_name":"pgke-1","host_header":"site.example.com","metadata":"site-v1","node_name":"gke-pgke-1-cluster-runtime-425beb23-vx9j.c.shawn-demo-2021.internal","pod_name":"site-v1-86dc4b4fbc-4g6jr","pod_name_emoji":"🌾","project_id":"shawn-demo-2021","timestamp":"2021-07-18T15:26:15","zone":"asia-southeast1-a"}(2)基于主机名:"store.example.com",分别测试(2.1)Header和(2.2))Prefix前缀机制:#testheadermatchshawnho@jumper2:~$curl-H"host:store.example.com"-H"env:canary"10.81.68.140{"cluster_name":"pgke-1","host_header":"store.example.com","metadata":"store-v2","node_name":"gke-pgke-1-cluster-runtime-425beb23-vx9j.c.shawn-demo-2021.internal","pod_name":"store-v2-6856f59f7f-49fv8","pod_name_emoji":"🎹","project_id":"shawn-demo-2021","timestamp":"2021-07-18T15:33:04","zone":"asia-southeast1-a"}#测试prefixmatchshawnho@jumper2:~$curl-H"host:store.example.com"10.81.68.140/de{"cluster_name":"pgke-1","host_header":"store.example.com","metadata":"Gutentag!",node_name":"gke-pgke-1-cluster-runtime-425beb23-vx9j.c.shawn-demo-2021.internal","pod_name":"store-german-66dcb75977-ttngz","pod_name_emoji":"💇🏼?","project_id":"shawn-demo-2021","timestamp":"2021-07-18T15:32:15","zone":"亚洲-southeast1-a"}(3)基于主机下默认路由的权重(1:1)路由服务:store.example.com:#testdefaultrouteshawnho@jumper2:~$curl-H"host:store.example。com"10.81.68.140{"cluster_name":"pgke-1","host_header":"store.example.com","metadata":"store-v1","node_name":"gke-pgke-1-cluster-runtime-425beb23-vx9j.c.shawn-demo-2021.internal","pod_name":"store-v1-65b47557df-rv65j","pod_name_emoji":"🧘🏿?♂?","project_id":"shawn-demo-2021","timestamp":"2021-07-18T15:32:09","zone":"asia-southeast1-a"}shawnho@jumper2:~$curl-H"host:store.example.com"10.81.68.140{"cluster_name":"pgke-2","host_header":"store.example.com","metadata":"store-v2","node_name":"gke-pgke-2-cluster-runtime-e7f1b4b7-wg5a。c.shawn-demo-2021.internal","pod_name":"store-v2-6856f59f7f-gkkct","pod_name_emoji":"👈🏼","project_id":"shawn-demo-2021","timestamp":"2021-07-18T15:32:29","zone":"asia-southeast1-a"}到这里可以看到测试成功!