»Ingress Gateway

The ingress-gateway config entry kind (IngressGateway on Kubernetes) allows you to configure ingress gateways with listeners that expose a set of services outside the Consul service mesh.

For Kubernetes, see Kubernetes Ingress Gateway for more information. For other platforms, see Ingress Gateway.

»Wildcard service specification

Ingress gateways can optionally target all services within a Consul namespace by specifying a wildcard * as the service name. A wildcard specifier allows for a single listener to route traffic to all available services on the Consul service mesh, differentiating between the services by their host/authority header.

A wildcard specifier provides the following properties for an ingress gateway:

  • All services with the same protocol as the listener will be routable.
  • The ingress gateway will route traffic based on the host/authority header, expecting a value matching <service-name>.ingress.*, or if using namespaces, <service-name>.ingress.<namespace>.*. This matches the Consul DNS ingress subdomain.

A wildcard specifier cannot be set on a listener of protocol tcp.

»Sample Config Entries

»TCP listener

Set up a TCP listener on an ingress gateway named "us-east-ingress" to proxy traffic to the "db" service:

HCL
Kind = "ingress-gateway"
Name = "us-east-ingress"

Listeners = [
  {
    Port     = 3456
    Protocol = "tcp"
    Services = [
      {
        Name = "db"
      }
    ]
  }
]
Kind = "ingress-gateway"Name = "us-east-ingress"
Listeners = [  {    Port     = 3456    Protocol = "tcp"    Services = [      {        Name = "db"      }    ]  }]
apiVersion: consul.hashicorp.com/v1alpha1
kind: IngressGateway
metadata:
  name: us-east-ingress
spec:
  listeners:
    - port: 3456
      protocol: tcp
      services:
        - name: db
apiVersion: consul.hashicorp.com/v1alpha1kind: IngressGatewaymetadata:  name: us-east-ingressspec:  listeners:    - port: 3456      protocol: tcp      services:        - name: db
{
  "Kind": "ingress-gateway",
  "Name": "us-east-ingress",
  "Listeners": [
    {
      "Port": 3456,
      "Protocol": "tcp",
      "Services": [
        {
          "Name": "db"
        }
      ]
    }
  ]
}
{  "Kind": "ingress-gateway",  "Name": "us-east-ingress",  "Listeners": [    {      "Port": 3456,      "Protocol": "tcp",      "Services": [        {          "Name": "db"        }      ]    }  ]}

»Wildcard HTTP listener

Set up a wildcard HTTP listener on an ingress gateway named "us-east-ingress" to proxy traffic to all services in the datacenter. Also make two services available over a custom port with user-provided hosts, and enable TLS on every listener:

HCL
Kind = "ingress-gateway"
Name = "us-east-ingress"

TLS {
  Enabled = true
}

Listeners = [
  {
    Port     = 8080
    Protocol = "http"
    Services = [
      {
        Name = "*"
      }
    ]
  },
  {
    Port     = 4567
    Protocol = "http"
    Services = [
      {
        Name  = "api"
        Hosts = ["foo.example.com"]
      },
      {
        Name  = "web"
        Hosts = ["website.example.com"]
      }
    ]
  }
]
Kind = "ingress-gateway"Name = "us-east-ingress"
TLS {  Enabled = true}
Listeners = [  {    Port     = 8080    Protocol = "http"    Services = [      {        Name = "*"      }    ]  },  {    Port     = 4567    Protocol = "http"    Services = [      {        Name  = "api"        Hosts = ["foo.example.com"]      },      {        Name  = "web"        Hosts = ["website.example.com"]      }    ]  }]
apiVersion: consul.hashicorp.com/v1alpha1
kind: IngressGateway
metadata:
  name: us-east-ingress
spec:
  tls:
    enabled: true
  listeners:
    - port: 8080
      protocol: http
      services:
        - name: '*'
    - port: 4567
      protocol: http
      services:
        - name: api
          hosts: ['foo.example.com']
        - name: web
          hosts: ['website.example.com']
