菜单
文档breadcrumb arrow Grafana Mimirbreadcrumb arrow 设置breadcrumb arrow 迁移breadcrumb arrow 使用 Thanos sidecar 从 Thanos 迁移
开源

使用 Thanos sidecar 从 Thanos 迁移到 Mimir

作为操作人员,您可以使用 Thanos sidecar 通过分步工作流程将指标迁移到 Grafana Mimir。

概览

一种迁移选项是允许 Thanos 查询 Mimir。这样,您可以通过现有的 Thanos 部署保留历史数据,同时将所有 Prometheus 服务器(或 Grafana Agent 和其他指标源)指向 Mimir。

整体设置包括在 Mimir 旁边设置 Thanos Sidecar,然后将 Thanos Query 指向该 sidecar,就像它是一个普通的 sidecar 一样。

这与其说是一个指南,不如说是一个成功使用过的配置集合。

警告:此设置不被支持,属于实验性,并且尚未经过实战检验。效果可能因环境而异,请确保您已为您的用例进行测试,并已进行适当的备份(并测试了您的恢复流程)。

技术细节

让此功能正常工作遇到的障碍很少。Thanos Sidecar 设计用于与 Prometheus API 协同工作,而 Mimir (几乎) 实现了该 API。只有 2 个端点未实现,我们需要“伪造”这些端点,以使 Thanos sidecar 相信它正在连接到 Prometheus 服务器:/api/v1/status/buildinfo/api/v1/status/config。我们使用 NGINX 来伪造这些端点(稍后提供更多详细信息)。

另一个障碍是 Mimir 要求请求中包含 X-Scope-Org-Id 头来标识租户。我们使用另一个位于 Thanos Sidecar 和 Mimir 之间的 NGINX 容器注入此头。

在我们的案例中,所有内容都部署在 Kubernetes 中。Mimir 使用 mimir-distributed helm chart 进行部署。因此,显示的配置将是需要根据您的环境进行修改的 Kubernetes Manifest。如果您不使用 Kubernetes,则需要为 NGINX 设置适当的配置以实现上述技术设置。您可以使用下面的配置作为参考,但它们无法直接使用。

部署 Thanos sidecar

我们使用以下 Kubernetes manifest 部署了 sidecar

Deployment

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: thanos-sidecar
  namespace: mimir
  labels:
    app: thanos-sidecar
spec:
  replicas: 1
  selector:
    matchLabels:
      app: thanos-sidecar
  template:
    metadata:
      labels:
        app: thanos-sidecar
    spec:
      volumes:
        - name: config
          configMap:
            name: sidecar-nginx
            defaultMode: 420
      containers:
        - name: nginx
          image: nginxinc/nginx-unprivileged:1.19-alpine
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          volumeMounts:
            - name: config
              mountPath: /etc/nginx
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
        - name: thanos-sidecar
          image: quay.io/thanos/thanos:v0.26.0
          args:
            - sidecar
            - "--prometheus.url=https://:8080/prometheus"
            - "--grpc-address=:10901"
            - "--http-address=:10902"
            - "--log.level=info"
            - "--log.format=logfmt"
          ports:
            - name: http
              containerPort: 10902
              protocol: TCP
            - name: grpc
              containerPort: 10901
              protocol: TCP
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600

Service

yaml
apiVersion: v1
kind: Service
metadata:
  name: thanos-sidecar
  namespace: mimir
  labels:
    app: thanos-sidecar
spec:
  ports:
    - name: 10901-10901
      protocol: TCP
      port: 10901
      targetPort: 10901
  selector:
    app: thanos-sidecar
  type: ClusterIP

Thanos sidecar 的 NGINX 配置

请注意,sidecar Deployment 定义中包含一个 NGINX 容器。这个 NGINX 实例位于 sidecar 和 Mimir 之间(即 sidecar --> nginx --> mimir),它负责将租户 ID 注入从 sidecar 发送给 Mimir 的请求中。此 NGINX 实例使用的配置如下:

conf
worker_processes  5;  ## Default: 1
error_log  /dev/stderr;
pid        /tmp/nginx.pid;
worker_rlimit_nofile 8192;

events {
  worker_connections  4096;  ## Default: 1024
}

http {
  client_body_temp_path /tmp/client_temp;
  proxy_temp_path       /tmp/proxy_temp_path;
  fastcgi_temp_path     /tmp/fastcgi_temp;
  uwsgi_temp_path       /tmp/uwsgi_temp;
  scgi_temp_path        /tmp/scgi_temp;

  default_type application/octet-stream;
  log_format   main '$remote_addr - $remote_user [$time_local]  $status '
        '"$request" $body_bytes_sent "$http_referer" '
        '"$http_user_agent" "$http_x_forwarded_for"';
  access_log   /dev/stderr  main;

  sendfile     on;
  tcp_nopush   on;
  resolver kube-dns.kube-system.svc.cluster.local;

  server {
    listen 8080;

    # Distributor endpoints
    location / {
      proxy_set_header X-Scope-OrgID 1;
      proxy_pass      http://mimir-distributed-nginx.mimir.svc.cluster.local:80$request_uri;
    }
  }
}

Mimir 的 NGINX 配置

现在我们修改了 Mimir 分布式 NGINX 配置,以允许 sidecar 获取我们“Prometheus”服务器的“外部标签”和“版本”。您应该小心处理外部标签,确保它们不会覆盖任何现有标签(在我们的案例中,我们使用了 “source=‘mimir’”)。您还应该考虑现有的仪表盘,并确保它们会按预期继续工作。请务必先测试您的设置。

