Consul
Deploy API gateway listeners in Kubernetes
This topic describes how to deploy Consul API gateway listeners to Kubernetes-orchestrated environments. If you want to implement API gateway listeners on VMs, refer to Deploy API gateway listeners to virtual machines.
Overview
API gateways have one or more listeners that serve as ingress points for requests to services in a Consul service mesh. Create an API gateway configuration and define listeners that expose ports on the endpoint for ingress. Apply the configuration to direct Kubernetes to start API gateway services.
Routes
After deploying the gateway, attach HTTP or TCP routes to listeners defined in the gateway to control how requests route to services in the network.
Intentions
Configure Consul intentions to allow or prevent traffic between gateway listeners and services in the mesh. Refer to Service intentions for additional information.
Requirements
- Verify that your environment meets the requirements specified in Technical specifications for Kubernetes.
- Verify that the Consul API Gateway CRDs were applied. Refer to Installation for details.
- If your Kubernetes-orchestrated network runs on OpenShift, verify that OpenShift is enabled for your Consul installation. Refer to OpenShift requirements for additional information.
Define the gateway and listeners
Create an API gateway values file that defines the gateway and listeners.
- Specify the following fields:
apiVersion: Specifies the Kubernetes gateway API version. Must begateway.networking.k8s.io/v1beta1.kind: Specifies the type of configuration entry to implement. This must beGateway.metadata.name: Specify a name for the gateway configuration. The name is metadata that you can use to reference the configuration when performing Consul operations.spec.gatewayClassName: Specify the name of agatewayClassconfiguration. Gateway classes are template-like resources in Kubernetes for instantiating gateway services. Specifyconsulto use the default gateway class shipped with Consul. Refer to the GatewayClass configuration reference for additional information.spec.listeners: Specify a list of listener configurations. Each listener is map containing the following fields:port: Specifies the port that the listener receives traffic on.name: Specifies a unique name for the listener.protocol: You can set eithertcporhttpallowedRoutes.namespaces: Contains configurations for determining which namespaces are allowed to attach a route to the listener.
- Configure any additional fields necessary for your use case, such as the namespace or admin partition. Refer to the API gateway configuration entry reference for additional information.
- Save the configuration.
In the following example, the API gateway specifies an HTTP listener on port 80:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: my-gateway
namespace: consul
spec:
gatewayClassName: consul
listeners:
- protocol: HTTP
port: 80
name: http
allowedRoutes:
namespaces:
from: "All"
Kubernetes SDS implementation in consul-k8s
This section reflects the current API Gateway SDS behavior in consul-k8s:
- Listener-level SDS from Gateway annotations and listener
tls.options - Backend-level SDS override from
RouteTLSSDSFilter
Listener SDS source of truth
Listener TLS SDS is resolved from these sources:
- Listener
tls.options(per-listener override) - Gateway
metadata.annotations(gateway-wide defaults)
Supported keys:
api-gateway.consul.hashicorp.com/tls_sds_cluster_nameapi-gateway.consul.hashicorp.com/tls_sds_cert_resource
SDS resolution behavior
For each listener:
- If both SDS keys are set in listener
tls.options, listener values are used. - Otherwise, Gateway annotations are used as defaults.
- If neither source sets SDS, listener SDS is unset.
Listener validation behavior
- If only one SDS field is provided, listener validation fails.
- SDS and
tls.certificateRefsare validated independently and can both be configured on the same listener.
Translation to Consul entries
- Resolved listener SDS is mapped to
APIGatewayListener.TLS.SDS. - Listener certificate refs are mapped to
APIGatewayListener.TLS.Certificates. - When both are configured, translated listener TLS includes both SDS and Certificates.
Example: Gateway listener SDS via annotations and listener tls.options
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: sds-gateway
namespace: default
annotations:
api-gateway.consul.hashicorp.com/tls_sds_cluster_name: sds-cluster
api-gateway.consul.hashicorp.com/tls_sds_cert_resource: wildcard.ingress.consul
spec:
gatewayClassName: consul
listeners:
- name: https
protocol: HTTPS
port: 8443
hostname: a.example.test
tls:
mode: Terminate
options:
api-gateway.consul.hashicorp.com/tls_sds_cluster_name: sds-cluster
api-gateway.consul.hashicorp.com/tls_sds_cert_resource: wil.ingr.consul
TLS SDS precedence
Effective certificate selection precedence is:
- Route service override
TLS.SDS - Listener
TLS.SDS - Gateway-level
TLS.SDS
Route service SDS overrides (Kubernetes)
RouteTLSSDSFilter remains the backend-level SDS override mechanism for HTTP routes.
- Kind:
RouteTLSSDSFilter - Spec fields:
spec.sds.clusterName(optional when inherited from listener/global SDS)spec.sds.certResource(required)
Inheritance behavior:
- If
spec.sds.clusterNameis omitted, it is accepted when the route resolves exactly one listener-level SDS cluster from parentRefs. - If inherited cluster resolution is missing or ambiguous, validation rejects the filter.
Usage pattern:
- Attach from
HTTPRoute.rules[].backendRefs[].filters[]withtype: ExtensionRef. - Use
extensionRef.group: consul.hashicorp.com. - Use
extensionRef.kind: RouteTLSSDSFilter. - Use
extensionRef.name: <filter-name>.
Validation and translation:
- Translation maps this to
HTTPService.TLS.SDS. - Missing filter object, wrong type, missing/empty
spec.sds.certResource, or missing/ambiguous inheritedclusterNameare rejected. - Rule-level placement (
HTTPRoute.rules[].filters[]) is invalid for this override; backendRef filter placement is required.
Example: HTTPRoute backendRef override using RouteTLSSDSFilter
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: api-route-override
namespace: default
spec:
parentRefs:
- name: sds-gateway
sectionName: https
hostnames:
- b.example.test
rules:
- backendRefs:
- name: svc-b
port: 5678
filters:
- type: ExtensionRef
extensionRef:
group: consul.hashicorp.com
kind: RouteTLSSDSFilter
name: route-sds-override-http
---
apiVersion: consul.hashicorp.com/v1alpha1
kind: RouteTLSSDSFilter
metadata:
name: route-sds-override-http
namespace: default
spec:
sds:
clusterName: sds-cluster-2
certResource: foo.example.com
Troubleshooting checklist
- Confirm both SDS keys are set together (listener
tls.optionsor Gateway annotation defaults). - If
tls.certificateRefsare used, verify referenced Secrets exist and are referenceable. - For backend overrides, ensure
RouteTLSSDSFilteris attached underbackendRefs[].filters[]. - Ensure
RouteTLSSDSFilter.spec.sds.certResourceis non-empty andclusterNameis set or inherited. - Verify rendered config contains
APIGatewayListener.TLS.SDS,APIGatewayListener.TLS.Certificates, and/orHTTPService.TLS.SDSas applicable. - For local probes on non-8443 ports (for example
18443), preserve hostname routing withHostand--resolve.
Refer to Define API gateway routes in Kubernetes, RouteTLSSDSFilter reference (Kubernetes), and Route Resource Configuration for route and filter configuration details.
Deploy the API gateway and listeners
Apply the configuration to your cluster using the kubectl command. The following command applies the configuration to the consul namespace:
$ kubectl apply -f my-gateway.yaml -n consul