在k8s中Prometheus 服务的 NodePort 已经正确配置,但集群外部无法通过 NodePort 方式访问 Prometheus 的 Web UI(集群使用了网络插件Calico)。

排查一:

在集群宿主机进行测试:

kubectl describe svc prometheus-k8s -n monitoring 

从输出结果来看,服务 prometheus-k8s 已经正确配置了两个端口:一个是用于 Web 端口的 9090(NodePort 为 32148),另一个是用于重新加载 Web 端口的 8080(NodePort 为 31109);

然后执行:

curl -L http://<node-ip>:<nodeport>

成功获取了Prometheus Web UI 的 HTML 页面。这表明集群内部可以通过 NodePort 访问 Prometheus 的 Web UI,可以排除 Prometheus Pod 和 Service 的基本配置问题,因为集群内部可以成功访问;

排查二:

尝试从集群的另一个一个节点使用 curl 直接访问 NodePort 服务,显示连接超时;这说明有可能是集群主机上的防火墙规则未允许外部流量到达 Prometheus 的 NodePort,需要手动添加规则以允许 TCP 流量通过端口。

解决方案一:

我的主机节点之前就已经把防火墙(firewalld)关了,需要重新开启,然后在开放防火墙端口:

########################
# master节点防火墙设置
########################

# 所有master节点开放相关防火墙端口
$ firewall-cmd --zone=public --add-port=6443/tcp --permanent
$ firewall-cmd --zone=public --add-port=2379-2380/tcp --permanent
$ firewall-cmd --zone=public --add-port=10250/tcp --permanent
$ firewall-cmd --zone=public --add-port=10251/tcp --permanent
$ firewall-cmd --zone=public --add-port=10252/tcp --permanent
$ firewall-cmd --zone=public --add-port=30000-32767/tcp --permanent

# 所有master节点必须开启firewalld该设置,否则dns无法解释
$ firewall-cmd --add-masquerade --permanent
$ firewall-cmd --reload
$ firewall-cmd --list-all --zone=public

########################
# worker节点防火墙设置
########################

# 所有worker节点开放相关防火墙端口
$ firewall-cmd --zone=public --add-port=10250/tcp --permanent
$ firewall-cmd --zone=public --add-port=30000-32767/tcp --permanent

# 所有worker节点必须开启firewalld该设置,否则dns无法解释
$ firewall-cmd --add-masquerade --permanent
$ firewall-cmd --reload
$ firewall-cmd --list-all --zone=public

# 所有节点清除iptables规则,解决firewalld引起nodeport无法访问问题
$ iptables -D INPUT -j REJECT --reject-with icmp-host-prohibited

测试端口连通性

完成防火墙规则的添加后,您可以使用 telnetnc(netcat)来测试端口的连通性。这里以 telnet 为例:

telnet 127.0.0.1 端口号
telnet 127.0.0.1 端口号

如果端口是开放的,您应该会看到类似下面的输出:

Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Connection closed by foreign host.

如果端口被拒绝连接,您会看到如下输出:

Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused


解决方案二:


不进行任何操作,当过段时间后,貌似又不能访问了,貌似是因为我将firewalld关闭了,然后就无法访问,但开启firewalld后似乎又可以访问了,询问通义千问后得到如下分析:

当关闭 firewalld 服务后,集群外部无法访问 Prometheus 的 Web UI,这可能是因为在默认情况下,即使 firewalld 被关闭,系统内核的防火墙规则仍然存在。这些规则可能会阻止特定端口的入站连接,从而导致从集群外部无法访问 Prometheus 的 Web UI。

分析问题

  1. 默认防火墙规则

    当 firewalld 关闭时,系统默认的防火墙规则仍然有效。这些规则可能会阻止某些端口的入站连接。
  2. iptables 配置

    当关闭 firewalld 时,CentOS 会恢复到默认的 iptables 配置,这意味着默认情况下会阻止未明确开放的端口。
  3. 定时任务或脚本

    过了一段时间后又无法访问,这可能是由于某些定时任务或脚本导致的。这些任务或脚本可能在后台运行,并修改了 iptables 规则或重新配置了防火墙。

解决方案

1.检查 cron 任务

可以检查是否有定时任务或脚本在后台运行,并修改了 iptables 规则或重新配置了防火墙。命令如下:

crontab -l
删除定时任务:
  1. 编辑 crontab 文件

    • 可以编辑 crontab 文件来删除上述定时任务。命令如下:
    crontab -e
  2. 删除定时任务

    • 在打开的 crontab 文件中找到定时任务的行,将其删除或注释掉。例如:
    # 5,15,25,35,45,55 * * * * /usr/sbin/iptables -D INPUT -j REJECT --reject-with icmp-host-prohibited
  3. 保存并退出

    • 保存文件并退出编辑器。如果使用的是 vi 或 vim,可以使用 :wq 命令保存并退出。
2. 使用 iptables 管理防火墙规则
  1. 检查 iptables 规则

    • 可以检查当前的 iptables 规则来确认是否有阻止外部访问的规则。命令如下:
    sudo iptables -L -n -v
  2. 添加 iptables 规则

    • 如果找到了阻止外部访问的规则,您可以添加一条新的规则来允许外部访问端口 31654/tcp。命令如下:
    sudo iptables -A INPUT -p tcp --dport 31654 -j ACCEPT
  3. 保存 iptables 规则

    • 为了让规则在系统重启后依然有效,需要保存这些规则。命令如下:
    sudo iptables-save > /etc/sysconfig/iptables
  4. 重启 iptables 服务

    • 为了使更改生效,需要重启 iptables 服务。命令如下:
    sudo systemctl restart iptables
3. 关闭 iptables

如果希望完全禁用 iptables 并依赖于 Calico 提供的安全策略,则可以按照以下步骤操作:

  1. 删除 iptables 规则

    • 删除所有 iptables 规则。命令如下:
    sudo iptables -F
    sudo iptables -X
  2. 验证 iptables 状态

    • 确认 iptables 已经没有任何规则。命令如下:
    sudo iptables -L -n -v

注意事项

  1. Calico 网络策略

    • 确认 Calico 是否正确配置了网络策略来允许外部访问集群内的服务。可以检查 Calico 的网络策略配置。
  2. 集群网络配置

    • 确认集群的网络配置是否允许从集群外部访问 NodePort 类型的服务。如果使用的是 Calico,请确保它支持从集群外部访问服务。
  3. 端口监听

    • 确认节点上是否监听了端口 31654。可以登录到节点并运行 netstat -an | grep 31654 来检查。
  4. 测试集群内部访问

    • 在集群内的一个 Pod 中运行以下命令来测试服务是否响应:
    kubectl run -it --rm --image=busybox curl-test -- /bin/sh -c "curl http://
------------------分割线
第二天发现还是不行,去b站搜了一下,在某prometheus教程下的评论区发现一位大佬的评论,说是prometheus的网络策略有问题,因为只接受来自​编辑prometheus自己的流量,要执行以下代码,然后又可以了:
kubectl -n monitoring delete networkpolicy --all
参考文章: 15.k8s集群防火墙配置_所有节点清除iptables规则,解决firewalld引起nodeport无法访问问题-CSDN博客
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