Here are some important things to know about the Kubernetes Ingress resource as implemented by ingress-nginx
(which is one of the Ingress controllers we support at Cloud Posse).
- An
Ingress
must send traffic to aService
in the sameNamespace
as theIngress
- An
Ingress
, if it uses a TLS secret, must use aSecret
from the sameNamespace
as theIngress
- It is completely legal and supported to have multiple ingresses defined for the same host, and this is how you can have one host refer to 2 services in different namespaces
- Multiple ingresses for the same host are mostly merged together as if they were one ingress, with some exceptions:
- While the ingresses must refer to resources in their own namespaces, the multiple ingresses can be in different namespaces
- Annotations that can be applied to only one ingress are applied only to that ingress
- In case of conflicts, such as multiple TLS certificates or server-scoped annotations, the oldest rule wins
- These rules are defined more rigorously in the documentation
- Because of the way multiple ingresses are merged, you can have an ingress in one namespace that defines the TLS secret and external DNS name target and not have that defined at all in the other ingresses and yet they will all appear with the same TLS certificate
The paths
section of the Ingress
deserves some special attention, too:
- The interpretation of the
path
is implementation-dependent. GCE ingress treats the path as an exact match, while Nginx treats it as a prefix. Starting with Kubernetes 1.18, there is apathType
field that can be either Exact or Prefix, but the default remains implementation-dependent. Generally, helm charts appear to expect the path to be interpreted the way Nginx does. - The general rule is that the longest matching path wins, but it gets complicated with regular expressions (more below)
- Prior to Kubernetes 1.18 (and maybe even then), there is no way for an Ingress to specify the native Nginx exact path match. The closest you can come is to use a regex match, but regex matches are case-independent. Furthermore, adding a regex path to an ingress makes all the paths of that ingress case-independent regexes, by default rooted as prefixes.
- The catch here is that it is still the longest rule that wins, even over an exact match: /[abc]pi/ will take precedence over
/api/
- There is a simple explainer of priorities and gotchas with multiple path rules in the ingress-nginx documentation and a fuller explanation in this tutorial from Digital Ocean.
- With Nginx, if a path ends in
/
, then it creates an implied 301 permanent redirect from the path without the trailing/
unless that path is also defined.path: /api/
will causehttps://host/api
to redirect tohttps://host/api/
. (Not sure if this applies to regex paths.)