Kubernetes Ingress With Dynamic routing?

3/23/2021

I have a Jenkins build process that deploys our code to several Kubernetes environments. Currently, it works fantastic with known/core branches (develop, release, master) and such, BUT we would like to make all of our feature branches and bug fix branches as well. In order to do this, we currently have it deploying an ingress with branch subdomains, like "{branchName}.domain.tld". The problem here is that there is a proliferation of ingresses and such for each branch.

I would LIKE to do something like "branch.domain.tld/{branchName}" and have the ingress dynamically route based on the "branchName" path. Unfortunately I only seem to get a single ingress per subdomain/host assignment (branch.domain.tld/bugfix_nasty doesn't route because branch.domain.tld/feat_cool already is defined).

What I would like to see is a single ingress that looks something like this:

apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    name: dynamic_ingress
    annotations:
      {...stuff here}
  spec:
    rules:
    - host: branch.domain.tld
      http:
        paths:
        - path: /{branchName}/*
          backend:
            serviceName: {branchName}
            servicePort: 80

Is there anyway to get to such a zenlike ingress?

All the stuff I see about this type of thing is advice on using regex for the path to capture and route to a known, defined service. I want this to route to variable service names.

-- zentechinc
jenkins
kubernetes
kubernetes-ingress

1 Answer

3/24/2021

As far as I know Ingress objects don't allow what you're trying to do. But there could be a workaround if you can modify the Ingress object every time you deploy a new branch.
Whenever a new branch is deployed update your "dynamic_ingress" to include an extra path for the new branch. This can be achieved using a small utility that can read and write YAMLs which can then be applied to update the existing Ingress OR you can use kubectl patch to update the existing Ingress at deploy time.
This way the Ingress definition has static paths but neither do you have to set the paths manually nor do you need multiple Ingress objects.
So you would have something like this.

apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    name: dynamic_ingress
    annotations:
      {...stuff here}
  spec:
    rules:
    - host: branch.domain.tld
      http:
        paths:
        - path: /bug_fix_nasty/
          pathType: Prefix
          backend:
            serviceName: bug_fix_nasty
            servicePort: 80
        - path: /feat_cool/
          pathType: Prefix
          backend:
            serviceName: feat_cool
            servicePort: 80

Check out all the examples in the Ingress doc and see which suits you best.

-- 0xf
Source: StackOverflow