Kubernetes: Reference a section or value inside a manifest

A colleague showed me this neat trick so I didn’t have to write the same information twice in a Ingress manifest file. I needed to map two hosts to the same path, and instead of duplicate the same information twice we can just reference the “http” section in the previous definition in the second host.

Example:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  namespace: default
  annotations:
spec:
  ingressClassName: nginx
  rules:
    - host: my-first.domain.se
      http: &http-paths
        paths:
          - path: /my-application
            pathType: Prefix
            backend:
              service:
                name: my-application-service
                port:
                  number: 8080
    - host: my-second.domain.se
      http: *http-paths

The trick here is to use the &-sign to mark a place in manifest that you want to reference. In this example I named the reference “&http-paths”. When we later define the second host (my-second.domain.se) we can just de-reference the reference with the *-sign, here show as “*http-paths”. This will “copy” the whole http section with path, service and port, from the first definition and “paste” it into the second host section.
In Kubernetes this will be de-referenced and look like I put the same information in both hosts

Tested on Tanzu Kubernetes v1.22

K9s: Adjust memory and cpu warning levels

Maybe you are like me and feel that the default memory warning level of 70% is a little off in the clusters you work.

Here is how to change them:
1. Open .config/k9s/config.yaml in your favorite editor (of course VIM 😉 )
2. Edit the section called “thresholds”

 thresholds:
    cpu:
      critical: 90
      warn: 70
    memory:
      critical: 90
      warn: 70

3. Save and restart k9s – done!

Apart from this, K9s is a wonderful tool that I don’t want to live a day without 🙂
You can find it here: https://k9scli.io/. Just download and enjoy!

Tested on K9s v.0.31.9 and Ubuntu 20.04.4 LTS (WSL2)

Path based routing in a Kubernetes Ingress (Nginx)

Here we want to route traffic to different applications within our cluster with the help of paths. One advantage of this approach is that we only need one server certificate, since all traffic is going to use the same host.

We will focus on the Ingress here and not the Service object (every application that exposes services will need a Service object as a bridge between the application and the Ingress)

Example:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-application-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  ingressClassName: nginx
  rules:
 - host: my.domain.com
   http:
     paths:
     - path: /app-a/(.*)
       pathType: Prefix
       backend:
         service:
           name: my-app-a-service
           port:
             number: 8080  
     - path: /app-b/(.*)
       pathType: Prefix
       backend:
         service:
           name: my-app-b-service
           port:
             number: 8080

With the example configuration above we see that the following url’s are valid:

my.domain.com/app-a/ # will hit the root of my-app-a-service at "/"
my.domain.com/app-a/actuator/health # my-app-a-service at "/actuator/health"
my.domain.com/app-b/service # will route to my-app-b-service at "/service"

How does it work?
First we look at the paths: “/app-a/(.*)”. The “(.*)” part is a regular expression that means “match all characters after the slash (“/”) and put it into a group” .

A little higher up in the configuration we find “nginx.ingress.kubernetes.io/rewrite-target: /$1” annotation. This tells the Ingress that we should extract the first group (“$1”) and forward it to the backend Service. This is the way we remove the first part of the path (/app-a/). We only use this part to separate to what service the call should go and do not want it to follow the call to the backend. Everything after the last slash (“/”) is forwarded to the application, both url and any query parameters.

A nifty solution when you don’t need every service to be a separate domain

Tested on VMWare Tanzu Kubernetes v1.22