Enabling the use of Gateway API

Gateway API is a flexible system for controlling incoming traffic to Kubernetes applications. You can configure Gateway API for Usage Metering Service.

Before you begin

Gateway API is supported from Kubernetes 1.26.

About this task

This procedure provides a validated example of configuring Gateway API by using the Envoy implementation. You might choose an alternative approach. However, if it does not work, it is your responsibility to troubleshoot the solution or use the one that is described in this procedure.

Procedure

  1. Deploy Gateway API with Envoy Gateway.
    1. Install Gateway API CRDs. For more information, see Getting started with Gateway API.
    2. Install Envoy Gateway from OCI registry, for example by using Helm. See the gateway repository on the Envoy Proxy GitHub project.
      For information about other installation options, see: Installation.
      Note: If you use the Helm installation, you can skip the CRDs installation during the Envoy deployment because you already deployed CRDs in step 1.a. You can use the --skip-crds parameter, for example in the Helm execution command.
  2. Create the default GatewayClass on the cluster. Use ibm-licensing as the Envoy name.
    cat <<EOF | kubectl apply -f -
    apiVersion: gateway.networking.k8s.io/v1
    kind: GatewayClass
    metadata:
      name: ibm-licensing
    spec:
      controllerName: gateway.envoyproxy.io/gatewayclass-controller
    EOF
  3. Create a ConfigMap for BackendTLSPolicy.

    By default, BackendTLSPolicy expects the certificate to be present under the ca.crt key. However, in the existing Secret, the certificate is stored under the crt.pem key.

    Create a copy of the certificate that exists in the ibm-usage-metering-instance secret. Place it in the ibm-usage-metering-gateway-api-config ConfigMap under the key ca.crt key.

    # Extract tls.crt from the secret (it is a self-signed cert that acts as CA)
    if kubectl get secret ibm-usage-metering-instance -n "$UMS_NS" &>/dev/null; then
      kubectl get secret ibm-usage-metering-instance -n "$UMS_NS" -o jsonpath='{.data.tls\.crt}' | \
        base64 -d | \
        kubectl create configmap ibm-usage-metering-gateway-api-config -n "$UMS_NS" \
          --from-file=ca.crt=/dev/stdin \
          --dry-run=client -o yaml | kubectl apply -f - && \
  4. Deploy Gateway, HTTPRoute, and BackendTLSPolicy for Usage Metering Service. Use the following YAMLs to deploy the new resources.
    1. Deploy Gateway deployment.
      Note: Adapt the port numbers in the YAML example to the values that you prefer using for external communication.
      kind: Gateway
      metadata: 
        name: ibm-usage-metering-gateway
        namespace: ${var.ums_instance_namespace}
      spec: 
        gatewayClassName: ibm-licensing
        listeners: 
          - name: http
            protocol: HTTP
            port: 80
            allowedRoutes: 
              namespaces: 
                from: All
          - name: https
            protocol: HTTPS
            port: 443
            allowedRoutes: 
              namespaces: 
                from: All
            tls: 
              mode: Terminate
              certificateRefs: 
              - kind: Secret
                name: ibm-usage-metering-instance
    2. Deploy HTTPRoute.
      kubectl apply -f - <<'EOF'
      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata: 
        name: ibm-usage-metering-route
        namespace: ${var.ums_instance_namespace}
      spec: 
        parentRefs: 
          - name: ibm-usage-metering-gateway
            namespace: ${var.ums_instance_namespace}
            # Optionally pin to HTTPS listener: 
            sectionName: https
        rules: 
          # Rule 1: Fetch endpoint (port 8080)
          - matches: 
              - path: 
                  type: PathPrefix
                  value: /ibm-usage-metering-instance
            filters: 
              - type: URLRewrite
                urlRewrite: 
                  path: 
                    type: ReplacePrefixMatch
                    replacePrefixMatch: /
            backendRefs: 
              - kind: Service
                name: ibm-usage-metering-instance
                port: 8080
          # Rule 2: Upload endpoint (port 8081)
          - matches: 
              - path: 
                  type: PathPrefix
                  value: /ibm-usage-metering-upload
            filters: 
              - type: URLRewrite
                urlRewrite: 
                  path: 
                    type: ReplacePrefixMatch
                    replacePrefixMatch: /
            backendRefs: 
              - kind: Service
                name: ibm-usage-metering-instance
                port: 8081
    3. Deploy BackendTLSPolicy.
      kubectl apply -f - <<'EOF'
      apiVersion: gateway.networking.k8s.io/v1alpha3
      kind: BackendTLSPolicy
      metadata: 
        name: usage-metering-backend-tls
        namespace: ${var.ums_instance_namespace}
      spec: 
        targetRefs: 
        - group: ""
          kind: Service
          name: ibm-usage-metering-instance
        validation: 
          hostname: ibm-usage-metering-instance.${var.ums_instance_namespace}.svc.cluster.local
          caCertificateRefs: 
          - group: ""
            kind: ConfigMap
            name: ibm-usage-metering-gateway-api-config
  5. Validate the installation. Check whether:
    • A new namespace for Envoy (for example, envoy-gateway-system) with GatewayClass is created. For other validation points, see: Testing the configuration.
    • Gateway, HTTPRoute, and BackendTLSPolicy exist.
  6. Retrieve the new host name. To retrieve the new host name from the Gateway created in the ibm-licensing namespace, run the following command.
    LIC_NS="${var.ums_instance_namespace}"
    kubectl get gateway ibm-usage-metering-gateway -n "$LIC_NS" 
    -o jsonpath='{.status.addresses[?(@.type=="Hostname")].value}{"\n"}'
    If the host name is not assigned, check whether the GatewayClass ibm-licensing was created and the cluster provides load balancer capabilities. Run the following command.
    kubectl get gatewayclass ibm-licensing