Kubernetes NGINX Ingress - Automating dynamic rules management

A few points to ensure you're interested in this argument.
  1. You set up a Kubernetes cluster where you deployed your brand new containerized application.
  2. You set up an NGINX based Ingress to expose it and manage TLS termination.
  3. You need to handle a lot of routing rules (growing from some to thousands) and, more important, you need automation.
I assume steps 1 and 2 are done, so let's dive in rules management and its automation.
The first option Kubernetes gives you is this cli command:

kubectl edit ingress <your_ingress_name>

An editor comes up you can modify the ingress resource, when you save the configuration is  automatically updated.
That's ok and really useful, but not suitable if you need automation, and a DevOps guy should automate everything! :-P
So I've found resources can also be patched, supplying a json string.
As an example you can create a file with json patch definition:

[{
    "op": "add",
    "path": "/spec/rules/-",
    "value": {
      "host": "<your_url>",
      "http": {
        "paths": [
          {
            "backend": {
              "serviceName": "<your_dest_service>",
              "servicePort": your_service_port 
            }
          }
        ]
      }
    }
}]

And apply it to your resource:

kubectl patch ingress <your_ingress> --type json -p "$(cat <your_json_file>"

This appends the new rule to rules array in ingress definition, see JSON Patch format details here.
The great advantage is that you focus on a single rule and the process can be easily automated.
I faced some more difficulties when I first tried to remove a rule.
Obviuosly you can edit the entire ingress definition, manually remove the lines regarding the rule to be removed and save.
But what about automation?
This is my solution using again Kubernetes' patching capabilities.
The main idea is to leverage the JSON Patch replace operation.
For instance this command removes the first rule from your Ingress:

kubectl patch ingress <your_ingress> --type json -p "[{\"op\": \"remove\", \"path\": \"/spec/rules/0\"}]"

Unfortunately JSON Patch supports only positional path for arrays, so my problem was to get the target rule position inside rules array.
I achieved that using jq command:

kubectl get ingress <your_ingress> -o json | jq ".spec.rules | map(.host == \"<url_to_be_removed>\") | index(true)"


So, putting all together, this Bash script does the trick:

#!/bin/bash
index=$(kubectl get ingress <your_ingress> -o json | jq ".spec.rules | map(.host == \"<url_to_be_removed>\") | index(true)");
kubectl patch ingress <your_ingress> --type json -p "[{\"op\": \"remove\", \"path\": \"/spec/rules/$index\"}]";


Now you can use this technique in your favourite automation environment.
As an example I've created a couple of Ansible roles, but the real work is done by Bash scripts (no Ansible modules available).


Commenti

Post popolari in questo blog

Jolie on Azure Functions

Gateway Consorzio Triveneto per WP e-commerce

FaaS - Fuffa as a Service [Prima parte]