diff --git a/charts/openklant/README.md b/charts/openklant/README.md index 559aab1..f32831a 100644 --- a/charts/openklant/README.md +++ b/charts/openklant/README.md @@ -56,6 +56,32 @@ Project dat de Klanten API | https://klanten-api.vng.cloud en Contactmomenten AP | livenessProbe.successThreshold | int | `1` | | | livenessProbe.timeoutSeconds | int | `5` | | | nameOverride | string | `""` | | +| nginx.autoscaling.enabled | bool | `false` | | +| nginx.config.clientMaxBodySize | string | `"10M"` | | +| nginx.existingConfigmap | string | `nil` | | +| nginx.image.pullPolicy | string | `"IfNotPresent"` | | +| nginx.image.repository | string | `"nginxinc/nginx-unprivileged"` | | +| nginx.image.tag | string | `"stable"` | | +| nginx.livenessProbe.failureThreshold | int | `3` | | +| nginx.livenessProbe.initialDelaySeconds | int | `60` | | +| nginx.livenessProbe.periodSeconds | int | `10` | | +| nginx.livenessProbe.successThreshold | int | `1` | | +| nginx.livenessProbe.timeoutSeconds | int | `5` | | +| nginx.podLabels | object | `{}` | | +| nginx.readinessProbe.failureThreshold | int | `3` | | +| nginx.readinessProbe.initialDelaySeconds | int | `30` | | +| nginx.readinessProbe.periodSeconds | int | `10` | | +| nginx.readinessProbe.successThreshold | int | `1` | | +| nginx.readinessProbe.timeoutSeconds | int | `5` | | +| nginx.replicaCount | int | `1` | | +| nginx.resources | object | `{}` | | +| nginx.securityContext.capabilities.drop[0] | string | `"ALL"` | | +| nginx.securityContext.readOnlyRootFilesystem | bool | `false` | | +| nginx.securityContext.runAsNonRoot | bool | `true` | | +| nginx.securityContext.runAsUser | int | `101` | | +| nginx.service.annotations | object | `{}` | | +| nginx.service.port | int | `80` | | +| nginx.service.type | string | `"ClusterIP"` | | | nodeSelector | object | `{}` | | | pdb.create | bool | `false` | | | pdb.maxUnavailable | string | `""` | | diff --git a/charts/openklant/templates/_helpers.tpl b/charts/openklant/templates/_helpers.tpl index 6c9ecfe..6bf0c63 100644 --- a/charts/openklant/templates/_helpers.tpl +++ b/charts/openklant/templates/_helpers.tpl @@ -98,6 +98,37 @@ config selector labels app.kubernetes.io/name: {{ include "openklant.configName" . }} {{- end }} +{{/* +Create a name for NGINX +We truncate at 57 chars in order to provide space for the "-nginx" suffix +*/}} +{{- define "openklant.nginxName" -}} +{{ include "openklant.name" . | trunc 57 | trimSuffix "-" }}-nginx +{{- end }} + +{{/* +Create a default fully qualified name for NGINX. +We truncate at 57 chars in order to provide space for the "-nginx" suffix +*/}} +{{- define "openklant.nginxFullname" -}} +{{ include "openklant.fullname" . | trunc 57 | trimSuffix "-" }}-nginx +{{- end }} + +{{/* +NGINX labels +*/}} +{{- define "openklant.nginxLabels" -}} +{{ include "openklant.commonLabels" . }} +{{ include "openklant.nginxSelectorLabels" . }} +{{- end }} + +{{/* +NGINX selector labels +*/}} +{{- define "openklant.nginxSelectorLabels" -}} +app.kubernetes.io/name: {{ include "openklant.nginxName" . }} +{{- end }} + {{/* Create a name for the worker We truncate at 56 chars in order to provide space for the "-worker" suffix diff --git a/charts/openklant/templates/configmap-nginx.yaml b/charts/openklant/templates/configmap-nginx.yaml new file mode 100644 index 0000000..a0220bc --- /dev/null +++ b/charts/openklant/templates/configmap-nginx.yaml @@ -0,0 +1,86 @@ +{{- if not .Values.nginx.existingConfigmap }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "openklant.nginxFullname" . }} + labels: + {{- include "openklant.nginxLabels" . | nindent 4 }} +data: + proxy: | + proxy_pass_header Server; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Scheme $scheme; + proxy_connect_timeout 300s; + proxy_read_timeout 300s; + {{- if .Values.settings.useXForwardedHost }} + proxy_set_header X-Forwarded-Host $http_host; + {{ else }} + proxy_set_header Host $http_host; + {{- end }} + + proxy_redirect off; + proxy_pass_request_headers on; + proxy_pass http://{{ include "openklant.fullname" . }}.{{ .Release.Namespace }}:{{ .Values.service.port }}; + proxy_http_version 1.1; # required if you're using istio, otherwise you get HTTP 426 errors + + default.conf: | + server { + listen 8000 default_server; + server_name {{ .Values.settings.allowedHosts | replace "," " "}} localhost; + server_tokens off; + client_max_body_size {{ .Values.nginx.config.clientMaxBodySize }}; + + gzip on; + gzip_http_version 1.0; + gzip_comp_level 2; + gzip_min_length 1100; + gzip_buffers 4 8k; + gzip_proxied any; + gzip_types + # text/html is always compressed by HttpGzipModule + text/css + text/javascript + text/xml + text/plain + text/x-component + application/javascript + application/json + application/xml + application/rss+xml + font/truetypenginc + font/opentype + application/vnd.ms-fontobject + image/svg+xml; + gzip_static on; + gzip_proxied expired no-cache no-store private auth; + gzip_disable "MSIE [1-6]\."; + gzip_vary on; + + add_header Feature-Policy "autoplay 'none'; camera 'none'" always; + add_header Referrer-Policy "same-origin"; + add_header X-Content-Type-Options "nosniff"; + add_header X-XSS-Protection "1; mode=block"; + + location / { + include conf.d/proxy; + + } + + location /_health/ { + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log error; + return 200 'OK'; + } + + location /private-media { + internal; + alias /app/private_media/; + } + + error_page 404 /404.html; + error_page 413 /413.json; + error_page 500 502 503 504 /500.json; + + } +{{- end }} \ No newline at end of file diff --git a/charts/openklant/templates/deployment.yaml b/charts/openklant/templates/deployment.yaml index 60c97ec..ad5e962 100644 --- a/charts/openklant/templates/deployment.yaml +++ b/charts/openklant/templates/deployment.yaml @@ -214,4 +214,91 @@ spec: {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} - {{- end }} \ No newline at end of file + {{- end }} + +--- + +# Deployment Nginx + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "openklant.nginxFullname" . }} + labels: + {{- include "openklant.nginxLabels" . | nindent 4 }} +spec: + {{- if not .Values.nginx.autoscaling.enabled }} + replicas: {{ .Values.nginx.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "openklant.nginxSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/configmap-nginx: {{ include (print $.Template.BasePath "/configmap-nginx.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "openklant.nginxSelectorLabels" . | nindent 8 }} + {{- with .Values.nginx.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "openklant.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ include "openklant.nginxFullname" . }} + securityContext: + {{- toYaml .Values.nginx.securityContext | nindent 12 }} + image: "{{ .Values.nginx.image.repository }}:{{ .Values.nginx.image.tag }}" + imagePullPolicy: {{ .Values.nginx.image.pullPolicy }} + livenessProbe: + httpGet: + path: /_health/ + port: http + ports: + - name: http + containerPort: 8000 + resources: + {{- toYaml .Values.nginx.resources | nindent 12 }} + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/conf.d/ + - name: media + mountPath: /app/private_media + subPath: {{ .Values.persistence.privateMediaMountSubpath | default "openklant/private_media" }} + - name: media + mountPath: /app/media + subPath: {{ .Values.persistence.mediaMountSubpath | default "openklant/media" }} + volumes: + - name: media + persistentVolumeClaim: + {{- if .Values.persistence.enabled }} + claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ include "openklant.fullname" . }}{{- end }} + {{- else }} + emptyDir: { } + {{- end }} + - name: nginx-config + configMap: + name: {{ if .Values.nginx.existingConfigmap }}{{ .Values.nginx.existingConfigmap }}{{- else }}{{ include "openklant.nginxFullname" . }}{{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + +--- diff --git a/charts/openklant/templates/hpa.yaml b/charts/openklant/templates/hpa.yaml index dd043fd..da4a1df 100644 --- a/charts/openklant/templates/hpa.yaml +++ b/charts/openklant/templates/hpa.yaml @@ -31,3 +31,38 @@ spec: {{- end }} {{- end }} + +--- + +{{- if .Values.nginx.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "openklant.nginxFullname" . }} + labels: + {{- include "openklant.nginxSelectorLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "openklant.nginxFullname" . }} + minReplicas: {{ .Values.nginx.autoscaling.minReplicas }} + maxReplicas: {{ .Values.nginx.autoscaling.maxReplicas }} + metrics: + {{- if .Values.nginx.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.nginx.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.nginx.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.nginx.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/openklant/templates/ingress.yaml b/charts/openklant/templates/ingress.yaml index a89e867..6196182 100644 --- a/charts/openklant/templates/ingress.yaml +++ b/charts/openklant/templates/ingress.yaml @@ -1,6 +1,6 @@ {{- if .Values.ingress.enabled -}} -{{- $fullName := include "openklant.fullname" . -}} -{{- $svcPort := .Values.service.port -}} +{{- $fullName := include "openklant.nginxFullname" . -}} +{{- $svcPort := .Values.nginx.service.port -}} {{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} diff --git a/charts/openklant/templates/persistent-volume-claim.yaml b/charts/openklant/templates/persistent-volume-claim.yaml new file mode 100644 index 0000000..0acc699 --- /dev/null +++ b/charts/openklant/templates/persistent-volume-claim.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "openklant.fullname" . }} + labels: + {{- include "openklant.labels" . | nindent 4 }} +spec: + accessModes: + - ReadWriteMany + storageClassName: {{ .Values.persistence.storageClassName }} + resources: + requests: + storage: {{ .Values.persistence.size }} +{{- end }} diff --git a/charts/openklant/templates/service.yaml b/charts/openklant/templates/service.yaml index 0a4707d..0fca61f 100644 --- a/charts/openklant/templates/service.yaml +++ b/charts/openklant/templates/service.yaml @@ -13,3 +13,26 @@ spec: name: http selector: {{- include "openklant.selectorLabels" . | nindent 4 }} + +--- + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "openklant.nginxFullname" . }} + labels: + {{- include "openklant.nginxLabels" . | nindent 4 }} + {{- with .Values.nginx.service.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }} : {{ tpl ($value | toString) $ }} + {{- end }} + {{- end }} +spec: + type: {{ .Values.nginx.service.type }} + ports: + - port: {{ .Values.nginx.service.port }} + targetPort: 8000 + name: http + selector: + {{- include "openklant.nginxSelectorLabels" . | nindent 4 }} diff --git a/charts/openklant/values.yaml b/charts/openklant/values.yaml index e5a3aee..21a8e92 100644 --- a/charts/openklant/values.yaml +++ b/charts/openklant/values.yaml @@ -149,6 +149,14 @@ tolerations: [] affinity: {} +persistence: + enabled: true + size: 1Gi + storageClassName: "" + existingClaim: null + mediaMountSubpath: openklant/media + privateMediaMountSubpath: openklant/private_media + # Existing Secret must be defined for AzureVaultSecret to work existingSecret: null @@ -277,6 +285,44 @@ worker: targetCPUUtilizationPercentage: 80 targetMemoryUtilizationPercentage: 80 + +nginx: + image: + repository: nginxinc/nginx-unprivileged + pullPolicy: IfNotPresent + tag: stable + existingConfigmap: null + config: + clientMaxBodySize: 10M + service: + type: ClusterIP + port: 80 + annotations: {} + replicaCount: 1 + podLabels: {} + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: false + runAsNonRoot: true + runAsUser: 101 + autoscaling: + enabled: false + livenessProbe: + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + successThreshold: 1 + readinessProbe: + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + successThreshold: 1 + resources: {} + ################## # Redis subchart # ##################