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-rulerymimir-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:
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:
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:
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:
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:
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:
endpointva sin esquema, por ejemplos3.eu-west-1.amazonaws.comominio.your_domain:9000. Si tu MinIO no usa TLS, añadeinsecure: truedentro decommon.storage.s3.replication_factor: 1es obligatorio con una sola instancia; en un clúster se usa 3.limitsfija los valores por defecto para todos los tenants: 1 millón de series activas y 1 año de retención. Sincompactor_blocks_retention_periodlos datos no se borran nunca.runtime_config.fileapunta 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:
sudo nano /etc/mimir/runtime.yaml
overrides: {}
Protege ambos archivos, ya que contienen credenciales:
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:
sudo nano /etc/systemd/system/mimir.service
[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:
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:
curl -s http://localhost:9009/ready
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:
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):
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:
global:
external_labels:
cluster: produccion
Valida y recarga Prometheus:
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:
curl -s -H "X-Scope-OrgID: infra" \
"http://localhost:9009/prometheus/api/v1/query?query=up" | python3 -m json.tool | head -20
{
"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:
sudo nano /etc/mimir/runtime.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:
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-OrgIDcon el valorinfra. - En Performance, selecciona
Mimircomo 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:
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:
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.