特别是,添加了以下 location 块(完整配置在后面)

conf
location /prometheus/api/v1/status/config {
        add_header Content-Type application/json;
        return 200 "{\"status\":\"success\",\"data\":{\"yaml\": \"global:\\n  external_labels:\\n    source: mimir\"}}";
    }

location /prometheus/api/v1/status/buildinfo {
        add_header Content-Type application/json;
        return 200 "{\"status\":\"success\",\"data\":{\"version\":\"2.35.0\",\"revision\":\"6656cd29fe6ac92bab91ecec0fe162ef0f187654\",\"branch\":\"HEAD\",\"buildUser\":\"root@cf6852b14d68\",\"buildDate\":\"20220421-09:53:42\",\"goVersion\":\"go1.18.1\"}}";
    }

您需要修改第一个来设置您的外部标签。第二个只允许 Thanos 检测运行的 Prometheus 版本。

要修改外部标签,请更改此字符串:"{\"status\":\"success\",\"data\":{\"yaml\": \"global:\\n external_labels:\\n source: mimir\"}}"。您会注意到它是转义后的 JSON。只需向 data.external_labels 字段添加元素即可添加更多所需的外部标签,或修改现有键进行更改。

完整的 Mimir 分布式 NGINX 配置

conf
worker_processes  5;  ## Default: 1
error_log  /dev/stderr;
pid        /tmp/nginx.pid;
worker_rlimit_nofile 8192;

events {
  worker_connections  4096;  ## Default: 1024
}

http {
  client_body_temp_path /tmp/client_temp;
  proxy_temp_path       /tmp/proxy_temp_path;
  fastcgi_temp_path     /tmp/fastcgi_temp;
  uwsgi_temp_path       /tmp/uwsgi_temp;
  scgi_temp_path        /tmp/scgi_temp;

  default_type application/octet-stream;
  log_format   main '$remote_addr - $remote_user [$time_local]  $status '
        '"$request" $body_bytes_sent "$http_referer" '
        '"$http_user_agent" "$http_x_forwarded_for"';
  access_log   /dev/stderr  main;

  sendfile     on;
  tcp_nopush   on;
  resolver kube-dns.kube-system.svc.cluster.local;

  server {
    listen 8080;

    location = / {
      return 200 'OK';
      auth_basic off;
    }

    # Distributor endpoints
    location /distributor {
      proxy_pass      http://mimir-distributed-distributor.mimir.svc.cluster.local:8080$request_uri;
    }
    location = /api/v1/push {
      proxy_pass      http://mimir-distributed-distributor.mimir.svc.cluster.local:8080$request_uri;
    }

    # Alertmanager endpoints
    location /alertmanager {
      proxy_pass      http://mimir-distributed-alertmanager.mimir.svc.cluster.local:8080$request_uri;
    }
    location = /multitenant_alertmanager/status {
      proxy_pass      http://mimir-distributed-alertmanager.mimir.svc.cluster.local:8080$request_uri;
    }
    location = /api/v1/alerts {
      proxy_pass      http://mimir-distributed-alertmanager.mimir.svc.cluster.local:8080$request_uri;
    }

    # Ruler endpoints
    location /prometheus/config/v1/rules {
      proxy_pass      http://mimir-distributed-ruler.mimir.svc.cluster.local:8080$request_uri;
    }
    location /prometheus/api/v1/rules {
      proxy_pass      http://mimir-distributed-ruler.mimir.svc.cluster.local:8080$request_uri;
    }

    location /api/v1/rules {
      proxy_pass      http://mimir-distributed-ruler.mimir.svc.cluster.local:8080$request_uri;
    }
    location /prometheus/api/v1/alerts {
      proxy_pass      http://mimir-distributed-ruler.mimir.svc.cluster.local:8080$request_uri;
    }
    location /prometheus/rules {
      proxy_pass      http://mimir-distributed-ruler.mimir.svc.cluster.local:8080$request_uri;
    }
    location = /ruler/ring {
      proxy_pass      http://mimir-distributed-ruler.mimir.svc.cluster.local:8080$request_uri;
    }

    location /prometheus/api/v1/status/config {
      add_header Content-Type application/json;
      return 200 "{\"status\":\"success\",\"data\":{\"yaml\": \"global:\\n  external_labels:\\n    source: mimir\"}}";
    }

    location /prometheus/api/v1/status/buildinfo {
    add_header Content-Type application/json;
    return 200 "{\"status\":\"success\",\"data\":{\"version\":\"2.35.0\",\"revision\":\"6656cd29fe6ac92bab91ecec0fe162ef0f187654\",\"branch\":\"HEAD\",\"buildUser\":\"root@cf6852b14d68\",\"buildDate\":\"20220421-09:53:42\",\"goVersion\":\"go1.18.1\"}}";
    }



    # Rest of /prometheus goes to the query frontend
    location /prometheus {
      proxy_pass      http://mimir-distributed-query-frontend.mimir.svc.cluster.local:8080$request_uri;
    }

    # Buildinfo endpoint can go to any component
    location = /api/v1/status/buildinfo {
      proxy_pass      http://mimir-distributed-query-frontend.mimir.svc.cluster.local:8080$request_uri;
    }
  }
}