DocsEmissary-ingressConfiguring Emissary-ingress Communications
Configuring Emissary-ingress Communications
For Emissary-ingress to do its job of managing network communications for your services, it first needs to know how its own communications should be set up. This is handled by a combination of resources: the Listener
, the Host
, and the TLSContext
.
Listener
: defines where, and how, Emissary-ingress should listen for requests from the network.Host
: defines which hostnames Emissary-ingress should care about, and how to handle different kinds of requests for those hosts.Host
s can be associated with one or moreListener
s.TLSContext
: defines whether, and how, Emissary-ingress will manage TLS certificates and options.TLSContext
s can be associated with one or moreHost
s.
Once the basic communications setup is in place, Emissary-ingress Mapping
s and TCPMapping
s can be associated with Host
s to actually do routing.
A Note on TLS
TLS can appear intractable if you haven't set up certificates correctly. If you're having trouble with TLS, always check the logs of your Emissary-ingress Pods and look for certificate errors.
Examples / Cookbook
Basic HTTP and HTTPS
A useful configuration is to support either HTTP or HTTPS, in this case on either port 8080 or port 8443. This
tends to make it as easy as possible to communicate with the services behind the Emissary-ingress instance. It uses
two Listener
s and at least one Host
.
Listener
s:
Both
Listener
s useprotocol: HTTPS
to allow Envoy to inspect incoming connections, determine whether or not TLS is in play, and setX-Forwarded-Proto
appropriately. ThesecurityModel
then specifies thatX-Forwarded-Proto
will determine whether requests will be considered secure or insecure.The
hostBinding
shown here will allow anyHost
in the same namespace as theListener
s to be associated with bothListener
s; in turn, that will allow access to thatHost
'sMapping
s from either port. For greater control, use aselector
instead.Note that the
Listener
s do not specify anything about TLS certificates. TheHost
handles that; see below.
Host
This example will assume that we expect to be reachable as foo.example.com
, and that the foo.example.com
certificate is stored in the Kubernetes Secret
named foo-secret
:
- The
tlsSecret
specifies the certificate in use for TLS termination. - The
requestPolicy
specifies routing HTTPS and redirecting HTTP to HTTPS. - Since the
Host
does not specify aselector
, onlyMapping
s with ahostname
that matchesfoo.example.com
will be associated with thisHost
. - Note well that simply defining a
TLSContext
is not sufficient to terminate TLS: you must define either aHost
or anIngress
. - Note that if no
Host
is present, but a TLS secret namedfallback-secret
is available, the system will currently define aHost
usingfallback-secret
. This behavior is subject to change.
HTTP-Only
Another straightforward configuration is to support only HTTP, in this case on port 8080. This uses a single
Listener
and a single Host
:
- Here, we listen only on port 8080, and only for HTTP. HTTPS will be rejected.
- Since requests are only allowed using HTTP, we declare all requests
INSECURE
by definition. - The
Host
specifies routing HTTP, rather than redirecting it.
TLS using ACME (Ambassador Edge Stack only)
This scenario uses ACME to get certificates for foo.example.com
and bar.example.com
. HTTPS traffic to either
host is routed; HTTP traffic to foo.example.com
will be redirected to HTTPS, but HTTP traffic to bar.example.com
will be rejected outright.
Since this example uses ACME, it is only supported in Ambassador Edge Stack.
For demonstration purposes, we show this example listening for HTTPS on port 9999, using X-Forwarded-Proto
.
(Mapping
s are not shown.)
- Our
Listener
s will accept HTTPS and HTTP on port 9999, and the protocol used will dictate whether the requests are secure (HTTPS) or insecure (HTTP). foo-host
defaults to ACME with Let's Encrypt, sinceacmeProvider.authority
is not provided.foo-host
defaults to redirecting insecure requests, since the default forrequestPolicy.insecure.action
isRedirect
.bar-host
uses Let's Encrypt as well, but it will reject insecure requests.
If you use ACME for multiple Hosts, add a wildcard Host too. This is required to manage a known issue. This issue will be resolved in a future Ambassador Edge Stack release.
Multiple TLS Certificates
This scenario uses TLS without ACME. Each of our two Host
s uses a distinct TLS certificate. HTTPS
traffic to eitherfoo.example.com
or bar.example.com
is routed, but this time foo.example.com
will redirect
HTTP requests, while bar.example.com
will route them.
Since this example does not use ACME, it is supported in Emissary-ingress as well as Ambassador Edge Stack.
For demonstration purposes, we show this example listening for HTTPS on port 4848, using X-Forwarded-Proto
.
foo-host
andbar-host
simply reference thetlsSecret
to use for termination.- If the secret involved contains a wildcard cert, or a cert with multiple SAN, both
Host
s could reference the sametlsSecret
.
- If the secret involved contains a wildcard cert, or a cert with multiple SAN, both
foo-host
relies on the default insecure routing action ofRedirect
.bar-host
must explicitly specify routing HTTP.
Using a TLSContext
If you need to share other TLS settings between two Host
s, you can reference a TLSContext
as well as
the tlsSecret
. This is the same as the previous example, but we use a TLSContext
to set ALPN
information,
and we assume that the Secret
contains a wildcard cert.
- Note that specifying the
tlsSecret
is still necessary, even whentlsContext
is specified.
ACME With a TLSContext (Ambassador Edge Stack Only)
In Ambassador Edge Stack, you can use a TLSContext
with ACME as well. This example is the same as "TLS using ACME",
but we use a TLSContext
to set ALPN
information. Again, ACME is only supported in Ambassador Edge Stack.
- Note that we don't provide the
Secret
: the ACME client will create it for us.
Using an L7 Load Balancer to Terminate TLS
In this scenario, a layer 7 load balancer ahead of Emissary-ingress will terminate TLS, so Emissary-ingress will always see HTTP with a known good X-Forwarded-Protocol
. We'll use that to route HTTPS and redirect HTTP.
- We set
l7Depth
to 1 to indicate that there's a single trusted L7 load balancer ahead of us. - We specifically set this Listener to HTTP-only, but we stick with port 8443 just because we expect people setting up TLS at all to expect to use port 8443. (There's nothing special about the port number, pick whatever you like.)
- Our
Host
does not specify atlsSecret
, so Emissary-ingress will not try to terminate TLS. - Since the
Listener
still pays attention toX-Forwarded-Proto
, both secure and insecure requests are possible, and we use theHost
to route HTTPS and redirect HTTP.
Using a Split L4 Load Balancer to Terminate TLS
Here, we assume that Emissary-ingress is behind a load balancer setup that handles TLS at layer 4:
- Incoming cleartext traffic is forwarded to Emissary-ingress on port 8080.
- Incoming TLS traffic is terminated at the load balancer, then forwarded to Emissary-ingress as cleartext on port 8443.
- This might involve multiple L4 load balancers, but the actual number doesn't matter.
- The actual port numbers we use don't matter either, as long as Emissary-ingress and the load balancer(s) agree on which port is for which traffic.
We're going to route HTTPS for both foo.example.com
and bar.example.com
, redirect HTTP for foo.example.com
, and reject HTTP for bar.example.com
.
- Since L4 load balancers cannot set
X-Forwarded-Protocol
, we don't use it at all here: instead, we dictate that 8080 and 8443 both speak cleartext HTTP, but everything arriving at port 8080 is insecure and everything at port 8443 is secure.
Listening on Multiple Ports
There's no reason you need to use ports 8080 and 8443, or that you're limited to two ports. Here we'll use ports 9001 and 9002 for HTTP, and port 4001 for HTTPS. We'll route traffic irrespective of protocol.
- We can use
X-Forwarded-Proto
for all ourListener
s: the HTTP-onlyListener
s will set it correctly. - Each
Listener
can specify only one port, but there's no hardcoded limit on the number ofListener
s you can have.
Using Labels to Associate Host
s and Listener
s
In the examples above, the Listener
s all associate with any Host
in their namespace. In this
example, we will use Kubernetes labels to control the association instead.
Here, we'll listen for HTTP to foo.example.com
on port 8888, and for either HTTP or HTTPS to bar.example.com
on
port 9999 (where we'll redirect HTTP to HTTPS). Traffic to baz.example.com
will work on both ports, and we'll route
HTTP for it rather than redirecting.
- Note the
labels
on eachHost
, which thehostBinding
on theListener
can reference.- Note also that only label selectors are supported at the moment.
Wildcard Host
s and Mapping
s
In a Mapping
, the host
is now treated as a glob rather than an exact match, with the goal of vastly reducing the need for host_regex
. (The hostname
in a Host
has always been treated as a glob).
- Note that only prefix and suffix matches are supported, so
*.example.com
andfoo.*
are both fine, butfoo.*.com
will not work -- you'll need to usehost_regex
if you really need that. (This is an Envoy limitation.)
In this example, we'll accept both HTTP and HTTPS, but:
- Cleartext traffic to any host in
lowsec.example.com
will be routed. - Cleartext traffic to any host in
normal.example.com
will be redirected. - Any other cleartext traffic will be rejected.
- We'll listen for HTTP or HTTPS on port 8443.
- The three
Host
s apply different insecure routing actions depending on the hostname. - You could also do this with
host_regex
, but usinghost
with globs will give better performance.- Being able to not associate a given
Mapping
with a givenHost
when theMapping
'shost
doesn't match helps a lot when you have manyHost
s. - Reliably determining if a regex (for the
Mapping
) matches a glob (for theHost
) isn't really possible, so we can't prunehost_regex
Mapping
s at all.
- Being able to not associate a given
ON THIS PAGE