feat: update kanidm replicaiton
- split to per-server configs - remove init containers that attempted to automate the replication config - add README.md
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
# kanidm
|
||||||
|
|
||||||
|
Single-replica kanidm identity server deployment.
|
||||||
|
|
||||||
|
## Initial setup
|
||||||
|
|
||||||
|
After the pod starts for the first time, generate the admin and idm_admin credentials:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl exec -n kanidm kanidm-0 -- /sbin/kanidmd recover-account admin
|
||||||
|
kubectl exec -n kanidm kanidm-0 -- /sbin/kanidmd recover-account idm_admin
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adding replication
|
||||||
|
|
||||||
|
If replication is needed in the future:
|
||||||
|
|
||||||
|
1. Scale the StatefulSet to 3 replicas and add `podAntiAffinity` to spread across nodes.
|
||||||
|
2. Add a `[replication]` section to `configmap.yaml` per pod (origin is pod-specific:
|
||||||
|
`repl://kanidm-N.kanidm-headless.kanidm.svc.cluster.local:8444`).
|
||||||
|
3. Add the replication port (8444) back to the StatefulSet container ports and headless service.
|
||||||
|
4. Restore `rbac.yaml` for the cert-publisher sidecar, or exchange certificates manually:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# On each pod, get its replication certificate
|
||||||
|
kubectl exec -n kanidm kanidm-0 -- /sbin/kanidmd renew-replication-certificate
|
||||||
|
|
||||||
|
# Add each peer's certificate to the other pods' configs under:
|
||||||
|
# [replication."repl://<peer-fqdn>:8444"]
|
||||||
|
# type = "mutual-pull"
|
||||||
|
# partner_cert = "<cert>"
|
||||||
|
```
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
name: kanidm-config
|
|
||||||
namespace: kanidm
|
|
||||||
labels:
|
|
||||||
app.kubernetes.io/name: kanidm
|
|
||||||
app.kubernetes.io/instance: kanidm
|
|
||||||
data:
|
|
||||||
server.toml: |
|
|
||||||
version = "2"
|
|
||||||
|
|
||||||
domain = "auth.unkin.net"
|
|
||||||
origin = "https://auth.unkin.net"
|
|
||||||
bindaddress = "[::]:8443"
|
|
||||||
db_path = "/data/kanidm.db"
|
|
||||||
db_arc_size = 2048
|
|
||||||
tls_chain = "/data/tls/tls.crt"
|
|
||||||
tls_key = "/data/tls/tls.key"
|
|
||||||
log_level = "info"
|
|
||||||
|
|
||||||
[online_backup]
|
|
||||||
path = "/data/backups/"
|
|
||||||
schedule = "0 22 * * *"
|
|
||||||
versions = 7
|
|
||||||
|
|
||||||
[replication]
|
|
||||||
origin = "__REPL_ORIGIN__"
|
|
||||||
bindaddress = "[::]:8444"
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
name: kanidm-repl-certs
|
|
||||||
namespace: kanidm
|
|
||||||
labels:
|
|
||||||
app.kubernetes.io/name: kanidm
|
|
||||||
app.kubernetes.io/instance: kanidm
|
|
||||||
data: {}
|
|
||||||
@@ -5,12 +5,23 @@ kind: Kustomization
|
|||||||
resources:
|
resources:
|
||||||
- namespace.yaml
|
- namespace.yaml
|
||||||
- serviceaccount.yaml
|
- serviceaccount.yaml
|
||||||
- rbac.yaml
|
|
||||||
- certificate.yaml
|
- certificate.yaml
|
||||||
- configmap.yaml
|
|
||||||
- service.yaml
|
- service.yaml
|
||||||
- statefulset.yaml
|
- statefulset.yaml
|
||||||
- poddisruptionbudget.yaml
|
- poddisruptionbudget.yaml
|
||||||
- gateway.yaml
|
- gateway.yaml
|
||||||
- httproute.yaml
|
- httproute.yaml
|
||||||
- tlsroute.yaml
|
- tlsroute.yaml
|
||||||
|
|
||||||
|
configMapGenerator:
|
||||||
|
- name: kanidm-config
|
||||||
|
namespace: kanidm
|
||||||
|
options:
|
||||||
|
disableNameSuffixHash: true
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: kanidm
|
||||||
|
app.kubernetes.io/instance: kanidm
|
||||||
|
files:
|
||||||
|
- server-0.toml=resources/server-0.toml
|
||||||
|
- server-1.toml=resources/server-1.toml
|
||||||
|
- server-2.toml=resources/server-2.toml
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
version = "2"
|
||||||
|
|
||||||
|
domain = "auth.unkin.net"
|
||||||
|
origin = "https://auth.unkin.net"
|
||||||
|
bindaddress = "[::]:8443"
|
||||||
|
db_path = "/data/kanidm.db"
|
||||||
|
db_arc_size = 2048
|
||||||
|
tls_chain = "/data/tls/tls.crt"
|
||||||
|
tls_key = "/data/tls/tls.key"
|
||||||
|
log_level = "info"
|
||||||
|
|
||||||
|
[online_backup]
|
||||||
|
path = "/data/backups/"
|
||||||
|
schedule = "0 22 * * *"
|
||||||
|
versions = 7
|
||||||
|
|
||||||
|
[replication]
|
||||||
|
origin = "repl://kanidm-0.kanidm-headless.kanidm.svc.cluster.local:8444"
|
||||||
|
bindaddress = "[::]:8444"
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
version = "2"
|
||||||
|
|
||||||
|
domain = "auth.unkin.net"
|
||||||
|
origin = "https://auth.unkin.net"
|
||||||
|
bindaddress = "[::]:8443"
|
||||||
|
db_path = "/data/kanidm.db"
|
||||||
|
db_arc_size = 2048
|
||||||
|
tls_chain = "/data/tls/tls.crt"
|
||||||
|
tls_key = "/data/tls/tls.key"
|
||||||
|
log_level = "info"
|
||||||
|
|
||||||
|
[online_backup]
|
||||||
|
path = "/data/backups/"
|
||||||
|
schedule = "0 22 * * *"
|
||||||
|
versions = 7
|
||||||
|
|
||||||
|
[replication]
|
||||||
|
origin = "repl://kanidm-1.kanidm-headless.kanidm.svc.cluster.local:8444"
|
||||||
|
bindaddress = "[::]:8444"
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
version = "2"
|
||||||
|
|
||||||
|
domain = "auth.unkin.net"
|
||||||
|
origin = "https://auth.unkin.net"
|
||||||
|
bindaddress = "[::]:8443"
|
||||||
|
db_path = "/data/kanidm.db"
|
||||||
|
db_arc_size = 2048
|
||||||
|
tls_chain = "/data/tls/tls.crt"
|
||||||
|
tls_key = "/data/tls/tls.key"
|
||||||
|
log_level = "info"
|
||||||
|
|
||||||
|
[online_backup]
|
||||||
|
path = "/data/backups/"
|
||||||
|
schedule = "0 22 * * *"
|
||||||
|
versions = 7
|
||||||
|
|
||||||
|
[replication]
|
||||||
|
origin = "repl://kanidm-2.kanidm-headless.kanidm.svc.cluster.local:8444"
|
||||||
|
bindaddress = "[::]:8444"
|
||||||
@@ -36,24 +36,10 @@ spec:
|
|||||||
fsGroup: 1000
|
fsGroup: 1000
|
||||||
initContainers:
|
initContainers:
|
||||||
- name: config-init
|
- name: config-init
|
||||||
image: kanidm/server:1.10.3
|
image: busybox:1.36
|
||||||
command: ["/bin/sh", "-c"]
|
command: ["/bin/sh", "-c"]
|
||||||
args:
|
args:
|
||||||
- |
|
- cp "/config-template/server-${POD_NAME##*-}.toml" /config/server.toml
|
||||||
set -e
|
|
||||||
REPL_ORIGIN="repl://${POD_NAME}.kanidm-headless.kanidm.svc.cluster.local:8444"
|
|
||||||
sed "s|__REPL_ORIGIN__|${REPL_ORIGIN}|g" /config-template/server.toml > /config/server.toml
|
|
||||||
for peer in kanidm-0 kanidm-1 kanidm-2; do
|
|
||||||
if [ "${peer}" = "${POD_NAME}" ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
cert_file="/repl-certs/${peer}"
|
|
||||||
if [ -s "${cert_file}" ]; then
|
|
||||||
fqdn="${peer}.kanidm-headless.kanidm.svc.cluster.local"
|
|
||||||
printf '\n[replication."repl://%s:8444"]\ntype = "mutual-pull"\npartner_cert = "%s"\n' \
|
|
||||||
"${fqdn}" "$(cat ${cert_file})" >> /config/server.toml
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
env:
|
env:
|
||||||
- name: POD_NAME
|
- name: POD_NAME
|
||||||
valueFrom:
|
valueFrom:
|
||||||
@@ -62,41 +48,12 @@ spec:
|
|||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: config-template
|
- name: config-template
|
||||||
mountPath: /config-template
|
mountPath: /config-template
|
||||||
|
readOnly: true
|
||||||
- name: config
|
- name: config
|
||||||
mountPath: /config
|
mountPath: /config
|
||||||
- name: repl-certs
|
|
||||||
mountPath: /repl-certs
|
|
||||||
readOnly: true
|
|
||||||
securityContext:
|
securityContext:
|
||||||
allowPrivilegeEscalation: false
|
allowPrivilegeEscalation: false
|
||||||
readOnlyRootFilesystem: true
|
readOnlyRootFilesystem: true
|
||||||
- name: repl-cert-publisher
|
|
||||||
image: bitnami/kubectl:1.33
|
|
||||||
restartPolicy: Always
|
|
||||||
command: ["/bin/sh", "-c"]
|
|
||||||
args:
|
|
||||||
- |
|
|
||||||
until kubectl exec "${POD_NAME}" -c kanidm -- /sbin/kanidmd renew-replication-certificate 2>/dev/null | grep -q '^# certificate:'; do
|
|
||||||
sleep 30
|
|
||||||
done
|
|
||||||
while true; do
|
|
||||||
cert=$(kubectl exec "${POD_NAME}" -c kanidm -- /sbin/kanidmd renew-replication-certificate 2>/dev/null \
|
|
||||||
| grep '^# certificate:' | sed 's/^# certificate: "\(.*\)"$/\1/')
|
|
||||||
if [ -n "${cert}" ]; then
|
|
||||||
kubectl patch configmap kanidm-repl-certs \
|
|
||||||
--type=merge \
|
|
||||||
-p "{\"data\":{\"${POD_NAME}\":\"${cert}\"}}"
|
|
||||||
fi
|
|
||||||
sleep 3600
|
|
||||||
done
|
|
||||||
env:
|
|
||||||
- name: POD_NAME
|
|
||||||
valueFrom:
|
|
||||||
fieldRef:
|
|
||||||
fieldPath: metadata.name
|
|
||||||
securityContext:
|
|
||||||
allowPrivilegeEscalation: false
|
|
||||||
readOnlyRootFilesystem: false
|
|
||||||
containers:
|
containers:
|
||||||
- name: kanidm
|
- name: kanidm
|
||||||
image: kanidm/server:1.10.3
|
image: kanidm/server:1.10.3
|
||||||
@@ -144,9 +101,6 @@ spec:
|
|||||||
name: kanidm-config
|
name: kanidm-config
|
||||||
- name: config
|
- name: config
|
||||||
emptyDir: {}
|
emptyDir: {}
|
||||||
- name: repl-certs
|
|
||||||
configMap:
|
|
||||||
name: kanidm-repl-certs
|
|
||||||
- name: tls
|
- name: tls
|
||||||
secret:
|
secret:
|
||||||
secretName: kanidm-tls
|
secretName: kanidm-tls
|
||||||
|
|||||||
Reference in New Issue
Block a user