ungleich-user/deploy/k8s/base/deployment.yaml
Sajeyks 4eeb25a3ea Add Kubernetes manifests
A kustomize base with a Deployment (2 replicas, migrate_locked init
container, liveness, readiness and startup probes, uid 10001 with a
read-only root filesystem, all capabilities dropped, RuntimeDefault
seccomp, no service account token, resource requests and limits), plus
a Service, an Ingress for account.ungleich.ch, a PodDisruptionBudget
and a ConfigMap with every non-secret setting.

The Secret is not part of the base, so credentials stay out of git;
secret.example.yaml and the README show how to create it. The README
also lists what the cluster must provide and what to confirm before
going live (StartTLS on the LDAP servers, HSTS).
2026-11-06 15:53:50 +03:00

76 lines
2.3 KiB
YAML

apiVersion: apps/v1
kind: Deployment
metadata:
name: ungleich-user
spec:
replicas: 2
revisionHistoryLimit: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
spec:
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
seccompProfile:
type: RuntimeDefault
# Migrations run before the app starts; migrate_locked serializes
# them when several pods start at once.
initContainers:
- name: migrate
image: ungleich-user
command: ["python", "manage.py", "migrate_locked"]
envFrom: &env
- configMapRef:
name: ungleich-user
- secretRef:
name: ungleich-user
securityContext: &containerSecurity
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeMounts: &mounts
- name: tmp
mountPath: /tmp
resources:
requests: {cpu: 50m, memory: 128Mi}
limits: {memory: 256Mi}
containers:
- name: web
image: ungleich-user
envFrom: *env
ports:
- name: http
containerPort: 8000
securityContext: *containerSecurity
volumeMounts: *mounts
# Liveness has no dependencies, so an LDAP outage never restarts
# pods; readiness takes a pod out of the Service when the
# database or every LDAP server is unreachable.
livenessProbe:
httpGet: {path: /healthz, port: http}
periodSeconds: 20
timeoutSeconds: 3
failureThreshold: 3
readinessProbe:
httpGet: {path: /readyz, port: http}
periodSeconds: 10
timeoutSeconds: 10
failureThreshold: 3
startupProbe:
httpGet: {path: /healthz, port: http}
periodSeconds: 2
failureThreshold: 30
resources:
requests: {cpu: 100m, memory: 192Mi}
limits: {memory: 512Mi}
volumes:
- name: tmp
emptyDir:
sizeLimit: 64Mi