Skip to content

Expose a service with Gateway API

Use kix.expose to create an HTTPRoute for a package Service when the cluster uses Gateway API.

This guide assumes:

  • Your cluster has the Gateway API CRDs and an Envoy Gateway controller.
  • You have a local package whose returned parts include a Service named service.

The envoy-gateway Kix package used below creates the GatewayClass and Gateway resources. Its default controller name is gateway.envoyproxy.io/gatewayclass-controller, which must match the controller installed in the cluster.

Add the standard ingress options to the package:

how-to/platform/exposure-app.nix (L21–L21)
options.ingress = kix.options.ingress;

View source on GitHub ↗

The option name is ingress for both supported exposure resources. Set config.ingress.host on an instance to choose its hostname.

Add kix.expose to the package’s build list and name the Service part it should route to:

how-to/platform/exposure-app.nix (L56–L56)
(kix.expose { service = "service"; })

View source on GitHub ↗

kix.expose reads the Service name and port from that part.

Add a Gateway instance with an HTTP listener:

how-to/platform/gateway-cluster.nix (L19–L29)
instances.gateway-system.gateway = {
package = packages."envoy-gateway";
config.listeners = [
{
name = "http";
port = 80;
protocol = "HTTP";
allowedRoutes.namespaces.from = "All";
}
];
};

View source on GitHub ↗

The Gateway is in gateway-system, while the application in the next step is in another namespace. allowedRoutes.namespaces.from = "All" permits that HTTPRoute to attach to this listener.

If your controller uses a different controller name, set config.controllerName on this instance to the value advertised by that controller.

Add the application instance and set the host clients will request:

how-to/platform/gateway-cluster.nix (L33–L36)
instances.gateway-example.web = {
package = exposureApp;
config.ingress.host = "web.example.test";
};

View source on GitHub ↗

Kix resolves the gateway dependency and creates an HTTPRoute for the application’s Service.

Evaluate the cluster before deploying it:

Run in kix-examples/
❱ kix check how-to-platform-gateway
 TOOL         RESULT  DETAILS                                                       
 eval         pass    15 manifests evaluated                                        
 kubeconform  pass    skipped (this validation tool is not yet integrated with Kix) 
 pluto        pass    skipped (this validation tool is not yet integrated with Kix) 
 kyverno      pass    skipped (this validation tool is not yet integrated with Kix) 
 scorecard    pass    0 errors, 9 warnings, 1 info

Inspect the generated HTTPRoute:

Run in kix-examples/ Output excerpt
❱ kix build how-to-platform-gateway --output json
{
  "apiVersion": "gateway.networking.k8s.io/v1",
  "kind": "HTTPRoute",
  "metadata": {
    "name": "web",
    "namespace": "gateway-example"
  },
  "spec": {
    "hostnames": [
      "web.example.test"
    ],
    "parentRefs": [
      {
        "name": "gateway",
        "namespace": "gateway-system"
      }
    ],
    "rules": [
      {
        "backendRefs": [
          {
            "name": "web",
            "port": 80
          }
        ],
        "matches": [
          {
            "path": {
              "type": "PathPrefix",
              "value": "/"
            }
          }
        ]
      }
    ]
  }
}

The route attaches to the gateway-system/gateway Gateway and sends requests for web.example.test to port 80 of the web Service.

Pass paths instead of service when one hostname fans out to several Service parts. Each entry names a path and the Service part behind it; pathType defaults to Prefix and port to the port the Service part publishes through out.port:

(kix.expose {
paths = [
{ path = "/"; service = "frontend"; }
{ path = "/api"; pathType = "Exact"; service = "api"; }
];
})

Kix renders one HTTPRoute with a rule per entry. In a cluster that routes through ingress-nginx, the same paths list renders one Ingress with a path entry per element.