You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Kubernetes多Worker的Flask+Gunicorn服务中通过独立端口暴露Prometheus指标

嘿,这个场景我太熟悉了——多Worker的Gunicorn部署下,直接用start_http_server会碰到端口冲突(每个Worker都想绑定同一个端口),还得满足指标只在集群内部访问的要求。给你几个经过实践验证的解决方案,按推荐程度排序:

方案1:用Prometheus Flask Exporter(最省心)

这个库专门为Flask应用做了Prometheus指标适配,还原生支持多Worker场景,不用自己处理端口冲突和指标汇总。

步骤1:安装依赖

pip install prometheus-flask-exporter

步骤2:修改Flask应用代码

from flask import Flask
from prometheus_flask_exporter import PrometheusMetrics

app = Flask(__name__)

# 初始化指标采集器,指定单独的指标端口(比如9090),绑定到localhost确保只有Pod内部能直接访问
metrics = PrometheusMetrics(
    app,
    path='/metrics',
    port=9090,
    addr='localhost'
)

# 自定义业务指标示例
requests_total = metrics.counter(
    'flask_requests_total', 'Total number of Flask requests',
    labels={'endpoint': lambda: request.endpoint}
)

@app.route('/')
def hello():
    return "Hello from Flask + Gunicorn!"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

步骤3:配置Gunicorn与Kubernetes

首先,需要设置环境变量让库支持多Worker的指标汇总,在Dockerfile或者Deployment里添加:

# 提前创建多进程指标存储目录
RUN mkdir -p /tmp/prometheus-multiproc

Gunicorn启动命令:

PROMETHEUS_MULTIPROC_DIR=/tmp/prometheus-multiproc gunicorn --workers=4 --bind=0.0.0.0:5000 app:app

然后在Kubernetes Deployment里配置ClusterIP类型的Service,只在集群内部暴露指标端口:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: flask-gunicorn-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: flask-app
  template:
    metadata:
      labels:
        app: flask-app
      annotations:
        # 告诉Prometheus自动采集这个Pod的指标
        prometheus.io/scrape: "true"
        prometheus.io/port: "9090"
        prometheus.io/path: "/metrics"
    spec:
      containers:
      - name: flask-app
        image: your-app-image:latest
        ports:
        - containerPort: 5000
          name: app-port
        - containerPort: 9090
          name: metrics-port
        env:
        - name: PROMETHEUS_MULTIPROC_DIR
          value: /tmp/prometheus-multiproc
        command: ["sh", "-c", "mkdir -p /tmp/prometheus-multiproc && gunicorn --workers=4 --bind=0.0.0.0:5000 app:app"]

---
apiVersion: v1
kind: Service
metadata:
  name: flask-app-metrics
spec:
  # ClusterIP是默认类型,只在集群内部可访问
  type: ClusterIP
  selector:
    app: flask-app
  ports:
  - port: 9090
    targetPort: metrics-port
    name: metrics

这个方案的优点:几乎不用自己写额外的指标逻辑,库已经封装好了多Worker的指标聚合,而且通过ClusterIP Service确保指标只在集群内部可见。

方案2:Sidecar容器解耦指标采集

如果想完全把业务应用和指标采集分开,可以用Kubernetes的Sidecar模式——一个容器跑Flask+Gunicorn,另一个容器专门暴露Prometheus指标,两者通过共享卷传递指标数据。

步骤1:修改业务应用代码

让业务Worker把指标写到共享目录:

from flask import Flask
from prometheus_client import Counter, multiprocess, CollectorRegistry

app = Flask(__name__)

# 初始化多进程兼容的注册表
registry = CollectorRegistry()
multiprocess.MultiProcessCollector(registry)

# 自定义指标
requests_total = Counter('flask_requests_total', 'Total requests', registry=registry)

@app.route('/')
def hello():
    requests_total.inc()
    return "Hello from Sidecar setup!"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

步骤2:编写Sidecar指标暴露代码

创建一个单独的metrics_exporter.py,负责读取共享目录的指标并暴露端口:

from prometheus_client import start_http_server, multiprocess, CollectorRegistry
import time

if __name__ == '__main__':
    registry = CollectorRegistry()
    multiprocess.MultiProcessCollector(registry)
    # 绑定到0.0.0.0:9090,让Pod内部的Sidecar能被Prometheus访问
    start_http_server(9090, registry=registry)
    # 保持进程运行
    while True:
        time.sleep(3600)

步骤3:Kubernetes配置

用emptyDir卷共享指标目录,部署两个容器:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: flask-sidecar-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: flask-sidecar-app
  template:
    metadata:
      labels:
        app: flask-sidecar-app
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9090"
        prometheus.io/path: "/metrics"
    spec:
      volumes:
      - name: metrics-shared-dir
        emptyDir: {}
      containers:
      - name: flask-app
        image: your-app-image:latest
        ports:
        - containerPort: 5000
          name: app-port
        env:
        - name: PROMETHEUS_MULTIPROC_DIR
          value: /tmp/metrics
        volumeMounts:
        - name: metrics-shared-dir
          mountPath: /tmp/metrics
        command: ["gunicorn", "--workers=4", "--bind=0.0.0.0:5000", "app:app"]
      - name: metrics-exporter
        image: your-exporter-image:latest
        ports:
        - containerPort: 9090
          name: metrics-port
        env:
        - name: PROMETHEUS_MULTIPROC_DIR
          value: /tmp/metrics
        volumeMounts:
        - name: metrics-shared-dir
          mountPath: /tmp/metrics
        command: ["python", "metrics_exporter.py"]

---
apiVersion: v1
kind: Service
metadata:
  name: flask-sidecar-metrics
spec:
  type: ClusterIP
  selector:
    app: flask-sidecar-app
  ports:
  - port: 9090
    targetPort: metrics-port
    name: metrics

这个方案的优点:业务代码和指标采集完全解耦,各自可以独立更新和维护,适合复杂的微服务场景。

注意事项
  • 无论用哪个方案,都要确保指标端口的Service是ClusterIP类型(默认就是),这样外部无法访问,满足集群内部访问的要求。
  • 多Worker场景下,必须启用Prometheus的多进程模式(通过PROMETHEUS_MULTIPROC_DIR环境变量),否则指标会被多个Worker覆盖,数据不准确。

内容的提问来源于stack exchange,提问作者Peanut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:31:01