apiVersion: consul.hashicorp.com/v1alpha1kind: IngressGatewaymetadata:  name: us-east-ingressspec:  tls:    enabled: true  listeners:    - port: 8080      protocol: http      services:        - name: '*'    - port: 4567      protocol: http      services:        - name: api          hosts: ['foo.example.com']        - name: web          hosts: ['website.example.com']
{
  "Kind": "ingress-gateway",
  "Name": "us-east-ingress",
  "TLS": {
    "Enabled": true
  },
  "Listeners": [
    {
      "Port": 8080,
      "Protocol": "http",
      "Services": [
        {
          "Name": "*"
        }
      ]
    },
    {
      "Port": 4567,
      "Protocol": "http",
      "Services": [
        {
          "Name": "api",
          "Hosts": ["foo.example.com"]
        },
        {
          "Name": "web",
          "Hosts": ["website.example.com"]
        }
      ]
    }
  ]
}
{  "Kind": "ingress-gateway",  "Name": "us-east-ingress",  "TLS": {    "Enabled": true  },  "Listeners": [    {      "Port": 8080,      "Protocol": "http",      "Services": [        {          "Name": "*"        }      ]    },    {      "Port": 4567,      "Protocol": "http",      "Services": [        {          "Name": "api",          "Hosts": ["foo.example.com"]        },        {          "Name": "web",          "Hosts": ["website.example.com"]        }      ]    }  ]}

»HTTP listener with path-based routing

Set up a HTTP listener on an ingress gateway named "us-east-ingress" to proxy traffic to a virtual service named "api".

HCL
Kind = "ingress-gateway"
Name = "us-east-ingress"

Listeners = [
  {
    Port     = 80
    Protocol = "http"
    Services = [
      {
        Name = "api"
      }
    ]
  }
]
Kind = "ingress-gateway"Name = "us-east-ingress"
Listeners = [  {    Port     = 80    Protocol = "http"    Services = [      {        Name = "api"      }    ]  }]
apiVersion: consul.hashicorp.com/v1alpha1
kind: IngressGateway
metadata:
  name: us-east-ingress
spec:
  listeners:
    - port: 80
      protocol: http
      services:
        - name: api
apiVersion: consul.hashicorp.com/v1alpha1kind: IngressGatewaymetadata:  name: us-east-ingressspec:  listeners:    - port: 80      protocol: http      services:        - name: api
{
  "Kind": "ingress-gateway",
  "Name": "us-east-ingress",
  "Listeners": [
    {
      "Port": 80,
      "Protocol": "http",
      "Services": [
        {
          "Name": "api"
        }
      ]
    }
  ]
}
{  "Kind": "ingress-gateway",  "Name": "us-east-ingress",  "Listeners": [    {      "Port": 80,      "Protocol": "http",      "Services": [        {          "Name": "api"        }      ]    }  ]}

The api service is not an actual registered service. It exist as a "virtual" service for L7 configuration only. A service-router (ServiceRouter on Kubernetes) is defined for this virtual service which uses path-based routing to route requests to different backend services:

HCL
Kind = "service-router"
Name = "api"
Routes = [
  {
    Match {
      HTTP {
        PathPrefix = "/billing"
      }
    }

    Destination {
      Service = "billing-api"
    }
  },
  {
    Match {
      HTTP {
        PathPrefix = "/payments"
      }
    }

    Destination {
      Service = "payments-api"
    }
  }
]
Kind = "service-router"Name = "api"Routes = [  {    Match {      HTTP {        PathPrefix = "/billing"      }    }
    Destination {      Service = "billing-api"    }  },  {    Match {      HTTP {        PathPrefix = "/payments"      }    }
    Destination {      Service = "payments-api"    }  }]
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceRouter
metadata:
  name: api
