前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Istio 1.16尝鲜:使用K8s Gateway API代替Istio Ingress Gateway

Istio 1.16尝鲜:使用K8s Gateway API代替Istio Ingress Gateway

作者头像
CNCF
发布2022-11-28 17:34:29
3.1K0
发布2022-11-28 17:34:29
举报
文章被收录于专栏:CNCF

作者:黄鑫,英特尔云原生软件开发工程师

随着Istio 1.16.0[1]的正式发布,也宣布了 Istio 基于Kubernetes Gateway API[2]的实现进入到了 Beta 阶段,这意味着 Istio 中所有南北向(Ingress)流量管理都可以迁移至 Kubernetes Gateway API。未来随着 Kubernetes Gateway API 的发展和成熟,Istio 东西向(Mesh)流量管理 API 也会被其慢慢代替。

本文将会介绍 Kuberenetes Gateway API 的背景,并且手把手带你体验使用 Kuberenetes Gateway API 代替 Istio Ingress Gateway。

Kubernetes Gateway API 是什么?

大家一定都知道 Kubernetes 中的 Ingress API 是对集群中服务的外部访问进行管理的 API 对象,同时也可以提供负载均衡,SSL 卸载以及虚拟路由等功能。Ingress API 也伴随着 Kubernetes 稳定服役了 5 年之久,但是慢慢随着集群规模的扩大,业务管理的复杂化,Ingress API 渐渐无法满足日益多样化的需求,人们发现 Ingress API 提供的功能太少且很难被扩展,各个厂商都提供了不同的扩展方式,例如加入不同的 annotation, 这导致应用很难在不同的厂商之间无缝迁移, 并且提供的权限管理模型也过于单一。

于是 Kubernetes 社区便孕育出了新一代的流量管理标准:Gateway API。相较于 Ingress API, Gateway API 的主要改进在于:

  • 提供了比 Ingress API 更丰富的,具有可扩展性的 API 集合,例如基于 Header 的流量匹配,流量加权以及其他在 Ingress API 中需要自定义注释实现的功能。
  • Gateway API 的设计是角色导向的,它允许不同的团队共享网络基础设施,并且通过角色策略约束不同角色的行为。
  • Gateway API 也添加了对东西向(Mesh)流量管理的支持,为此各大 Service Mesh 厂商还成立了GAMMA(Gateway API Mesh Management and Administration)[3]工作小组来探索和讨论在 Gateway API 中处理东西向流量的规范。

Kubernetes Gateway API 是如何工作的?

在理解 Kubernetes Gateway API 是如何工作之前,需要先对其中几个基本资源类型有个大致的了解:

  • GatewayClass: 类似于 Ingress 中的 Ingress Class 对象,定义了一组共享通用配置和行为的 Gateway 集合,一个 GatewayClass 被一个 Controller 控制。
  • Gateway: 描述了流量被分配到集群中服务的方式,可以直接由管理员创建,也可以由控制 GatewayClass 的 Controller 创建。
  • Route: 描述了通过网关的流量如何映射到服务,目前 Gateway API 中提供了五种不同协议的 Route,分别是 HTTPRoute,TLSRoute,TCPRoute,UDPRoute 和 GRPCRoute。

下图展示了这三种资源类型的拓扑关系:

接着我们通过一个实际例子说明基于角色的 Kubernetes Gateway API 是如果工作的,如下图所示,一个集群管理员创建了一个 Gateway 资源,该 Gateway 对访问 foo.example.com 的流量进行了 TLS 配置并设置了默认策略。在和集群管理员达成一致后,负责存储的开发人员创建了一个 HTTPRoute,将访问foo.example.com/store/*的流量导入到 Store Namespace 下的 foo-store 服务中,并且对这些流量进行了加权分发,将 90%的流量导入到 foo-store v1 中,另外 10%的流量导入到 foo-store v2 中。另外一边,负责网站的开发人员也创建了一个 HTTPRoute,将访问foo.example.com/site/* 的流量导入到 Site Namespace 下的 foo-site 服务中。这种用户模型在为基础设施提供灵活性的同时也保证了对不同角色之间的控制。

如何在 Istio 中使用 Kubernetes Gateway API?

接下来,我们通过实际操作展示在 Istio 中通过 Kubernetes Gateway API 将一个服务暴露到集群外部。

安装 Kubernetes Gateway API CRD

大多数 Kubernetes 集群中没有默认安装 Gateway API,因此需要手动安装 Gateway API 的 CRD:

代码语言:javascript
复制
$ kubectl get crd gateways.gateway.networking.k8s.io || kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v0.5.1" | kubectl apply -f -;

使用最小配置安装 Istio, 因为我们不再需要istio-ingressgateway

代码语言:javascript
复制
$ istioctl install --set profile=minimal -y

安装完成后,Istio 会自动创建一个 GatewayClass,Controller 为istio.io/gateway-controller

代码语言:javascript
复制
$ kubectl get gatewayclass
NAME    CONTROLLER                    ACCEPTED   AGE
istio   istio.io/gateway-controller   True       6s

创建服务并配置 Gateway

需要加以区分的是,这里的Gateway指的是 Kuberentes Gateway APIgateway.networking.k8s.io/v1beta1 中的 Gateway 资源,而不是 Istio API networking.istio.io/v1beta1 中的Gateway

我们会部署一个名为httpbin的简单服务,并且将它用Gateway暴露到集群外部。

  1. 部署httpbin服务:
代码语言:javascript
复制
$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/1.16.0/samples/httpbin/httpbin.yaml
  1. 部署GatewayHTTPRoute,将访问httpbin.example.com/get/* 的流量导入到httpbin服务中:
代码语言:javascript
复制
$ kubectl create namespace istio-ingress
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
  name: gateway
  namespace: istio-ingress
spec:
  gatewayClassName: istio # 这里指定使用istio gatewayclass
  listeners:
  - name: default
    hostname: "*.example.com"
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: http
  namespace: default
spec:
  parentRefs:
  - name: gateway
    namespace: istio-ingress
  hostnames: ["httpbin.example.com"]
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /get
    backendRefs:
    - name: httpbin
      port: 8000
EOF
  1. 等待Gateway部署完成并设置Ingress Host环境变量:
代码语言:javascript
复制
$ kubectl wait -n istio-ingress --for=condition=ready gateways.gateway.networking.k8s.io gateway
$ export INGRESS_HOST=$(kubectl get gateways.gateway.networking.k8s.io gateway -n istio-ingress -ojsonpath='{.status.addresses[*].value}')

默认情况下,每个Gateway 会自动创建同名的ServiceDeployment ,如果更新了Gateway,它们也会随之更新:

代码语言:javascript
复制
$ kubectl get deployment -n istio-ingress
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
gateway   1/1     1            1           3m29s

$ kubectl get service -n istio-ingress
NAME      TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                        AGE
gateway   LoadBalancer   10.107.79.229   <pending>     15021:30088/TCP,80:31690/TCP   4m13s
  1. 访问httpbin 服务:
代码语言:javascript
复制
$ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/get"
HTTP/1.1 200 OK
server: istio-envoy
...

请注意,这里使用了-H将 HTTP Header 中的Host设置为httpbin.example.com, 因为 HTTPRoute 配置的是处理httpbin.example.com的流量。

  1. 访问没有配置过的路由/headers,会得到 HTTP 404 的错误:
代码语言:javascript
复制
$ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/headers"
HTTP/1.1 404 Not Found
...
  1. 更新路由规则,将访问/headers 的流量也暴露出来,并给请求加上 header:
代码语言:javascript
复制
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: http
  namespace: default
spec:
  parentRefs:
  - name: gateway
    namespace: istio-ingress
  hostnames: ["httpbin.example.com"]
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /get
    - path:
        type: PathPrefix
        value: /headers
    filters:
    - type: RequestHeaderModifier
      requestHeaderModifier:
        add:
        - name: my-added-header
          value: added-value
    backendRefs:
    - name: httpbin
      port: 8000
EOF
  1. 再次访问/headers
代码语言:javascript
复制
$ curl -s -HHost:httpbin.example.com "http://$INGRESS_HOST/headers"
{
  "headers": {
    "Accept": "*/*",
    "Host": "httpbin.example.com",
    "My-Added-Header": "added-value",
