文档

使用Gateway API定义路由规则

更新时间:

Gateway API是由SIG-NETWORK社区管理的开源项目,通过提供可表达的、可扩展的、面向角色的接口来改善服务网络。您可以使用Gateway API对集群内应用访问的路由规则进行条件限制。本文介绍如何使用Gateway API定义集群内应用的路由规则。

前提条件

使用说明

  • 版本说明:

    • ASM 1.18支持GatewayAPI v0.6.0

    • ASM 1.22开始支持GatewayAPI v1.1,并且新增GRPCRoute支持。

  • 多集群模式下,如果两个数据面集群中相同命名空间配置了相同名称的Gateway相关资源,后应用的资源会覆盖之前创建的资源。

步骤一:确认ACK集群已存在GatewayAPI相关CRD

ACK 1.24及以上版本集群默认安装Gateway API组件相关的CRD资源。您可以通过以下操作确认ACK集群已存在GatewayAPI相关CRD。

执行以下命令,查看ACK集群是否安装Gateway API组件相关CRD。

kubectl get crds | grep gateway.networking.k8s.io
  • 若预期输出如下,表明已安装Gateway API组件相关CRD。

    gatewayclasses.gateway.networking.k8s.io                         2023-05-10T02:51:33Z
    gateways.gateway.networking.k8s.io                               2023-05-10T02:51:33Z
    httproutes.gateway.networking.k8s.io                             2023-05-10T02:51:33Z
    referencegrants.gateway.networking.k8s.io                        2023-05-10T02:51:33Z

    执行以下命令,查看CRD的版本。

    kubectl get crds -o yaml | grep 'gateway.networking.k8s.io/bundle-version'

    预期输出:

    gateway.networking.k8s.io/bundle-version: v0.6.0
    gateway.networking.k8s.io/bundle-version: v0.6.0
    gateway.networking.k8s.io/bundle-version: v0.6.0
    gateway.networking.k8s.io/bundle-version: v0.6.0
  • 若预期输出中不存在Gateway API组件相关CRD,您可以登录容器服务管理控制台组件管理页面,安装Gateway API组件。具体操作,请参见管理组件

步骤二:开启ASM实例的GatewayAPI支持开关

在ASM实例对应的KubeConfig环境下,在名为default的ASMMeshConfig的资源中添加enableGatewayAPI: true的字段。

apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMMeshConfig
metadata:
  name: default
spec:
  enableGatewayAPI: true

开启 enableGatewayAPI开关后,控制面会生成GatewayAPI相关的CRD。由于GatewayAPI中有Gateway资源,Isito本身也有Gateway资源,所以使用kubectl时会存在冲突。您可以使用kubectl get gtw命令获取GatewayAPI的Gateway资源;使用kubectl get gw命令获取Istio本身的Gateway资源。

步骤三:配置HTTP路由规则