spec:
  routes:
    - match:
        http:
          pathPrefix: '/billing'
      destination:
        service: billing-api
    - match:
        http:
          pathPrefix: '/payments'
      destination:
        service: payments-api
apiVersion: consul.hashicorp.com/v1alpha1kind: ServiceRoutermetadata:  name: apispec:  routes:    - match:        http:          pathPrefix: '/billing'      destination:        service: billing-api    - match:        http:          pathPrefix: '/payments'      destination:        service: payments-api
{
  "Kind": "service-router",
  "Name": "api",
  "Routes": [
    {
      "Match": {
        "HTTP": {
          "PathPrefix": "/billing"
        }
      },
      "Destination": {
        "Service": "billing-api"
      }
    },
    {
      "Match": {
        "HTTP": {
          "PathPrefix": "/payments"
        }
      },
      "Destination": {
        "Service": "payments-api"
      }
    }
  ]
}
{  "Kind": "service-router",  "Name": "api",  "Routes": [    {      "Match": {        "HTTP": {          "PathPrefix": "/billing"        }      },      "Destination": {        "Service": "billing-api"      }    },    {      "Match": {        "HTTP": {          "PathPrefix": "/payments"        }      },      "Destination": {        "Service": "payments-api"      }    }  ]}

»Available Fields

  • Kind - Must be set to ingress-gateway

  • Name (string: <required>) - Set to the name of the gateway being configured.

  • Namespace (string: "default")

    Enterprise
    - Specifies the namespace the config entry will apply to. This must be the namespace the gateway is registered in. If omitted, the namespace will be inherited from the request or will default to the default namespace.
  • Meta (map<string|string>: nil) - Specifies arbitrary KV metadata pairs. Added in Consul 1.8.4.

  • TLS (TLSConfig: <optional>) - TLS configuration for this gateway.

    • Enabled (bool: false) - Set this configuration to enable TLS for every listener on the gateway.

      If TLS is enabled, then each host defined in the Host field will be added as a DNSSAN to the gateway's x509 certificate.

  • Listeners (array<IngressListener>: <optional>)) - A list of listeners that the ingress gateway should setup, uniquely identified by their port number.

    • Port (int: 0) - The port on which the ingress listener should receive traffic. The port will be bound to the IP address that was specified in the -address flag when starting the gateway. Note: The ingress listener port must not conflict with the health check port specified in the -address flag.

    • Protocol (string: "tcp") - The protocol associated with the listener. One of tcp, http, http2, or grpc.

    • Services (array<IngressService>: <optional>) - A list of services to be exposed via this listener. For tcp listeners, only a single service is allowed.

      • Name (string: "") - The name of the service that should be exposed through this listener. This can be either a service registered in the catalog, or a service defined only by other config entries. If the wildcard specifier, *, is provided, then ALL services will be exposed through the listener. This is not supported for listener's with protocol tcp.

      • Namespace (string: "")

        Enterprise
        - The namespace to resolve the service from instead of the current namespace. If empty the current namespace is assumed.
      • Hosts (array<string>: <optional>) - A list of hosts that specify what requests will match this service. This cannot be used with a tcp listener, and cannot be specified alongside a * service name. If not specified, the default domain .ingress.* will be used to match services. Requests must send the correct host to be routed to the defined service.

        The wildcard specifier, *, can be used by itself to match all traffic coming to the ingress gateway, if TLS is not enabled. This allows a user to route all traffic to a single service without specifying a host, allowing simpler tests and demos. Otherwise, the wildcard specifier can be used as part of the host to match multiple hosts, but only in the leftmost DNS label. This ensures that all defined hosts are valid DNS records. For example, *.example.com is valid, while example.* and *-suffix.example.com are not.

»ACLs

Configuration entries may be protected by ACLs.

Reading an ingress-gateway config entry requires service:read on the Name field of the config entry.

Creating, updating, or deleting an ingress-gateway config entry requires operator:write.