--- title: "Cómo instalar Grafana Mimir en Ubuntu 24.04 con S3" description: "Instala Grafana Mimir en modo monolítico en Ubuntu 24.04, guarda las métricas en S3, envía datos desde Prometheus con remote write y separa equipos por tenant." category: "Observabilidad Avanzada" language: es source: https://cubepath.com/es/docs/observabilidad-avanzada/grafana-mimir-backend-de-metricas-escalable updated: 2026-09-25 --- # Cómo instalar Grafana Mimir en Ubuntu 24.04 con S3 Grafana Mimir es una base de datos de métricas compatible con Prometheus que escala horizontalmente, guarda los datos en almacenamiento de objetos y separa la información por tenants (inquilinos). Recibe las métricas por `remote_write` y responde a consultas PromQL, así que Prometheus y Grafana funcionan con él sin cambios. En este tutorial instalarás Mimir en modo monolítico (todos los componentes en un proceso) en Ubuntu 24.04 con un bucket S3 como backend, conectarás Prometheus y Grafana y configurarás límites por tenant. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 4 GB de RAM y 2 vCPU. El consumo de memoria crece con el número de series activas. - Un usuario no root con privilegios `sudo`. - Un almacenamiento de objetos compatible con S3 (AWS S3, MinIO, Wasabi...) con tres buckets creados: `mimir-blocks`, `mimir-ruler` y `mimir-alertmanager`, y unas credenciales con permisos de lectura, escritura, listado y borrado sobre ellos. Los buckets deben ser distintos entre sí. - Un servidor Prometheus que enviará las métricas (puede ser el mismo host). - Opcional: Grafana para consultar los datos. ## Paso 1: Instalar el binario de Mimir Mimir se distribuye como un único binario. Consulta la última versión estable en `github.com/grafana/mimir/releases` y ajusta la variable. Los releases se etiquetan como `mimir-X.Y.Z`: ```bash MIMIR_VERSION=2.17.0 cd /tmp curl -fLo mimir "https://github.com/grafana/mimir/releases/download/mimir-${MIMIR_VERSION}/mimir-linux-amd64" sudo install -m 0755 mimir /usr/local/bin/mimir ``` En un servidor arm64 descarga `mimir-linux-arm64`. Comprueba la instalación: ```bash mimir -version ``` La salida muestra la versión instalada, la rama y la revisión del binario. Crea un usuario de sistema y los directorios de configuración y datos: ```bash sudo useradd --system --no-create-home --shell /usr/sbin/nologin mimir sudo mkdir -p /etc/mimir /var/lib/mimir sudo chown mimir:mimir /var/lib/mimir ``` ## Paso 2: Crear la configuración de Mimir La configuración define el almacenamiento, los anillos de hash (que en modo monolítico solo contienen esta instancia) y los directorios locales. Mimir escribe primero las muestras en un TSDB local en los ingesters y sube los bloques al bucket cada 2 horas. Crea el archivo: ```bash sudo nano /etc/mimir/mimir.yaml ``` Sustituye `your_s3_endpoint`, `your_region`, `your_access_key` y `your_secret_key` por los datos de tu proveedor: ```yaml target: all server: http_listen_port: 9009 grpc_listen_port: 9095 log_level: info common: storage: backend: s3 s3: endpoint: your_s3_endpoint region: your_region access_key_id: your_access_key secret_access_key: your_secret_key blocks_storage: s3: bucket_name: mimir-blocks tsdb: dir: /var/lib/mimir/tsdb bucket_store: sync_dir: /var/lib/mimir/tsdb-sync ruler_storage: s3: bucket_name: mimir-ruler alertmanager_storage: s3: bucket_name: mimir-alertmanager compactor: data_dir: /var/lib/mimir/compactor sharding_ring: kvstore: store: memberlist distributor: ring: instance_addr: 127.0.0.1 kvstore: store: memberlist ingester: ring: instance_addr: 127.0.0.1 kvstore: store: memberlist replication_factor: 1 store_gateway: sharding_ring: replication_factor: 1 limits: max_global_series_per_user: 1000000 compactor_blocks_retention_period: 1y runtime_config: file: /etc/mimir/runtime.yaml ``` Puntos importantes: - `endpoint` va sin esquema, por ejemplo `s3.eu-west-1.amazonaws.com` o `minio.your_domain:9000`. Si tu MinIO no usa TLS, añade `insecure: true` dentro de `common.storage.s3`. - `replication_factor: 1` es obligatorio con una sola instancia; en un clúster se usa 3. - `limits` fija los valores por defecto para todos los tenants: 1 millón de series activas y 1 año de retención. Sin `compactor_blocks_retention_period` los datos no se borran nunca. - `runtime_config.file` apunta a un archivo que Mimir relee periódicamente sin reiniciar; ahí irán los límites por tenant. Crea el archivo de configuración en tiempo de ejecución, de momento con un override vacío: ```bash sudo nano /etc/mimir/runtime.yaml ``` ```yaml overrides: {} ``` Protege ambos archivos, ya que contienen credenciales: ```bash sudo chown root:mimir /etc/mimir/mimir.yaml /etc/mimir/runtime.yaml sudo chmod 640 /etc/mimir/mimir.yaml /etc/mimir/runtime.yaml ``` ## Paso 3: Ejecutar Mimir como servicio systemd Crea la unidad: ```bash sudo nano /etc/systemd/system/mimir.service ``` ```ini [Unit] Description=Grafana Mimir After=network-online.target Wants=network-online.target [Service] User=mimir Group=mimir WorkingDirectory=/var/lib/mimir ExecStart=/usr/local/bin/mimir -config.file=/etc/mimir/mimir.yaml Restart=on-failure RestartSec=10 LimitNOFILE=65536 [Install] WantedBy=multi-user.target ``` Arranca el servicio: ```bash sudo systemctl daemon-reload sudo systemctl enable --now mimir sudo systemctl status mimir --no-pager ``` Mimir tarda unos segundos en unir sus anillos. Comprueba que está listo: ```bash curl -s http://localhost:9009/ready ``` ```output ready ``` Si devuelve otro texto (por ejemplo, que el ingester aún no está activo), espera 15-30 segundos y repite. Los errores de acceso al bucket aparecen en `sudo journalctl -u mimir -n 50 --no-pager`. ## Paso 4: Enviar métricas desde Prometheus Mimir tiene la multi-tenancy activada por defecto: cada petición debe llevar la cabecera `X-Scope-OrgID` con el identificador del tenant. Aquí se usa el tenant `infra`. Abre la configuración de Prometheus: ```bash sudo nano /etc/prometheus/prometheus.yml ``` Añade un bloque `remote_write` al nivel superior del archivo (sustituye `localhost` por la IP de Mimir si está en otro servidor): ```yaml remote_write: - url: http://localhost:9009/api/v1/push headers: X-Scope-OrgID: infra ``` Añade también una etiqueta externa que identifique a este Prometheus, dentro del bloque `global`: ```yaml global: external_labels: cluster: produccion ``` Valida y recarga Prometheus: ```bash promtool check config /etc/prometheus/prometheus.yml sudo systemctl restart prometheus ``` Espera un minuto y consulta los datos a través de la API compatible con Prometheus de Mimir, que cuelga de la ruta `/prometheus`: ```bash curl -s -H "X-Scope-OrgID: infra" \ "http://localhost:9009/prometheus/api/v1/query?query=up" | python3 -m json.tool | head -20 ``` ```output { "status": "success", "data": { "resultType": "vector", "result": [ { "metric": { "__name__": "up", "cluster": "produccion", "instance": "localhost:9090", "job": "prometheus" }, ... ``` Si repites la consulta con otro tenant (por ejemplo `X-Scope-OrgID: otro`), el resultado estará vacío: los datos de cada tenant están aislados. ## Paso 5: Configurar límites por tenant Los límites de `mimir.yaml` se aplican a todos los tenants. Para dar más capacidad o retención a uno concreto, usa el archivo de runtime: ```bash sudo nano /etc/mimir/runtime.yaml ``` ```yaml overrides: infra: max_global_series_per_user: 3000000 compactor_blocks_retention_period: 2y equipo-web: max_global_series_per_user: 200000 compactor_blocks_retention_period: 90d ``` No hace falta reiniciar: Mimir recarga el archivo cada 10 segundos por defecto. Comprueba que los overrides se han aplicado: ```bash curl -s http://localhost:9009/runtime_config ``` La salida muestra el contenido cargado, incluidos los límites de `infra` y `equipo-web`. Si un tenant supera `max_global_series_per_user`, Mimir rechaza las series nuevas con un error `per-user series limit` que verás en los logs de Prometheus. Es la forma de evitar que un equipo agote la memoria de los ingesters. ## Paso 6: Conectar Grafana En Grafana, ve a **Connections > Data sources > Add data source** y elige **Prometheus**. Configura: - **Prometheus server URL**: `http://localhost:9009/prometheus` (o la IP de Mimir). - En **HTTP headers**, añade la cabecera `X-Scope-OrgID` con el valor `infra`. - En **Performance**, selecciona `Mimir` como **Prometheus type** si tu versión de Grafana ofrece la opción. Pulsa **Save & test**. Crea un data source por tenant si varios equipos comparten Mimir. Para consultar varios tenants en una sola consulta, activa la federación en `mimir.yaml`: ```yaml tenant_federation: enabled: true ``` Tras reiniciar Mimir, una cabecera como `X-Scope-OrgID: infra|equipo-web` devuelve datos de ambos tenants. ## Paso 7: Proteger el acceso Mimir no incluye autenticación: cualquiera que alcance el puerto 9009 puede escribir o leer datos de cualquier tenant indicando la cabecera. Si Prometheus y Grafana están en otros servidores, permite solo sus IP con UFW: ```bash sudo ufw allow from your_prometheus_ip to any port 9009 proto tcp sudo ufw allow from your_grafana_ip to any port 9009 proto tcp ``` Para exponer Mimir fuera de una red privada, ponlo detrás de un proxy inverso con TLS que autentique a los clientes y fije el `X-Scope-OrgID` según el usuario, en lugar de confiar en el valor que envía el cliente. ## Cuándo pasar al modo distribuido El modo monolítico aguanta bien cientos de miles de series activas en un solo servidor. Cuando necesites alta disponibilidad o más capacidad, el mismo binario puede ejecutar cada componente por separado (`-target=distributor`, `-target=ingester`, `-target=querier`, `-target=store-gateway`, `-target=compactor`...) y escalarlos de forma independiente: más ingesters para más escritura, más queriers para más consultas. En la práctica, el despliegue distribuido se hace en Kubernetes con el chart de Helm oficial `mimir-distributed` del repositorio `https://grafana.github.io/helm-charts`, que ya configura réplicas, memberlist y cachés. ## Solución de problemas **`/ready` nunca devuelve `ready`.** Revisa `journalctl -u mimir`. Los fallos más habituales son credenciales S3 incorrectas, un bucket inexistente o compartir el mismo bucket entre bloques, ruler y alertmanager, algo que Mimir no admite. **Prometheus muestra `401` o `no org id` al enviar datos.** Falta la cabecera `X-Scope-OrgID` en `remote_write`. Si solo tendrás un tenant, puedes desactivar la multi-tenancy con `multitenancy_enabled: false` al principio de `mimir.yaml`; los datos irán al tenant `anonymous`. **Errores `err-mimir-sample-out-of-order` o `sample too old`.** Dos Prometheus envían las mismas series sin etiquetas externas que los distingan, o un Prometheus reenvía datos antiguos. Da a cada Prometheus un `external_labels` único. **Consumo de memoria alto.** La memoria de los ingesters depende de las series activas. Consulta cuántas tiene cada tenant con `curl -s http://localhost:9009/metrics | grep cortex_ingester_active_series` y ajusta los límites por tenant. ## Conclusión Has instalado Grafana Mimir en modo monolítico con los bloques en S3, has conectado Prometheus con `remote_write`, has aislado los datos por tenant con límites propios y has añadido Mimir a Grafana. Como siguientes pasos, puedes importar los dashboards de la mixin oficial de Mimir para vigilar el propio servicio, cargar reglas de alerta por tenant con `mimirtool` y, cuando el volumen lo pida, migrar al chart `mimir-distributed` en Kubernetes.