|
| 1 | +# vault-operator-helper |
| 2 | + |
| 3 | +A small sidecar that keeps a ConfigMap in sync with the set of namespaces |
| 4 | +matching a label selector, and restarts a co-located "main" container whenever |
| 5 | +that set changes. |
| 6 | + |
| 7 | +It is intended to run alongside a container (such as Vault) that reads a |
| 8 | +comma-separated list of namespaces from a ConfigMap (for example via a |
| 9 | +`WATCH_NAMESPACE` key) and only picks up changes on restart. |
| 10 | + |
| 11 | +## How it works |
| 12 | + |
| 13 | +1. On startup it builds a Kubernetes client (in-cluster config, falling back to |
| 14 | + a local kubeconfig). |
| 15 | +2. It starts a shared informer that watches **namespaces** matching |
| 16 | + `--label-selector`. |
| 17 | +3. Whenever a matching namespace is added, updated, or deleted, it recomputes |
| 18 | + the sorted namespace list and writes it to the ConfigMap under |
| 19 | + `--watch-key`. |
| 20 | +4. If (and only if) the value actually changed, it sends `SIGTERM` to the main |
| 21 | + container's process so it reloads the new configuration. |
| 22 | + |
| 23 | +The namespace list is read from the informer's in-memory cache (no extra API |
| 24 | +calls per event) and sorted, so the ConfigMap value is stable and does not |
| 25 | +flip — and trigger needless restarts — due to cache iteration order. |
| 26 | + |
| 27 | +## Flags |
| 28 | + |
| 29 | +| Flag | Default | Description | |
| 30 | +| --- | --- | --- | |
| 31 | +| `-configmap-name` | `watch-namespace-config` | Name of the ConfigMap to update | |
| 32 | +| `-configmap-namespace` | `vault` | Namespace of the ConfigMap | |
| 33 | +| `-label-selector` | `foo=bar` | Label selector for namespaces to watch | |
| 34 | +| `-watch-key` | `WATCH_NAMESPACE` | Key in the ConfigMap holding the namespace list | |
| 35 | +| `-main-container` | `main-container` | Process name of the main container to restart | |
| 36 | +| `-health-addr` | `:8081` | Address for the liveness probe server | |
| 37 | + |
| 38 | +## Health probe |
| 39 | + |
| 40 | +The process serves a liveness endpoint on `--health-addr`: |
| 41 | + |
| 42 | +- `GET /healthz` — returns `200` once the process is running. |
| 43 | + |
| 44 | +Example probe configuration: |
| 45 | + |
| 46 | +```yaml |
| 47 | +livenessProbe: |
| 48 | + httpGet: |
| 49 | + path: /healthz |
| 50 | + port: 8081 |
| 51 | +``` |
| 52 | +
|
| 53 | +## Deployment notes |
| 54 | +
|
| 55 | +### Shared process namespace |
| 56 | +
|
| 57 | +The restart works by signalling the main container's process directly, so the |
| 58 | +two containers must share a process namespace. Set this on the pod spec: |
| 59 | +
|
| 60 | +```yaml |
| 61 | +spec: |
| 62 | + shareProcessNamespace: true |
| 63 | +``` |
| 64 | +
|
| 65 | +`-main-container` must match a string in the target process's command line. |
| 66 | + |
| 67 | +### Running as root |
| 68 | + |
| 69 | +The helper signals a process that belongs to another container. Across a shared |
| 70 | +process namespace this generally requires matching privileges, so the image |
| 71 | +runs as root by design. Switching to an unprivileged user will break the |
| 72 | +restart on most setups. |
| 73 | + |
| 74 | +### RBAC |
| 75 | + |
| 76 | +The helper needs to list namespaces and to get/create/update the ConfigMap. |
| 77 | +A minimal example: |
| 78 | + |
| 79 | +```yaml |
| 80 | +apiVersion: rbac.authorization.k8s.io/v1 |
| 81 | +kind: ClusterRole |
| 82 | +metadata: |
| 83 | + name: vault-operator-helper |
| 84 | +rules: |
| 85 | + - apiGroups: [""] |
| 86 | + resources: ["namespaces"] |
| 87 | + verbs: ["get", "list", "watch"] |
| 88 | +--- |
| 89 | +apiVersion: rbac.authorization.k8s.io/v1 |
| 90 | +kind: Role |
| 91 | +metadata: |
| 92 | + name: vault-operator-helper |
| 93 | + namespace: vault |
| 94 | +rules: |
| 95 | + - apiGroups: [""] |
| 96 | + resources: ["configmaps"] |
| 97 | + verbs: ["get", "create", "update"] |
| 98 | +``` |
| 99 | + |
| 100 | +Bind both to the ServiceAccount used by the pod. |
| 101 | + |
| 102 | +## Image |
| 103 | + |
| 104 | +Images are published to `ghcr.io/hsiaoairplane/vault-operator-helper`. |
| 105 | + |
| 106 | +## Development |
| 107 | + |
| 108 | +```sh |
| 109 | +make fmt # gofmt |
| 110 | +make vet # go vet |
| 111 | +make test # go test |
| 112 | +make build # build the binary (-race) |
| 113 | +``` |
0 commit comments