diff --git a/.gitignore b/.gitignore index f7623a94f..560a16f2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +*.db +*.bak +*.backup mcpgateway.sbom.xml gateway_service_leader.lock docs/docs/test/ diff --git a/charts/README.md b/charts/README.md index fe0cdc43c..080f1b817 100644 --- a/charts/README.md +++ b/charts/README.md @@ -168,13 +168,13 @@ helm lint . ```bash # Upgrade only the gateway image -ahelm upgrade mcp-stack . -n mcp \ +ahelm upgrade mcp-stack . -n mcp-private\ --set mcpContextForge.image.tag=v1.2.3 \ --wait # Preview changes (requires helm‑diff plugin) helm plugin install https://github.com/databus23/helm-diff -helm diff upgrade mcp-stack . -n mcp -f my-values.yaml +helm diff upgrade mcp-stack . -n mcp-private-f my-values.yaml # Roll back to revision 1 helm rollback mcp-stack 1 -n mcp @@ -376,7 +376,7 @@ helm upgrade --install mcp-stack charts/mcp-stack \ # Later: raise the ceiling & make scaling more aggressive helm upgrade mcp-stack charts/mcp-stack \ - -n mcp \ + -n mcp-private\ --reuse-values \ --set mcpContextForge.hpa.maxReplicas=20 \ --set mcpContextForge.hpa.targetCPUUtilizationPercentage=60 \ @@ -391,12 +391,12 @@ Useful in emergencies or during load tests. ```bash # Bump minReplicas from 3 → 5 -kubectl patch hpa mcp-stack-mcpgateway -n mcp \ +kubectl patch hpa mcp-stack-mcpgateway -n mcp-private\ --type merge \ -p '{"spec":{"minReplicas":5}}' # Drop the CPU target from 80 % → 65 % (scale up sooner) -kubectl patch hpa mcp-stack-mcpgateway -n mcp \ +kubectl patch hpa mcp-stack-mcpgateway -n mcp-private\ --type json \ -p '[{"op":"replace","path":"/spec/metrics/0/resource/target/averageUtilization","value":65}]' ``` @@ -421,6 +421,25 @@ NAME TARGETS MINPODS MAXPODS REPLICAS mcp-stack-mcpgateway 55%/70% 2 15 4 ``` +### Check scaling events + +```bash +# 1. Show the last few scale-up / scale-down events +kubectl describe hpa mcp-stack-mcpgateway -n mcp-private | tail -n 20 + +# 2. Stream HPA events as they happen +kubectl get events -n mcp-private \ + --field-selector involvedObject.kind=HorizontalPodAutoscaler,\ +involvedObject.name=mcp-stack-mcpgateway \ + --watch + +# 3. Watch target utilisation & replica count refresh every 2 s +watch -n2 kubectl get hpa mcp-stack-mcpgateway -n mcp-private + +# 4. Live pod-level CPU / memory (confirm the numbers the HPA sees) +kubectl top pods -l app=mcp-stack-mcpgateway -n mcp-private --sort-by=cpu +``` + --- ### Prerequisites & Gotchas diff --git a/charts/mcp-stack/values.yaml b/charts/mcp-stack/values.yaml index 220465a7c..2a474b75d 100644 --- a/charts/mcp-stack/values.yaml +++ b/charts/mcp-stack/values.yaml @@ -12,12 +12,19 @@ global: ######################################################################## mcpContextForge: replicaCount: 2 # horizontal scaling for the gateway - hpa: # Horizontal pod autoscaler - enabled: true # default on; switch to false to disable HPA - minReplicas: 2 # must be >= 1 - maxReplicas: 10 - targetCPUUtilizationPercentage: 80 # average CPU utilisation target - targetMemoryUtilizationPercentage: 80 # uncomment to add memory metric + + # --- HORIZONTAL POD AUTOSCALER -------------------------------------- + # * Percentages compare live usage with the container *request* values + # (limits are ignored by the HPA). + # * If both CPU and memory targets are set, crossing either threshold + # triggers a scale event. + # -------------------------------------------------------------------- + hpa: + enabled: true # Set to false to keep a fixed replica count + minReplicas: 2 # Never scale below this + maxReplicas: 10 # Never scale above this + targetCPUUtilizationPercentage: 90 # Scale up when avg CPU > 90 % of *request* + targetMemoryUtilizationPercentage: 90 # Scale up when avg memory > 90 % of *request* image: repository: ghcr.io/ibm/mcp-context-forge @@ -68,7 +75,7 @@ mcpContextForge: memory: 1024Mi requests: cpu: 100m - memory: 256Mi + memory: 512Mi # Optional ingress for HTTP traffic ingress: diff --git a/charts/mcpgateway/Chart.yaml b/charts/mcpgateway/Chart.yaml deleted file mode 100644 index f2ff4e597..000000000 --- a/charts/mcpgateway/Chart.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v2 -name: mcpgateway -description: A Helm chart for deploying MCP Gateway to Kubernetes -type: application -version: 0.2.0 -appVersion: "latest" -keywords: - - mcp - - gateway - - kubernetes - - helm -maintainers: - - name: Mihai Criveti - email: redacted@ibm.com -sources: - - https://github.com/IBM/mcp-context-forge diff --git a/charts/mcpgateway/templates/_helpers.tpl b/charts/mcpgateway/templates/_helpers.tpl deleted file mode 100644 index c38b864af..000000000 --- a/charts/mcpgateway/templates/_helpers.tpl +++ /dev/null @@ -1,28 +0,0 @@ -{{- define "mcpgateway.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end }} - -{{- define "mcpgateway.fullname" -}} -{{- if .Values.fullnameOverride }} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end }} - -{{- define "mcpgateway.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version -}} -{{- end }} - -{{- define "mcpgateway.labels" -}} -app.kubernetes.io/name: {{ include "mcpgateway.name" . }} -helm.sh/chart: {{ include "mcpgateway.chart" . }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -app.kubernetes.io/instance: {{ .Release.Name }} -app.kubernetes.io/version: {{ .Chart.AppVersion }} -{{- end }} diff --git a/charts/mcpgateway/templates/configmap.yaml b/charts/mcpgateway/templates/configmap.yaml deleted file mode 100644 index e356791c5..000000000 --- a/charts/mcpgateway/templates/configmap.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "mcpgateway.fullname" . }}-config - labels: - app: {{ include "mcpgateway.name" . }} - chart: {{ include "mcpgateway.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -data: - # Add any configuration data here as key-value pairs - # Example: - # config.yaml: |- - # key: value diff --git a/charts/mcpgateway/templates/deployment.yaml b/charts/mcpgateway/templates/deployment.yaml deleted file mode 100644 index fe9bb497d..000000000 --- a/charts/mcpgateway/templates/deployment.yaml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "mcpgateway.fullname" . }} - labels: - app: {{ include "mcpgateway.name" . }} - chart: {{ include "mcpgateway.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -spec: - replicas: 1 - selector: - matchLabels: - app: {{ include "mcpgateway.name" . }} - release: {{ .Release.Name }} - template: - metadata: - labels: - app: {{ include "mcpgateway.name" . }} - release: {{ .Release.Name }} - spec: - containers: - - name: mcpgateway - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - ports: - - containerPort: {{ .Values.env.PORT | default 4444 | int }} - env: -{{- range $key, $value := .Values.env }} - - name: {{ $key }} -{{- if and (index $.Values.secrets $key) (not (empty (index $.Values.secrets $key))) }} - valueFrom: - secretKeyRef: - name: {{ index $.Values.secrets $key }} - key: {{ $key }} -{{- else }} - value: {{ $value | quote }} -{{- end }} -{{- end }} diff --git a/charts/mcpgateway/templates/ingress.yaml b/charts/mcpgateway/templates/ingress.yaml deleted file mode 100644 index f3a0c47ec..000000000 --- a/charts/mcpgateway/templates/ingress.yaml +++ /dev/null @@ -1,33 +0,0 @@ -{{- if .Values.ingress.enabled }} -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: {{ include "mcpgateway.fullname" . }} - labels: - app: {{ include "mcpgateway.name" . }} - chart: {{ include "mcpgateway.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} - annotations: -{{ toYaml .Values.ingress.annotations | indent 4 }} -spec: - rules: -{{- range .Values.ingress.hosts }} - - host: {{ .host }} - http: - paths: -{{- range .paths }} - - path: {{ .path }} - pathType: {{ .pathType }} - backend: - service: - name: {{ include "mcpgateway.fullname" $ }} - port: - number: {{ $.Values.service.port }} -{{- end }} -{{- end }} - {{- if .Values.ingress.tls }} - tls: -{{ toYaml .Values.ingress.tls | indent 4 }} - {{- end }} -{{- end }} diff --git a/charts/mcpgateway/templates/service.yaml b/charts/mcpgateway/templates/service.yaml deleted file mode 100644 index 29888a4c4..000000000 --- a/charts/mcpgateway/templates/service.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "mcpgateway.fullname" . }} - labels: - app: {{ include "mcpgateway.name" . }} - chart: {{ include "mcpgateway.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -spec: - type: {{ .Values.service.type }} - ports: - - port: {{ .Values.service.port }} - targetPort: {{ .Values.env.PORT | default 4444 | int }} - protocol: TCP - name: http - selector: - app: {{ include "mcpgateway.name" . }} - release: {{ .Release.Name }} diff --git a/charts/mcpgateway/values.yaml b/charts/mcpgateway/values.yaml deleted file mode 100644 index 56ffb9493..000000000 --- a/charts/mcpgateway/values.yaml +++ /dev/null @@ -1,52 +0,0 @@ -# Default values for mcpgateway Helm chart - -image: - repository: ghcr.io/ibm/mcp-context-forge - tag: local-arm64 - pullPolicy: IfNotPresent - -env: - APP_NAME: "MCP_Gateway" - HOST: "0.0.0.0" - PORT: 4444 - DATABASE_URL: "sqlite:///./mcp.db" - APP_ROOT_PATH: "" - CACHE_TYPE: "database" - REDIS_URL: "redis://redis:6379/0" - CACHE_PREFIX: "mcpgw:" - SESSION_TTL: 3600 - MESSAGE_TTL: 600 - BASIC_AUTH_USER: "admin" - BASIC_AUTH_PASSWORD: "changeme" - AUTH_REQUIRED: "true" - JWT_SECRET_KEY: "my-test-key" - JWT_ALGORITHM: "HS256" - TOKEN_EXPIRY: 10080 - AUTH_ENCRYPTION_SECRET: "my-test-salt" - MCPGATEWAY_UI_ENABLED: "true" - MCPGATEWAY_ADMIN_API_ENABLED: "true" - CORS_ENABLED: "true" - ALLOWED_ORIGINS: - - "http://localhost:3000" - LOG_LEVEL: "INFO" - LOG_FORMAT: "json" - TRANSPORT_TYPE: "all" - FEDERATION_ENABLED: "true" - FEDERATION_DISCOVERY: "false" - FEDERATION_PEERS: [] - -secrets: {} - -service: - type: ClusterIP - port: 4444 - -ingress: - enabled: false - annotations: {} - hosts: - - host: gateway.example.com - paths: - - path: / - pathType: Prefix - tls: []