diff --git a/charts/document-engine/templates/deployment.yaml b/charts/document-engine/templates/deployment.yaml index c68842c..927b797 100644 --- a/charts/document-engine/templates/deployment.yaml +++ b/charts/document-engine/templates/deployment.yaml @@ -203,13 +203,34 @@ spec: lifecycle: {{- toYaml . | nindent 12 }} {{- end }} + {{- if .Values.nginxSidecar.enabled }} + - name: nginx-sidecar + image: {{ .Values.nginxSidecar.image }} + imagePullPolicy: IfNotPresent + ports: + - name: nginx + containerPort: {{ .Values.nginxSidecar.port }} + protocol: TCP + resources: + {{- toYaml .Values.nginxSidecar.resources | nindent 12 }} + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + {{- end }} {{- if .Values.sidecars }} {{ toYaml .Values.sidecars | nindent 8 }} {{- end }} {{- if or .Values.extraVolumeMounts - .Values.certificateTrust.digitalSignatures - .Values.certificateTrust.customCertificates }} + .Values.certificateTrust.digitalSignatures + .Values.certificateTrust.customCertificates + .Values.nginxSidecar.enabled }} volumes: + {{- if .Values.nginxSidecar.enabled }} + - name: nginx-config + configMap: + name: {{ include "document-engine.fullname" . }}-nginx-sidecar + {{- end }} {{- with .Values.extraVolumes }} {{ toYaml . | nindent 8 }} {{- end }} diff --git a/charts/document-engine/templates/nginx-sidecar-configmap.yaml b/charts/document-engine/templates/nginx-sidecar-configmap.yaml new file mode 100644 index 0000000..61a4d81 --- /dev/null +++ b/charts/document-engine/templates/nginx-sidecar-configmap.yaml @@ -0,0 +1,63 @@ +{{- if .Values.nginxSidecar.enabled -}} +{{- $fullName := include "document-engine.fullname" . -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ $fullName }}-nginx-sidecar + labels: + {{- include "document-engine.labels" . | nindent 4 }} +data: + nginx.conf: | + events { + worker_connections 1024; + } + + http { + # Extract document ID from URI + map $uri $document_id { + default ""; + ~^/api/documents/([a-zA-Z0-9._~-]+) $1; + ~^/i/d/([a-zA-Z0-9._~-]+) $1; + ~^/documents/([a-zA-Z0-9._~-]+) $1; + ~^/dashboard/api/document/([a-zA-Z0-9._~-]+) $1; + } + + # Use hash_key for routing decision + map $document_id $hash_key { + default $request_id; + "~." $document_id; + } + + resolver kube-dns.kube-system.svc.cluster.local valid=5s; + + upstream document_engine_backend { + # Resolve DNS to get all pod IPs from headless service + server {{ $fullName }}-headless.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.port }} resolve; + + # Consistent hash based on document ID + hash $hash_key consistent; + } + + server { + listen {{ .Values.nginxSidecar.port }}; + + location / { + # Add debug headers + add_header X-Hash-Key $hash_key always; + add_header X-Pod-Name $hostname always; + + # Forward to consistent backend + proxy_pass http://document_engine_backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Timeouts + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + } + } +{{- end }} diff --git a/charts/document-engine/templates/service-headless.yaml b/charts/document-engine/templates/service-headless.yaml new file mode 100644 index 0000000..127231c --- /dev/null +++ b/charts/document-engine/templates/service-headless.yaml @@ -0,0 +1,17 @@ +{{- if .Values.nginxSidecar.enabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "document-engine.fullname" . }}-headless + labels: + {{- include "document-engine.labels" . | nindent 4 }} +spec: + clusterIP: None + selector: + {{- include "document-engine.selectorLabels" . | nindent 4 }} + ports: + - port: {{ .Values.service.port }} + targetPort: api + protocol: TCP + name: api +{{- end }} diff --git a/charts/document-engine/templates/service.yaml b/charts/document-engine/templates/service.yaml index 109a05b..dd98576 100644 --- a/charts/document-engine/templates/service.yaml +++ b/charts/document-engine/templates/service.yaml @@ -18,7 +18,11 @@ spec: {{- end }} ports: - port: {{ .Values.service.port }} + {{- if .Values.nginxSidecar.enabled }} + targetPort: nginx + {{- else }} targetPort: api + {{- end }} protocol: TCP name: api {{- with .Values.observability.metrics.prometheusEndpoint }} diff --git a/charts/document-engine/values.yaml b/charts/document-engine/values.yaml index d5c5408..cd08325 100644 --- a/charts/document-engine/values.yaml +++ b/charts/document-engine/values.yaml @@ -890,6 +890,29 @@ extraIngresses: {} # pathType: Prefix # tls: [] +# -- (object) Nginx sidecar for consistent hashing by document ID +# @section -- C. Networking +# @notationType -- reference +nginxSidecar: + # -- Enable nginx sidecar for consistent hashing + # @section -- C. Networking + enabled: false + # -- Nginx sidecar image + # @section -- C. Networking + image: nginx:1.25-alpine + # -- Port where nginx sidecar listens + # @section -- C. Networking + port: 8080 + # -- Resource limits for nginx sidecar + # @section -- C. Networking + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 50m + memory: 64Mi + # https://editor.networkpolicy.io/ # -- (object) [Network policy](https://kubernetes.io/docs/concepts/services-networking/network-policies/) # @section -- C. Networking