运行 使用 docker 的 Prometheus 在 --enable-feature=promql-at-modifier 时失败

Run Prometheus with docker failed when --enable-feature=promql-at-modifier

在Windows 我从这样的 docker 图像中成功 运行 Prometheus。

docker run -p 9090:9090 \
-v D:/WORK/MyProject/grafana:/etc/prometheus \
prom/prometheus

D:/WORK/MyProject/grafana 包含 prometheus.yml 包含我需要的所有配置的文件。

现在我需要启用@运算符用法所以我添加了promql-at-modifier试图运行

docker run -p 9090:9090 \
-v D:/WORK/MyProject/grafana:/etc/prometheus \
prom/prometheus --enable-feature=promql-at-modifier

我得到以下信息:

level=info ts=2021-07-30T14:56:29.139Z caller=main.go:143 msg="Experimental promql-at-modifier enabled"
level=error ts=2021-07-30T14:56:29.139Z caller=main.go:356 msg="Error loading config (--config.file=prometheus.yml)" err="open prometheus.yml: no such file or directory"

已尝试 google。有挂载文件的建议

docker run -p 9090:9090 \
-v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus

(来自https://www.promlts.com/resources/wheres-my-prometheus-yml) 但是运气不好。

尝试指定配置文件选项,但再次失败。

你能帮忙吗?

你可以尝试添加:

--config.file=/etc/prometheus/prometheus.yml 

docker run --publish=9090:9090 \
--volume=D:/WORK/MyProject/grafana:/etc/prometheus \
prom/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --enable-feature=promql-at-modifier

Explanation: Once you add flags (e.g. --enable-feature), other flags take default values. The default value for --config.file is prometheus.yml which is not what you want (you want /etc/prometheus/prometheus.yml) and so you must explicitly reference it.

DazWilkin 的回答背后的一些简短细节:

如果您 docker inspect prom/prometheus 图片,您会发现 以下:

            "Entrypoint": [
                "/bin/prometheus"
            ],
            "Cmd": [
                "--config.file=/etc/prometheus/prometheus.yml",
                "--storage.tsdb.path=/prometheus",
                "--web.console.libraries=/usr/share/prometheus/console_libraries",
                "--web.console.templates=/usr/share/prometheus/consoles"
            ],

当你运行:

docker run ... prom/prometheus --enable-feature=promql-at-modifier

您正在替换现有的 Cmd 设置,因此命令实际上 执行的是/bin/prometheus --enable-feature=promql-at-modifier。到 提供与默认情况下相同的行为,您实际上会 想要 运行:

docker run ... prom/prometheus \
  --enable-feature=promql-at-modifier \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/prometheus \
  --web.console.libraries=/usr/share/prometheus/console_libraries \
  --web.console.templates=/usr/share/prometheus/consoles

我是docker的粉丝,但它确实有一些摩擦点,你找到了其中之一。

https://github.com/prometheus/prometheus/blob/main/Dockerfile#L25是上游prometheus定义ENTRYPOINTCMD:

的地方
ENTRYPOINT [ "/bin/prometheus" ]
CMD        [ "--config.file=/etc/prometheus/prometheus.yml", \
             "--storage.tsdb.path=/prometheus", \
             "--web.console.libraries=/usr/share/prometheus/console_libraries", \
             "--web.console.templates=/usr/share/prometheus/consoles" ]

问题是,提供给 docker run 命令的任何参数都将 替换 默认值 CMD。因此,为了 附加 参数到默认值 CMD,您很遗憾需要复制上游 CMD,然后将您的参数添加到列表中。

遗憾的是,docker 不(目前!)支持任何方式将某些内容“附加”到上游的 CMD。 How to append an argument to a container command? 提供了一种使用环境变量来完成此操作的想法。

在我想提供默认参数 允许调用提供额外参数的一般情况下,我通常遵循以下模式:

  • 使入口点启动一个 shell 脚本
  • exec shell 脚本末尾的真正入口点。 exec 用真正的入口点替换 shell,因此 exec 很重要,因此信号被传递到入口点而不是包装器 shell 脚本.
  • 在脚本中 exec 的参数末尾,添加 "$@",它扩展为 shell 脚本的参数,适当引用(是的,shell 非常深奥!您可能认为它会引用 all 个参数,但它引用了 each 个参数,因为该标记是魔法)

这样,“默认”命令就在 shell 脚本中,因此不需要包含在 CMD 中。这种方法的缺点是 shell 脚本提供的参数更难删除(如果您愿意的话)。

这是一个例子:

https://github.com/farrellit/Whosebug/tree/main/68593213

docker文件包含默认 CMD:

FROM alpine
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["7"]

entrypoint.sh 包括一组附加了 CMD 的“自动”参数,默认或覆盖。

#!/bin/sh
exec echo 1 2 3 "$@"

Makefile 演示了两个调用:

    docker run --rm Whosebug-68593213
    docker run --rm Whosebug-68593213 4 5 6
docker run --rm Whosebug-68593213
1 2 3 7
docker run --rm Whosebug-68593213 4 5 6
1 2 3 4 5 6

这里,1 2 3是我一直想传递给ENTRYPOINT的默认“基本”参数,7是默认的“附加”参数, 并提供 4 5 6 以覆盖默认参数。