Deploy internal user-engine portal foundation
This commit is contained in:
parent
480a84abfb
commit
49f727c54c
4 changed files with 180 additions and 4 deletions
26
sso-mfa/k8s/user-engine/README.md
Normal file
26
sso-mfa/k8s/user-engine/README.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# user-engine portal on reef-railiance
|
||||
|
||||
This is a stateful `rail-kubernetes` platform workload. It intentionally has
|
||||
no public Ingress until the KeyCape authorization-code/PKCE edge and
|
||||
`user-engine-portal` client are configured. Direct access to protected routes
|
||||
must remain impossible because the application accepts identity only from a
|
||||
trusted edge marker plus verified claims.
|
||||
|
||||
For the current pre-production bootstrap the image is imported directly into
|
||||
k3s and uses `imagePullPolicy: Never`. Replace it with the immutable Forgejo
|
||||
OCI digest after the OpenBao package-publisher lane is available.
|
||||
|
||||
The CloudNativePG operator creates `user-engine-pg-app`, including its `uri`
|
||||
field. `user-engine-runtime` contains only the generated edge marker and must
|
||||
be replaced by an ExternalSecret before public exposure.
|
||||
|
||||
```bash
|
||||
kubectl apply -f runtime.yaml
|
||||
kubectl -n user-engine rollout status deployment/user-engine
|
||||
kubectl -n user-engine get cluster,pod,service,networkpolicy
|
||||
```
|
||||
|
||||
Rollback sets the Deployment image to the preceding immutable digest.
|
||||
Database migrations are additive and run before serving; restore uses the
|
||||
standard CNPG recovery contract once the offsite object-store reference is
|
||||
attached.
|
||||
142
sso-mfa/k8s/user-engine/runtime.yaml
Normal file
142
sso-mfa/k8s/user-engine/runtime.yaml
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: user-engine
|
||||
labels:
|
||||
railiance.io/workload-class: platform
|
||||
---
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: Cluster
|
||||
metadata:
|
||||
name: user-engine-pg
|
||||
namespace: user-engine
|
||||
spec:
|
||||
instances: 1
|
||||
imageName: ghcr.io/cloudnative-pg/postgresql:17.5
|
||||
storage:
|
||||
size: 5Gi
|
||||
bootstrap:
|
||||
initdb:
|
||||
database: user_engine
|
||||
owner: user_engine
|
||||
resources:
|
||||
requests: {cpu: 100m, memory: 256Mi}
|
||||
limits: {cpu: "1", memory: 1Gi}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: user-engine
|
||||
namespace: user-engine
|
||||
labels: &labels
|
||||
app.kubernetes.io/name: user-engine
|
||||
app.kubernetes.io/component: portal
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels: {app.kubernetes.io/name: user-engine}
|
||||
template:
|
||||
metadata:
|
||||
labels: *labels
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile: {type: RuntimeDefault}
|
||||
containers:
|
||||
- name: portal
|
||||
image: user-engine:portal-c27012a
|
||||
imagePullPolicy: Never
|
||||
ports: [{name: http, containerPort: 8080}]
|
||||
env:
|
||||
- name: USER_ENGINE_DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef: {name: user-engine-pg-app, key: uri}
|
||||
- name: USER_ENGINE_PROXY_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef: {name: user-engine-runtime, key: proxy-secret}
|
||||
- {name: USER_ENGINE_LOGIN_URL, value: "https://kc.coulomb.social/"}
|
||||
- {name: USER_ENGINE_OIDC_ISSUER, value: "https://kc.coulomb.social"}
|
||||
- {name: USER_ENGINE_OIDC_AUDIENCE, value: user-engine-portal}
|
||||
- {name: USER_ENGINE_PUBLIC_REGISTRATION, value: "false"}
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: {drop: ["ALL"]}
|
||||
readOnlyRootFilesystem: true
|
||||
resources:
|
||||
requests: {cpu: 50m, memory: 64Mi}
|
||||
limits: {cpu: 500m, memory: 256Mi}
|
||||
startupProbe:
|
||||
httpGet: {path: /readyz, port: http}
|
||||
failureThreshold: 30
|
||||
periodSeconds: 5
|
||||
readinessProbe:
|
||||
httpGet: {path: /readyz, port: http}
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
httpGet: {path: /healthz, port: http}
|
||||
periodSeconds: 20
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: {name: user-engine, namespace: user-engine}
|
||||
spec:
|
||||
selector: {app.kubernetes.io/name: user-engine}
|
||||
ports: [{name: http, port: 8080, targetPort: http}]
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata: {name: user-engine-default-deny, namespace: user-engine}
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes: [Ingress, Egress]
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata: {name: user-engine-runtime, namespace: user-engine}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels: {app.kubernetes.io/name: user-engine}
|
||||
policyTypes: [Ingress, Egress]
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels: {kubernetes.io/metadata.name: kube-system}
|
||||
ports: [{protocol: TCP, port: 8080}]
|
||||
egress:
|
||||
- to:
|
||||
- podSelector:
|
||||
matchLabels: {cnpg.io/cluster: user-engine-pg}
|
||||
ports: [{protocol: TCP, port: 5432}]
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels: {kubernetes.io/metadata.name: kube-system}
|
||||
ports: [{protocol: UDP, port: 53}, {protocol: TCP, port: 53}]
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata: {name: user-engine-postgres, namespace: user-engine}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels: {cnpg.io/cluster: user-engine-pg}
|
||||
policyTypes: [Ingress, Egress]
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels: {app.kubernetes.io/name: user-engine}
|
||||
ports: [{protocol: TCP, port: 5432}]
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels: {kubernetes.io/metadata.name: cnpg-system}
|
||||
ports:
|
||||
- {protocol: TCP, port: 5432}
|
||||
- {protocol: TCP, port: 8000}
|
||||
- {protocol: TCP, port: 9187}
|
||||
egress:
|
||||
# CNPG instance manager must read its Cluster resource during bootstrap.
|
||||
# K3s network policy evaluates the API service after DNAT on port 6443.
|
||||
- ports: [{protocol: TCP, port: 6443}]
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels: {kubernetes.io/metadata.name: kube-system}
|
||||
ports: [{protocol: UDP, port: 53}, {protocol: TCP, port: 53}]
|
||||
Loading…
Add table
Add a link
Reference in a new issue