下文介绍如何使用Gateway API配置HTTP路由规则,将httpbin应用暴露在网关上。您需要在ACK集群中创建Gateway和HTTPRoute资源。

  1. 创建Gateway资源。

    1. 使用以下内容,创建gateway.yaml文件。

      该配置表示在指定ASM网关上执行该Gateway规则,并创建一个host*.aliyun.com的监听器,允许所有命名空间的路由规则引用该监听器。该监听器使用80端口,协议为HTTP协议。YAML中的${ASM网关名称}请替换为真实的网关名称。

      展开查看gateway.yaml

      apiVersion: gateway.networking.k8s.io/v1beta1
      kind: Gateway
      metadata:
        name: gateway
        namespace: istio-system
      spec:
        addresses:  # 用于指定ASM网关Service。此处支持apply到多个ASM网关的服务上。
        - type: Hostname
          value: istio-${ASM网关名称}.istio-system.svc.cluster.local
        gatewayClassName: istio
        listeners:
        - allowedRoutes:
            namespaces:
              from: All
          hostname: '*.aliyun.com'  # 不支持直接匹配“*”。如果要匹配“*”,不填写此字段即可。
          name: default
          port: 80
          protocol: HTTP
    2. 在ACK集群对应的KubeConfig环境下,执行以下命令,部署Gateway。

      kubectl apply -f gateway.yaml
  2. 创建HTTPRoute资源。

    1. 使用以下内容,创建http-route.yaml文件。

      该配置表示路由规则引用istio-system命名空间下名为gateway的Gateway资源。因为未指定监听器名称,此处会尝试引用该Gateway的所有监听器。对于路径前缀为/get的请求,将路由到同命名空间下的httpbin服务的8000端口。

      展开查看http-route.yaml

      apiVersion: gateway.networking.k8s.io/v1beta1
      kind: HTTPRoute
      metadata:
        name: http
        namespace: default
      spec:
        parentRefs:  # 此处的route也支持attach到不同的Gateway上。
        - name: gateway
          namespace: istio-system
        hostnames: ["*.aliyun.com"]
        rules:
        - matches:
          - path:
              type: PathPrefix
              value: /get
          backendRefs:  # 这里默认只允许引用相同命名空间下的服务。如果需要使用不同命名空间下的服务,请配置ReferenceGrant资源。https://gateway-api.sigs.k8s.io/api-types/referencegrant/
          - name: httpbin 
            port: 8000
    2. 在ACK集群对应的KubeConfig环境下,执行以下命令,部署HTTPRoute。

      kubectl apply -f http-route.yaml
  3. 执行以下命令,通过ASM网关访问httpbin应用,查看HTTP路由规则是否生效。

    curl -I -HHost:httpbin.aliyun.com "http://${ASM网关IP}:80/get"

    预期输出:

    HTTP/1.1 200 OK
    server: istio-envoy
    date: Fri, 12 May 2023 08:16:30 GMT
    content-type: application/json
    content-length: 516
    access-control-allow-origin: *
    access-control-allow-credentials: true
    x-envoy-upstream-service-time: 4

    返回200 OK,表明HTTP路由规则生效。

步骤四:配置HTTPS路由规则

下文介绍如何使用Gateway API配置HTTPS路由规则,将httpbin应用暴露在网关上,并在ASM网关上完成TLS终止。您需要在ACK集群中创建Gateway和HTTPRoute资源。

  1. 使用ASM全局证书管理,为a.aliyun.com创建HTTPS中用到的证书,且证书名称为myexample-credential。具体操作,请参见步骤一:为多个主机准备服务器证书和私钥

  2. 创建Gateway资源。

    1. 使用以下内容,创建gateway-https.yaml文件。

      YAML文件中的${ASM网关名称}请替换为真实的网关名称。

      展开查看gateway-https.yaml

      apiVersion: gateway.networking.k8s.io/v1beta1
      kind: Gateway
      metadata:
        name: gateway-https
        namespace: istio-system
      spec:
        addresses:  # 此处用于指定ASM网关Service,支持apply到多个ASM网关的服务上。
        - type: Hostname
          value: istio-${ASM网关名称}.istio-system.svc.cluster.local
        gatewayClassName: istio
        listeners:
        - name: https
          hostname: "*.aliyun.com"
          port: 443
          protocol: HTTPS
          tls:
            mode: Terminate
            certificateRefs:
            - name: myexample-credential
          allowedRoutes:
            namespaces:
              from: All
    2. 在ACK集群对应的KubeConfig环境下,执行以下命令,部署Gateway。

      kubectl apply -f gateway-https.yaml
  3. 创建HTTPRoute资源。

    1. 使用以下内容,创建httpbin-https.yaml文件。

      展开查看httpbin-https.yaml

      apiVersion: gateway.networking.k8s.io/v1beta1
      kind: HTTPRoute
      metadata:
        name: httpbin-https
        namespace: default
      spec:
        parentRefs:
        - name: gateway-https
          namespace: istio-system
        hostnames: ["*.aliyun.com"]
        rules:
        - matches:
          - path:
              type: PathPrefix
              value: /status
          - path:
              type: PathPrefix
              value: /delay
          backendRefs:
          - name: httpbin
            port: 8000
    2. 在ACK集群对应的KubeConfig环境下,执行以下命令,部署HTTPRoute。

      kubectl apply -f httpbin-https.yaml
  4. 执行以下命令,通过ASM网关访问httpbin应用,验证HTTPS路由规则是否生效。

    curl -k -H Host:a.aliyun.com --resolve a.aliyun.com:443:{替换成真实的入口网关IP地址}  https://a.aliyun.com/status/418

    预期输出:

        -=[ teapot ]=-
    
           _...._
         .'  _ _ `.
        | ."` ^ `". _,
        \_;`"---"`|//
          |       ;/
          \_     _/
            `"""`

    预期输出表明HTTPS路由规则生效。