Prometheus 指标与 Docker Swarm

问题描述 投票:0回答:1

使用 Docker 部署副本进行指标收集

我是一名开发人员,但在我的新工作中,公司没有DevOps团队。因此,我们没有任何类型的指标收集或适当的 CI/CD 流程。因此,我正在尝试在这里实施一些事情,但我不是专家。

我想做的第一件事是使用 Prometheus 和 Grafana 实现指标收集和可视化,以监控一些 Python 和 Node.js 本地应用程序。我使用 Flask 应用程序进行测试,并使用 Docker 在本地安装 Prometheus 和 Grafana,然后再将它们设置在适当的服务器上。我使用

prometheus-flask-exporter
让它轻松工作,但我开始注意到一些问题,并对什么最适合我的应用程序堆栈有一些疑问。

应用程序堆栈:

  • Python

  • 烧瓶

  • Gunicorn 有 2 个工人和 2 个线程

  • 带有副本的 Docker

  • Nginx

问题与疑问:

  1. Docker 部署副本:我立即意识到我的应用程序有一个用于负载平衡的 Docker 副本。因此,当 Prometheus 抓取 /metrics 路径时,Docker 会将请求发送到其中一个副本。我相信两者都应该在 Grafana 上有单独的指标,以查看负载平衡是否正常工作。我所做的是为每个副本创建不同的路径,例如 Nginx 上的 /metrics_1 和 /metrics_2 以及 Prometheus 上的两个不同作业,并且它有效,但我认为这不是正确的方法。

  2. 指标准确性:我想要基本指标,例如百分比延迟、每条路径上每秒的请求数、2xx 请求、3xx 请求、4xx 请求和 5xx 请求。然而,就我实现它的方式而言,我无法信任这些指标,因为当我将它们与 K6 负载测试进行比较时,我得到了完全不同的指标,尤其是百分位延迟和每秒请求数。

发生这些问题后,我很生气,并回滚了我所做的一切。现在,我想从头开始。我的问题主要是关于良好的监控实践。考虑到我的堆栈,我应该重点监控什么?我还需要从 Nginx 收集指标吗?如何处理 Docker 副本?使用

statsd-exporter
之类的东西来监控 Gunicorn 是否比使用
prometheus-flask-exporter
的 Flask 更好?我需要多进程模式吗?

我的配置文件:

compose.yml:


services:
api:
image: api-auth-ad
build: .
expose:
\- "8000"
environment:
\- SECRET_KEY=${SECRET_KEY}
\- LDAP_DOMAIN=${LDAP_DOMAIN}
deploy:
replicas: 2
resources:
limits:
cpus: "0.75"
memory: "1gb"
restart: always

nginx:
container_name: api-auth-ad-nginx
image: nginx:1.27.0
ports:
\- "80:80"
\- "443:443"
volumes:
\- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
\- api
restart: always

Dockerfile:


FROM python:3.11

WORKDIR /app

COPY pyproject.toml ./

RUN pip install poetry

RUN poetry lock

RUN poetry install --only main

COPY . .

CMD \["poetry", "run", "gunicorn", "--config", "gunicorn_config.py", "src.app:create_app()"\]

gunicorn_config.py:

workers = 2
threads = 2
bind = "0.0.0.0:8000"
loglevel = "info"
accesslog = "-"
errorlog = "-"
worker_class = "gthread"

nginx.conf:

worker_processes  auto;
worker_rlimit_nofile 500000;

events {
    use epoll;
    worker_connections 512;
}

http {
    access_log off;
    error_log /dev/null emerg;

    upstream api_auth {
        server api:8000;
        keepalive 400;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://api_auth;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_intercept_errors off;
        }
        
    }

}
python nginx prometheus gunicorn docker-swarm
1个回答
0
投票

这里发生了很多事情,所以我将处理副本:

处理副本的一种方法是将“实例”重写为任务级别指标中的副本名称。

您可以使用“dns_sd_configs”并设置 A 记录抓取器并使用“tasks.{service_name}”。这会在用于抓取指标的 ADDR 变量中返回服务的每个单独的 IP - 将实例重写为有趣的方式会更困难。

有一个更好的方法,通过将 Prometheus 实例固定到管理节点,您可以使用 dockerswarm_sd_configs 来提取指标:

  - job_name: 'dockerswarm'
    dockerswarm_sd_configs:
      - host: unix:///var/run/docker.sock
        role: tasks

您可以添加重新标签配置。我将实例重写为服务正在运行的节点:

    relabel_configs:
      - source_labels: [__meta_dockerswarm_node_hostname]
        target_label: instance

dockerswarm_sd_config 不知道您的服务正在监听哪个端口的指标。我定义了一个部署标签“prometheus.metrics.port”来承载它并分配它:

    relable_configs:
      - source_labels:
          - __address__
          - __meta_dockerswarm_service_label_prometheus_metrics_port
        regex: '(.*):(\d+);(\d+)'
        target_label: __address__
        replacement: '$1:$3'

要抓取服务,还需要将其附加到监控网络。 dockerswarm_sd_configs 将为每个连接的网络和发布的端口生成一个服务发现条目,因此我们可以过滤到全局 docker 网络。这里我假设“指标”存在:

    relabel_configs:
      - source_labels: [__meta_dockerswarm_network_name]
        regex: monitoring
        action: keep
© www.soinside.com 2019 - 2024. All rights reserved.