Prometheus Adapter HPA on k3s
This lab adds prometheus-adapter to an existing kube-prometheus-stack install on k3s, then scales a Deployment with HPA on a custom metric.
Prerequisites: Installing Prometheus and Grafana on k3s completed (monitoring namespace, release name monitoring). CPU-only HPA first: HPA on k3s.
EKS production path: Prometheus Adapter for HPA on EKS.
Step 1: Confirm Prometheus is reachable
Section titled “Step 1: Confirm Prometheus is reachable”kubectl get pods -n monitoringkubectl port-forward -n monitoring svc/monitoring-kube-prometheus-prometheus 9090:9090Open http://127.0.0.1:9090 and run Status → Targets — core targets should be UP.
Prometheus Service DNS (used by the adapter):
http://monitoring-kube-prometheus-prometheus.monitoring.svc:9090If your release name differs, adjust: kubectl get svc -n monitoring.
Step 2: Adapter rules
Section titled “Step 2: Adapter rules”Create adapter-rules.yaml:
rules: - seriesQuery: 'http_requests_total{namespace!="",pod!=""}' resources: overrides: namespace: { resource: "namespace" } pod: { resource: "pod" } name: matches: "^(.*)_total$" as: "${1}_per_second" metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'Step 3: Install prometheus-adapter
Section titled “Step 3: Install prometheus-adapter”Create prometheus-adapter-values.yaml:
prometheus: url: http://monitoring-kube-prometheus-prometheus.monitoring.svc port: 9090
rules: existing: adapter-rules
replicas: 1helm repo add prometheus-community https://prometheus-community.github.io/helm-chartshelm repo update
helm upgrade --install prometheus-adapter prometheus-community/prometheus-adapter \ --namespace monitoring \ -f prometheus-adapter-values.yaml \ --waitVerify:
kubectl get apiservice v1beta1.custom.metrics.k8s.iokubectl get pods -n monitoring -l app.kubernetes.io/name=prometheus-adapterkubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | head -c 1500Step 4: Sample app with metrics
Section titled “Step 4: Sample app with metrics”Deploy httpbin (or any exporter of http_requests_total) in namespace hpa-promo:
kubectl create namespace hpa-promohttpbin-promo.yaml:
apiVersion: apps/v1kind: Deploymentmetadata: name: httpbin namespace: hpa-promospec: replicas: 2 selector: matchLabels: app: httpbin template: metadata: labels: app: httpbin spec: containers: - name: httpbin image: mccutchen/go-httpbin:v2.15.0 ports: - containerPort: 8080 resources: requests: cpu: 50m memory: 64Mi---apiVersion: v1kind: Servicemetadata: name: httpbin namespace: hpa-promo labels: app: httpbinspec: selector: app: httpbin ports: - name: http port: 80 targetPort: 8080For kube-prometheus-stack to scrape the app, add a ServiceMonitor (labels must match your Prometheus serviceMonitorSelector — often release: monitoring):
apiVersion: monitoring.coreos.com/v1kind: ServiceMonitormetadata: name: httpbin namespace: hpa-promo labels: release: monitoringspec: selector: matchLabels: app: httpbin endpoints: - port: http path: /metrics interval: 15sgo-httpbin may not expose Prometheus metrics by default — for a reliable lab, use an image with /metrics or add a small exporter sidecar. If no series appear, HPA will not scale; confirm a metric exists in Prometheus Explore before applying HPA.
For a known-good pattern, copy scrape config from Observability setup — ServiceMonitor for your app’s metric names.
kubectl apply -f httpbin-promo.yaml# apply ServiceMonitor when your app exports /metricsStep 5: HPA on custom metric
Section titled “Step 5: HPA on custom metric”When Prometheus shows http_requests_per_second (or your rule’s output name):
apiVersion: autoscaling/v2kind: HorizontalPodAutoscalermetadata: name: httpbin-hpa namespace: hpa-promospec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: httpbin minReplicas: 2 maxReplicas: 6 metrics: - type: Pods pods: metric: name: http_requests_per_second target: type: AverageValue averageValue: "10"kubectl apply -f httpbin-hpa.yamlkubectl describe hpa httpbin-hpa -n hpa-promoGenerate load (port-forward + hey, or wget loop) as in HPA on k3s.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Check |
|---|---|
| custom.metrics APIService missing | Adapter pod logs, Helm release |
| No metric in API | PromQL in Prometheus UI; adapter rules |
| HPA unknown | Metric name must match adapter as: rule |
| ServiceMonitor ignored | release label vs Prometheus selector |
Cleanup
Section titled “Cleanup”helm uninstall prometheus-adapter -n monitoringkubectl delete namespace hpa-promoTo remove the full stack, see Prometheus + Grafana on k3s — Cleanup.