如何将 Docker 容器中的 Grafana 运行 连接到主机上的 Prometheus 数据源 运行(在 Docker 上 Mac)?
How to connect Grafana running in a Docker container to a Prometheus data source running on the host machine (on Docker for Mac)?
我在 localhost:57475/metrics
:
启动了 Prometheus 服务器
使用以下 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
}
我还使用以下命令(在 https://grafana.com/docs/installation/docker/ 之后)在容器中启动了 Grafana:
> docker run --detach --publish 3000:3000 --env "GF_SECURITY_ADMIN_PASSWORD=secret" grafana/grafana
2a17ad2bcc05e2955190129b981b3329cd2c5e89098e28b443337ac79ed607f2
在 Grafana 中,我想连接到 Mac localhost
上的 Prometheus 导出器 运行。在 https://docs.docker.com/docker-for-mac/networking/ 之后,我尝试使用特殊的 DNS 名称 host.docker.internal
,因此将 URL 指定为 http://host.docker.internal:57475/metrics
。但是,当我单击 "Save & Test":
时,这会导致 HTTP Error Not Found
知道为什么这不起作用吗?
更新
我没有使用特殊的 DNS 名称 host.docker.internal
,而是尝试将服务器和 Grafana 组合成一个 Docker Compose 多容器应用程序,并使用 Docker 网桥连接它们,但这也没有用。目录结构如下:
.
├── docker-compose.yml
└── server
├── Dockerfile
├── go.mod
├── go.sum
└── main.go
和以下 docker-compose.yml
:
version: '3'
services:
server:
build: ./server
ports:
- "8080:8080"
- "57475:57475"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
以及以下 Dockerfile
:
FROM golang:1.12
WORKDIR /go/src/app
COPY . .
RUN go get -d -v ./...
RUN go install -v ./...
CMD ["app"]
如果我附加到 Grafana 容器并卷曲 server:8080
或 server: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
但是,如果我尝试在 Grafana 管理中添加相同的 URL,我会得到同样的错误:
换句话说,虽然我能够从 Grafana 容器 curl
这个端点,但我不能将它用作 Grafana 仪表板中的数据源 URL,这让我想到了这个是 Grafana 特有的东西。知道为什么这不起作用吗?
将 --network host
添加到您的 docker run
命令:
docker run --network host...
然后在Grafana设置中使用localhost:[prometheus_port]
相关docs
原来我不太明白普罗米修斯的工作原理。示例中的 Go 应用程序创建了一个 Prometheus exporter,它仍然必须由 Prometheus server 抓取,而 Prometheus server 又是格拉法纳
我把目录结构修改成这样:
.
├── docker-compose.yml
├── prometheus
│ ├── Dockerfile
│ └── prometheus.yml
└── server
├── Dockerfile
├── go.mod
├── go.sum
└── main.go
其中 docker-compose.yml
是
version: '3'
services:
server:
build: ./server
ports:
- "8080:8080"
- "57475:57475"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
prometheus:
build: ./prometheus
ports:
- "9090:9090"
而 prometheus/Dockerfile
是
FROM prom/prometheus
ADD prometheus.yml /etc/prometheus
而 prometheus/prometheus.yml
是
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'server'
static_configs:
- targets: ['server:57475']
现在我可以添加 prometheus:9090
作为数据源 URL:
格拉法纳 - 普罗米修斯
只要您同时拥有 Grafana 和 Prometheus 运行ning 作为 docker 图像,这就会起作用,所以在您开始之前,请 运行 下面的命令以确保 prometheus 和 Grafana 图像都是通过 运行ning 这个命令 'docker ps'
如果没有启动,请在终端运行执行此命令
docker run -p 9090:9090 prom/prometheus .
docker run -d -p 3000:3000 grafana/grafana-enterprise
要将 prometheus 连接到 GRAFANA,您需要从主机获取 运行ning 作为 docker 图像的 prometheus 服务器 IP 地址。在您的终端上使用此命令显示所有容器 ID docker ps -a
您将看到您的 prometheus 服务器容器 ID,例如“faca0c893603”。请在您的终端上复制 ID 和 运行 下面的命令以查看您的 Prometheus 服务器的 IP 地址
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' faca0c893603
注意:(faca0c893603是prom/prometheus服务器的ContainerID)当你运行命令时会显示需要映射的Prometheus容器的IP地址(172.17.0.4)使用 Grafana 上的 prometheus 服务器的端口。
在 Grafana 上的数据源上,将其放在 URL http://172.17.0.3:9090 上并尝试保存并测试
我在 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
}
我还使用以下命令(在 https://grafana.com/docs/installation/docker/ 之后)在容器中启动了 Grafana:
> docker run --detach --publish 3000:3000 --env "GF_SECURITY_ADMIN_PASSWORD=secret" grafana/grafana
2a17ad2bcc05e2955190129b981b3329cd2c5e89098e28b443337ac79ed607f2
在 Grafana 中,我想连接到 Mac localhost
上的 Prometheus 导出器 运行。在 https://docs.docker.com/docker-for-mac/networking/ 之后,我尝试使用特殊的 DNS 名称 host.docker.internal
,因此将 URL 指定为 http://host.docker.internal:57475/metrics
。但是,当我单击 "Save & Test":
HTTP Error Not Found
知道为什么这不起作用吗?
更新
我没有使用特殊的 DNS 名称 host.docker.internal
,而是尝试将服务器和 Grafana 组合成一个 Docker Compose 多容器应用程序,并使用 Docker 网桥连接它们,但这也没有用。目录结构如下:
.
├── docker-compose.yml
└── server
├── Dockerfile
├── go.mod
├── go.sum
└── main.go
和以下 docker-compose.yml
:
version: '3'
services:
server:
build: ./server
ports:
- "8080:8080"
- "57475:57475"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
以及以下 Dockerfile
:
FROM golang:1.12
WORKDIR /go/src/app
COPY . .
RUN go get -d -v ./...
RUN go install -v ./...
CMD ["app"]
如果我附加到 Grafana 容器并卷曲 server:8080
或 server: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
但是,如果我尝试在 Grafana 管理中添加相同的 URL,我会得到同样的错误:
换句话说,虽然我能够从 Grafana 容器 curl
这个端点,但我不能将它用作 Grafana 仪表板中的数据源 URL,这让我想到了这个是 Grafana 特有的东西。知道为什么这不起作用吗?
将 --network host
添加到您的 docker run
命令:
docker run --network host...
然后在Grafana设置中使用localhost:[prometheus_port]
相关docs
原来我不太明白普罗米修斯的工作原理。示例中的 Go 应用程序创建了一个 Prometheus exporter,它仍然必须由 Prometheus server 抓取,而 Prometheus server 又是格拉法纳
我把目录结构修改成这样:
.
├── docker-compose.yml
├── prometheus
│ ├── Dockerfile
│ └── prometheus.yml
└── server
├── Dockerfile
├── go.mod
├── go.sum
└── main.go
其中 docker-compose.yml
是
version: '3'
services:
server:
build: ./server
ports:
- "8080:8080"
- "57475:57475"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
prometheus:
build: ./prometheus
ports:
- "9090:9090"
而 prometheus/Dockerfile
是
FROM prom/prometheus
ADD prometheus.yml /etc/prometheus
而 prometheus/prometheus.yml
是
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'server'
static_configs:
- targets: ['server:57475']
现在我可以添加 prometheus:9090
作为数据源 URL:
格拉法纳 - 普罗米修斯 只要您同时拥有 Grafana 和 Prometheus 运行ning 作为 docker 图像,这就会起作用,所以在您开始之前,请 运行 下面的命令以确保 prometheus 和 Grafana 图像都是通过 运行ning 这个命令 'docker ps'
如果没有启动,请在终端运行执行此命令
docker run -p 9090:9090 prom/prometheus .
docker run -d -p 3000:3000 grafana/grafana-enterprise
要将 prometheus 连接到 GRAFANA,您需要从主机获取 运行ning 作为 docker 图像的 prometheus 服务器 IP 地址。在您的终端上使用此命令显示所有容器 ID docker ps -a
您将看到您的 prometheus 服务器容器 ID,例如“faca0c893603”。请在您的终端上复制 ID 和 运行 下面的命令以查看您的 Prometheus 服务器的 IP 地址
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' faca0c893603
注意:(faca0c893603是prom/prometheus服务器的ContainerID)当你运行命令时会显示需要映射的Prometheus容器的IP地址(172.17.0.4)使用 Grafana 上的 prometheus 服务器的端口。
在 Grafana 上的数据源上,将其放在 URL http://172.17.0.3:9090 上并尝试保存并测试