Files
net-kingdom/sso-mfa/k8s/privacyidea/deployment.yaml
Bernd Worsch bececac7b8 fix(privacyidea): correct image to ghcr.io/gpappsoft, port 5001→8080
privacyidea/privacyidea:3.12 and privacyidea/otpserver:3.12.2 do not
exist on Docker Hub. Correct image is ghcr.io/gpappsoft/privacyidea-docker:3.12.2
which listens on port 8080.

Update all port references: deployment, service, ingress, netpol-mfa,
netpol-sso (keycape→privacyIDEA egress rule).

Also: creds-bootstrap-agent.sh — restart privacyIDEA deployment after
applying new secrets so the pod picks up updated env vars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 09:37:38 +00:00

150 lines
5.5 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Deployment + Service — privacyIDEA (namespace: mfa)
#
# Prerequisites (apply in order):
# 1. pvc.yaml — privacyidea-data and privacyidea-logs PVCs
# 2. configmap.yaml — privacyidea-cfg (pi.cfg template)
# 3. create-secrets.sh — privacyidea-config Secret (PI_SECRET_KEY, PI_PEPPER, DB URI)
# 4. This file
#
# After first pod starts successfully:
# 5. enckey-bootstrap.sh — extract enckey + audit keys, create DR Secrets
# 6. bootstrap-admin.sh — create pi-admin (+ MFA enrolment) and trigger-admin
#
# Container port: 8080.
# ghcr.io/gpappsoft/privacyidea-docker listens on port 8080 (gunicorn).
apiVersion: apps/v1
kind: Deployment
metadata:
name: privacyidea
namespace: mfa
labels:
app.kubernetes.io/name: privacyidea
app.kubernetes.io/part-of: net-kingdom-sso-mfa
net-kingdom/component: mfa
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: privacyidea
strategy:
type: Recreate # single-node — avoid split-brain on PVC
template:
metadata:
labels:
app.kubernetes.io/name: privacyidea
app.kubernetes.io/part-of: net-kingdom-sso-mfa
net-kingdom/component: mfa
spec:
# ── Security context ───────────────────────────────────────────────────
securityContext:
runAsNonRoot: false # privacyIDEA nginx needs root to bind port; revisit
fsGroup: 999 # privacyidea group inside container
# ── Init: ensure log dir exists and has correct permissions ───────────
initContainers:
- name: init-logdir
image: busybox:1.36
command: ["sh", "-c", "mkdir -p /var/log/privacyidea && chmod 777 /var/log/privacyidea"]
volumeMounts:
- name: logs
mountPath: /var/log/privacyidea
containers:
- name: privacyidea
# Pin to a specific release; update via image update policy.
# Official image: https://github.com/gpappsoft/privacyidea-docker
# privacyidea/privacyidea:3.12 and privacyidea/otpserver:3.12.2 do not exist.
# Correct image: ghcr.io/gpappsoft/privacyidea-docker:3.12.2 (port 8080)
image: ghcr.io/gpappsoft/privacyidea-docker:3.12.2
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080
protocol: TCP
# ── Environment — sensitive values from Secret ──────────────────
envFrom:
- secretRef:
name: privacyidea-config
# ── Volume mounts ───────────────────────────────────────────────
volumeMounts:
# pi.cfg overlaid into the data PVC as a single file (subPath).
- name: config
mountPath: /etc/privacyidea/pi.cfg
subPath: pi.cfg
readOnly: true
# Data PVC: enckey, audit keys, scripts, and other PI runtime files.
- name: data
mountPath: /etc/privacyidea
# Logs PVC: persistent application logs.
- name: logs
mountPath: /var/log/privacyidea
# ── Probes ──────────────────────────────────────────────────────
# Startup probe: give PI up to 3 min to run DB migrations on first boot.
startupProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 18 # 18 × 10s = 3 min
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 0
periodSeconds: 15
failureThreshold: 3
readinessProbe:
httpGet:
path: /token/
port: 8080
initialDelaySeconds: 0
periodSeconds: 10
failureThreshold: 3
# ── Resources ───────────────────────────────────────────────────
# Raise limits for production; privacyIDEA handles crypto and DB queries.
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
# ── Volumes ─────────────────────────────────────────────────────────
volumes:
- name: config
configMap:
name: privacyidea-cfg
- name: data
persistentVolumeClaim:
claimName: privacyidea-data
- name: logs
persistentVolumeClaim:
claimName: privacyidea-logs
---
# Service — ClusterIP; Traefik and Keycloak reach privacyIDEA via this.
apiVersion: v1
kind: Service
metadata:
name: privacyidea
namespace: mfa
labels:
app.kubernetes.io/name: privacyidea
app.kubernetes.io/part-of: net-kingdom-sso-mfa
net-kingdom/component: mfa
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: privacyidea
ports:
- name: http
port: 8080
targetPort: 8080
protocol: TCP