Emissary-ingress is designed so that the author of a given Kubernetes service can easily and flexibly configure how traffic gets routed to the service. The core abstraction used to support service authors is a mapping, which maps a target backend service to a given host or prefix. For Layer 7 protocols such as HTTP, gRPC, or WebSockets, the
Mapping resource is used. For TCP, the
TCPMapping resource is used.
Emissary-ingress must have one or more mappings defined to provide access to any services at all. The name of the mapping must be unique.
Certain aspects of mappings can be set system-wide using the
defaults element of the
see using defaults for more information. The
Mapping element will look first in
httpmapping default class.
Emissary-ingress sorts mappings such that those that are more highly constrained are evaluated before those less highly constrained. The prefix length, the request method, constraint headers, and query parameters are all taken into account.
If absolutely necessary, you can manually set a
precedence on the mapping (see below). In general, you should not need to use this feature unless you're using the
host_regex matching features. If there's any question about how Emissary-ingress is ordering rules, the diagnostic service is a good first place to look: the order in which mappings appear in the diagnostic service is the order in which they are evaluated.
Emissary-ingress will respond with a
404 Not Found to any request for which no mapping exists. If desired, you can define a fallback "catch-all" mapping so all unmatched requests will be sent to an upstream service.
For example, defining a mapping with only a
/ prefix will catch all requests previously unhandled and forward them to an external service:
---apiVersion: getambassador.io/v3alpha1kind: Mappingmetadata:name: catch-allspec:prefix: /service: https://www.getambassador.io
Emissary-ingress sorts mappings such that those that are more highly constrained are evaluated before those less highly constrained. The prefix length, the request method, and the constraint headers are all taken into account. These mechanisms, however, may not be sufficient to guarantee the correct ordering when regular expressions or highly complex constraints are in play.
For those situations, a
Mapping can explicitly specify the
Mapping with no
precedence is assumed to have a
precedence of 0; the higher the
precedence value, the earlier the
Mapping is attempted.
Mappings have the same
precedence, Emissary-ingress's normal sorting determines the ordering within the
precedence; however, there is no way that Emissary-ingress can ever sort a
Mapping with a lower
precedence ahead of one at a higher
To originate TLS, use a
service with an
https:// prefix. By itself, this will cause Emissary-ingress to originate TLS without presenting a client certificate to the upstream service:
---apiVersion: getambassador.io/v3alpha1kind: Mappingmetadata:name: mapping-no-certspec:prefix: /prefix/service: https://upstream/
If you do need to supply a client certificate, you will also need to set
tls to the name of a defined TLS context. The client certificate given in that context will be presented to the upstream service.
---apiVersion: getambassador.io/v3alpha1kind: Mappingmetadata:name: mapping-with-certspec:prefix: /prefix/service: https://upstream/tls: upstream-cert-context
tls is present, Emissary-ingress will originate TLS even if the
service does not have an
cluster_tag attribute is present, its value will be prepended to cluster names generated from
Mapping. This provides a simple mechanism for customizing the
cluster name when working with metrics.
dns_type attribute is present, its value will determine how the DNS is used when locating the upstream service. Valid values are:
strict_dns(the default): The DNS result is assumed to define the exact membership of the cluster. For example, if DNS returns three IP addresses, the cluster is assumed to have three distinct upstream hosts. If a successful DNS query returns no hosts, the cluster is assumed to be empty.
strict_dnsmakes sense for situations like a Kubernetes service, where DNS resolution is fast and returns a relatively small number of IP addresses.
logical_dns: Instead of assuming that the DNS result defines the full membership of the cluster, every new connection simply uses the first IP address returned by DNS.
logical_dnsmakes sense for a service with a large number of IP addresses using round-robin DNS for upstream load balancing: typically each DNS query returns a different first result, and it is not necessarily possible to know the full membership of the cluster. With
logical_dns, no attempt is made to garbage-collect connections: they will stay open until the upstream closes them.
dns_type is not given,
strict_dns is the default, as this is the most conservative choice. When interacting with large web services with many IP addresses, switching to
logical_dns may be a better choice. For more on the different types of DNS, see the
strict_dns Envoy documentation or the
logical_dns Envoy documentation.
AMBASSADOR_NAMESPACE is correctly set, Emissary-ingress can map to services in other namespaces by taking advantage of Kubernetes DNS:
service: servicenamewill route to a service in the same namespace as Emissary-ingress, and
service: servicename.namespacewill route to a service in a different namespace.
When using Linkerd, requests going to an upstream service need to include the
l5d-dst-override header to ensure that Linkerd will route them correctly. Setting
add_linkerd_headers does this automatically, based on the
service attribute in the
add_linkerd_headers is not specified for a given
Mapping, the default is taken from the
ambassadorModule. The overall default is
false: you must explicitly enable
add_linkerd_headers for Emissary-ingress to add the header for you (although you can always add it yourself with
add_request_headers, of course).
HTTP has a mechanism where the client can say
Connection: upgrade /
Upgrade: PROTOCOL to switch ("upgrade") from
the current HTTP version to a different one, or even a different
protocol entirely. Emissary-ingress itself understands and can handle the
different HTTP versions, but for other protocols you need to tell
Emissary-ingress to get out of the way, and let the client speak that
protocol directly with your upstream service. You can do this by
allow_upgrade field to a case-insensitive list of
protocol names Emissary-ingress will allow switching to from HTTP. After
the upgrade, Emissary-ingress does not interpret the traffic, and behaves
similarly to how it does for
This "upgrade" mechanism is a useful way of adding HTTP-based authentication and access control to another protocol that might not support authentication; for this reason the designers of the WebSocket protocol made this "upgrade" mechanism the only way of initiating a WebSocket connection. In a Mapping for an upstream service that supports WebSockets, you would write
The Kubernetes apiserver itself uses this "upgrade" mechanism to
perform HTTP authentication before switching to SPDY for endpoint used
kubectl exec; if you wanted to use Emissary-ingress to expose the
Kubernetes apiserver such that
kubectl exec functions, you would
---apiVersion: getambassador.io/v3alpha1kind: Mappingmetadata:name: apiserverspec:hostname: "*"service: https://kubernetes.defaultprefix: /allow_upgrade:- spdy/3.1
There is a deprecated setting
true is equivalent to setting
respect_dns_ttl can be set to
true to force the DNS refresh rate for this
Mapping to be set to the record’s TTL obtained from DNS resolution.
- Allowed values:
dns_type can be used to configure the service discovery type between Strict DNS and Logical DNS. You can
- Allowed values:
strict_dns: Ambassador will continuously and asynchronously resolve the specified DNS targets.
logical_dns: Similar to
strict_dns, but only uses the first IP address returned when a new connection needs to be initiated and Connections are never drained. More optimal for large scale web services that must be accessed via DNS.
For more information on the differences between dns types, see the Envoy documentation for service discovery.
Note: When the endpoint resolver is used in a
dns_typewill be ignored in favor of the endpoint resolver's service discovery.
---apiVersion: getambassador.io/v3alpha1kind: Mappingmetadata:name: dnsoverwritespec:service: quoteprefix: /backend/dns_type: logical_dnsrespect_dns_ttl: true