irb*_*ull 8 memory-management kubernetes
https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/上的 Kubernetes 文档状态:
调度器保证,对于每种资源类型,被调度的Container的资源请求总和小于节点的容量。
Kubernetes 在计算容量时会考虑节点的当前状态吗?为了强调我的意思,这里有一个具体的例子:
假设我有一个具有 10Gi RAM 的节点,运行 10 个 Pod,每个 Pod 具有 500Mi 的资源请求,并且没有限制。假设它们正在“爆发”,并且每个 Pod 实际上都在使用 1Gi 的 RAM。在这种情况下,节点被充分利用(10 x 1Gi = 10Gi),但资源请求仅为10 x 500Mi = 5Gi。Kubernetes 会考虑在该节点上调度另一个 pod,因为该节点上只有 50% 的内存容量已经被占用requested,还是会使用当前 100% 的内存正在被使用,并且该节点已满负荷运行的事实?
默认情况下,kubernetes 将使用 cgroups 来管理和监控节点上 pod 的“可分配”内存。可以配置kubelet为完全依赖来自部署的静态预留和 pod请求,因此该方法取决于您的集群部署。
在任何一种情况下,节点本身都会跟踪“内存压力”,它监控节点现有的整体内存使用情况。如果节点处于内存压力之下,则不会调度新的 Pod,并且会驱逐现有的 Pod。
最好为所有工作负载设置合理的内存请求和限制,以尽可能帮助调度程序。如果 kubernetes 部署未配置 cgroup 内存监控,则所有工作负载都需要设置请求。如果部署使用 cgroup 内存监控,至少设置请求会为调度程序提供额外的详细信息,以确定要调度的 pod 是否应该适合某个节点。
该Kubernetes储备计算资源docco拥有的内存是如何在节点上看到一个很好的概述。
Node Capacity
---------------------------
| kube-reserved |
|-------------------------|
| system-reserved |
|-------------------------|
| eviction-threshold |
|-------------------------|
| |
| allocatable |
| (available for pods) |
| |
| |
---------------------------
Run Code Online (Sandbox Code Playgroud)
默认调度程序会检查节点是否处于内存压力之下,然后查看节点上可用的可分配内存以及新的 pod请求是否适合其中。
可用的可分配内存是total-available-memory - kube-reserved - system-reserved - eviction-threshold - scheduled-pods.
的值scheduled-pods可以通过动态 cgroup 计算,也可以通过 pods资源请求静态计算。
kubelet--cgroups-per-qos选项默认true启用 cgroup 跟踪调度的 pod。kubernetes 运行的 pods 将在
如果那样的--cgroups-per-qos=false话,可分配的内存只会因在节点上调度的资源请求而减少。
这eviction-threshold是 Kubernetes 开始驱逐 Pod 时的可用内存级别。默认为 100MB,但可以通过 kubelet 命令行设置。此设置与节点的可分配值以及下一节中节点的内存压力状态有关。
kubeletssystem-reserved值可以配置为静态值 ( --system-reserved=) 或通过 cgroup ( --system-reserved-cgroup=)动态监控。这是用于运行kubernetes之外的任何系统守护进程(sshd,systemd等)。如果你配置了一个cgroup,那么所有的进程都需要放在那个cgroup中。
kubeletskube-reserved值可以配置为静态值(通过--kube-reserved=)或通过 cgroup(--kube-reserved-cgroup=)动态监控。这适用于在 kubernetes 之外运行的任何 kubernetes 服务,通常kubelet和容器运行时。
容量存储在 Node 对象中。
$ kubectl get node node01 -o json | jq '.status.capacity'
{
"cpu": "2",
"ephemeral-storage": "61252420Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "4042284Ki",
"pods": "110"
}
Run Code Online (Sandbox Code Playgroud)
可以在节点上找到可分配的值,您可以注意到现有使用不会更改此值。只有具有资源请求的调度 pod 才会从该allocatable值中删除。
$ kubectl get node node01 -o json | jq '.status.allocatable'
{
"cpu": "2",
"ephemeral-storage": "56450230179",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "3939884Ki",
"pods": "110"
}
Run Code Online (Sandbox Code Playgroud)
一个 kube 节点也可以有一个“内存压力”事件。此检查是在上面的可分配资源检查之外完成的,并且更像是系统级别的全部检查。内存压力查看当前根 cgroup 内存使用量减去不活动的文件缓存/缓冲区,类似于free删除文件缓存的计算。
处于内存压力下的节点不会调度 Pod,并且会主动尝试驱逐现有的 Pod,直到内存压力状态得到解决。
您可以通过--eviction-hard=[memory.available<500Mi]标志设置 kubelet 将保持可用的内存驱逐阈值量。Pod 的内存请求和使用情况可以帮助通知驱逐过程。
kubectl top node 将为您提供每个节点的现有内存统计信息(如果您正在运行指标服务)。
$ kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
node01 141m 7% 865Mi 22%
Run Code Online (Sandbox Code Playgroud)
如果您没有使用cgroups-per-qos和许多没有资源限制的 pod,或许多系统守护进程,那么集群可能会在内存受限的系统上调度一些问题,因为可分配的会很高,但实际值可能真的很低。
Kubernetes Out Of Resource Handling docco包含一个模拟 kubelets 内存监控过程的脚本:
# This script reproduces what the kubelet does
# to calculate memory.available relative to root cgroup.
# current memory usage
memory_capacity_in_kb=$(cat /proc/meminfo | grep MemTotal | awk '{print $2}')
memory_capacity_in_bytes=$((memory_capacity_in_kb * 1024))
memory_usage_in_bytes=$(cat /sys/fs/cgroup/memory/memory.usage_in_bytes)
memory_total_inactive_file=$(cat /sys/fs/cgroup/memory/memory.stat | grep total_inactive_file | awk '{print $2}')
memory_working_set=${memory_usage_in_bytes}
if [ "$memory_working_set" -lt "$memory_total_inactive_file" ];
then
memory_working_set=0
else
memory_working_set=$((memory_usage_in_bytes - memory_total_inactive_file))
fi
memory_available_in_bytes=$((memory_capacity_in_bytes - memory_working_set))
memory_available_in_kb=$((memory_available_in_bytes / 1024))
memory_available_in_mb=$((memory_available_in_kb / 1024))
echo "memory.capacity_in_bytes $memory_capacity_in_bytes"
echo "memory.usage_in_bytes $memory_usage_in_bytes"
echo "memory.total_inactive_file $memory_total_inactive_file"
echo "memory.working_set $memory_working_set"
echo "memory.available_in_bytes $memory_available_in_bytes"
echo "memory.available_in_kb $memory_available_in_kb"
echo "memory.available_in_mb $memory_available_in_mb"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2225 次 |
| 最近记录: |