refactor(kubernetes): extract wait-for-kubeconfig init into shared helper
The three control-plane-side Deployments (cluster-autoscaler, kccm, kcsi-controller) carried three copies of the same 20-line init container. That already drifted: the CSI copy used 4-space nesting while the other two used 2-space. Any future update to the image, the deadline, or the poll script had to land in three places or silently diverge. Extract the block into a new kubernetes.waitForAdminKubeconfig helper in templates/_helpers.tpl and include it at each call site. Tighten the deadline from 20m to 10m so it stays strictly below the 15m HelmRelease Install.Timeout and the CrashLoopBackOff surfaces in dashboards before flux remediation can fire. Also clarify the wait message so operators debugging a stuck init container do not chase Kamaji for what is actually kubelet's optional-Secret refresh cadence. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la>
This commit is contained in:
parent
b38ae60549
commit
1757567218
4 changed files with 43 additions and 60 deletions
|
|
@ -49,3 +49,43 @@ Selector labels
|
|||
app.kubernetes.io/name: {{ include "kubernetes.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
wait-for-kubeconfig init container shared by the control-plane-side
|
||||
Deployments (cluster-autoscaler, kccm, kcsi-controller) that mount the
|
||||
*-admin-kubeconfig Secret provisioned asynchronously by Kamaji. The
|
||||
Secret volume is declared optional so kubelet does not FailedMount while
|
||||
Kamaji is still bootstrapping; this container polls the mounted path and
|
||||
exits only when super-admin.svc appears, which happens after kubelet's
|
||||
optional-Secret refresh cycle.
|
||||
|
||||
The 10m deadline stays strictly below the 15m HelmRelease
|
||||
Install.Timeout scoped to the Kubernetes Application kind so the
|
||||
CrashLoopBackOff surfaces before flux remediation fires and uninstalls
|
||||
the Cluster CR.
|
||||
|
||||
Call site owns the surrounding volumes block; the kubeconfig volume
|
||||
must exist on the pod and mount at /etc/kubernetes/kubeconfig.
|
||||
*/}}
|
||||
{{- define "kubernetes.waitForAdminKubeconfig" -}}
|
||||
- name: wait-for-kubeconfig
|
||||
image: "{{ .Files.Get "images/busybox.tag" | trim }}"
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
set -eu
|
||||
deadline=$(( $(date +%s) + 600 ))
|
||||
until [ -s /etc/kubernetes/kubeconfig/super-admin.svc ]; do
|
||||
if [ "$(date +%s)" -ge "$deadline" ]; then
|
||||
echo "admin kubeconfig was not provisioned within 10m; exiting so the pod goes CrashLoopBackOff and surfaces in dashboards" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "waiting for admin kubeconfig (provisioned by Kamaji, visible after kubelet Secret refresh)..."
|
||||
sleep 5
|
||||
done
|
||||
volumeMounts:
|
||||
- name: kubeconfig
|
||||
mountPath: /etc/kubernetes/kubeconfig
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
|
|
|
|||
|
|
@ -24,26 +24,7 @@ spec:
|
|||
operator: Exists
|
||||
effect: "NoSchedule"
|
||||
initContainers:
|
||||
- name: wait-for-kubeconfig
|
||||
image: "{{ $.Files.Get "images/busybox.tag" | trim }}"
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
set -eu
|
||||
deadline=$(( $(date +%s) + 1200 ))
|
||||
until [ -s /etc/kubernetes/kubeconfig/super-admin.svc ]; do
|
||||
if [ "$(date +%s)" -ge "$deadline" ]; then
|
||||
echo "admin kubeconfig was not provisioned within 20m; exiting so the pod goes CrashLoopBackOff and surfaces in dashboards" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "waiting for admin kubeconfig to be provisioned by Kamaji..."
|
||||
sleep 5
|
||||
done
|
||||
volumeMounts:
|
||||
- name: kubeconfig
|
||||
mountPath: /etc/kubernetes/kubeconfig
|
||||
readOnly: true
|
||||
{{- include "kubernetes.waitForAdminKubeconfig" $ | nindent 6 }}
|
||||
containers:
|
||||
- image: "{{ $.Files.Get "images/cluster-autoscaler.tag" | trim }}"
|
||||
name: cluster-autoscaler
|
||||
|
|
|
|||
|
|
@ -25,26 +25,7 @@ spec:
|
|||
operator: Exists
|
||||
effect: "NoSchedule"
|
||||
initContainers:
|
||||
- name: wait-for-kubeconfig
|
||||
image: "{{ $.Files.Get "images/busybox.tag" | trim }}"
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
set -eu
|
||||
deadline=$(( $(date +%s) + 1200 ))
|
||||
until [ -s /etc/kubernetes/kubeconfig/super-admin.svc ]; do
|
||||
if [ "$(date +%s)" -ge "$deadline" ]; then
|
||||
echo "admin kubeconfig was not provisioned within 20m; exiting so the pod goes CrashLoopBackOff and surfaces in dashboards" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "waiting for admin kubeconfig to be provisioned by Kamaji..."
|
||||
sleep 5
|
||||
done
|
||||
volumeMounts:
|
||||
- name: kubeconfig
|
||||
mountPath: /etc/kubernetes/kubeconfig
|
||||
readOnly: true
|
||||
{{- include "kubernetes.waitForAdminKubeconfig" $ | nindent 6 }}
|
||||
containers:
|
||||
- name: csi-driver
|
||||
imagePullPolicy: Always
|
||||
|
|
|
|||
|
|
@ -23,26 +23,7 @@ spec:
|
|||
operator: Exists
|
||||
effect: "NoSchedule"
|
||||
initContainers:
|
||||
- name: wait-for-kubeconfig
|
||||
image: "{{ $.Files.Get "images/busybox.tag" | trim }}"
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
set -eu
|
||||
deadline=$(( $(date +%s) + 1200 ))
|
||||
until [ -s /etc/kubernetes/kubeconfig/super-admin.svc ]; do
|
||||
if [ "$(date +%s)" -ge "$deadline" ]; then
|
||||
echo "admin kubeconfig was not provisioned within 20m; exiting so the pod goes CrashLoopBackOff and surfaces in dashboards" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "waiting for admin kubeconfig to be provisioned by Kamaji..."
|
||||
sleep 5
|
||||
done
|
||||
volumeMounts:
|
||||
- name: kubeconfig
|
||||
mountPath: /etc/kubernetes/kubeconfig
|
||||
readOnly: true
|
||||
{{- include "kubernetes.waitForAdminKubeconfig" $ | nindent 6 }}
|
||||
containers:
|
||||
- name: kubevirt-cloud-controller-manager
|
||||
args:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue