kube-prometheus-stack es el chart de Helm de la comunidad Prometheus que despliega de una vez Prometheus Operator, Prometheus, Alertmanager, Grafana, node-exporter y kube-state-metrics, junto con dashboards y reglas de alerta ya preparados para Kubernetes. En este tutorial lo instalarás con almacenamiento persistente, accederás a Prometheus y Grafana, añadirás una aplicación propia al monitoreo con un ServiceMonitor y crearás una alerta con un PrometheusRule.

Requisitos previos

Para seguir esta guía necesitas:

  • Un clúster de Kubernetes 1.29 o superior con unos 4 GB de RAM y 2 vCPU libres para el stack, por ejemplo desplegado sobre VPS de CubePath.
  • Una StorageClass por defecto para los volúmenes de Prometheus, Alertmanager y Grafana (kubectl get storageclass).
  • Una estación de trabajo con kubectl configurado contra el clúster y Helm 3 o superior.

Qué instala el chart

ComponenteFunción
Prometheus OperatorGestiona Prometheus y Alertmanager a partir de recursos personalizados (ServiceMonitor, PodMonitor, PrometheusRule).
PrometheusRecoge y almacena las métricas.
AlertmanagerAgrupa las alertas y las envía a correo, Slack, PagerDuty, etc.
GrafanaVisualización, con dashboards de Kubernetes preinstalados.
node-exporterDaemonSet con métricas de cada nodo: CPU, memoria, disco, red.
kube-state-metricsMétricas del estado de los objetos: réplicas, reinicios, pods pendientes.

La idea clave es que no editas la configuración de Prometheus a mano: creas objetos ServiceMonitor o PrometheusRule y el operador los traduce.

Paso 1: Añadir el repositorio de Helm

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

Comprueba que el chart está disponible:

helm search repo prometheus-community/kube-prometheus-stack
NAME                                            CHART VERSION   APP VERSION   DESCRIPTION
prometheus-community/kube-prometheus-stack      ...             ...           kube-prometheus-stack collects Kubernetes manif...

Paso 2: Preparar el fichero de valores

Los valores por defecto guardan las métricas en un volumen efímero (se pierden si el pod se reinicia) y hacen que Prometheus solo recoja los ServiceMonitor creados por el propio chart. Crea un fichero de valores que corrija ambas cosas:

nano kps-values.yaml
grafana:
  adminPassword: your_strong_password
  persistence:
    enabled: true
    size: 5Gi

prometheus:
  prometheusSpec:
    retention: 15d
    retentionSize: 18GB
    # Recoger ServiceMonitor, PodMonitor y reglas de cualquier namespace,
    # no solo los que llevan la etiqueta del release de Helm
    serviceMonitorSelectorNilUsesHelmValues: false
    podMonitorSelectorNilUsesHelmValues: false
    ruleSelectorNilUsesHelmValues: false
    storageSpec:
      volumeClaimTemplate:
        spec:
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 20Gi

alertmanager:
  alertmanagerSpec:
    storage:
      volumeClaimTemplate:
        spec:
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 2Gi

Sustituye your_strong_password por una contraseña segura para el usuario admin de Grafana. retentionSize limita el espacio que ocupan las métricas; déjalo algo por debajo del tamaño del volumen para que Prometheus borre datos antiguos antes de llenar el disco.

Paso 3: Instalar kube-prometheus-stack

Instala el chart en el namespace monitoring:

helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack \
  --namespace monitoring --create-namespace \
  -f kps-values.yaml

La primera instalación tarda uno o dos minutos. Comprueba los pods:

kubectl get pods -n monitoring
NAME                                                        READY   STATUS    RESTARTS   AGE
alertmanager-kube-prometheus-stack-alertmanager-0           2/2     Running   0          90s
kube-prometheus-stack-grafana-5c7f9b8d6b-7xk2p              3/3     Running   0          95s
kube-prometheus-stack-kube-state-metrics-6d9c8b7f4-lm9qz    1/1     Running   0          95s
kube-prometheus-stack-operator-7b9d6c5f8-pp4tw              1/1     Running   0          95s
kube-prometheus-stack-prometheus-node-exporter-4hq8x        1/1     Running   0          95s
kube-prometheus-stack-prometheus-node-exporter-9rt2c        1/1     Running   0          95s
prometheus-kube-prometheus-stack-prometheus-0               2/2     Running   0          90s

Debe haber un pod de node-exporter por nodo. Comprueba también que los volúmenes se han creado:

kubectl get pvc -n monitoring

Los tres PVC (Prometheus, Alertmanager y Grafana) deben estar en estado Bound.

Paso 4: Acceder a Prometheus y Grafana

Los servicios del chart son de tipo ClusterIP, así que no están expuestos fuera del clúster. Para una primera prueba usa port-forward desde tu estación de trabajo:

kubectl port-forward -n monitoring svc/kube-prometheus-stack-prometheus 9090:9090

Abre http://localhost:9090 y ve a Status > Target health. Todos los objetivos deben aparecer como UP, salvo lo que se explica en la sección de solución de problemas sobre kubeadm. Prueba una consulta en la pestaña Query, por ejemplo el uso de CPU por nodo:

100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

Detén el port-forward con Ctrl+C y abre el de Grafana:

kubectl port-forward -n monitoring svc/kube-prometheus-stack-grafana 3000:80

