Initial commit — LoginMaster tenant deployment toolkit
Toolkit per deployare/aggiornare un tenant LoginMaster su qualsiasi Kubernetes (EKS/AKS/DOKS/Scaleway/vSphere/...). Contiene: - deploy.sh: bootstrap di un nuovo tenant (idempotente, re-run protection, storage class auto-rilevata, prompt separati api/admin tag, generazione segreti crittografici via openssl rand). - update.sh: rolling update zero-downtime con tag api/admin separati, rollback hint via 'kubectl rollout undo', riapplicazione opzionale del ConfigMap. - templates/: 8 manifest parametrici (envsubst): namespace, cert-manager TLS Mongo, NetworkPolicy intra-namespace, ConfigMap, MongoDB StatefulSet 3 repliche con TLS interno + initContainer per keyfile/PEM, tenant-api Deployment 2 repliche con CA validation, tenant-admin, ingress nginx + Let's Encrypt. Sicurezza: TLS interno Mongo (cert-manager CA self-signed 10y), keyFile per auth replica set, password client mai in argv, NetworkPolicy che isola il tenant, pod Mongo non-root (uid 999) con initContainer come root per i file runtime in tmpfs.
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: ${NAMESPACE}
|
||||
@@ -0,0 +1,76 @@
|
||||
# TLS interno MongoDB (cert-manager).
|
||||
# Catena: Issuer self-signed → CA cert → Issuer CA → cert membri replica set.
|
||||
# Il Secret 'mongodb-tenant-tls' (creato da cert-manager) contiene tls.crt, tls.key, ca.crt.
|
||||
#
|
||||
# Note operative:
|
||||
# - mongod usa keyFile per cluster auth e TLS solo per il transport (non x.509).
|
||||
# - Il rinnovo del cert membri (renewBefore: 30d, duration: 1y) NON riavvia
|
||||
# automaticamente i pod mongo. Quando cert-manager riemette il Secret va
|
||||
# fatto manualmente: kubectl rollout restart statefulset/mongodb-tenant.
|
||||
# - SAN coprono: nome service headless, FQDN brevi e completi dei 3 pod.
|
||||
# Per connessioni da deploy.sh via 127.0.0.1 si usa --tlsAllowInvalidHostnames
|
||||
# (la CA è validata, solo l'hostname check è skippato).
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Issuer
|
||||
metadata:
|
||||
name: mongodb-tenant-selfsigned
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
selfSigned: {}
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: mongodb-tenant-ca
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
isCA: true
|
||||
commonName: mongodb-tenant-ca
|
||||
duration: 87600h # 10 anni (CA interna)
|
||||
renewBefore: 720h # 30 giorni
|
||||
secretName: mongodb-tenant-ca
|
||||
privateKey:
|
||||
algorithm: ECDSA
|
||||
size: 256
|
||||
issuerRef:
|
||||
name: mongodb-tenant-selfsigned
|
||||
kind: Issuer
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Issuer
|
||||
metadata:
|
||||
name: mongodb-tenant-ca
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
ca:
|
||||
secretName: mongodb-tenant-ca
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: mongodb-tenant-tls
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
secretName: mongodb-tenant-tls
|
||||
duration: 8760h # 1 anno
|
||||
renewBefore: 720h # 30 giorni
|
||||
privateKey:
|
||||
algorithm: ECDSA
|
||||
size: 256
|
||||
issuerRef:
|
||||
name: mongodb-tenant-ca
|
||||
kind: Issuer
|
||||
dnsNames:
|
||||
- mongodb-tenant-headless
|
||||
- mongodb-tenant-headless.${NAMESPACE}.svc
|
||||
- mongodb-tenant-headless.${NAMESPACE}.svc.cluster.local
|
||||
- mongodb-tenant-0
|
||||
- mongodb-tenant-1
|
||||
- mongodb-tenant-2
|
||||
- mongodb-tenant-0.mongodb-tenant-headless
|
||||
- mongodb-tenant-1.mongodb-tenant-headless
|
||||
- mongodb-tenant-2.mongodb-tenant-headless
|
||||
- mongodb-tenant-0.mongodb-tenant-headless.${NAMESPACE}.svc.cluster.local
|
||||
- mongodb-tenant-1.mongodb-tenant-headless.${NAMESPACE}.svc.cluster.local
|
||||
- mongodb-tenant-2.mongodb-tenant-headless.${NAMESPACE}.svc.cluster.local
|
||||
@@ -0,0 +1,71 @@
|
||||
# NetworkPolicy: isolamento del namespace tenant.
|
||||
# - mongodb-tenant: ingress solo dai pod tenant-api e dagli altri membri del replica set.
|
||||
# - tenant-api: ingress solo dall'ingress controller (namespace 'ingress-nginx').
|
||||
# - tenant-admin: ingress solo dall'ingress controller.
|
||||
# Egress: non vincolato (DNS, registry, SMTP, LOGINMASTER_API_URL devono restare raggiungibili).
|
||||
#
|
||||
# Nota: la namespace label 'kubernetes.io/metadata.name' è automatica dal K8s 1.22+.
|
||||
# Se l'ingress controller è installato in un namespace diverso, modificare il selector.
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: mongodb-tenant
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app: mongodb-tenant
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app: mongodb-tenant
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app: tenant-api
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 27017
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: tenant-api
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app: tenant-api
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: ingress-nginx
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 3000
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: tenant-admin
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app: tenant-admin
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: ingress-nginx
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
@@ -0,0 +1,25 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: tenant-api-config
|
||||
namespace: ${NAMESPACE}
|
||||
data:
|
||||
NODE_ENV: "production"
|
||||
PORT: "3000"
|
||||
# MONGODB_URI è nel Secret mongodb-tenant-auth (contiene credenziali)
|
||||
LOGINMASTER_API_URL: "${LOGINMASTER_API_URL}"
|
||||
ADMIN_ALLOWED_ORIGIN: "${ADMIN_ALLOWED_ORIGIN}"
|
||||
TENANT_ADMIN_URL: "${TENANT_ADMIN_URL}"
|
||||
# CORS_ORIGIN e MANAGE_ALLOWED_ORIGIN sono alias di TENANT_ADMIN_URL: nomi
|
||||
# storici letti dal codice API. Tenuti per compat — se l'API ne legge solo
|
||||
# uno è innocuo, ma è preferibile che il codice legga TENANT_ADMIN_URL.
|
||||
CORS_ORIGIN: "${TENANT_ADMIN_URL}"
|
||||
MANAGE_ALLOWED_ORIGIN: "${TENANT_ADMIN_URL}"
|
||||
JWT_ACCESS_EXPIRY: "15m"
|
||||
JWT_REFRESH_EXPIRY: "7d"
|
||||
LOG_LEVEL: "info"
|
||||
SMTP_HOST: "${SMTP_HOST}"
|
||||
SMTP_PORT: "${SMTP_PORT}"
|
||||
SMTP_SECURE: "${SMTP_SECURE}"
|
||||
SMTP_USER: "${SMTP_USER}"
|
||||
EMAIL_FROM: "${EMAIL_FROM}"
|
||||
@@ -0,0 +1,198 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mongodb-tenant-headless
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
clusterIP: None
|
||||
selector:
|
||||
app: mongodb-tenant
|
||||
ports:
|
||||
- port: 27017
|
||||
targetPort: 27017
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: mongodb-tenant
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
serviceName: mongodb-tenant-headless
|
||||
replicas: 3
|
||||
podManagementPolicy: Parallel
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mongodb-tenant
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mongodb-tenant
|
||||
spec:
|
||||
imagePullSecrets:
|
||||
- name: registry-codebaker
|
||||
securityContext:
|
||||
# fsGroup garantisce ownership corretta sul PVC (mongo data) per uid 999.
|
||||
# runAsUser/Group: il container principale gira come mongodb (uid 999),
|
||||
# non root. L'init invece deve essere root per poter chmod 400 + chown.
|
||||
runAsUser: 999
|
||||
runAsGroup: 999
|
||||
fsGroup: 999
|
||||
initContainers:
|
||||
# Prepara keyfile e PEM nel tmpfs /run/mongo con owner=mongodb mode=0400.
|
||||
# Mongod richiede esattamente 0400/0600 owned-by-self e quel mode non si
|
||||
# può ottenere via secret defaultMode senza far girare il container come
|
||||
# root. Quindi: init come root, main come 999.
|
||||
- name: init-tls
|
||||
image: mongo:6.0
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
runAsGroup: 0
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- >-
|
||||
cp /etc/secrets/keyfile /run/mongo/mongodb-keyfile &&
|
||||
cat /etc/mongo-tls/tls.crt /etc/mongo-tls/tls.key > /run/mongo/mongo-server.pem &&
|
||||
chown 999:999 /run/mongo/mongodb-keyfile /run/mongo/mongo-server.pem &&
|
||||
chmod 400 /run/mongo/mongodb-keyfile /run/mongo/mongo-server.pem
|
||||
volumeMounts:
|
||||
- name: mongo-runtime
|
||||
mountPath: /run/mongo
|
||||
- name: mongo-keyfile
|
||||
mountPath: /etc/secrets
|
||||
readOnly: true
|
||||
- name: mongo-tls
|
||||
mountPath: /etc/mongo-tls
|
||||
readOnly: true
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchLabels:
|
||||
app: mongodb-tenant
|
||||
topologyKey: kubernetes.io/hostname
|
||||
containers:
|
||||
- name: mongodb
|
||||
image: mongo:6.0
|
||||
# I file runtime (keyfile + PEM cert+key) sono già stati preparati dall'
|
||||
# initContainer in /run/mongo con owner mongodb:mongodb mode 0400.
|
||||
command:
|
||||
- mongod
|
||||
- --bind_ip_all
|
||||
- --replSet
|
||||
- rs0
|
||||
- --auth
|
||||
- --keyFile
|
||||
- /run/mongo/mongodb-keyfile
|
||||
- --tlsMode
|
||||
- requireTLS
|
||||
- --tlsCertificateKeyFile
|
||||
- /run/mongo/mongo-server.pem
|
||||
- --tlsCAFile
|
||||
- /etc/mongo-tls/ca.crt
|
||||
# Senza questo flag, --tlsCAFile mette mongod in mTLS e rifiuta ogni
|
||||
# client che non presenta un cert. I membri del replica set si autenticano
|
||||
# via keyFile (clusterAuthMode keyFile, default), non x.509: quindi non
|
||||
# serve mTLS. I client (API, probe, mongosh) presentano solo password.
|
||||
- --tlsAllowConnectionsWithoutCertificates
|
||||
ports:
|
||||
- containerPort: 27017
|
||||
volumeMounts:
|
||||
- name: mongodb-data
|
||||
mountPath: /data/db
|
||||
- name: mongo-runtime
|
||||
mountPath: /run/mongo
|
||||
readOnly: true
|
||||
- name: mongo-tls
|
||||
mountPath: /etc/mongo-tls
|
||||
readOnly: true
|
||||
resources:
|
||||
requests:
|
||||
cpu: "${MONGO_CPU_REQUEST}"
|
||||
memory: "${MONGO_MEM_REQUEST}"
|
||||
limits:
|
||||
cpu: "${MONGO_CPU_LIMIT}"
|
||||
memory: "${MONGO_MEM_LIMIT}"
|
||||
# quit(N) propaga N come exit code: probe fallisce solo se ping.ok != 1.
|
||||
# Connessione su 127.0.0.1 con --tlsAllowInvalidHostnames perché il cert
|
||||
# non include localhost nei SAN (la CA però viene validata).
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
- mongosh
|
||||
- --quiet
|
||||
- --tls
|
||||
- --tlsCAFile
|
||||
- /etc/mongo-tls/ca.crt
|
||||
- --tlsAllowInvalidHostnames
|
||||
- --host
|
||||
- "127.0.0.1"
|
||||
- --eval
|
||||
- "quit(db.adminCommand('ping').ok===1?0:1)"
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- mongosh
|
||||
- --quiet
|
||||
- --tls
|
||||
- --tlsCAFile
|
||||
- /etc/mongo-tls/ca.crt
|
||||
- --tlsAllowInvalidHostnames
|
||||
- --host
|
||||
- "127.0.0.1"
|
||||
- --eval
|
||||
- "quit(db.adminCommand('ping').ok===1?0:1)"
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
volumes:
|
||||
- name: mongo-runtime
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
sizeLimit: 16Mi
|
||||
- name: mongo-keyfile
|
||||
secret:
|
||||
secretName: mongodb-tenant-auth
|
||||
items:
|
||||
- key: keyfile
|
||||
path: keyfile
|
||||
# Con fsGroup=999 il file è root:mongodb 0440 — leggibile solo dal gruppo
|
||||
# mongodb (uid/gid 999), non world-readable. Il container poi lo copia in
|
||||
# /data/db/ e fa chmod 400 perché mongod richiede mode 0400/0600 owner-only.
|
||||
defaultMode: 0440
|
||||
- name: mongo-tls
|
||||
secret:
|
||||
# Secret popolato da cert-manager (vedi templates/01-mongodb-tls.yaml).
|
||||
# Contiene tls.crt, tls.key, ca.crt — leggibili dal gruppo 999 via fsGroup.
|
||||
secretName: mongodb-tenant-tls
|
||||
defaultMode: 0440
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: mongodb-data
|
||||
spec:
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
storageClassName: "${STORAGE_CLASS}"
|
||||
resources:
|
||||
requests:
|
||||
storage: ${STORAGE_SIZE}
|
||||
---
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: mongodb-tenant-pdb
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
# Il replica set tollera la perdita di 1 membro (quorum = 2/3).
|
||||
# minAvailable: 2 evita che drain/voluntary disruption tolga il quorum.
|
||||
minAvailable: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mongodb-tenant
|
||||
# NB: rs.initiate e la creazione degli utenti root/app sono eseguite da
|
||||
# `deploy.sh` via `kubectl exec` nel pod mongodb-tenant-0 (sfrutta la
|
||||
# "localhost exception" di Mongo per creare il primo utente senza auth).
|
||||
@@ -0,0 +1,111 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: tenant-api
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
selector:
|
||||
app: tenant-api
|
||||
ports:
|
||||
- port: 3000
|
||||
targetPort: 3000
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: tenant-api
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
replicas: 2
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
selector:
|
||||
matchLabels:
|
||||
app: tenant-api
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: tenant-api
|
||||
spec:
|
||||
imagePullSecrets:
|
||||
- name: registry-codebaker
|
||||
containers:
|
||||
- name: tenant-api
|
||||
image: hub.codebaker.it/loginmaster-tenant/api-tenant:${IMAGE_TAG_API}
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: tenant-api-config
|
||||
env:
|
||||
- name: MONGODB_URI
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mongodb-tenant-auth
|
||||
key: MONGODB_URI
|
||||
- name: MASTER_ENCRYPTION_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: tenant-api-secrets
|
||||
key: MASTER_ENCRYPTION_KEY
|
||||
- name: SMTP_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: tenant-api-secrets
|
||||
key: SMTP_PASSWORD
|
||||
volumeMounts:
|
||||
- name: mongo-ca
|
||||
mountPath: /etc/mongo-tls
|
||||
readOnly: true
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3000
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
failureThreshold: 30
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3000
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3000
|
||||
periodSeconds: 20
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
volumes:
|
||||
- name: mongo-ca
|
||||
secret:
|
||||
# Solo la ca.crt dal Secret cert-manager; il cert di servizio non serve
|
||||
# all'API (non fa mTLS, valida solo il server).
|
||||
secretName: mongodb-tenant-tls
|
||||
items:
|
||||
- key: ca.crt
|
||||
path: ca.crt
|
||||
defaultMode: 0444
|
||||
---
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: tenant-api-pdb
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
minAvailable: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: tenant-api
|
||||
@@ -0,0 +1,72 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: tenant-admin
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
selector:
|
||||
app: tenant-admin
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: tenant-admin
|
||||
namespace: ${NAMESPACE}
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
selector:
|
||||
matchLabels:
|
||||
app: tenant-admin
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: tenant-admin
|
||||
spec:
|
||||
imagePullSecrets:
|
||||
- name: registry-codebaker
|
||||
containers:
|
||||
- name: tenant-admin
|
||||
image: hub.codebaker.it/loginmaster-tenant/admin-tenant:${IMAGE_TAG_ADMIN}
|
||||
env:
|
||||
- name: VITE_APP_NAME
|
||||
value: "LoginMaster Tenant Admin"
|
||||
- name: VITE_API_BASE_URL
|
||||
value: "https://${DOMAIN_API}"
|
||||
ports:
|
||||
- containerPort: 80
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 32Mi
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 64Mi
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 80
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 5
|
||||
failureThreshold: 20
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 80
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 80
|
||||
periodSeconds: 20
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
@@ -0,0 +1,36 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: tenant-ingress
|
||||
namespace: ${NAMESPACE}
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts:
|
||||
- ${DOMAIN_API}
|
||||
- ${DOMAIN_ADMIN}
|
||||
secretName: tenant-tls
|
||||
rules:
|
||||
- host: ${DOMAIN_API}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: tenant-api
|
||||
port:
|
||||
number: 3000
|
||||
- host: ${DOMAIN_ADMIN}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: tenant-admin
|
||||
port:
|
||||
number: 80
|
||||
Reference in New Issue
Block a user