使用 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
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
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 实例使用的配置如下:
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 块(完整配置在后面)
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 配置
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;
}
}
}