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號