Skip to content

Commit

Permalink
feat: fix postgres persistence
Browse files Browse the repository at this point in the history
BREAKING CHANGE: create db password secret; move values in frond- and
backend; use ImplementationSpecific ingress path on backend
  • Loading branch information
tjorbo committed Aug 19, 2024
1 parent 29ddc35 commit ab907e8
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 377 deletions.
38 changes: 15 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ It's recommended to use a dedicated PostgreSQL instance for production usage.
1. install and run minikube or other local K8s services https://kubernetes.io/docs/tasks/tools/
2. use scripts in installation below

### Minikube

```bash
$ minikube addons enable ingress
$ minikube tunnel
```

## Installation

### Recommendations
Expand All @@ -31,31 +38,17 @@ It's recommended to use a dedicated PostgreSQL instance for production usage.
CoreDNS.
* For production usage, may use an own postgres instance. (Recommended, use
the [Cloud Native PG Operator](https://cloudnative-pg.io) in Kubernetes)
*

### Installation steps
### Installation & upgrade steps

1. Prepare the value files.
2. Install the helm charts with `helm install ...` CLI Command:

```bash
# Create a namespace (or use default), where to work in:
$ kubectl create namespace terminfinder-demo

# First installing the helm chart, to the name
$ helm install terminfinder-demo terminfinder-chart -n terminfinder-demo

# Verify installation of helm charts:
$ helm list -n terminfinder-demo
$ kubectl get deploy -n terminfinder-demo
```

### Upgrade release

To upgrade the helm chart, use the `helm upgrade ...` command:

```bash
# Upgrade HelmChart
$ helm upgrade terminfinder-demo terminfinder-chart -n terminfinder-demo
$ helm upgrade --install -n tf --create-namespace tf1 terminfinder-chart
$ helm list -n tf
$ kubectl get pod,deploy,pvc,svc,ing,ep -n tf
```

### Debug Container
Expand All @@ -71,10 +64,9 @@ To delete the helm chart (release), use the `helm uninstall...` command.
Note that the persistent volume may be available even if the helm release is uninstalled.

```bash
# Delete namespace
$ helm uninstall terminfinder-demo -n terminfinder-demo
$ kubectl delete pvc --all -n terminfinder-demo
$ kubectl delete namespace terminfinder-demo
$ helm uninstall tf1 -n tf
$ kubectl delete pvc --all -n tf
$ kubectl delete namespace tf
```

## Using an own PostgreSQL DB instance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "terminfinder-backend.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}
echo "Visit http://127.0.0.1:{{ .Values.application.port}} to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME {{ .Values.application.port }}:$CONTAINER_PORT
{{- end }}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- $svc := .Values.global.postgresql.service.name | default (printf "%s-postgresql" .Release.Name) }}
{{- $svc := printf "%s-postgresql" .Release.Name }}
apiVersion: apps/v1
kind: Deployment
metadata:
Expand Down Expand Up @@ -45,29 +45,33 @@ spec:
- name: DB_USERNAME
value: {{ .Values.global.postgresql.auth.username }}
- name: ASPNETCORE_URLS
value: http://+:8080
# Secrets:
value: {{printf "http://+:%d" (int .Values.application.port) }}
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.global.postgresql.auth.existingSecret | default (printf "%s" $svc) }}
key: {{ .Values.global.postgresql.auth.secretKeys.userPasswordKey | default "password" }}
# Patches
name: {{ required "Postgres DB secret name not set" .Values.global.postgresql.auth.existingSecret }}
key: {{ required "Postgres DB password secretkey not set" .Values.global.postgresql.auth.secretKeys.userPasswordKey }}
- name: Terminfinder__UseHttps
value: "false"
- name: Terminfinder__UseCors
value: "false"
value: {{ .Values.application.useCors | quote }}
- name: Terminfinder__Log4NetConfigFilename
value: log4net.Console.debug.config
- name: ConnectionStrings__TerminfinderConnection
value: "Server=$(DB_ADDRESS),$(DB_PORT);Database=$(DB_DATABASE);User ID=$(DB_USERNAME);password=$(DB_PASSWORD);"
ports:
- name: http
containerPort: 8080
containerPort: {{ int .Values.application.port }}
protocol: TCP
command:
- "dotnet"
- "Dataport.Terminfinder.WebAPI.dll"
{{- if .Values.application.migrateDB }}
- "--dbmigrate"
{{- end }}
startupProbe:
failureThreshold: 3
periodSeconds: 10
periodSeconds: 30
httpGet:
path: /app
port: http
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: postgresql-default-auth
type: kubernetes.io/basic-auth
stringData:
password: {{ randAlphaNum 20 | b64enc | quote }}
80 changes: 36 additions & 44 deletions terminfinder-chart/charts/terminfinder-backend/values.yaml
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
# Default values for terminfinder-backend.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

global:
postgresql:
auth:
username: terminfinder
database: terminfinder
existingSecret: "" # if not set, default: "{{ Release.Name }}-postgres"
username: terminfinder
existingSecret: postgresql-default-auth
secretKeys:
userPasswordKey: "" # if not set, default: "password"
userPasswordKey: password
service:
name: "" # if not set, default: "{{ Release.Name }}-postgres"
ports:
postgresql: 5432 # Default port
postgresql: 5432

replicaCount: 1

Expand All @@ -22,17 +17,20 @@ image:
pullPolicy: IfNotPresent
tag: "0.1.0"

