为什么内存使用量大于我在 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-systemtest-ns有pods,所以给它们各分配1000Mi(来自kubectl describe nodes) 旨在小于 2GB
3. 假设kube-systemtest-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,从而更有可能杀死内存中的容器中的进程在它们的内存 requestlimit 之间,并使其最有可能在没有内存 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 事件将更可预测。