DEV Community

Cover image for Set node affinity to all pods in a namespace
Ivan Genchev
Ivan Genchev

Posted on

Set node affinity to all pods in a namespace

Recently I had to install a fairly large system on an existing k8s cluster and make sure its pods run only on specific nodes. Initially I thought to myself, the PodNodeAffinity plugin will do that for me easy! The bad news is, that’s not available on GKE (or EKS for that matter) and that's what I was using. I started googling around as I was sure that there must be an alternative for this, but the only thing I managed to find were a few very old, unanswered questions on stack overflow :(
As I have not worked on any open-source projects outside of work in quite a while and really wanted to publish something, that stuck out as a good problem to solve! That's how I ended up creating the Namespace Node Affinity mutating webhook.

Implementation

Using a mutating webhook sounded like a good solution to that problem - just inject the nodeAffinity as pods are created. I wanted to create the easiest possible to use, plug-and-play solution, so I decided to include an init container with the webhook that can create the mutating webhook configuration, the certificate authority and the self-signed certificates. I have not dealt with creating CAs and signing certificates in golang before, but there were some excellent guides around the web such as this one from Shane Utt which made it fairly easy to learn and implement :)

Most of the interesting things happen in the affinityinjector package, which deals with the AdmissionReviews. The AffinityInjector reads the k8s object from the admission review request, then reads the configuration for the object's namespace and constructs the admission review response with the patched object.

Build

I always wanted to try the GitHub actions, but never had the chance before as they never seemed like a good fit for the projects I've been working on recently or I had to stick to some existing build system. Using them for my personal open source project seemed like the perfect chance to try them! Overall I really enjoyed using them and it seems like the marketplace is full of useful tools! The only thing that I found annoying was that there are still some bugs for scenarios that in my opinion come up quite often. For example workflow_run is not working at all for tags. Initially I wanted to set up two separate workflows, one to run the tests and another for building the docker images and pushing them to Docker Hub. At the end I ended up combining them and the docker job is just skipped for pull requests now with if: ${{ github.event_name != 'pull_request' }}. That worked out great as it seems enough to run the CI/CD only on master, tags and PRs anyway and it seems like a good idea to build and push images to Docker Hub on changes to master and when tags are created. I will definitely continue exploring GitHub actions more and will write up another post to share my findings :)

I hope you found that post and the Namespace Node Affinity tool useful!

Top comments (0)