如何将 Docker 容器中运行的 Grafana 连接到主机上运行的 Prometheus 数据源(在 Docker for Mac 上)?

Kur*_*eek 5 go docker grafana docker-networking prometheus

我在以下位置启动了 Prometheus 服务器localhost:57475/metrics

在此处输入图片说明

使用以下 Go 代码:

package main

import (
    "net/http"

    "contrib.go.opencensus.io/exporter/prometheus"
    log "github.com/sirupsen/logrus"
    "go.opencensus.io/plugin/ochttp"
    "go.opencensus.io/stats/view"
)

func main() {
    stop := make(chan struct{})

    server := &http.Server{Addr: ":8080"}

    statsMux := http.NewServeMux()
    statsServer := &http.Server{Handler: statsMux, Addr: ":57475"}

    if err := view.Register(ochttp.DefaultServerViews...); err != nil {
        log.WithError(err).Fatal("register HTTP metrics view")
    }

    exporter, err := prometheus.NewExporter(prometheus.Options{
        Namespace: "default",
    })
    if err != nil {
        log.WithError(err).Fatal("create Prometheus exporter")
    }

    view.RegisterExporter(exporter)

    statsMux.Handle("/metrics", exporter)

    originalHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, World!"))
    })
    och := &ochttp.Handler{
        Handler: originalHandler,
    }

    server.Handler = och

    go func() {
        log.Info("Starting stats server...")
        if err := statsServer.ListenAndServe(); err != nil {
            log.WithError(err).Fatal("listen and serve stats")
        }
    }()

    go func() {
        log.Info("Starting server...")
        if err := server.ListenAndServe(); err != nil {
            log.WithError(err).Fatal("listen and serve service endpoints")
        }
    }()

    <-stop
}
Run Code Online (Sandbox Code Playgroud)

我还使用以下命令(遵循https://grafana.com/docs/installation/docker/)在容器中启动了 Grafana :

> docker run --detach --publish 3000:3000  --env "GF_SECURITY_ADMIN_PASSWORD=secret" grafana/grafana
2a17ad2bcc05e2955190129b981b3329cd2c5e89098e28b443337ac79ed607f2
Run Code Online (Sandbox Code Playgroud)

在 Grafana 中,我想连接到在我的 Mac 上运行的 Prometheus 导出器localhost。在https://docs.docker.com/docker-for-mac/networking/之后,我尝试使用特殊的 DNS name host.docker.internal,因此将 URL 指定为http://host.docker.internal:57475/metrics. 但是,这会导致HTTP Error Not Found当我单击“保存并测试”时:

在此处输入图片说明

知道为什么这不起作用吗?

更新

host.docker.internal我没有使用特殊的 DNS 名称,而是尝试将服务器和 Grafana 组合成一个 Docker Compose 多容器应用程序,并使用 Docker 桥连接它们,但这也不起作用。使用以下目录结构:

.
??? docker-compose.yml
??? server
    ??? Dockerfile
    ??? go.mod
    ??? go.sum
    ??? main.go
Run Code Online (Sandbox Code Playgroud)

以及以下内容docker-compose.yml

version: '3'
services:
  server:
    build: ./server
    ports:
      - "8080:8080"
      - "57475:57475"
  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
Run Code Online (Sandbox Code Playgroud)

以及以下内容Dockerfile

FROM golang:1.12

WORKDIR /go/src/app
COPY . .

RUN go get -d -v ./...
RUN go install -v ./...

CMD ["app"]
Run Code Online (Sandbox Code Playgroud)

如果我附加到 Grafana 容器并 curlserver:8080server:57475/metrics,我会收到响应:

useprometheus> docker exec -it --user root useprometheus_grafana_1 /bin/ash
/usr/share/grafana # apk add curl
fetch http://dl-cdn.alpinelinux.org/alpine/v3.10/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.10/community/x86_64/APKINDEX.tar.gz
(1/3) Installing nghttp2-libs (1.39.2-r0)
(2/3) Installing libcurl (7.66.0-r0)
(3/3) Installing curl (7.66.0-r0)
Executing busybox-1.30.1-r2.trigger
OK: 17 MiB in 24 packages
/usr/share/grafana # curl server:8080
Hello, World!/usr/share/grafana # curl server:57475/metrics
# HELP default_opencensus_io_http_server_latency Latency distribution of HTTP requests
# TYPE default_opencensus_io_http_server_latency histogram
default_opencensus_io_http_server_latency_bucket{le="1"} 1
default_opencensus_io_http_server_latency_bucket{le="2"} 1
default_opencensus_io_http_server_latency_bucket{le="3"} 1
default_opencensus_io_http_server_latency_bucket{le="4"} 1
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试在 Grafana 管理员中添加相同的 URL,则会收到相同的错误:

在此处输入图片说明

换句话说,虽然我可以curl从 Grafana 容器访问这个端点,但我不能将它用作 Grafana 仪表板中的数据源 URL,这让我觉得这是 Grafana 特定的东西。知道为什么这不起作用吗?

Kur*_*eek 7

原来我不太明白 Prometheus 是如何工作的。示例中的 Go 应用程序创建了一个 Prometheus导出器,它仍然需要由 Prometheus服务器抓取,而 Prometheus 服务器又是 Grafana 的数据源。

\n\n

我将目录结构修改为这样:

\n\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 docker-compose.yml\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 prometheus\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Dockerfile\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 prometheus.yml\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 server\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Dockerfile\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 go.mod\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 go.sum\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 main.go\n
Run Code Online (Sandbox Code Playgroud)\n\n

哪里docker-compose.yml

\n\n
version: \'3\'\nservices:\n  server:\n    build: ./server\n    ports:\n      - "8080:8080"\n      - "57475:57475"\n  grafana:\n    image: grafana/grafana\n    ports:\n      - "3000:3000"\n  prometheus:\n    build: ./prometheus\n    ports:\n      - "9090:9090"\n
Run Code Online (Sandbox Code Playgroud)\n\n

prometheus/Dockerfile

\n\n
FROM prom/prometheus\n\nADD prometheus.yml /etc/prometheus\n
Run Code Online (Sandbox Code Playgroud)\n\n

prometheus/prometheus.yml

\n\n
global:\n  scrape_interval:     15s\n\nscrape_configs:\n  - job_name: \'server\'\n\n    static_configs:\n      - targets: [\'server:57475\']\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在我可以添加prometheus:9090作为数据源 URL:

\n\n

在此输入图像描述

\n