Configure Tyk Operator as Ingress Controller

Last updated: 6 minutes read.

Tyk Operator offers an Ingress Controller, which dynamically manages ApiDefinition resources as per the ingress spec. Tyk Gateway can be configured as a drop-in replacement for a standard Kubernetes Ingress.

Most Ingress Controllers heavily rely on annotations to configure the ingress gateway. With Tyk Operator, our Ingress Controller prefers to reference a strongly typed custom resource template.

Motivation

The standard Ingress resource is very basic and does not natively support many advanced capabilities that are required for API Management use-cases. Despite this, the community have built tooling, capabilities and dependencies on top of the ingress resource. These all rely on abuse of the metadata annotations. This practice is apparent with the standard Kubernetes NginX Ingress resource.

In order to decouple, gain all the benefits of Kubernetes, offer a Native & consistent API, we introduced the Tyk ApiDefinition custom resource, which adds additional API Management capabilities, like security policy and rate limiting to Kubernetes Ingress. A side effect of this meant a potential trade-off between offering a K8s native experience & integrating with Ingress which would facilitate clean integration with 3rd party tooling built on-top of and dependent on the Ingress Resource.

As a compromise & attempt to propose an alternative & more scalable solution, we have introduced the concept of the ingress template ApiDefinition resource. The Template ApiDefinition resource offers a means to extend the capabilities of the standard Ingress Resource, by merging features of the ingress specification with that of the template.

The following sections shows some example of Tyk ApiDefinition template and Ingress specification.

How to configure Tyk Operator to handle Ingress resources

To configure Tyk Operator to handle Ingress resources, first create a ApiDefinition resource template. The template provides default API configurations. Next, specify ingress class as tyk in the Ingress resource. This allows Tyk Operator to read the Ingress resource and create API Definition resources based on ingress path and ApiDefinition template.

Here are some Ingress Examples we provided on GitHub:

Ingress Class

The value of the kubernetes.io/ingress.class annotation identifies the IngressClass that will process Ingress objects.

Tyk Operator by default looks for the value tyk and will ignore all other ingress classes. If you wish to override this default behaviour, you may do so by setting the environment variable WATCH_INGRESS_CLASS in the operator manager deployment. See Installing Tyk Operator for further information.

Sample Template ApiDefinition resource

apiVersion: tyk.tyk.io/v1alpha1
kind: ApiDefinition
metadata:
 name: myapideftemplate
 labels:
  template: "true"
spec:
 name: foo
 protocol: http
 use_keyless: true
 proxy:
  target_url: http://example.com

Pay particular attention to the ApiDefinition metadata. This specifies that we have an ApiDefinition object with the label template: true.

When applying this manifest, the ApiDefinition controller will skip reconciliation. This will allow the ApiDefinition to be stored inside Kubernetes as a resource, but will not reconcile the ApiDefinition inside Tyk.

All mandatory fields inside the ApiDefinition spec are still mandatory, but can be replaced with placeholders as they will be overwritten by the Ingress reconciler.

Sample HTTP Ingress resource

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: httpbin-ingress
 annotations:
  kubernetes.io/ingress.class: tyk # <----------------- REFERENCES TYK INGRESS CONTROLLER
  tyk.io/template: myapideftemplate # <---------------- REFERENCE TO APIDEFINITION IN SAME NAMESPACE
spec:
 rules:
  - http:
     paths:
      - path: /httpbin
        pathType: Prefix
        backend:
         service:
          name: httpbin
          port:
           number: 8000

Tyk Ingress Controller will create APIs in Tyk for each path defined for a specific rule in Ingress resource. Each API created inside Tyk will follow a special naming convention as follows:

<ingress_namespace>-<ingress_name>-<hash(Host + Path)>

