kubectl top node与实际节点不一致

1.查看本地kubectl参数

ps -ef |grep kubelet
root       601     1  3  2024 ?        18-14:03:40 /etc/kube/bin/kubelet --address=192.168.150.60 --allow-privileged=true --anonymous-auth=false --authentication-token-webhook --authorization-mode=Webhook --client-ca-file=/etc/kubernetes/ssl/ca.pem --cluster-dns=10.68.0.2 --cluster-domain=cluster.local. --cni-bin-dir=/etc/kube/bin --cni-conf-dir=/etc/cni/net.d --fail-swap-on=false --hairpin-mode hairpin-veth --hostname-override=192.168.150.60 --kubeconfig=/etc/kubernetes/kubelet.kubeconfig --max-pods=110 --network-plugin=cni --pod-infra-container-image=mirrorgooglecontainers/pause-amd64:3.1 --register-node=true --root-dir=/var/lib/kubelet --tls-cert-file=/etc/kubernetes/ssl/kubelet.pem --tls-private-key-file=/etc/kubernetes/ssl/kubelet-key.pem --cgroups-per-qos=true --cgroup-driver=cgroupfs --enforce-node-allocatable=pods,kube-reserved --kube-reserved=cpu=200m,memory=500Mi,ephemeral-storage=1Gi --kube-reserved-cgroup=/system.slice/kubelet.service --eviction-hard=memory.available<200Mi,nodefs.available<10 --v=2

kubelet 的启动参数
以下是 kubelet 的启动参数及其含义:
--address=192.168.150.60:
指定 kubelet 监听的 IP 地址为 192.168.150.60。
--allow-privileged=true:
允许运行特权容器(privileged containers)。特权容器可以访问宿主机的底层资源。
--anonymous-auth=false:
禁用匿名认证,即不允许未认证的用户访问 kubelet。
--authentication-token-webhook:
启用基于 Webhook 的认证,通过 Kubernetes API Server 进行认证。
--authorization-mode=Webhook:
使用 Webhook 模式进行授权,即通过 Kubernetes API Server 的授权 Webhook 进行授权。
--client-ca-file=/etc/kubernetes/ssl/ca.pem:
指定客户端证书的 CA 文件路径。
--cluster-dns=10.68.0.2:
指定集群 DNS 服务的 IP 地址。
--cluster-domain=cluster.local.:
指定集群的域名为 cluster.local。
--cni-bin-dir=/etc/kube/bin:
指定 CNI 插件的可执行文件目录。
--cni-conf-dir=/etc/cni/net.d:
指定 CNI 配置文件的目录。
--fail-swap-on=false:
禁用对交换空间(swap)的检查。如果为 true,kubelet 会检查系统是否启用了 swap,如果启用了则会报错。
--hairpin-mode=hairpin-veth:
指定 hairpin 模式,用于处理 Pod 之间的网络通信。
--hostname-override=192.168.150.60:
覆盖节点的主机名,将其设置为 192.168.150.60。
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig:
指定 kubelet 的配置文件路径。
--max-pods=110:
指定每个节点上允许的最大 Pod 数量为 110。
--network-plugin=cni:
使用 CNI(Container Network Interface)作为网络插件。
--pod-infra-container-image=mirrorgooglecontainers/pause-amd64:3.1:
指定 Pod 基础容器镜像,用于提供 Pod 的网络命名空间。
--register-node=true:
允许 kubelet 自动向 Kubernetes API Server 注册节点。
--root-dir=/var/lib/kubelet:
指定 kubelet 的根目录。
--tls-cert-file=/etc/kubernetes/ssl/kubelet.pem:
指定 TLS 证书文件路径。
--tls-private-key-file=/etc/kubernetes/ssl/kubelet-key.pem:
指定 TLS 私钥文件路径。
--cgroups-per-qos=true:
启用基于 QoS 的 Cgroups。
--cgroup-driver=cgroupfs:
指定 Cgroup 驱动为 cgroupfs。
--enforce-node-allocatable=pods,kube-reserved:
指定 Kubernetes 需要为 Pod 和 kube-reserved 保留的资源。
--kube-reserved=cpu=200m,memory=500Mi,ephemeral-storage=1Gi:
为 Kubernetes 系统保留的资源:200m CPU、500Mi 内存和 1Gi 临时存储。
--kube-reserved-cgroup=/system.slice/kubelet.service:
指定 Kubernetes 系统保留资源的 Cgroup 路径。
--eviction-hard=memory.available<200Mi,nodefs.available<10:
配置驱逐条件:当可用内存小于 200Mi 或节点文件系统可用空间小于 10% 时,触发驱逐。
--v=2:
设置日志级别为 2,表示输出较详细的信息。

