From 962274e9a5c7ddf6276e8e576f28db21b905093f Mon Sep 17 00:00:00 2001 From: Nickolay Kondratenko Date: Sun, 25 May 2025 23:09:10 +0300 Subject: [PATCH 1/6] add helm chart --- infra/charts/mongodb/values.yaml | 19 ++++++++ infra/charts/server/Chart.yaml | 8 ++++ infra/charts/server/templates/_helpers.tpl | 18 ++++++++ infra/charts/server/templates/deployment.yaml | 44 +++++++++++++++++++ infra/charts/server/templates/hpa.yaml | 21 +++++++++ .../server/templates/prometheus-rules.yaml | 20 +++++++++ infra/charts/server/templates/secret.yaml | 7 +++ infra/charts/server/templates/service.yaml | 13 ++++++ .../server/templates/servicemonitor.yaml | 19 ++++++++ infra/charts/server/values.yaml | 31 +++++++++++++ 10 files changed, 200 insertions(+) create mode 100644 infra/charts/mongodb/values.yaml create mode 100644 infra/charts/server/Chart.yaml create mode 100644 infra/charts/server/templates/_helpers.tpl create mode 100644 infra/charts/server/templates/deployment.yaml create mode 100644 infra/charts/server/templates/hpa.yaml create mode 100644 infra/charts/server/templates/prometheus-rules.yaml create mode 100644 infra/charts/server/templates/secret.yaml create mode 100644 infra/charts/server/templates/service.yaml create mode 100644 infra/charts/server/templates/servicemonitor.yaml create mode 100644 infra/charts/server/values.yaml diff --git a/infra/charts/mongodb/values.yaml b/infra/charts/mongodb/values.yaml new file mode 100644 index 0000000..8d80313 --- /dev/null +++ b/infra/charts/mongodb/values.yaml @@ -0,0 +1,19 @@ +auth: + enabled: true + rootUser: mongo + rootPassword: mongo + usernames: + - appuser + passwords: + - apppass + databases: + - appdb + +architecture: standalone + +persistence: + enabled: true + size: 8Gi + storageClass: default + +replicaCount: 2 diff --git a/infra/charts/server/Chart.yaml b/infra/charts/server/Chart.yaml new file mode 100644 index 0000000..f79f53d --- /dev/null +++ b/infra/charts/server/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v2 +name: server +version: 0.1.0 +description: A Helm chart for the connection management server + +dependencies: [] + +type: application diff --git a/infra/charts/server/templates/_helpers.tpl b/infra/charts/server/templates/_helpers.tpl new file mode 100644 index 0000000..4273b4c --- /dev/null +++ b/infra/charts/server/templates/_helpers.tpl @@ -0,0 +1,18 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "server.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end }} + +{{/* +Create a fully qualified name. +*/}} +{{- define "server.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} diff --git a/infra/charts/server/templates/deployment.yaml b/infra/charts/server/templates/deployment.yaml new file mode 100644 index 0000000..bc64ad7 --- /dev/null +++ b/infra/charts/server/templates/deployment.yaml @@ -0,0 +1,44 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "server.fullname" . }} + labels: + app: {{ include "server.name" . }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: {{ include "server.name" . }} + template: + metadata: + labels: + app: {{ include "server.name" . }} + spec: + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: {{ .Values.server.port }} + env: + - name: SERVER_HOSTNAME + value: {{ .Values.server.hostname | quote }} + - name: SERVER_PORT + value: {{ .Values.server.port | quote }} + - name: MONGO_URL + valueFrom: + secretKeyRef: + name: {{ include "server.fullname" . }}-secret + key: url + readinessProbe: + httpGet: + path: /health + port: {{ .Values.server.port }} + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + httpGet: + path: /health + port: {{ .Values.server.port }} + initialDelaySeconds: 15 + periodSeconds: 20 diff --git a/infra/charts/server/templates/hpa.yaml b/infra/charts/server/templates/hpa.yaml new file mode 100644 index 0000000..5ee9d54 --- /dev/null +++ b/infra/charts/server/templates/hpa.yaml @@ -0,0 +1,21 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "server.fullname" . }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "server.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + - type: Pods + pods: + metric: + name: request_latency_seconds + target: + type: AverageValue + averageValue: {{ .Values.autoscaling.targetLatency }} +{{- end }} diff --git a/infra/charts/server/templates/prometheus-rules.yaml b/infra/charts/server/templates/prometheus-rules.yaml new file mode 100644 index 0000000..4d585a8 --- /dev/null +++ b/infra/charts/server/templates/prometheus-rules.yaml @@ -0,0 +1,20 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ include "server.fullname" . }}-rules + labels: + release: prometheus +spec: + groups: + - name: {{ include "server.fullname" . }}.rules + rules: + - record: job:request_latency_seconds:avg + expr: avg(rate(request_latency_seconds_sum[1m])) by (job) + - alert: HighRequestLatency + expr: avg(rate(request_latency_seconds_sum[1m])) > 0.3 + for: 1m + labels: + severity: warning + annotations: + summary: "High request latency detected (>300ms)" + description: "Request latency is above threshold for more than 1 minute." diff --git a/infra/charts/server/templates/secret.yaml b/infra/charts/server/templates/secret.yaml new file mode 100644 index 0000000..d6089c4 --- /dev/null +++ b/infra/charts/server/templates/secret.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "server.fullname" . }}-secret +stringData: + url: {{ .Values.mongo.url }} +type: Opaque diff --git a/infra/charts/server/templates/service.yaml b/infra/charts/server/templates/service.yaml new file mode 100644 index 0000000..1beb1b6 --- /dev/null +++ b/infra/charts/server/templates/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "server.fullname" . }} +spec: + type: {{ .Values.service.type }} + selector: + app: {{ include "server.name" . }} + ports: + - port: {{ .Values.service.port }} + targetPort: {{ .Values.server.port }} + protocol: TCP + name: http diff --git a/infra/charts/server/templates/servicemonitor.yaml b/infra/charts/server/templates/servicemonitor.yaml new file mode 100644 index 0000000..81dd2db --- /dev/null +++ b/infra/charts/server/templates/servicemonitor.yaml @@ -0,0 +1,19 @@ +{{- if .Values.prometheus.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "server.fullname" . }}-servicemonitor + labels: + release: prometheus +spec: + selector: + matchLabels: + app: {{ include "server.name" . }} + endpoints: + - port: http + path: /metrics + interval: {{ .Values.prometheus.serviceMonitor.interval }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} +{{- end }} diff --git a/infra/charts/server/values.yaml b/infra/charts/server/values.yaml new file mode 100644 index 0000000..7a90d24 --- /dev/null +++ b/infra/charts/server/values.yaml @@ -0,0 +1,31 @@ +replicaCount: 1 + +image: + repository: ghcr.io/kont-noor/server + tag: latest + pullPolicy: IfNotPresent + +service: + type: LoadBalancer + port: 80 + +server: + port: 3000 + hostname: 0.0.0.0 + +mongo: + #url: mongodb://mongo:mongo@mongo:27017 + url: mongodb://appuser:apppass@mongodb.mongodb.svc.cluster.local:27017/appdb + +resources: {} + +autoscaling: + enabled: true + minReplicas: 1 + maxReplicas: 10 + targetLatency: 200m + +prometheus: + enabled: true + serviceMonitor: + interval: 15s From 4c6f39fc2d2770b5095a10fa4af65161d3d623a7 Mon Sep 17 00:00:00 2001 From: Nickolay Kondratenko Date: Mon, 26 May 2025 00:22:00 +0300 Subject: [PATCH 2/6] fix local PVC provisioner --- infra/charts/mongodb/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/charts/mongodb/values.yaml b/infra/charts/mongodb/values.yaml index 8d80313..29cc325 100644 --- a/infra/charts/mongodb/values.yaml +++ b/infra/charts/mongodb/values.yaml @@ -14,6 +14,6 @@ architecture: standalone persistence: enabled: true size: 8Gi - storageClass: default + storageClass: local-path replicaCount: 2 From c353e7b94616c384ef58bdd8cfc5cc685327f7eb Mon Sep 17 00:00:00 2001 From: Nickolay Kondratenko Date: Mon, 26 May 2025 13:17:31 +0300 Subject: [PATCH 3/6] fix mongo connection --- README.md | 41 +++++++++++++++++++++- infra/charts/mongodb/values.yaml | 2 +- infra/charts/server/templates/ingress.yaml | 30 ++++++++++++++++ infra/charts/server/values.yaml | 5 ++- 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 infra/charts/server/templates/ingress.yaml diff --git a/README.md b/README.md index d1072d7..86c1191 100644 --- a/README.md +++ b/README.md @@ -129,4 +129,43 @@ Which technology stack do you recommend? 1. Node.js + redis, rack + redis, rails3 + redis, or anything else? How many dynos do you estimate we'll need to meet our performance requirements? (it's ok if you don't know, we're just wondering if you have experience with apps of such high loads) 2. Which database? -3. Where do you store the state table of connected users? (for performance reasons, we suggest keeping this in memory only) How do you make sure that it's shared across multiple dynos? \ No newline at end of file +3. Where do you store the state table of connected users? (for performance reasons, we suggest keeping this in memory only) How do you make sure that it's shared across multiple dynos? + +### Local Setup + +#### Overmind + +* It does not use dotenv setup so set the vars from `.env` +* Setup Mongo +* Run `overmind start` + +#### Docker compose + +Just run + +```bash +docker compose build +docker compose up +``` + +### K8s + +#### Local + +Setup Mongo + +```bash +helm upgrade --install mongodb bitnami/mongodb -f ./infra/charts/mongodb/values.yaml --namespace connection-request-server --create-namespace +``` + +Setup Service + +```bash +helm upgrade --install server ./infra/charts/server --namespace connection-request-server +``` + +To forward port to host machine (testing purpose) run the following + +```bash +kubectl port-forward service/server-server 8080:80 -n connection-request-server +``` \ No newline at end of file diff --git a/infra/charts/mongodb/values.yaml b/infra/charts/mongodb/values.yaml index 29cc325..9fdb432 100644 --- a/infra/charts/mongodb/values.yaml +++ b/infra/charts/mongodb/values.yaml @@ -7,7 +7,7 @@ auth: passwords: - apppass databases: - - appdb + - connections architecture: standalone diff --git a/infra/charts/server/templates/ingress.yaml b/infra/charts/server/templates/ingress.yaml new file mode 100644 index 0000000..8a8fa2f --- /dev/null +++ b/infra/charts/server/templates/ingress.yaml @@ -0,0 +1,30 @@ +{{- if .Values.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "server.fullname" . }} + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / + {{- if .Values.ingress.certManager }} + cert-manager.io/cluster-issuer: {{ .Values.ingress.clusterIssuer }} + {{- end }} +spec: + ingressClassName: nginx + rules: + - host: {{ .Values.ingress.host }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ include "server.fullname" . }} + port: + number: {{ .Values.service.port }} + {{- if .Values.ingress.tls }} + tls: + - hosts: + - {{ .Values.ingress.host }} + secretName: {{ .Values.ingress.tlsSecret }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/infra/charts/server/values.yaml b/infra/charts/server/values.yaml index 7a90d24..d9bec8c 100644 --- a/infra/charts/server/values.yaml +++ b/infra/charts/server/values.yaml @@ -15,7 +15,7 @@ server: mongo: #url: mongodb://mongo:mongo@mongo:27017 - url: mongodb://appuser:apppass@mongodb.mongodb.svc.cluster.local:27017/appdb + url: mongodb://appuser:apppass@mongodb:27017/?authSource=connections resources: {} @@ -29,3 +29,6 @@ prometheus: enabled: true serviceMonitor: interval: 15s + +ingress: + enabled: false \ No newline at end of file From 369f2b4763aae5e99a57582b0c08df78087fddf0 Mon Sep 17 00:00:00 2001 From: Nickolay Kondratenko Date: Mon, 26 May 2025 17:40:51 +0300 Subject: [PATCH 4/6] setup mongo config --- infra/charts/server/templates/deployment.yaml | 10 ++++++++++ infra/charts/server/templates/secret.yaml | 2 ++ infra/charts/server/values.yaml | 3 ++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/infra/charts/server/templates/deployment.yaml b/infra/charts/server/templates/deployment.yaml index bc64ad7..f9883b0 100644 --- a/infra/charts/server/templates/deployment.yaml +++ b/infra/charts/server/templates/deployment.yaml @@ -30,6 +30,16 @@ spec: secretKeyRef: name: {{ include "server.fullname" . }}-secret key: url + - name: MONGO_DB + valueFrom: + secretKeyRef: + name: {{ include "server.fullname" . }}-secret + key: dbname + - name: MONGO_COLLECTION + valueFrom: + secretKeyRef: + name: {{ include "server.fullname" . }}-secret + key: collectionname readinessProbe: httpGet: path: /health diff --git a/infra/charts/server/templates/secret.yaml b/infra/charts/server/templates/secret.yaml index d6089c4..8190bad 100644 --- a/infra/charts/server/templates/secret.yaml +++ b/infra/charts/server/templates/secret.yaml @@ -4,4 +4,6 @@ metadata: name: {{ include "server.fullname" . }}-secret stringData: url: {{ .Values.mongo.url }} + dbname: {{ .Values.mongo.dbname }} + collectionname: {{ .Values.mongo.collectionname }} type: Opaque diff --git a/infra/charts/server/values.yaml b/infra/charts/server/values.yaml index d9bec8c..0e8686e 100644 --- a/infra/charts/server/values.yaml +++ b/infra/charts/server/values.yaml @@ -14,8 +14,9 @@ server: hostname: 0.0.0.0 mongo: - #url: mongodb://mongo:mongo@mongo:27017 url: mongodb://appuser:apppass@mongodb:27017/?authSource=connections + dbname: connections + collectionname: connections resources: {} From f51bc300610737041b1f1d556ecbbe4537c9192f Mon Sep 17 00:00:00 2001 From: Nickolay Kondratenko Date: Mon, 26 May 2025 17:41:09 +0300 Subject: [PATCH 5/6] add prometeus --- README.md | 6 ++++++ infra/charts/prometeus/values.yaml | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 infra/charts/prometeus/values.yaml diff --git a/README.md b/README.md index 86c1191..638e452 100644 --- a/README.md +++ b/README.md @@ -168,4 +168,10 @@ To forward port to host machine (testing purpose) run the following ```bash kubectl port-forward service/server-server 8080:80 -n connection-request-server +``` + +Setup Prometeus + +```bash +helm upgrade --install prometheus prometheus-community/kube-prometheus-stack -f ./infra/charts/prometeus/values.yaml --namespace monitoring --create-namespace ``` \ No newline at end of file diff --git a/infra/charts/prometeus/values.yaml b/infra/charts/prometeus/values.yaml new file mode 100644 index 0000000..ff10111 --- /dev/null +++ b/infra/charts/prometeus/values.yaml @@ -0,0 +1,16 @@ +prometheus: + prometheusSpec: + serviceMonitorSelector: + matchLabels: + release: prometheus + podMonitorSelector: {} + ruleSelector: + matchLabels: + release: prometheus + +alertmanager: + enabled: true + +grafana: + enabled: true + adminPassword: crsAdmin \ No newline at end of file From 4efff4e8b9cdb0e1d2a545d7ad51b1d2878099be Mon Sep 17 00:00:00 2001 From: Nickolay Kondratenko Date: Tue, 27 May 2025 00:06:54 +0300 Subject: [PATCH 6/6] enable prometheus metrics --- infra/charts/server/templates/deployment.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/infra/charts/server/templates/deployment.yaml b/infra/charts/server/templates/deployment.yaml index f9883b0..d8b49d5 100644 --- a/infra/charts/server/templates/deployment.yaml +++ b/infra/charts/server/templates/deployment.yaml @@ -21,6 +21,8 @@ spec: ports: - containerPort: {{ .Values.server.port }} env: + - name: PROMETHEUS_ENABLED + value: {{ .Values.prometheus.enabled | quote }} - name: SERVER_HOSTNAME value: {{ .Values.server.hostname | quote }} - name: SERVER_PORT