The Gateway API is a collection of resources that model Service networking in Kubernetes. These resources are intended for modeling Service networking through expressive, extensible, and role-oriented interfaces. This topic describes how to use the Gateway API to access Services.

Prerequisites

  • The version of your Container Service for Kubernetes (ACK) cluster is 1.24 or later.
  • The Gateway API component is installed. For more information, see Manage system components.
    Note By default, the Gateway API component is automatically installed in ACK clusters whose version is 1.24 and later.

Background information

By default, the custom resource definition (CRD) of the Gateway API component is automatically created in ACK clusters whose version is 1.24 and later. You can install a gateway that supports the Gateway API to use the features provided by the Gateway API. For more information, see Gateway API.

Procedure

Procedure

Preparations

  1. Connect to ACK clusters by using kubectl.
  2. Create a test application named go-httpbin.
    1. Create a file named httpbin.yaml and add the following content to the file:
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: go-httpbin
        namespace: default
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: go-httpbin
        template:
          metadata:
            labels:
              app: go-httpbin
              version: v1
          spec:
            containers:
              - image: specialyang/go-httpbin:v3
                args:
                  - "--port=8090"
                  - "--version=v1"
                imagePullPolicy: Always
                name: go-httpbin
                ports:
                  - containerPort: 8090
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: go-httpbin
        namespace: default
      spec:
        ports:
          - port: 80
            targetPort: 8090
            protocol: TCP
        selector:
          app: go-httpbin
    2. Run the following command to create the application named go-httpbin:
      kubectl apply -f httpbin.yaml
  3. Install Kong Kubernetes Ingress Controller.
    No component is provided by ACK to support the Gateway API. In this topic, the kubernetes-ingress-controller gateway is used as an example.
    1. Run the following command to install Kong Kubernetes Ingress Controller.
      Note Kong Kubernetes Ingress Controller uses a LoadBalancer type kong-proxy Service to expose Services. You are billed for the Classic Load Balancer (CLB) instance created for the kong-proxy Service. For more information about the billing of CLB instances, see Billing overview.
      kubectl create -f https://raw.githubusercontent.com/Kong/kubernetes-ingress-controller/v2.8.0/deploy/single/all-in-one-dbless.yaml

      The resources are created in the kong namespace.

    2. Check whether Kong Kubernetes Ingress Controller is installed.
      1. Run the following command to query the LoadBalancer IP address of the Service:
        kubectl get svc -n kong kong-proxy

        Expected output:

        NAME         TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)                      AGE
        kong-proxy   LoadBalancer   172.16.19.238   47.14.**.**  80:31611/TCP,443:30936/TCP     10s

        The IP address is displayed in the EXTERNAL IP field of the output.

      2. Run the following command to access Kong Kubernetes Ingress Controller:
        curl http://<EXTERNAL-IP>

        Expected output:

        {"message":"no Route matched with those values"}
      If {"message":"no Route matched with those values"} is returned, Kong Kubernetes Ingress Controller has been installed.
  4. Create a GatewayClass and a gateway.
    1. Create a file named gateway.yaml and add the following content to the file:
      apiVersion: gateway.networking.k8s.io/v1beta1
      kind: GatewayClass
      metadata:
        name: kong
        annotations:
          konghq.com/gatewayclass-unmanaged: 'true'
      spec:
        controllerName: konghq.com/kic-gateway-controller
      ---
      apiVersion: gateway.networking.k8s.io/v1beta1
      kind: Gateway
      metadata:
        name: kong
      spec:
        gatewayClassName: kong
        listeners:
        - name: proxy
          port: 80
          protocol: HTTP
        - name: proxy-ssl
          port: 443
          protocol: HTTPS
    2. Run the following command to create a GatewayClass and a gateway:
      kubectl apply -f gateway.yaml
    3. Run the following command to query the public endpoint of the gateway:
      kubectl get gateway kong

      Expected output:

      NAME   CLASS   ADDRESS        PROGRAMMED   AGE
      kong   kong    47.14.**.**              68s

      The output indicates that the GatewayClass and gateway are created.

Use HTTPRoutes

This section describes how to use HTTPRoutes.

Feature 1: Create an HTTPRoute to match path prefixes

You can create an HTTPRoute to match path prefixes. Only requests whose path prefixes match the rules of the HTTPRoute are routed to the application.

  1. Create a file named demo-route.yaml and add the following content to the file:
    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: HTTPRoute
    metadata:
      name: demo-route
    spec:
      parentRefs: # Reference the Gateway resource. 
        - group: gateway.networking.k8s.io
          kind: Gateway
          name: kong
      hostnames:
        - example.com # Set the host to example.com.
      rules:
        - matches: # Create a path prefix match rule. 
            - path:
                type: PathPrefix
                value: /
          backendRefs: # Set the backend to a Service named go-httpbin and set the port to 80. 
            - kind: Service
              name: go-httpbin
              port: 80
  2. Run the following command to create an HTTPRoute:
    kubectl apply -f demo-route.yaml
  3. Run the following command to access the go-httpbin application:
    curl http://example.com/version --resolve example.com:80:<EXTERNAL-IP>

    Expected output:

    version:v1

    The output indicates that the go-httpbin application can be accessed and the HTTPRoute can match path prefixes.

Feature 2: Create an HTTPRoute to implement weighted routing