Entra en http://localhost:3000 con el usuario admin y la contraseña del fichero de valores. En Dashboards encontrarás decenas de paneles ya configurados. Empieza por:

  • Kubernetes / Compute Resources / Cluster: CPU y memoria por namespace.
  • Kubernetes / Compute Resources / Namespace (Pods): consumo de cada pod frente a sus requests y limits.
  • Node Exporter / Nodes: disco, red y carga de cada nodo.

Paso 5: Monitorizar una aplicación con ServiceMonitor

Un ServiceMonitor le dice al operador qué Service debe consultar Prometheus y en qué puerto están las métricas. Para probarlo desplegarás podinfo, una pequeña aplicación de ejemplo que expone métricas en /metrics en el puerto 9898:

nano podinfo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: podinfo
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: podinfo
  template:
    metadata:
      labels:
        app: podinfo
    spec:
      containers:
        - name: podinfo
          image: ghcr.io/stefanprodan/podinfo:6.7.1
          ports:
            - name: http
              containerPort: 9898
---
apiVersion: v1
kind: Service
metadata:
  name: podinfo
  namespace: default
  labels:
    app: podinfo
spec:
  selector:
    app: podinfo
  ports:
    - name: http
      port: 9898
      targetPort: http
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: podinfo
  namespace: default
spec:
  selector:
    matchLabels:
      app: podinfo
  endpoints:
    - port: http
      path: /metrics
      interval: 30s

Dos detalles importantes: el selector del ServiceMonitor apunta a las etiquetas del Service, no del pod, y port es el nombre del puerto del Service. Aplica el manifiesto:

kubectl apply -f podinfo.yaml

En uno o dos minutos, la página Status > Target health de Prometheus mostrará un nuevo grupo serviceMonitor/default/podinfo/0 con dos objetivos UP, uno por réplica. También puedes comprobarlo con una consulta:

up{job="podinfo"}
up{container="podinfo", endpoint="http", instance="10.244.1.23:9898", job="podinfo", namespace="default", pod="podinfo-7c9b8d5f6-2klqx", service="podinfo"}  1
up{container="podinfo", endpoint="http", instance="10.244.2.17:9898", job="podinfo", namespace="default", pod="podinfo-7c9b8d5f6-v8xrt", service="podinfo"}  1

Paso 6: Crear una alerta con PrometheusRule

Las reglas de alerta también se declaran como recursos. Crea una alerta que salte si alguna réplica de podinfo deja de responder durante dos minutos:

nano podinfo-rules.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: podinfo-alerts
  namespace: default
spec:
  groups:
    - name: podinfo
      rules:
        - alert: PodinfoTargetDown
          expr: up{job="podinfo"} == 0
          for: 2m
          labels:
            severity: warning
          annotations:
            summary: "podinfo no responde en {{ $labels.pod }}"
            description: "Prometheus no puede leer las métricas de {{ $labels.instance }} desde hace 2 minutos."

Aplica la regla:

kubectl apply -f podinfo-rules.yaml

Verifica que Prometheus la ha cargado en la página Alerts o con port-forward activo:

curl -s http://localhost:9090/api/v1/rules | grep -o '"name":"PodinfoTargetDown"'
"name":"PodinfoTargetDown"

Para probarla, escala podinfo a cero réplicas no sirve (desaparecen los objetivos en lugar de fallar). En su lugar, cambia temporalmente el path del ServiceMonitor a una ruta inexistente como /nometrics: los objetivos pasarán a DOWN y, tras dos minutos, la alerta aparecerá como Firing en Prometheus y en Alertmanager (kubectl port-forward -n monitoring svc/kube-prometheus-stack-alertmanager 9093:9093). Restaura el path al terminar.

Solución de problemas

  • Los objetivos kube-controller-manager, kube-scheduler, kube-etcd y kube-proxy aparecen como DOWN en clústeres kubeadm. Por defecto esos componentes solo escuchan en 127.0.0.1. Cambia --bind-address a 0.0.0.0 en los manifiestos de /etc/kubernetes/manifests/ del plano de control (y --listen-metrics-urls para etcd, metricsBindAddress en el ConfigMap de kube-proxy), protegiendo esos puertos con el firewall, o desactiva esos monitores en los valores del chart (kubeControllerManager.enabled: false, etc.) si no los necesitas.
  • Un ServiceMonitor no aparece en los objetivos. Comprueba que las etiquetas del selector coinciden con las del Service, que el nombre del puerto es correcto y que usaste serviceMonitorSelectorNilUsesHelmValues: false. Los logs del operador ayudan: kubectl logs -n monitoring deploy/kube-prometheus-stack-operator.
  • Los pods de Prometheus se quedan en Pending. Suele ser el PVC sin StorageClass. Revisa kubectl describe pvc -n monitoring.

Conclusión

Tienes un stack de monitoreo completo: métricas de nodos, del plano de control y de los objetos de Kubernetes, dashboards en Grafana, y la forma declarativa de añadir tus aplicaciones y alertas con ServiceMonitor y PrometheusRule. Como siguientes pasos, configura los receptores de Alertmanager (valor alertmanager.config del chart) para recibir las alertas por correo o Slack, publica Grafana con Ingress y TLS, y ajusta la retención según el espacio disponible o envía las métricas a un almacenamiento a largo plazo con remoteWrite.