mirror of https://github.com/hashicorp/consul
280 lines
9.9 KiB
Markdown
280 lines
9.9 KiB
Markdown
---
|
|
layout: docs
|
|
page_title: External <> Internal Services - Ingress Gateways
|
|
description: >-
|
|
An ingress gateway enables ingress traffic from services outside the Consul
|
|
service mesh to services inside the Consul service mesh. This section details
|
|
how to use Envoy and describes how you can plug in a gateway of your choice.
|
|
---
|
|
|
|
# Ingress Gateways
|
|
|
|
-> **1.8.0+:** This feature is available in Consul versions 1.8.0 and newer.
|
|
|
|
Ingress gateways enable ingress traffic from services outside the Consul
|
|
service mesh to services inside the Consul service mesh. An ingress gateway is
|
|
a type of proxy and must be registered as a service in Consul, with the
|
|
[kind](/api/agent/service#kind) set to "ingress-gateway". They are an
|
|
entrypoint for outside traffic and allow you to define what services should be
|
|
exposed and on what port. You configure an ingress gateway by defining a set of
|
|
[listeners](/docs/connect/config-entries/ingress-gateway#listeners) that each map
|
|
to a set of backing
|
|
[services](/docs/connect/config-entries/ingress-gateway#services).
|
|
|
|
To enable easier service discovery, a new Consul [DNS
|
|
subdomain](/docs/discovery/dns#ingress-service-lookups) is provided, on
|
|
`<service>.ingress.<domain>`.
|
|
|
|
For listeners with a
|
|
[protocol](/docs/connect/config-entries/ingress-gateway#protocol) other than
|
|
`tcp`, multiple services can be specified for a single listener. In this
|
|
case, the ingress gateway relies on host/authority headers to decide the
|
|
service that should receive the traffic. The host used to match traffic
|
|
defaults to the [Consul DNS ingress
|
|
subdomain](/docs/discovery/dns#ingress-service-lookups), but can be changed using
|
|
the [hosts](/docs/connect/config-entries/ingress-gateway#hosts) field.
|
|
|
|
![Ingress Gateway Architecture](/img/ingress-gateways.png)
|
|
|
|
## Prerequisites
|
|
|
|
Ingress gateways also require that your Consul datacenters are configured correctly:
|
|
|
|
- You'll need to use Consul version 1.8.0 or newer.
|
|
- Consul [Connect](/docs/agent/options#connect) must be enabled on the datacenter's Consul servers.
|
|
- [gRPC](/docs/agent/options#grpc_port) must be enabled on all client agents.
|
|
|
|
Currently, [Envoy](https://www.envoyproxy.io/) is the only proxy with ingress gateway capabilities in Consul.
|
|
|
|
## Running and Using an Ingress Gateway
|
|
|
|
For a complete example of how to allow external traffic inside your Consul service mesh,
|
|
review the [ingress gateway tutorial](https://learn.hashicorp.com/tutorials/consul/service-mesh-ingress-gateways).
|
|
|
|
## Ingress Gateway Configuration
|
|
|
|
Ingress gateways are configured in service definitions and registered with Consul like other services, with two exceptions.
|
|
The first is that the [kind](/api/agent/service#kind) must be "ingress-gateway". Second,
|
|
the ingress gateway service definition may contain a `Proxy.Config` entry just like a
|
|
Connect proxy service, to define opaque configuration parameters useful for the actual proxy software.
|
|
For Envoy there are some supported [gateway options](/docs/connect/proxies/envoy#gateway-options) as well as
|
|
[escape-hatch overrides](/docs/connect/proxies/envoy#escape-hatch-overrides).
|
|
|
|
-> **Note:** If ACLs are enabled, ingress gateways must be registered with a token granting `service:write` for the ingress gateway's service name,
|
|
`service:read` for all services in the ingress gateway's configuration entry, and `node:read` for all nodes of the services
|
|
in the ingress gateway's configuration entry. These privileges authorize the token to route communications to other Connect services.
|
|
If the Consul client agent on the gateway's node is not configured to use the default gRPC port, 8502, then the gateway's token
|
|
must also provide `agent:read` for its node's name in order to discover the agent's gRPC port. gRPC is used to expose Envoy's xDS API to Envoy proxies.
|
|
|
|
~> [Configuration entries](/docs/agent/config-entries) are global in scope. A configuration entry for a gateway name applies
|
|
across all federated Consul datacenters. If ingress gateways in different Consul datacenters need to route to different
|
|
sets of services within their datacenter then the ingress gateways **must** be registered with different names.
|
|
|
|
<!-- Add a "permalink" anchor here since this title is long and may be edited
|
|
but we need to deep-link to it elsewhere -->
|
|
<a name="sds"></a>
|
|
|
|
## Custom TLS Certificates via Secret Discovery Service (SDS)
|
|
|
|
~> **Advanced Topic!** This is a low-level feature designed for developers
|
|
building integrations with custom TLS management solutions.
|
|
|
|
Consul 1.11 added support for Ingress Gateways to serve TLS certificates to
|
|
inbound traffic that are sourced from an external service. The external service
|
|
must implement Envoy's [gRPC Secret Discovery
|
|
Service](https://www.envoyproxy.io/docs/envoy/latest/configuration/security/secret)
|
|
(or SDS) API.
|
|
|
|
The steps below are necessary to fully configure an Ingress Gateway with TLS
|
|
certificates from an SDS source. They assume the operator is familiar with Envoy
|
|
configuration and the SDS protocol.
|
|
|
|
### 1. Configure Static SDS Cluster(s).
|
|
|
|
Each Ingress Gateway Envoy instance must have one or more additional [static
|
|
clusters](/docs/connect/proxies/envoy#envoy_extra_static_clusters_json) defined
|
|
when registering the ingress gateway to specify how to connect to the external
|
|
service. This requires a manual registration of the Ingress Gateway proxy rather
|
|
than relying on `-register` flag to `consul connect envoy -gateway=ingress`.
|
|
|
|
The cluster(s) must provide connection information and any necessary
|
|
authentication information such as mTLS credentials.
|
|
|
|
In this example we will show:
|
|
- A DNS name to discover the SDS service addresses
|
|
- Local certificate files for TLS client authentication with the SDS server
|
|
(the certificates are assumed to be created and managed by some other
|
|
process)
|
|
|
|
#### 1.1 Registering the Proxy Service
|
|
|
|
The following Proxy Service Definition defines the bootstrap overrides needed to
|
|
add this configuration to Envoy when it starts. With this TLS configuration,
|
|
Envoy will detect changes to the certificate and key files on disk so an
|
|
external process may maintain and rotate them without needing an Envoy restart.
|
|
|
|
```hcl
|
|
// public-ingress.hcl
|
|
Services {
|
|
Name = "public-ingress"
|
|
Kind = "ingress-gateway"
|
|
|
|
Proxy {
|
|
Config {
|
|
envoy_extra_static_clusters_json = <<EOF
|
|
{
|
|
"name": "sds-cluster",
|
|
"connect_timeout": "5s",
|
|
"http2_protocol_options": {},
|
|
"type": "LOGICAL_DNS",
|
|
"transport_socket": {
|
|
"name":"tls",
|
|
"typed_config": {
|
|
"@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
|
|
"common_tls_context":{
|
|
"tls_certificate_sds_secret_configs": [
|
|
{
|
|
"name":"tls_sds",
|
|
"sds_config":{
|
|
"path":"/certs/sds-auth-cert.json"
|
|
}
|
|
}
|
|
],
|
|
"validation_context_sds_secret_config": {
|
|
"name":"validation_context_sds",
|
|
"sds_config":{
|
|
"path":"/certs/sds-validation.json"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"load_assignment": {
|
|
"cluster_name": "sds-cluster",
|
|
"endpoints": [
|
|
{
|
|
"lb_endpoints": [
|
|
{
|
|
"endpoint": {
|
|
"address": {
|
|
"socket_address": {
|
|
"address": "sds-server.svc.cluster.local",
|
|
"port_value": 8080,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
EOF
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Run `consul services register public-ingress.hcl`** to create the
|
|
registration. This must be run on the node where the Envoy proxy is going to run
|
|
to register the proxy with the local Consul agent.
|
|
|
|
#### 1.2 Setup TLS Client Authentication for SDS
|
|
|
|
This configuration relies on files like the following being present on disk
|
|
where the Envoy proxy will run, along with the actual certificates and keys
|
|
referenced.
|
|
|
|
* `sds-client-auth.{crt,key}` are the PEM-encoded certificate and key
|
|
files to be used for TLS Client Authentication with the SDS service.
|
|
* `sds-ca.crt` is the Certificate Authority certificate used to validate the the
|
|
SDS server's TLS credentials.
|
|
|
|
Please refer to [Envoy's
|
|
documentation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/bootstrap/bootstrap)
|
|
for more details on this configuration and other possible authentication
|
|
options.
|
|
|
|
```json
|
|
// /certs/sds-auth-cert.json
|
|
{
|
|
"resources": [
|
|
{
|
|
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret",
|
|
"name": "tls_sds",
|
|
"tls_certificate": {
|
|
"certificate_chain": {
|
|
"filename": "/certs/sds-client-auth.crt"
|
|
},
|
|
"private_key": {
|
|
"filename": "/certs/sds-client-auth.key"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
```json
|
|
// /certs/sds-validation.json
|
|
{
|
|
"resources": [
|
|
{
|
|
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret",
|
|
"name": "validation_context_sds",
|
|
"validation_context": {
|
|
"trusted_ca": {
|
|
"filename": "/certs/sds-ca.crt"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
#### 1.3 Start Envoy
|
|
|
|
**Start Envoy** with:
|
|
|
|
```bash
|
|
$ consul connect envoy -gateway=ingress -service public-ingress
|
|
```
|
|
|
|
### 2. Configure the Ingress Gateway to use certificates from SDS
|
|
|
|
SDS certificates may now be configured in the `ingress-gateway` Config Entry.
|
|
|
|
The following example shows a single default certificate and key being used for
|
|
all listeners.
|
|
|
|
```hcl
|
|
// public-ingress-cfg.hcl
|
|
Kind = "ingress-gateway"
|
|
Name = "public-ingress"
|
|
|
|
TLS {
|
|
SDS {
|
|
# This must match the name of the static cluster from step #1
|
|
ClusterName = "sds-cluster"
|
|
# This is the name of the certificate resource to load.
|
|
CertResource = "example.com-public-cert"
|
|
}
|
|
}
|
|
|
|
Listeners = [
|
|
{
|
|
Port = 8443
|
|
Protocol = "http"
|
|
Services = ["*"]
|
|
}
|
|
]
|
|
|
|
```
|
|
|
|
Run `consul config write public-ingress-cfg.hcl` to write this configuration.
|
|
|
|
The Envoy instance will now start a listener on port 8443 and attempt to fetch
|
|
the TLS certificate named from the SDS server.
|
|
|
|
Separate certificates may be loaded per listener or per-service with hostname
|
|
(SNI) switching. See the [Config Entry
|
|
reference](/docs/connect/config-entries/ingress-gateway) for more details. |