--- # ServiceAccount for the CronJob that monitors Redis secret changes apiVersion: v1 kind: ServiceAccount metadata: name: redis-restart-sa namespace: gitlab --- # Role to allow patching StatefulSets and reading Secrets apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: redis-restart-role namespace: gitlab rules: - apiGroups: ["apps"] resources: ["statefulsets"] verbs: ["get", "patch"] - apiGroups: [""] resources: ["secrets"] verbs: ["get"] - apiGroups: ["apps"] resources: ["statefulsets/status"] verbs: ["get"] --- # RoleBinding to grant permissions to the ServiceAccount apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: redis-restart-binding namespace: gitlab roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: redis-restart-role subjects: - kind: ServiceAccount name: redis-restart-sa namespace: gitlab --- # CronJob to monitor Redis secret and trigger StatefulSet restart on changes apiVersion: batch/v1 kind: CronJob metadata: name: redis-secret-monitor namespace: gitlab spec: # Run every hour to check for secret changes # This aligns with the 24-hour secret rotation schedule schedule: "*/60 * * * *" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 1 failedJobsHistoryLimit: 1 jobTemplate: spec: template: metadata: labels: app: redis-secret-monitor spec: serviceAccountName: redis-restart-sa restartPolicy: OnFailure containers: - name: monitor image: docker.io/alpine/k8s:1.32.13 securityContext: runAsUser: 10000 runAsGroup: 10000 runAsNonRoot: true allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: ["ALL"] seccompProfile: type: RuntimeDefault volumeMounts: - name: tmp mountPath: /tmp command: - /bin/bash - -c - | set -e # Get current secret version SECRET_VERSION=$(kubectl get secret -n gitlab redis-gitlab-secret -o jsonpath='{.metadata.resourceVersion}') # Get last known secret version from StatefulSet annotation LAST_VERSION=$(kubectl get statefulset -n gitlab redis-gitlab -o jsonpath='{.spec.template.metadata.annotations.secret-version/redis-password}' 2>/dev/null || echo "") echo "Current secret version: $SECRET_VERSION" echo "Last known version: $LAST_VERSION" # If versions differ, restart StatefulSet if [ "$SECRET_VERSION" != "$LAST_VERSION" ]; then echo "Secret has changed! Updating StatefulSet with new version annotation..." # Patch StatefulSet with new secret version annotation # This will trigger a rolling restart of the Redis pod kubectl patch statefulset -n gitlab redis-gitlab -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"secret-version/redis-password\":\"$SECRET_VERSION\",\"restarted-at\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}}}}}" echo "StatefulSet will now perform a rolling restart to pick up the new password." else echo "Secret has not changed. No restart needed." fi volumes: - name: tmp emptyDir: {}