Skip to content

Commit 8f4f0a1

Browse files
committed
create a helm chart
1 parent 86daa4e commit 8f4f0a1

File tree

20 files changed

+779
-201
lines changed

20 files changed

+779
-201
lines changed

.envrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/bash
2+
3+
# Automatically sets up your devbox environment whenever you cd into this
4+
# directory via our direnv integration:
5+
6+
eval "$(devbox generate direnv --print-envrc)"
7+
8+
# check out https://www.jetify.com/docs/devbox/ide_configuration/direnv/
9+
# for more details

.github/workflows/ci.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
pull_request:
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: read
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
17+
- name: Install devbox
18+
uses: jetify-com/devbox-install-action@v0.14.0
19+
20+
- name: Install project dependencies
21+
run: devbox install
22+
23+
- name: Helm lint
24+
run: devbox run lint
25+
26+
- name: Kind end-to-end test
27+
env:
28+
CLUSTER_NAME: ci-evict-rollout
29+
run: devbox run test
30+

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.devbox

README.md

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,50 @@ export DRY_RUN=true
5555
./evict_to_rollout.sh
5656
```
5757

58-
### 3. Deploy as CronJob
58+
## Deployment Options
5959

60-
See `cronjob.yaml` for the full manifest including RBAC permissions.
60+
### Helm (recommended)
61+
62+
This repository ships a Helm chart (`chart/evict-to-rollout`) so you can tweak the schedule, annotation selector, and naming without forking the manifest.
63+
64+
```bash
65+
helm upgrade --install evict-to-rollout \
66+
oci://ghcr.io/cornerman/charts/evict-to-rollout \
67+
--version 0.1.0 \
68+
--namespace kube-system --create-namespace \
69+
--set schedule="*/2 * * * *" \
70+
--set annotationSelector.key="evict-with-rollout" \
71+
--set annotationSelector.value="true"
72+
```
73+
74+
Key values:
75+
76+
| Value | Description | Default |
77+
| --- | --- | --- |
78+
| `schedule` | Cron expression for how often to scan nodes | `*/1 * * * *` |
79+
| `annotationSelector.key`/`.value` | Annotation pair that marks pods for rollout | `evict-with-rollout` / `true` |
80+
| `image.repository` / `.tag` | Container image that provides `kubectl` + `jq` | `us.gcr.io/k8s-artifacts-prod/kubectl` / `v1.29.4` |
81+
| `serviceAccount.create` | Whether to create a dedicated SA | `true` |
82+
| `rbac.create` | Whether to install ClusterRole + binding | `true` |
83+
84+
See `chart/evict-to-rollout/values.yaml` for the full list.
85+
86+
## Development & Testing
87+
88+
This repo ships a `devbox.json` so everyone (including CI) uses the same versions of `helm`, `kubectl`, `kind`, and `jq`.
89+
90+
```bash
91+
# Start a dev shell with all tools:
92+
devbox shell
93+
94+
# Lint the chart:
95+
devbox run lint
96+
97+
# Run the end-to-end test (requires Docker since it spins up kind):
98+
devbox run test
99+
```
100+
101+
The test script (`scripts/test-kind.sh`) creates a 3-node kind cluster, installs the Helm chart, deploys a sample annotated app, cordons a node, runs the controller job manually, and asserts that the deployment was restarted and rescheduled onto a different node.
102+
103+
GitHub Actions mirrors the same flow via `.github/workflows/ci.yaml`, so every PR runs `helm lint` plus the integration test automatically.
61104

chart/evict-to-rollout/Chart.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
apiVersion: v2
2+
name: evict-to-rollout
3+
description: Trigger rollout restarts for annotated workloads before draining nodes
4+
type: application
5+
version: 0.1.0
6+
appVersion: "0.1.0"
7+
keywords:
8+
- kubernetes
9+
- availability
10+
- eviction
11+
- pdb
12+
- cronjob
13+
maintainers:
14+
- name: Cornerman
15+
url: https://github.com/cornerman
16+
sources:
17+
- https://github.com/cornerman/evict-to-rollout
18+
home: https://github.com/cornerman/evict-to-rollout
19+
20+

evict_to_rollout.sh renamed to chart/evict-to-rollout/files/evict_to_rollout.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
set -euo pipefail
33

44
# Configuration
5-
ANNOTATION_KEY="evict-with-rollout"
6-
ANNOTATION_VALUE="true"
5+
ANNOTATION_KEY=${ANNOTATION_KEY:-"evict-with-rollout"}
6+
ANNOTATION_VALUE=${ANNOTATION_VALUE:-"true"}
77
DRY_RUN=${DRY_RUN:-false} # Set to true to print actions without executing
88

99
log() {
@@ -116,3 +116,5 @@ for NODE in $NODES; do
116116
done
117117

118118
log "Done."
119+
120+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
To verify your installation:
2+
1. Check the CronJob status:
3+
kubectl get cronjob {{ include "evict-to-rollout.fullname" . }} -n {{ .Release.Namespace }}
4+
2. Inspect the latest job/pod logs:
5+
kubectl logs job/$(kubectl get jobs -n {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} -o jsonpath='{.items[-1:].metadata.name}') -n {{ .Release.Namespace }}
6+
7+
To trigger a dry run manually:
8+
kubectl create job --from=cronjob/{{ include "evict-to-rollout.fullname" . }} evict-to-rollout-debug -n {{ .Release.Namespace }} \
9+
--dry-run=client -o yaml | kubectl apply -f -
10+
11+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{{- define "evict-to-rollout.name" -}}
2+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
3+
{{- end -}}
4+
5+
{{- define "evict-to-rollout.fullname" -}}
6+
{{- if .Values.fullnameOverride -}}
7+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
8+
{{- else -}}
9+
{{- $name := default .Chart.Name .Values.nameOverride -}}
10+
{{- if contains $name .Release.Name -}}
11+
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
12+
{{- else -}}
13+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
14+
{{- end -}}
15+
{{- end -}}
16+
{{- end -}}
17+
18+
{{- define "evict-to-rollout.serviceAccountName" -}}
19+
{{- if .Values.serviceAccount.create -}}
20+
{{- if .Values.serviceAccount.name -}}
21+
{{- .Values.serviceAccount.name | trunc 63 | trimSuffix "-" -}}
22+
{{- else -}}
23+
{{- printf "%s-sa" (include "evict-to-rollout.fullname" .) | trunc 63 | trimSuffix "-" -}}
24+
{{- end -}}
25+
{{- else -}}
26+
{{- .Values.serviceAccount.name | default "default" -}}
27+
{{- end -}}
28+
{{- end -}}
29+
30+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{{- if .Values.rbac.create }}
2+
apiVersion: rbac.authorization.k8s.io/v1
3+
kind: ClusterRole
4+
metadata:
5+
name: {{ printf "%s-role" (include "evict-to-rollout.fullname" .) | trunc 63 | trimSuffix "-" }}
6+
labels:
7+
app.kubernetes.io/name: {{ include "evict-to-rollout.name" . }}
8+
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
9+
app.kubernetes.io/instance: {{ .Release.Name }}
10+
app.kubernetes.io/managed-by: {{ .Release.Service }}
11+
rules:
12+
- apiGroups: [""]
13+
resources: ["nodes"]
14+
verbs: ["get", "list", "watch"]
15+
- apiGroups: [""]
16+
resources: ["pods"]
17+
verbs: ["get", "list", "watch"]
18+
- apiGroups: ["apps"]
19+
resources: ["replicasets"]
20+
verbs: ["get", "list"]
21+
- apiGroups: ["apps"]
22+
resources: ["deployments"]
23+
verbs: ["get", "list", "patch"]
24+
{{- end }}
25+
26+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{{- if .Values.rbac.create }}
2+
apiVersion: rbac.authorization.k8s.io/v1
3+
kind: ClusterRoleBinding
4+
metadata:
5+
name: {{ printf "%s-binding" (include "evict-to-rollout.fullname" .) | trunc 63 | trimSuffix "-" }}
6+
labels:
7+
app.kubernetes.io/name: {{ include "evict-to-rollout.name" . }}
8+
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
9+
app.kubernetes.io/instance: {{ .Release.Name }}
10+
app.kubernetes.io/managed-by: {{ .Release.Service }}
11+
subjects:
12+
- kind: ServiceAccount
13+
name: {{ include "evict-to-rollout.serviceAccountName" . }}
14+
namespace: {{ .Release.Namespace }}
15+
roleRef:
16+
apiGroup: rbac.authorization.k8s.io
17+
kind: ClusterRole
18+
name: {{ printf "%s-role" (include "evict-to-rollout.fullname" .) | trunc 63 | trimSuffix "-" }}
19+
{{- end }}
20+
21+

0 commit comments

Comments
 (0)