wildduck: fix cert renewal

This commit is contained in:
2026-07-21 15:55:30 +03:00
parent edceeabd31
commit 636e0f72cc
2 changed files with 90 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
---
# WildDuck and ZoneMTA read the mounted wildduck-tls cert into an in-memory
# TLS cache at startup and never re-read it, so after cert-manager renews the
# secret, long-lived pods keep serving the boot-time cert until restarted
# (IMAP/submission served an expired cert on 2026-07-21). Haraka watches the
# cert files and reloads on its own, but is stamped too for a uniform
# guarantee.
#
# This CronJob stamps a hash of the current cert onto the pod templates:
# unchanged hash is a no-op (k8s only rolls when the template changes), a
# changed cert triggers a rollout. Idempotent and self-healing.
apiVersion: v1
kind: ServiceAccount
metadata:
name: wildduck-cert-reconciler
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: wildduck-cert-reconciler
rules:
# Enough to patch the pod template annotation on the mail-server deployments.
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: wildduck-cert-reconciler
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: wildduck-cert-reconciler
subjects:
- kind: ServiceAccount
name: wildduck-cert-reconciler
namespace: wildduck
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: wildduck-cert-reconciler
spec:
# cert-manager renews ~30 days before expiry; daily is plenty to pick up.
schedule: "17 3 * * *"
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 3
concurrencyPolicy: Forbid
jobTemplate:
spec:
backoffLimit: 2
ttlSecondsAfterFinished: 86400
template:
spec:
serviceAccountName: wildduck-cert-reconciler
restartPolicy: OnFailure
containers:
- name: reconcile
image: mirror.gcr.io/library/alpine:3.19
command:
- sh
- -euc
- |
apk add --no-cache curl >/dev/null
CERT_HASH=$(sha256sum /cert/tls.crt | cut -c1-16)
echo "Cert content hash: $CERT_HASH"
APISERVER=https://kubernetes.default.svc
SA=/var/run/secrets/kubernetes.io/serviceaccount
KTOKEN=$(cat "$SA/token")
for DEP in wildduck zonemta haraka; do
curl -fsS --cacert "$SA/ca.crt" \
-H "Authorization: Bearer $KTOKEN" \
-H "Content-Type: application/strategic-merge-patch+json" \
-X PATCH \
"$APISERVER/apis/apps/v1/namespaces/wildduck/deployments/$DEP" \
--data '{"spec":{"template":{"metadata":{"annotations":{"k-space.ee/wildduck-tls-hash":"'"$CERT_HASH"'"}}}}}' \
>/dev/null
echo " stamped $DEP (rolls only if hash changed)"
done
echo "done"
volumeMounts:
- name: cert
mountPath: /cert
readOnly: true
volumes:
- name: cert
secret:
secretName: wildduck-tls