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,可能由以下原因造成:
--kube-reserved的内存预留:- 配置了
memory=500Mi,这 500Mi 内存被预留给了系统组件,无法分配给 Pod。
- 配置了
--eviction-hard的驱逐阈值:- 配置了
memory.available<200Mi,这意味着节点上至少需要保留 200Mi 内存,不能分配给 Pod。
- 配置了
- 其他系统开销:
- 除了
--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 参数引起的。这种设计是为了确保系统组件有足够的资源运行,并避免节点因资源耗尽而触发驱逐。如果你认为当前配置过于保守,可以依据实际需求调整这些参数,以更高效地利用节点资源。

浙公网安备 33010602011771号