The above ingress resource will create an ApiDefinition called default-httpbin-ingress-78acd160d inside Tyk’s Gateway. ApiDefinition’s name comes from:

  • default: The namespace of this Ingress resource,
  • httpbin-ingress: The name of this Ingress resource,
  • 78acd160d: Short hash (first 9 characters) of Host ("") and Path (/httpbin). The hash algorithm is SHA256.

The ApiDefinition will offer path-based routing listening on /httpbin. Because the referenced template is myapideftemplate, the IngressReconciler will retrieve the myapideftemplate resource and determine that the ApiDefinition object it creates needs to have standard auth enabled.

Sample HTTPS Ingress resource

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: httpbin-ingress-tls
  annotations:
    kubernetes.io/ingress.class: tyk # <----------------- REFERENCES TYK INGRESS CONTROLLER
    tyk.io/template: myapideftemplate # <---------------- REFERENCE TO APIDEFINITION IN SAME NAMESPACE
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    acme.cert-manager.io/http01-edit-in-place: "true"
spec:
  tls:
    - hosts:
        - myingress.do.poc.tyk.technology
      secretName: httpbin-ingress-tls
  rules:
    - host: myingress.do.poc.tyk.technology
      http:
        paths:
          - path: /httpbin
            pathType: Prefix
            backend:
              service:
                name: httpbin
                port:
                  number: 8000

Assuming you already have a letsencrypt-prod cluster issuer, it is possible to automatically provision TLS certificates issued by LetsEncrypt.

metadata:
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    acme.cert-manager.io/http01-edit-in-place: "true"

Tyk ingress controller can then handle the acme challenge when cert-manager edits the ingress resource.

Ingress Path Types

Each path in an Ingress must have its own particular path type. Kubernetes offers three types of path types: ImplementationSpecific, Exact, and Prefix. Currently, not all path types are supported. The below table shows the unsupported path types for Sample HTTP Ingress Resource based on the examples in the Kubernetes Ingress documentation.

Kind Path(s) Request path(s) Expected to match? Works as Expected
Exact /foo /foo/ No No.
Prefix /foo/ /foo, /foo/ Yes No, /foo/ matches, /foo does not match.
Prefix /aaa/bb /aaa/bbb No No, the request forwarded to service.
Prefix /aaa/bbb/ /aaa/bbb Yes, ignores trailing slash No, /aaa/bbb does not match.
Prefix /aaa/bbb /aaa/bbbxyz No, does not match string prefix No, the request forwarded to service.

Please bear in mind that if proxy.strip_listen_path is set to true on API Definition, Tyk strips the listen-path (for example, the listen-path for the Ingress under Sample HTTP Ingress Resource is /httpbin) with an empty string.

The following table shows an example of path matching if the listen-path is set to /httpbin or /httpbin/.

Kind Path(s) Request path(s) Matches?
Exact /httpbin /httpbin, /httpbin/ Yes. The request forwarded as / to your service.
Prefix /httpbin /httpbin, /httpbin/ Yes. The request forwarded as / to your service.
ImplementationSpecific /httpbin /httpbin, /httpbin/ Yes. The request forwarded as / to your service.
Exact /httpbin /httpbinget, /httpbin/get Yes. The request forwarded as /get to your service.
Prefix /httpbin /httpbinget, /httpbin/get Yes. The request forwarded as /get to your service.
ImplementationSpecific /httpbin /httpbinget, /httpbin/get Yes. The request forwarded as /get to your service.
Exact /httpbin/ /httpbin/, /httpbin/get Yes. The request forwarded as /get to your service.
Prefix /httpbin/ /httpbin/, /httpbin/get Yes. The request forwarded as /get to your service.
ImplementationSpecific /httpbin/ /httpbin/, /httpbin/get Yes. The request forwarded as /get to your service.
Exact /httpbin/ /httpbin No. Ingress cannot find referenced service.
Prefix /httpbin/ /httpbin No. Ingress cannot find referenced service.
ImplementationSpecific /httpbin/ /httpbin No. Ingress cannot find referenced service.