2.具体不一致原因 , 以下由AI作答

是的,kubectl top node 展示的内存和实际节点内存之间存在差异,可能与 --kube-reserved--eviction-hard 参数有关。以下是对这两个参数及其影响的详细分析:


1. --kube-reserved 参数

  • 作用--kube-reserved 用于为 Kubernetes 系统组件(如 kubelet、容器运行时等)预留资源。

  • 配置示例

    --kube-reserved=cpu=200m,memory=500Mi,ephemeral-storage=1Gi
    

    表示为系统组件预留了:

    • CPU: 200m(0.2 核)
    • 内存: 500Mi
    • 临时存储: 1Gi
  • kubectl top node 的影响

    • kubectl top node 显示的是节点上可供分配给 Pod 的资源量,而不是节点的总物理资源。
    • 预留的资源会被从可分配资源中扣除,因此 kubectl top node 显示的内存会比实际物理内存少。

2. --eviction-hard 参数

  • 作用--eviction-hard 定义了节点资源不足时触发驱逐的阈值。

  • 配置示例

    --eviction-hard=memory.available<200Mi,nodefs.available<10%
    

    表示当节点的可用内存低于 200Mi 或者磁盘空间低于 10% 时,Kubernetes 会开始驱逐 Pod。

  • kubectl top node 的影响

    • --eviction-hard 并不会直接减少 kubectl top node 中显示的资源量,但它会影响调度器的资源分配决策。
    • 调度器会确保节点上始终保留一定的资源(如 200Mi 内存),以避免触发驱逐。这部分资源也会被从可分配资源中扣除,导致 kubectl top node 显示的资源量减少。

3. 差异的来源

结合你的描述,kubectl top node 显示的内存比实际节点内存少 700MB,可能由以下原因造成:

  1. --kube-reserved 的内存预留
    • 配置了 memory=500Mi,这 500Mi 内存被预留给了系统组件,无法分配给 Pod。
  2. --eviction-hard 的驱逐阈值
    • 配置了 memory.available<200Mi,这意味着节点上至少需要保留 200Mi 内存,不能分配给 Pod。
  3. 其他系统开销
    • 除了 --kube-reserved--eviction-hard 外,操作系统和其他非 Kubernetes 进程也会占用部分内存。

因此,总的差值可以分解为:

500Mi (kube-reserved) + 200Mi (eviction-hard) = 700Mi

4. 如何验证

你可以通过以下方式验证这些参数的影响:

(1) 查看节点的 Allocatable 资源

使用以下命令查看节点的可分配资源(Allocatable):

kubectl describe node <node-name>

在输出中找到 Allocatable 字段,例如:

Allocatable:
  cpu:                4
  memory:             15500Mi
  ephemeral-storage:  100Gi

这里的 memory 值就是节点可供 Pod 使用的内存总量,已经扣除了 --kube-reserved 和其他预留资源。

(2) 查看节点的实际资源

通过操作系统命令查看节点的总物理内存:

free -h

或者:

cat /proc/meminfo | grep MemTotal

(3) 对比差异

kubectl describe node 中的 Allocatable 内存与实际物理内存对比,确认差值是否符合 --kube-reserved--eviction-hard 的配置。


5. 解决方案

如果希望减少 kubectl top node 和实际内存之间的差异,可以调整以下参数:

(1) 调整 --kube-reserved

  • 如果节点上的系统组件实际占用内存较少,可以适当降低 --kube-reserved 的内存预留值,例如:
    --kube-reserved=cpu=200m,memory=300Mi,ephemeral-storage=1Gi
    

(2) 调整 --eviction-hard

  • 如果节点的内存较大,可以适当放宽驱逐阈值,例如:
    --eviction-hard=memory.available<500Mi,nodefs.available<10%
    

(3) 监控和优化

  • 监控节点的实际内存使用情况,确保预留资源不会过多浪费。
  • 使用工具(如 Prometheus 和 Grafana)分析节点资源使用趋势,动态调整预留参数。

总结

kubectl top node 显示的内存和实际节点内存之间的差异确实是由 --kube-reserved--eviction-hard 参数引起的。这种设计是为了确保系统组件有足够的资源运行,并避免节点因资源耗尽而触发驱逐。如果你认为当前配置过于保守,可以依据实际需求调整这些参数,以更高效地利用节点资源。

posted @ 2025-04-29 17:04  凨筝  阅读(74)  评论(0)    收藏  举报