Rancher Metadata / Confd Equivalent in Kubernetes

10/12/2018

On our current Rancher environment, we dynamically configure an Nginx configuration based on calls to the Rancher metadata, using labels on the containers to determine if that container is included in the Nginx routing.
We use confd with a Rancher backend to accomplish this metadata check and to dynamically change/reload a new Nginx configuration.

We have started working on migrating to Kubernetes (AWS EKS). Is there an equivalent to this confd/Rancher available for Kubernetes ?

Due to some technical reasons and time scoping reasons, we can't replace this nginx with an ingress equivalent at this time, so are looking into using annotations or labels on services/pods to keep a dynamic configuration capability.

-- Steele
kubernetes
rancher

2 Answers

10/14/2018

Hosted Kubernetes providers don't generally give you direct access to the backing etcd so your best and desired option is to mine the Kubernetes API for the resources you are interested in and generate your configuration.

This is precisely what an ingress controller does - watches for changes in Kubernetes resources and generates configuration for a load balancer like nginx.

One of the nginx controllers lets you completely replace the template that it uses with one of your own.

The NGINX template is located in the file /etc/nginx/template/nginx.tmpl.

Using a Volume it is possible to use a custom template. This includes using a Configmap as source of the template

        volumeMounts:
      - mountPath: /etc/nginx/template
        name: nginx-template-volume
        readOnly: true
  volumes:
    - name: nginx-template-volume
      configMap:
        name: nginx-template
        items:
        - key: nginx.tmpl
          path: nginx.tmpl

You could deploy a version of the nginx ingress controller under a custom class like nginx-legacy so it doesn't try to expose services that are expecting the normal nginx ingress.

To do this, the option --ingress-class must be changed to a value unique for the cluster within the definition of the replication controller.

spec:
  template:
     spec:
       containers:
         - name: nginx-ingress-legacy-controller
           args:
             - /nginx-ingress-controller
             - '--election-id=ingress-controller-leader-internal'
             - '--ingress-class=nginx-legacy'
             - '--configmap=ingress/nginx-ingress-internal-controller'

And then annotate legacy services to assign resources to that ingress using:

metadata:
  name: foo
  annotations:
    kubernetes.io/ingress.class: "nginx-legacy"
-- Scott Anderson
Source: StackOverflow

12/20/2018

To add a little further detail on what we eventually found thanks to Scott Anderson's answer.

Using the nginx custom template technique, we were able to dynamically configure the nginx configuration by using annotations in the Ingress resources and referencing them in the nginx custom template.

With an Ingress resource metadata defined as:

metadata:
  name: foo
  annotations:
    kubernetes.io/ingress.class: "nginx-legacy"
    mycompany/bar: "path_to_service"

Within the custom Nginx template (location block), to see if the annotation is present:

{{if index $ing.Annotations "mycompany/bar"}}

To get a value from an annotation:

{{$bar:= index $ing.Annotations "mycompany/bar"}}
-- Steele
Source: StackOverflow