...

清理

  1. 卸载 Istio 和 httpbin 服务:
代码语言:javascript
复制
$ kubectl delete -f samples/httpbin/httpbin.yaml
$ kubectl delete httproute http
$ kubectl delete gateways.gateway.networking.k8s.io gateway -n istio-ingress
$ istioctl uninstall -y --purge
$ kubectl delete ns istio-system
$ kubectl delete ns istio-ingress
  1. 删除 Kubernetes Gateway API CRD
代码语言:javascript
复制
$ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v0.5.1" | kubectl delete -f -

可以自动将现有的 Istio Ingress Gateway 替换成 Kubernetes Gateway API 吗?

很遗憾,目前无法自动将现有的 Istio Ingress Gateway 资源迁移成 Kubernetes Gateway API 资源,不过社区也注意到了这个需求并创建了ingress2gateway[4]项目,目标是可以自动读取 Ingress 配置并翻译成 Gateway API 相关的资源,不过目前只支持ingress-nginx

现在是正式迁移到 Kubernetes Gateway API 的时候吗?

如果 Istio Ingress Gateway 已经满足了你对流量管控的所有需求,建议继续使用 Istio Ingress Gateway,因为 Istio Ingress Gateway 经过时间的检验已经非常稳定。根据 Kubernetes 社区的讨论,Ingress API 和 Gateway API 在未来长时间内会并存。Istio 社区也表示,Istio 相关的 API(Gateway、VirtualService 和 DestinationRule)在可预见的未来也将继续得到支持。

如果你对流量管控有更多的需求,希望在不同厂商之间无缝迁移,那么未来 Kubernetes Gateway API 必然会是一个好选择。在得到社区认可和力挺后,随着 Kuberenetes Gateway API 日益成熟,生态的不断完善,相信在不久的将来我们能使用 Kubernetes Gateway API 这样的规范 API 来管理 Mesh,L4 层的流量。我们也在积极参与社区的相关讨论,欢迎加入我们:https://gateway-api.sigs.k8s.io/contributing/。

相关链接

  • Kubernetes Gateway API 官网:https://gateway-api.sigs.k8s.io/
  • Kubernetes Gateway API Github:https://github.com/kubernetes-sigs/gateway-api/
  • Kubernetes Gateway API in Istio:https://istio.io/latest/docs/tasks/traffic-management/ingress/gateway-api/
  • 图片出处:https://gateway-api.sigs.k8s.io/

参考资料

[1]

Istio 1.16.0: https://istio.io/latest/news/releases/1.16.x/announcing-1.16/#kubernetes-gateway-api-implementation-promoted-to-beta

[2]

Kubernetes Gateway API: https://gateway-api.sigs.k8s.io/

[3]

GAMMA(Gateway API Mesh Management and Administration): https://gateway-api.sigs.k8s.io/contributing/gamma/

[4]

ingress2gateway: https://github.com/kubernetes-sigs/ingress2gateway

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-11-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CNCF 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Kubernetes Gateway API 是什么?
  • Kubernetes Gateway API 是如何工作的?
  • 如何在 Istio 中使用 Kubernetes Gateway API?
  • 可以自动将现有的 Istio Ingress Gateway 替换成 Kubernetes Gateway API 吗?
  • 现在是正式迁移到 Kubernetes Gateway API 的时候吗?
  • 相关链接
    • 参考资料
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档