从容器内部抓取 docker 个指标
scrape docker metrics from inside container
我正在尝试抓取 docker metrics from inside a container. I have seen the creator of Prometheus doing it this way see video here。我无法复制它。
配置
我已经通过 json 配置公开了 docker 指标页面。
{
"metrics-addr" : "172.17.0.1:4999",
"experimental" : true
}
我也试过 0.0.0.0。在任何情况下,我都可以从主机本身卷曲而不会出现任何问题。
$ curl 172.17.0.1:4999/metrics | more
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0# HELP builder_builds_failed_total Number of failed image builds
# TYPE builder_builds_failed_total counter
builder_builds_failed_total{reason="build_canceled"} 0
builder_builds_failed_total{reason="build_target_not_reachable_error"} 0
...
来自容器内部
但是,我无法从容器内部获取相同的指标页面。我试过 basi/socat 图像,与视频中的图像相同。我还尝试了一些其他方法,例如从容器内部使用 curl 等。
图像基本上只做一件事
ENV IN="172.17.0.1:4999" \
OUT="4999"
ENTRYPOINT socat -d -d TCP-L:$OUT,fork TCP:$IN
启动 Socat 容器
docker run --rm -p 4998:4999 basi/socat
2021/04/02 16:27:47 socat[8] N listening on AF=2 0.0.0.0:4999
curl 容器发布端口
curl localhost:4998/metrics
连接刚刚挂起
socat
图像识别连接,但挂起 1-2 分钟并超时。
2021/04/02 16:29:53 socat[8] N accepting connection from AF=2 172.17.0.1:57678 on AF=2 172.17.0.2:4999
2021/04/02 16:29:53 socat[8] N forked off child process 9
2021/04/02 16:29:53 socat[8] N listening on AF=2 0.0.0.0:4999
2021/04/02 16:29:53 socat[9] N opening connection to AF=2 172.17.0.1:4999
2021/04/02 16:32:04 socat[9] E connect(5, AF=2 172.17.0.1:4999, 16): Operation timed out
2021/04/02 16:32:04 socat[9] N exit(1)
2021/04/02 16:32:04 socat[8] N childdied(): handling signal 17
2021/04/02 16:32:04 socat[8] W waitpid(): child 9 exited with status 1
curl: (52) Empty reply from server
防火墙
我慢慢地想知道这是否可能是我的 iptables
规则中的内容。我已在 INPUT
和 DOCKER-USER
链下发布。这些是我自己改变的唯一。
sudo iptables -L -n -v
Chain INPUT (policy DROP 32060 packets, 1810K bytes)
pkts bytes target prot opt in out source destination
716K 1484M ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
599K 1069M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
Chain DOCKER-USER (1 references)
pkts bytes target prot opt in out source destination
16 3138 ACCEPT all -- eth0 * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
12 624 DROP all -- eth0 * 0.0.0.0/0 0.0.0.0/0
74921 139M RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
原来问题确实出在 iptables 上。在这种情况下,INPUT
链的默认策略是 DROP
。由于容器现在正在尝试到达主机系统本身,因此它的流量将通过输入链。
所以我现在添加了 2 个简单的规则,这将允许来自 docker0
和 docker_gwbridge
.
的 INPUT
链中的所有流量
sudo iptables -A INPUT -i docker0 -j ACCEPT
sudo iptables -A INPUT -i docker_gwbridge -j ACCEPT
之后,我终于能够从容器内部查询 docker 指标。
docker run --rm curlimages/curl -I -m 10 172.17.0.1:4999/metrics
HTTP/1.1 200 OK
Content-Type: text/plain; version=0.0.4; charset=utf-8
Date: Sat, 03 Apr 2021 10:53:12 GMT
我正在尝试抓取 docker metrics from inside a container. I have seen the creator of Prometheus doing it this way see video here。我无法复制它。
配置
我已经通过 json 配置公开了 docker 指标页面。
{
"metrics-addr" : "172.17.0.1:4999",
"experimental" : true
}
我也试过 0.0.0.0。在任何情况下,我都可以从主机本身卷曲而不会出现任何问题。
$ curl 172.17.0.1:4999/metrics | more
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0# HELP builder_builds_failed_total Number of failed image builds
# TYPE builder_builds_failed_total counter
builder_builds_failed_total{reason="build_canceled"} 0
builder_builds_failed_total{reason="build_target_not_reachable_error"} 0
...
来自容器内部
但是,我无法从容器内部获取相同的指标页面。我试过 basi/socat 图像,与视频中的图像相同。我还尝试了一些其他方法,例如从容器内部使用 curl 等。
图像基本上只做一件事
ENV IN="172.17.0.1:4999" \
OUT="4999"
ENTRYPOINT socat -d -d TCP-L:$OUT,fork TCP:$IN
启动 Socat 容器
docker run --rm -p 4998:4999 basi/socat
2021/04/02 16:27:47 socat[8] N listening on AF=2 0.0.0.0:4999
curl 容器发布端口
curl localhost:4998/metrics
连接刚刚挂起
socat
图像识别连接,但挂起 1-2 分钟并超时。
2021/04/02 16:29:53 socat[8] N accepting connection from AF=2 172.17.0.1:57678 on AF=2 172.17.0.2:4999
2021/04/02 16:29:53 socat[8] N forked off child process 9
2021/04/02 16:29:53 socat[8] N listening on AF=2 0.0.0.0:4999
2021/04/02 16:29:53 socat[9] N opening connection to AF=2 172.17.0.1:4999
2021/04/02 16:32:04 socat[9] E connect(5, AF=2 172.17.0.1:4999, 16): Operation timed out
2021/04/02 16:32:04 socat[9] N exit(1)
2021/04/02 16:32:04 socat[8] N childdied(): handling signal 17
2021/04/02 16:32:04 socat[8] W waitpid(): child 9 exited with status 1
curl: (52) Empty reply from server
防火墙
我慢慢地想知道这是否可能是我的 iptables
规则中的内容。我已在 INPUT
和 DOCKER-USER
链下发布。这些是我自己改变的唯一。
sudo iptables -L -n -v
Chain INPUT (policy DROP 32060 packets, 1810K bytes)
pkts bytes target prot opt in out source destination
716K 1484M ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
599K 1069M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
Chain DOCKER-USER (1 references)
pkts bytes target prot opt in out source destination
16 3138 ACCEPT all -- eth0 * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
12 624 DROP all -- eth0 * 0.0.0.0/0 0.0.0.0/0
74921 139M RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
原来问题确实出在 iptables 上。在这种情况下,INPUT
链的默认策略是 DROP
。由于容器现在正在尝试到达主机系统本身,因此它的流量将通过输入链。
所以我现在添加了 2 个简单的规则,这将允许来自 docker0
和 docker_gwbridge
.
INPUT
链中的所有流量
sudo iptables -A INPUT -i docker0 -j ACCEPT
sudo iptables -A INPUT -i docker_gwbridge -j ACCEPT
之后,我终于能够从容器内部查询 docker 指标。
docker run --rm curlimages/curl -I -m 10 172.17.0.1:4999/metrics
HTTP/1.1 200 OK
Content-Type: text/plain; version=0.0.4; charset=utf-8
Date: Sat, 03 Apr 2021 10:53:12 GMT