kube-prometheus 使用 blackbox-exporter 进行icmp 监控

安装kube-prometheus 后默认在monitoring namespace中有创建 blackbox-exporter deployment。但默认没有icmp的module配置,无法执行ping探测。因为即使有icmp module,默认配置也是无法执行ping探测的(这篇文章要解决的就是这个问题),这可能也是默认没有icmp module的原因。

首先把icmp module加上,然后增加icmp 的probe配置:

第一步修改blackbox 的config map,添加icmp的modules:

kubectl -n monitoring edit cm blackbox-exporter-configuration
添加如下module配置
      "icmp_example":
         "prober": "icmp"
         "timeout": "5s"
         "icmp":
            "preferred_ip_protocol": "ip4"

创建probe

注意这里的module 名要与刚创建的对应

kind: Probe
apiVersion: monitoring.coreos.com/v1
metadata:
  name: example-ping
  namespace: monitoring
spec:
  interval: 60s
  module: icmp_example
  prober:
    url: blackbox-exporter.monitoring.svc.cluster.local:19115
  targets:
    staticConfig:
      static:
      - 127.0.0.1

至此,你的prometheus中应该有这个target了,并且状态也是up,类似如下
kube-prometheus 使用 blackbox-exporter 进行icmp 监控_第1张图片
但是在Prometheus 中查询 probe_success 的结果时返回值是0,也就时ping不通。值为1表示ping成功。
也可以通过访问blackbox的如下url进行测试:

curl -s http://192.168.112.123:9115/probe?module=icmp_example&target=127.0.0.1

此时检查blcakbox-exporter的日志毫无发现。
下面调整日志级别为debug试试

在blackbox容器args新曾参数--log.level=debug
kubectl -n monitoring edit deployments.apps  blackbox-exporter 
      containers:
      - args:
        - --config.file=/etc/blackbox_exporter/config.yml
        - --web.listen-address=:19115
        - --log.level=debug #新增行,开启debug模式

开启debug日志后再查看日志,将看到有如下报错

ts=2023-08-08T01:15:43.133Z caller=handler.go:184 module=icmp_example target=192.168.199.123 level=debug msg="Unable to do unprivileged listen on socket, will attempt privileged" err="socket: permission denied"
ts=2023-08-08T01:15:43.133Z caller=handler.go:184 module=icmp_example target=192.168.199.123 level=debug msg="Error listening to socket" err="listen ip4:icmp 0.0.0.0: socket: operation not permitted"
ts=2023-08-08T01:15:43.133Z caller=handler.go:184 module=icmp_example target=192.168.199.123 level=debug msg="Probe failed" duration_seconds=0.00031592

这看起来是权限问题导致的。找到如下解释:
https://github.com/prometheus/blackbox_exporter#permissions

The ICMP probe requires elevated privileges to function:
Windows: Administrator privileges are required.
Linux: either a user with a group within net.ipv4.ping_group_range, the CAP_NET_RAW capability or the root user is required.
1. Your distribution may configure net.ipv4.ping_group_range by default in /etc/sysctl.conf or similar. If not you can set net.ipv4.ping_group_range = 0 2147483647 to allow any user the ability to use ping.
2. Alternatively the capability can be set by executing setcap cap_net_raw+ep blackbox_exporter
BSD: root user is required.
bNo additional privileges are needed.

Linux ping 命令需要 “cap_net_raw”(或 “CAP_NET_RAW”)的 Capabilities 权限,因为该命令需要对数据包进行原始套接字访问。如果不具备此权限,则无法构建和发送 ICMP 包,或者无法接 ICMP 包的响应。
请注意,ping 命令需要在网络层上执行操作,因此它需要特殊的权限。使用 Capabilities 机制覆盖了普通 Linux 用户的权限限制。设置 “cap_net_raw” 权限时,用户将能够执行“ping”命令,而无需以 root 用户的身份登录到系统。
如果使用 root 用户运行 ping 命令,则无需为 ping 命令设置 “cap_net_raw” 的 Capabilities 权限即可成功运行。这是因为 root 用户具有所有系统资源和 Capabilities 权限。使用 root 用户时,系统将允许 ping 命令访问原始套接字,而无需 Capabilities 权限。

那么也就说应该有两种方式解决这个问题,一是简单粗暴使用root运行(安全性低)。二是给与容器NET_RAW权限。下面分别测试一下:

方案1,给root权限

kubectl -n monitoring edit deployments.apps  blackbox-exporter
	securityContext部分修改为如下:
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          runAsNonRoot: false
          runAsUser: 0

  (注意这里去掉了原来的capabilities)也就是这部分,因为即使是有root权限,如果显示的移除了权限,也仍然没权限。
         capabilities:
            drop:          
            - ALL

这样修改之后再在Prometheus 中查询 probe_success 的结果值应该是1了。也就是正常了。

再看第二种方案:为容器增加NET_RAW
开始想直接修改deployment的capabilities配置,加上如下配置即可。

        capabilities:
            add:
            - NET_RAW

但是经过测试发现不行,初步判断是因为blackbox-exporter容器镜像本身处于安全性考虑的原因,禁用了一些权限,(如Alpine 镜像,加也没效果,可以通过进入容器内cat /proc/1/status命令查看CapPrm和CapEff的值。可参照文档 https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/security-context/)

在 Linux 操作系统中,进程的系统权限可以通过掩码方式进行控制。这些掩码通常被称为“capabilities”,每个掩码通常代表一项特定的系统操作功能。
如果 /proc/1/status 文件中 CapPrm 和 CapEff 的值都为 0,这意味着该进程没有启用任何权限。这可能是由于系统管理员将该进程的权限掩码设置为 0,或者该进程在启动时未显式启用任何额外的权限。另外一些 Linux 发行版(如 Alpine)默认在容器中禁用权限,因此 /proc/1/status 中的权限值通常为 0。如果您有特定的权限要求,请确保正确配置容器和 Pod 的权限

所以如果我们即不想用root用户运行blackbox,又想用icmp监控。则需要重新build一个镜像。
Dockerfile 如下

FROM scionproto/docker-caps as caps

FROM prom/blackbox-exporter:v0.23.0
COPY --from=caps /bin/setcap /bin
RUN setcap cap_net_raw+ep /bin/blackbox_exporter && rm /bin/setcap

修改blackbox-exporter deployment 的镜像为刚刚build的镜像。再修改securityContext配置,去掉原有的:

        capabilities:
            drop:          
            - ALL
	securityContext部分修改为如下:
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 65534

blackbox-extporter pod正常运行后在Prometheus 中查询 probe_success 的结果值应该是1了。也就是正常了。

参考资料
https://blog.csdn.net/qq_33745102/article/details/131042025
https://github.com/prometheus/blackbox_exporter/issues/689
https://github.com/scionproto/docker-caps

你可能感兴趣的:(prometheus,kubernetes,kube-prometheus)