Sidecar to watch a config folder and reload a process when it changes

config-reloader-sidecar

A small (3MB uncompressed docker image), efficient (via inotify) sidecar to trigger application reloads when configuration changes.

Rationale

A fairly common way to implement configuration hot-reloading is to have the app re-read configuration files when receiving a specific unix signal, usually SIGHUP.

Applications using this method include:

In Kubernetes, the "recommended" / usual way of managing configuration is instead to:

  • Have a ConfigMap (or Secret) holding the configuration
  • When it changes, trigger a rolling-upgrade of the matching Deployment or DaemonSet

While this method is great to ensure configuration changes are highly visible and ensures all replicas use the same config (see immutable infrastructure), it is best for stateless apps which can easily handle rolling upgrades.

Stateful apps, by contrast, might be better off reloading their config so as to not disrupt long-lived open connections, or not to incur a long restart time.

In Kubernetes, an upgrade to a ConfigMap or Secret is eventually (note: see gotchas) propagated to the running Pods, meaning we can watch configuration loaded via ConfigMaps or Secrets and send a signal to the main app when it changes, triggering a hot reload.

The config-reloader-sidecar exists specifically for that use case!

How it works

config-reloader-sidecar uses Go's fsnotify package to watch one (or more) configuration folders, and send a signal to a process when any change is detected within that folder. This includes file created, file updated, file renamed & file deleted, but excludes file permissions changes.

config-reloader-sidecar needs to run, as the name implies, as a separate container in the same Pod as the application you want to reload, i.e. a sidecar.

In addition, you'll need to set shareProcessNamespace: true on your Pod to send signals across containers.

config-reloader-sidecar is then configured through the following env vars:

  • CONFIG_DIR: comma-separated list of configuration directories to watch (mandatory)
  • PROCESS_NAME: process to send the signal to (mandatory)
  • RELOAD_SIGNAL: signal to send (optional, defaults to SIGHUP)

Example Pod configuration

apiVersion: v1
kind: Pod
metadata:
  name: auto-reloading-pgbouncer
spec:
  shareProcessNamespace: true
  containers:
  - name: pgbouncer
    image: bitnami/pgbouncer:latest
    command:
    - pgbouncer
    args:
    - /etc/pgbouncer/pgbouncer.ini
    volumeMounts:
    - mountPath: /etc/pgbouncer/
      name: secret-volume
  - name: config-reloader-sidecar
    image: some-private-repo.example.com/config-reloader-sidecar # Note: this isn't yet available on the Docker hub!
    env:
    - name: CONFIG_DIR
      value: /etc/pgbouncer/
    - name: PROCESS_NAME
      value: pgbouncer
    volumeMounts:
    - mountPath: /etc/pgbouncer/
      name: secret-volume
  volumes:
  - name: secret-volume
    secret:
      secretName: pgbouncer-secret

Gotchas

Share Process Namespace

In order for the sidecar to find which process to send the signal to, the Pod needs to be configured to Share Process Namespace with shareProcessNamespace: true.

Update speed

You might noticed when editing a Secret or ConfigMap that your process isn't being reloaded immediately.

This is because the projected values of ConfigMaps and Secrets are not updated exactly when the underlying object changes, but instead they're updated periodically according to the syncFrequency argument to the kubelet config. This defaults to 1 minute.

Config files mounted via subPath are never updated

This is a long-standing Kubernetes issue: ConfigMap and Secrets mounted as files with a subPath key do not get updated by the kubelet. See issue #50345 on Github.

The (pretty ugly) workaround involves mounting the secret/configmap without subPath in a different folder and manually creating a symlink from an initContainer ahead of time to that folder, or if possible at all switching to not using subPath.

Similar Resources

A lightweight yet powerful config package for Go projects

Config GoLobby Config is a lightweight yet powerful config package for Go projects. It takes advantage of env files and OS variables alongside config

Dec 11, 2022

go implementation of lightbend's HOCON configuration library https://github.com/lightbend/config

HOCON (Human-Optimized Config Object Notation) Configuration library for working with the Lightbend's HOCON format. HOCON is a human-friendly JSON sup

Dec 3, 2022

🔥🔥 🌈 Golang configuration,use to Viper reading from remote Nacos config systems. Viper remote for Naocs.

Viper remote for Nacos Golang configuration,use to Viper reading from remote Nacos config systems. Viper remote for Naocs. runtime_viper := viper.New(

Dec 6, 2022

create a bootable disk image from Docker image or a yaml config

docker2boot docker2boot creates a bootable disk from either a Docker image or a config yaml file Features status dns Y cloud-init Y network Y ssh TODO

Oct 30, 2022

Nacos is a service config & discovery.

Kratos Nacos example sc := []constant.ServerConfig{ *constant.NewServerConfig("127.0.0.1", 8848), } cc := &constant.ClientConfig{ NamespaceId:

Oct 28, 2021

Little Go tool to infer an uncrustify config file from an expected format

uncrustify-infer Little Go tool to infer an uncrustify config file from an expected format Install This tool relies on an uncrustify executable, you m

Oct 8, 2021

Ewwwwwww - Yuck Config

Ewwwwwww - Yuck Config

Eww Config What is it Using Eww Widgets to create a replacement for my bumblebee-status bars in i3 Window Manager. Eww allows you to create widgets an

Dec 29, 2022

A lightweight config center written by golang.

A lightweight config center written by golang.

Jan 21, 2022

Project my config into your prebuild

Projector A simple key value store per path. Building From Source git clone [email protected]:ThePrimeagen/projector.git cd projector # Install it where

Jun 23, 2022
Comments
  • Adding a license

    Adding a license

    Hello Florent,

    Thanks you for sharing this project publicly. It could be useful for us but we need to know on which license this repository is under. Could you explicitly add one ?

    There is a well made guide for this on https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/adding-a-license-to-a-repository.

    For exemple, one of the most used one is the MIT license (https://choosealicense.com/licenses/mit/).

    Again thanks a lot

Go-config - Config parser for go that supports environment vars and multiple yaml files

go-multiconfig This package is able to parse yaml config files. It supports gett

Jun 23, 2022
Ambiente com Docker de "live-reload" para aplicações Go

Ambiente Go Um ambiente de "live reload", onde as alterações no código são observadas e re-executadas automaticamente, com Docker e Docker Compose. O

Jun 17, 2022
Harvest configuration, watch and notify subscriber

Harvester Harvester is a configuration library which helps setting up and monitoring configuration values in order to dynamically reconfigure your app

Dec 26, 2022
Simple, useful and opinionated config loader.

aconfig Simple, useful and opinionated config loader. Rationale There are many solutions regarding configuration loading in Go. I was looking for a si

Dec 26, 2022
Composable, observable and performant config handling for Go for the distributed processing era

Konfig Composable, observable and performant config handling for Go. Written for larger distributed systems where you may have plenty of configuration

Dec 11, 2022
Viper wrapper with config inheritance and key generation

piper - Simple Wrapper For Viper Single Source of Truth Generated Key Structs, No Typo Config Inheritance Multiple Config Strategies Support Cache For

Sep 26, 2022
Quick and easy way to load config files based on a simple set of rules.
Quick and easy way to load config files based on a simple set of rules.

config Quick and easy way to load config files based on a simple set of rules. Project inspired by https://github.com/lorenwest/node-config Important

Apr 9, 2021
Gonfigure - Read and write config files in go

Gonfigure Reads ini files in golang. Reading INI Files Load file File can be loa

Jan 27, 2022
Jul 4, 2022