Ambassador as an Ingress Controller
An Ingress
resource is a popular way to expose Kubernetes services to the Internet. In order to use Ingress
resources, you need to install an ingress controller. The Ambassador Edge Stack can function as a fully-fledged Ingress controller, making it easy to work with other Ingress
-oriented tools within the Kubernetes ecosystem.
When and How to Use the Ingress
Resource
If you're new to the Ambassador Edge Stack and to Kubernetes, we'd recommend you start with our quickstart, instead of using Ingress
. If you're a power user and need to integrate with other software that leverages the Ingress
resource, read on. The Ingress
specification is very basic, and, as such, does not support many of the features of the Ambassador Edge Stack, so you'll be using both Ingress
resources and Mapping
resources to manage your Kubernetes services.
What is Required to Use the Ingress
Resource?
Know what version of Kubernetes you are using.
In Kubernetes 1.13 and below, the
Ingress
was only included in theextensions
api.Starting in Kubernetes 1.14, the
Ingress
was added to the newnetworking.k8s.io
api.Kubernetes 1.18 introduced the
IngressClass
resource to the existingnetworking.k8s.io/v1beta1
api.Note: If you are using 1.14 and above, it is recommended to use
apiVersion: networking.k8s.io/v1beta1
when definingIngresses
. Since both are still supported in all 1.14+ versions of Kubernetes, this document will useextensions/v1beta1
for compatibility reasons. If you are using 1.18 and above, sample usage of theIngressClass
resource andpathType
field are available on our blog.You will need RBAC permissions to create
Ingress
resources in either theextensions
apiGroup
(present in all supported versions of Kubernetes) or thenetworking.k8s.io
apiGroup
(introduced in Kubernetes 1.14).The Ambassador Edge Stack will need RBAC permissions to get, list, watch, and update
Ingress
resources.You can see this in the
aes-crds.yaml
file, but this is the critical rule to add to the Ambassador Edge Stack'sRole
orClusterRole
:- apiGroups: [ "extensions", "networking.k8s.io" ]resources: [ "ingresses", "ingressclasses" ]verbs: ["get", "list", "watch"]- apiGroups: [ "extensions", "networking.k8s.io" ]resources: [ "ingresses/status" ]verbs: ["update"]Note: This is included by default in all recent versions of the Ambassador install YAML
You must create your
Ingress
resource with the correctingress.class
.The Ambassador Edge Stack will automatically read Ingress resources with the annotation
kubernetes.io/ingress.class: ambassador
.You may need to set your
Ingress
resources'ambassador-id
.If you're not using the
default
ID, you'll need to add thegetambassador.io/ambassador-id
annotation to yourIngress
. See the examples below.You must create a
Service
resource with the correctapp.kubernetes.io/component
label.The Ambassador Edge Stack will automatically load balance Ingress resources using the endpoint exposed from the Service with the annotation
app.kubernetes.io/component: ambassador-service
.kind: ServiceapiVersion: v1metadata:name: ingress-ambassadorlabels:app.kubernetes.io/component: ambassador-servicespec:externalTrafficPolicy: Localtype: LoadBalancerselector:service: ambassadorports:- name: httpport: 80targetPort: http- name: httpsport: 443targetPort: https```
When Should I Use an Ingress
Instead of Annotations or CRDs?
As of 0.80.0, Datawire recommends that the Ambassador Edge Stack be configured with CRDs. The Ingress
resource is available to users who need it for integration with other ecosystem tools, or who feel that it more closely matches their workflows -- however, it is important to recognize that the Ingress
resource is rather more limited than the Ambassador Edge Stack Mapping
is (for example, the Ingress
spec has no support for rewriting or for TLS origination). When in doubt, use CRDs.
Ambassador Ingress
Support
The Ambassador Edge Stack supports basic core functionality of the Ingress
resource, as
defined by the Ingress
resource itself:
- Basic routing, including the
route
specification and the default backend functionality, is supported.- It's particularly easy to use a minimal
Ingress
to the Ambassador Edge Stack diagnostic UI
- It's particularly easy to use a minimal
- TLS termination is supported.
- you can use multiple
Ingress
resources for SNI
- you can use multiple
- Using the
Ingress
resource in concert with the Ambassador Edge Stack CRDs or annotations is supported.- this includes the Ambassador Edge Stack annotations on the
Ingress
resource itself
- this includes the Ambassador Edge Stack annotations on the
The Ambassador Edge Stack does not extend the basic Ingress
specification except as follows:
The
getambassador.io/ambassador-id
annotation allows you to set the Ambassador Edge Stack ID for theIngress
itself; andThe
getambassador.io/config
annotation can be provided on theIngress
resource, just as on aService
.
Note that if you need to set getambassador.io/ambassador-id
on the Ingress
, you will also need to set ambassador-id
on resources within the annotation.
Ingress
Routes and Mapping
s
The Ambassador Edge Stack actually creates Mapping
objects from the Ingress
route rules. These Mapping
objects interact with Mapping
s defined in CRDs exactly as they would if the Ingress
route rules had been specified with CRDs originally.
For example, this Ingress
resource
---apiVersion: extensions/v1beta1kind: Ingressmetadata:annotations:kubernetes.io/ingress.class: ambassadorname: test-ingressspec:rules:- http:paths:- path: /foo/backend:serviceName: service1servicePort: 80
is exactly equivalent to a Mapping
CRD of
---apiVersion: getambassador.io/v2kind: Mappingmetadata:name: test-ingress-0-0spec:prefix: /foo/service: service1:80
This means that the following YAML:
---apiVersion: extensions/v1beta1kind: Ingressmetadata:annotations:kubernetes.io/ingress.class: ambassadorname: test-ingressspec:rules:- http:paths:- path: /foo/backend:serviceName: service1servicePort: 80---apiVersion: getambassador.io/v2kind: Mappingmetadata:name: my-mappingspec:prefix: /foo/service: service2
will set up the Ambassador Edge Stack to do canary routing where 50% of the traffic will go to service1
and 50% will go to service2
.
The Minimal Ingress
An Ingress
resource must provide at least some routes or a default backend. The default backend provides for a simple way to direct all traffic to some upstream service:
apiVersion: extensions/v1beta1kind: Ingressmetadata:annotations:kubernetes.io/ingress.class: ambassadorname: test-ingressspec:backend:serviceName: exampleserviceservicePort: 8080
This is equivalent to
---apiVersion: getambassador.io/v2kind: Mappingmetadata:name: test-ingressspec:prefix: /service: exampleservice:8080
Name based virtual hosting with an Ambassador Edge Stack ID
---apiVersion: extensions/v1beta1kind: Ingressmetadata:annotations:kubernetes.io/ingress.class: ambassadorgetambassador.io/ambassador-id: externalidname: name-virtual-host-ingressspec:rules:- host: foo.bar.comhttp:paths:- backend:serviceName: service1servicePort: 80- host: bar.foo.comhttp:paths:- backend:serviceName: service2servicePort: 80
This is equivalent to
---apiVersion: getambassador.io/v2kind: Mappingmetadata:name: host-foo-mappingspec:ambassador_id: externalidprefix: /host: foo.bar.comservice: service1---apiVersion: getambassador.io/v2kind: Mappingmetadata:name: host-bar-mappingspec:ambassador_id: externalidprefix: /host: bar.foo.comservice: service2
and will result in all requests to foo.bar.com
going to service1
, and requests to bar.foo.com
going to service2
.
Read more from Kubernetes here.
TLS Termination
apiVersion: extensions/v1beta1kind: Ingressmetadata:annotations:kubernetes.io/ingress.class: ambassadorname: tls-example-ingressspec:tls:- hosts:- sslexample.foo.comsecretName: testsecret-tlsrules:- host: sslexample.foo.comhttp:paths:- path: /backend:serviceName: service1servicePort: 80
This is equivalent to
---apiVersion: getambassador.io/v2kind: TLSContextmetadata:name: sslexample-termination-contextspec:hosts:- sslexample.foo.comsecretName: testsecret-tls---apiVersion: getambassador.io/v2kind: Mappingmetadata:name: sslexample-mappingspec:host: sslexample.foo.comprefix: /service: service1
Note that this shows TLS termination, not origination: the Ingress
spec does not support origination. Read about Kubernetes TLS termination here.
Questions?
We’re here to help. If you have questions, join our Slack or contact us.