application:
port: 8080
useCors: true
migrateDB: true

imagePullSecrets: [ ]

nameOverride: ""

fullnameOverride: ""

serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: { }
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""

podAnnotations: { }
Expand All @@ -51,31 +49,24 @@ securityContext:

service:
type: ClusterIP
port: 80
port: 8080

ingress:
enabled: false
enabled: true
className: "nginx"
annotations:
{ }
# kubernetes.io/ingress.class: nginx
# nginx.ingress.kubernetes.io/rewrite-target: /
# nginx.ingress.kubernetes.io/ssl-redirect: "true"
# cert-manager.io/cluster-issuer: letsencrypt-production
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/enable-cors: "true"
hosts:
- host: terminfinder.opencode.de
- host: localhost
port: 80
paths:
- path: /api
pathType: Prefix
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
tls: [ ]
# - secretName: cert-terminfinder.opencode.de
# hosts:
# - terminfinder.de

resources:
# We recommend to not use limits, since workload spikes can hinder the application or cause crashes
# due to OOM errors. Read more about it here:
# https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-resource-requests-and-limits?hl=en
limits:
cpu: 500m
memory: 256Mi
Expand All @@ -99,27 +90,28 @@ affinity: { }
postgresql:
enabled: true

serviceAccount:
create: true
auth:
enablePostgresUser: false

## Set permissions for the data volume
## Only needed when volume has not correct permissions
volumePermissions:
enabled: true
primary:
persistence:
enabled: true

image:
registry: docker.io # Notice, may this is not allowed
repository: bitnami/bitnami-shell
# tag: 11-debian-11-r77
# pullPolicy: Always
# pullSecrets: []
resources:
requests:
memory: 256Mi
cpu: 250m
limits:
memory: 256Mi
cpu: 250m

initdb:
# Enabling the UUID-OSSP
scripts:
99-enable-uuid.sql: |
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
ALTER EXTENSION "uuid-ossp" SET SCHEMA public;
# More variables / parameters can be found here:
# https://github.com/bitnami/charts/tree/main/bitnami/postgresql#parameters
readReplicas:
replicaCount: 0
persistence:
enabled: false
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "terminfinder-frontend.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
echo "Visit http://127.0.0.1:80 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 80:$CONTAINER_PORT
{{- end }}
2. Don't forget to deploy the Backend!
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,18 @@ spec:
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: ADDRESSING
value: {{ .Values.customerConfig.ADDRESSING }}
- name: LOCALE
value: {{ .Values.customerConfig.LOCALE }}
- name: CUSTOMER_ID
value: {{ required "no customerId set" .Values.application.customerId }}
- name: API_URL
value: {{ .Values.application.apiUrl }}
- name: TITLE
value: {{ .Values.customerConfig.TITLE }}
value: {{ .Values.application.title }}
- name: LOCALE
value: {{ required "no locale set" .Values.application.locale }}
- name: ADDRESSING
value: {{ required "no addressing set" .Values.application.addressing }}
- name: EMAIL
value: {{ .Values.customerConfig.EMAIL }}
- name: API_URL
value: {{ .Values.app.backend_url }}
value: {{ required "no email set" .Values.application.email }}
ports:
- name: http
containerPort: 8080
Expand Down
49 changes: 13 additions & 36 deletions terminfinder-chart/charts/terminfinder-frontend/values.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
# Default values for terminfinder-frontend.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
application:
customerId: "80248A42-8FE2-4D4A-89DA-02E683511F76"
apiUrl: ""
title: ""
locale: "de-DE"
addressing: "du"
email: "[email protected]"

customerConfig:
ADDRESSING: "du" # supported: du, sie
LOCALE: "de-DE" # supported: DE-de, EN-en
TITLE: "Terminfinder Demo"
EMAIL: ""

app:
backend_url: https://terminfinder.opencode.de/api # Public URL to Backend

replicaCount: 1 # Not HA for now!
replicaCount: 1

image:
repository: registry.opencode.de/dataport/terminfinder/terminfinder-frontend
Expand All @@ -23,12 +18,8 @@ nameOverride: ""
fullnameOverride: ""

serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
create: false
annotations: { }
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""

podAnnotations: { }
Expand All @@ -41,39 +32,26 @@ podSecurityContext:

securityContext:
capabilities:
# add:
# - NET_BIND_SERVICE
drop:
- ALL
readOnlyRootFilesystem: false
# runAsUser: 1000

service:
type: ClusterIP
port: 80
port: 8080

ingress:
enabled: false
enabled: true
className: "nginx"
annotations:
{ }
# kubernetes.io/ingress.class: nginx
# nginx.ingress.kubernetes.io/ssl-redirect: "true"
# cert-manager.io/cluster-issuer: letsencrypt-production
hosts:
- host: terminfinder.opencode.de
- host: localhost
port: 80
paths:
- path: /
pathType: Prefix
tls: [ ]
# - secretName: cert-terminfinder.opencode.de
# hosts:
# - terminfinder.de

resources:
# We recommend to not use limits, since workload spikes can hinder the application or cause crashes
# due to OOM errors. Read more about it here:
# https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-resource-requests-and-limits?hl=en
limits:
cpu: 500m
memory: 256Mi
Expand All @@ -86,7 +64,6 @@ autoscaling:
minReplicas: 1
maxReplicas: 20
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80

nodeSelector: { }

Expand Down
Loading

0 comments on commit ab907e8

Please sign in to comment.