为什么内存使用量大于我在 Kubernetes 的节点中设置的?
Why memory usage is greater than what I set in Kubernetes's node?
我只用 650MB/30% 的内存将资源分配给 1 个 pod(使用其他内置 pods,限制内存仅为 69%)
但是在pod处理过程中,pod的使用率在650MB以内,而node的整体使用率为94%。
为什么会这样,因为它应该有 69% 的上限?是不是其他内置的pods没有设置限制?如果内存使用率 > 100%,我的 pod 有时会出错,如何防止这种情况?
我的分配设置(kubectl describe nodes
):
空闲时Kubernetes Node和Pod的内存使用:
kubectl top nodes
kubectl top pods
运行任务时Kubernetes节点和Pod的内存使用:
kubectl top nodes
kubectl top pods
进一步测试的行为:
1.准备部署,pods和命名空间test-ns
下的服务
2、由于只有kube-system和test-ns有pods,所以给它们各分配1000Mi(来自kubectl describe nodes
) 旨在小于 2GB
3. 假设kube-system和test-ns使用的内存不到2GB也就是不到100%,为什么内存占用可以106%?
在.yaml 文件中:
apiVersion: v1
kind: LimitRange
metadata:
name: default-mem-limit
namespace: test-ns
spec:
limits:
- default:
memory: 1000Mi
type: Container
---
apiVersion: v1
kind: LimitRange
metadata:
name: default-mem-limit
namespace: kube-system
spec:
limits:
- default:
memory: 1000Mi
type: Container
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: devops-deployment
namespace: test-ns
labels:
app: devops-pdf
spec:
selector:
matchLabels:
app: devops-pdf
replicas: 2
template:
metadata:
labels:
app: devops-pdf
spec:
containers:
- name: devops-pdf
image: dev.azurecr.io/devops-pdf:latest
imagePullPolicy: Always
ports:
- containerPort: 3000
resources:
requests:
cpu: 600m
memory: 500Mi
limits:
cpu: 600m
memory: 500Mi
imagePullSecrets:
- name: regcred
---
apiVersion: v1
kind: Service
metadata:
name: devops-pdf
namespace: test-ns
spec:
type: LoadBalancer
ports:
- port: 8007
selector:
app: devops-pdf
这种效果很可能是由于 Pods 在该节点 上 运行 没有指定 内存限制造成的,显示为 0 (0%)
.当然 0 并不意味着它甚至不能使用单个字节的内存,因为没有内存就无法启动任何程序;相反,它意味着没有限制,它可以尽可能多地使用。 运行ning 不在 pod 中的程序(ssh、cron、...)也包含在使用总数中,但不受 kubernetes(cgroups)的限制。
现在 kubernetes 以一种巧妙的方式设置内核 oom 调整值,以支持内存中的容器 request,从而更有可能杀死内存中的容器中的进程在它们的内存 request 和 limit 之间,并使其最有可能在没有内存 limits 的容器中终止进程].但是,这仅在长 运行 中表现得相当好,有时内核会在您最喜欢的容器中杀死您最喜欢的进程,该容器表现良好(使用少于其内存 request).参见 https://kubernetes.io/docs/tasks/administer-cluster/out-of-resource/#node-oom-behavior
在这种特殊情况下,没有内存限制的 pods 来自 aks 系统本身,因此在 pod 模板中设置内存限制不是一个选项,因为有一个协调器可以恢复它(最终).为了补救这种情况,我建议您在 kube-system 命名空间中创建一个 LimitRange 对象,该对象将为所有 pods 分配内存限制而没有限制(在创建时):
apiVersion: v1
kind: LimitRange
metadata:
name: default-mem-limit
namespace: kube-system
spec:
limits:
- default:
memory: 150Mi
type: Container
(您需要删除已经存在的 Pods 才能生效;它们将被重新创建)
这不会完全消除问题,因为您最终可能会遇到一个过度使用的节点;然而,内存使用将是有意义的,并且 oom 事件将更可预测。
我只用 650MB/30% 的内存将资源分配给 1 个 pod(使用其他内置 pods,限制内存仅为 69%)
但是在pod处理过程中,pod的使用率在650MB以内,而node的整体使用率为94%。
为什么会这样,因为它应该有 69% 的上限?是不是其他内置的pods没有设置限制?如果内存使用率 > 100%,我的 pod 有时会出错,如何防止这种情况?
我的分配设置(kubectl describe nodes
):
空闲时Kubernetes Node和Pod的内存使用:
kubectl top nodes
kubectl top pods
运行任务时Kubernetes节点和Pod的内存使用:
kubectl top nodes
kubectl top pods
进一步测试的行为:
1.准备部署,pods和命名空间test-ns
下的服务
2、由于只有kube-system和test-ns有pods,所以给它们各分配1000Mi(来自kubectl describe nodes
) 旨在小于 2GB
3. 假设kube-system和test-ns使用的内存不到2GB也就是不到100%,为什么内存占用可以106%?
在.yaml 文件中:
apiVersion: v1
kind: LimitRange
metadata:
name: default-mem-limit
namespace: test-ns
spec:
limits:
- default:
memory: 1000Mi
type: Container
---
apiVersion: v1
kind: LimitRange
metadata:
name: default-mem-limit
namespace: kube-system
spec:
limits:
- default:
memory: 1000Mi
type: Container
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: devops-deployment
namespace: test-ns
labels:
app: devops-pdf
spec:
selector:
matchLabels:
app: devops-pdf
replicas: 2
template:
metadata:
labels:
app: devops-pdf
spec:
containers:
- name: devops-pdf
image: dev.azurecr.io/devops-pdf:latest
imagePullPolicy: Always
ports:
- containerPort: 3000
resources:
requests:
cpu: 600m
memory: 500Mi
limits:
cpu: 600m
memory: 500Mi
imagePullSecrets:
- name: regcred
---
apiVersion: v1
kind: Service
metadata:
name: devops-pdf
namespace: test-ns
spec:
type: LoadBalancer
ports:
- port: 8007
selector:
app: devops-pdf
这种效果很可能是由于 Pods 在该节点 上 运行 没有指定 内存限制造成的,显示为 0 (0%)
.当然 0 并不意味着它甚至不能使用单个字节的内存,因为没有内存就无法启动任何程序;相反,它意味着没有限制,它可以尽可能多地使用。 运行ning 不在 pod 中的程序(ssh、cron、...)也包含在使用总数中,但不受 kubernetes(cgroups)的限制。
现在 kubernetes 以一种巧妙的方式设置内核 oom 调整值,以支持内存中的容器 request,从而更有可能杀死内存中的容器中的进程在它们的内存 request 和 limit 之间,并使其最有可能在没有内存 limits 的容器中终止进程].但是,这仅在长 运行 中表现得相当好,有时内核会在您最喜欢的容器中杀死您最喜欢的进程,该容器表现良好(使用少于其内存 request).参见 https://kubernetes.io/docs/tasks/administer-cluster/out-of-resource/#node-oom-behavior
在这种特殊情况下,没有内存限制的 pods 来自 aks 系统本身,因此在 pod 模板中设置内存限制不是一个选项,因为有一个协调器可以恢复它(最终).为了补救这种情况,我建议您在 kube-system 命名空间中创建一个 LimitRange 对象,该对象将为所有 pods 分配内存限制而没有限制(在创建时):
apiVersion: v1
kind: LimitRange
metadata:
name: default-mem-limit
namespace: kube-system
spec:
limits:
- default:
memory: 150Mi
type: Container
(您需要删除已经存在的 Pods 才能生效;它们将被重新创建)
这不会完全消除问题,因为您最终可能会遇到一个过度使用的节点;然而,内存使用将是有意义的,并且 oom 事件将更可预测。