You can create an HTTPRoute to route traffic to multiple applications in proportions.

  1. Create test applications named new-nginx and old-nginx.
    1. Create a file named nginx.yaml and add the following content to the file:
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: old-nginx
      spec:
        replicas: 1
        selector:
          matchLabels:
            run: old-nginx
        template:
          metadata:
            labels:
              run: old-nginx
          spec:
            containers:
            - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/old-nginx
              imagePullPolicy: Always
              name: old-nginx
              ports:
              - containerPort: 80
                protocol: TCP
            restartPolicy: Always
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: old-nginx
      spec:
        ports:
        - port: 80
          protocol: TCP
          targetPort: 80
        selector:
          run: old-nginx
        sessionAffinity: None
        type: NodePort
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: new-nginx
      spec:
        replicas: 1
        selector:
          matchLabels:
            run: new-nginx
        template:
          metadata:
            labels:
              run: new-nginx
          spec:
            containers:
            - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx
              imagePullPolicy: Always
              name: new-nginx
              ports:
              - containerPort: 80
                protocol: TCP
            restartPolicy: Always
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: new-nginx
      spec:
        ports:
        - port: 80
          protocol: TCP
          targetPort: 80
        selector:
          run: new-nginx
        sessionAffinity: None
        type: NodePort
    2. Run the following command to create the applications named new-nginx and old-nginx:
      kubectl apply -f nginx.yaml
  2. Create an HTTPRoute.
    1. Run the following command to create a file named demo-weight.yaml:
      apiVersion: gateway.networking.k8s.io/v1beta1
      kind: HTTPRoute
      metadata:
        name: demo-weight
      spec:
        parentRefs: # Reference the Gateway resource. 
          - group: gateway.networking.k8s.io
            kind: Gateway
            name: kong
        hostnames:
          - weight.example.com # Set the host to weight.example.com.
        rules:
          - matches: # Create a path prefix match rule. 
              - path:
                  type: PathPrefix
                  value: /
            backendRefs:
              # Specify the backend and the weight of the backend. The weights are not percentage values. Therefore, the sum of the weights does not need to be 100. 
              - kind: Service
                name: old-nginx
                port: 80
                weight: 1 # Set the weight of the old-nginx application to 1. 
              - kind: Service
                name: new-nginx
                port: 80
                weight: 1 # Set the weight of the new-nginx application to 1. 

      weight: the proportion of the traffic routed to an application. In this example, the weight of old-nginx is 1 and the weight of new-nginx is 1. This indicates that 50% of the traffic is routed to old-nginx and 50% of the traffic is routed to new-nginx.

    2. Run the following command to create an HTTPRoute:
      kubectl apply -f demo-weight.yaml
  3. Run the following command multiple times to access the new-nginx and old-nginx applications:
    curl http://weight.example.com/ --resolve weight.example.com:80:<EXTERNAL-IP>

    Expected output:

    old
    new
    old
    new
    old
    new

    The output indicates that the HTTPRoute routes traffic to the new-nginx and old-nginx applications in the ratio of 1:1.

Feature 3: Create an HTTPRoute to modify request headers

You can use the filters provided by HTTPRoutes to process request headers during the request or response lifecycle. This section provides an example on how to add headers to the requests that are sent to a backend Service. For more information about filters, see HTTPRoute.

  1. Create an HTTPRoute.
    1. Run the following command to create a file named demo-filter.yaml:
      apiVersion: gateway.networking.k8s.io/v1beta1
      kind: HTTPRoute
      metadata:
        name: demo-filter
      spec:
        parentRefs: # Reference the Gateway resource. 
          - group: gateway.networking.k8s.io
            kind: Gateway
            name: kong
        hostnames:
          - filter.example.com # Set the host to filter.example.com. 
        rules:
          - matches: # Create a path prefix match rule. 
              - path:
                  type: PathPrefix
                  value: /
            filters:
              - type: RequestHeaderModifier # Add the my-header: foo header. 
                requestHeaderModifier:
                  add:
                    - name: my-header
                      value: foo
            backendRefs: # Set the backend to a Service named go-httpbin and set the port to 80. 
              - kind: Service
                name: go-httpbin
                port: 80
    2. Run the following command to create an HTTPRoute:
      kubectl apply -f demo-filter.yaml
  2. Run the following command to access the go-httpbin application:
    curl http://filter.example.com/ --resolve filter.example.com:80:<EXTERNAL-IP>

    Expected output:

    headers: {
        // ...
        "My-Header": [
          "foo"
        ],
        // ...
    }

    The output displays the My-Header:foo header, which indicates that the header is added to the request.

Configure a TLS certificate

  1. Run the following OpenSSL commands to create a self-signed certificate:
    openssl req -subj '/CN=example.com' -new -newkey rsa:2048 -sha256 \
      -days 365 -nodes -x509 -keyout server.key -out server.crt \
      -addext "subjectAltName = DNS:example.com" \
      -addext "keyUsage = digitalSignature" \
      -addext "extendedKeyUsage = serverAuth" 2> /dev/null;
      openssl x509 -in server.crt -subject -noout

    The certificate file server.crt and private key file server.key are stored in the current directory.

  2. Run the following command to use the server.crt and server.key files to create a TLS Secret:
    kubectl create secret tls example.com --key server.key --cert server.crt

    Expected output:

    secret/example.com created
  3. Install the certificate on the gateway.
    1. Run the following command to create a file named gateway1.yaml:
      apiVersion: gateway.networking.k8s.io/v1beta1
      kind: Gateway
      metadata:
        name: kong
      spec:
        gatewayClassName: kong
        listeners:
        - name: proxy
          port: 80
          protocol: HTTP
        - name: proxy-ssl
          port: 443
          protocol: HTTPS
          tls: # Configure TLS. 
            mode: Terminate
            certificateRefs: # Reference the Secret. 
              - kind: Secret
                name: example.com
    2. Run the following command to install the certificate on the gateway:
      kubectl apply -f gateway1.yaml
  4. Run the following command to check whether the TLS certificate is configured:
    openssl s_client -servername example.com -connect <EXTERNAL-IP>:443

    The output displays CN = example.com, which indicates that the TLS certificate is configured.