Configure Default Memory Requests and Limits for a Namespace

If a Container is created in a namespace that has a default memory limit, and the Container does not specify its own memory limit, then the Container is assigned the default memory limit.

Before you begin

  • Each node in your cluster must have at least 2 GiB of memory.

Create a namespace

Create a namespace so that the resources you create in this exercise are isolated from the rest of your cluster.

kubectl create namespace default-mem-example
namespace "default-mem-example" created

Create a LimitRange and a Pod

Here’s the configuration file for a LimitRange object. The configuration specifies a default memory request and a default memory limit.

cat << EOF > memory-defaults.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
spec:
  limits:
  - default:
      memory: 512Mi
    defaultRequest:
      memory: 256Mi
    type: Container
EOF

Create the LimitRange in the default-mem-example namespace:

kubectl create -f memory-defaults.yaml --namespace=default-mem-example
limitrange "mem-limit-range" created

Now if a Container is created in the default-mem-example namespace, and the Container does not specify its own values for memory request and memory limit, the Container is given a default memory request of 256 MiB and a default memory limit of 512 MiB.

Here’s the configuration file for a Pod that has one Container. The Container does not specify a memory request and limit.

cat << EOF > memory-defaults-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: default-mem-demo
spec:
  containers:
  - name: default-mem-demo-ctr
    image: nginx
EOF

Create the Pod.

kubectl create -f memory-defaults-pod.yaml --namespace=default-mem-example
pod "default-mem-demo" created

View detailed information about the Pod:

kubectl get pod default-mem-demo --output=yaml --namespace=default-mem-example
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubernetes.io/limit-ranger:
      "LimitRanger plugin set: memory request for container
      default-mem-demo-ctr; memory limit for container default-mem-demo-ctr"
  creationTimestamp: 2019-01-04T10:31:54Z
  name: default-mem-demo
  namespace: default-mem-example
  resourceVersion: "238660"
  selfLink: /api/v1/namespaces/default-mem-example/pods/default-mem-demo
  uid: f4c51d59-100b-11e9-8810-42010a8000ba
spec:
  containers:
    - image: nginx
      imagePullPolicy: Always
      name: default-mem-demo-ctr
      resources:
        limits:
          memory: 512Mi
        requests:
          memory: 256Mi
      terminationMessagePath: /dev/termination-log
      terminationMessagePolicy: File
      volumeMounts:
        - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
          name: default-token-r77l2
          readOnly: true
  dnsPolicy: ClusterFirst
  nodeName: gke-admatic-cluster-default-pool-e5aae271-0b3v
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
    - effect: NoExecute
      key: node.kubernetes.io/not-ready
      operator: Exists
      tolerationSeconds: 300
    - effect: NoExecute
      key: node.kubernetes.io/unreachable
      operator: Exists
      tolerationSeconds: 300
  volumes:
    - name: default-token-r77l2
      secret:
        defaultMode: 420
        secretName: default-token-r77l2
status:
  conditions:
    - lastProbeTime: null
      lastTransitionTime: 2019-01-04T10:31:54Z
      status: "True"
      type: Initialized
    - lastProbeTime: null
      lastTransitionTime: 2019-01-04T10:31:59Z
      status: "True"
      type: Ready
    - lastProbeTime: null
      lastTransitionTime: 2019-01-04T10:31:54Z
      status: "True"
      type: PodScheduled
  containerStatuses:
    - containerID: docker://f279508a8553a919f0f7f026c4e27629ad84f7e3c7cc6b5b92a41fb4e801bf19
      image: nginx:latest
      imageID: docker-pullable://nginx@sha256:e2847e35d4e0e2d459a7696538cbfea42ea2d3b8a1ee8329ba7e68694950afd3
      lastState: {}
      name: default-mem-demo-ctr
      ready: true
      restartCount: 0
      state:
        running:
          startedAt: 2019-01-04T10:31:58Z
  hostIP: 10.128.0.3
  phase: Running
  podIP: 10.4.2.31
  qosClass: Burstable
  startTime: 2019-01-04T10:31:54Z

The output shows that the Pod’s Container has a memory request of 256 MiB and a memory limit of 512 MiB. These are the default values specified by the LimitRange.

containers:
  - image: nginx
    imagePullPolicy: Always
    name: default-mem-demo-ctr
    resources:
      limits:
        memory: 512Mi
      requests:
        memory: 256Mi

Delete your Pod:

kubectl delete pod default-mem-demo --namespace=default-mem-example
pod "default-mem-demo" deleted

What if you specify a Container’s limit, but not its request?

Here’s the configuration file for a Pod that has one Container. The Container specifies a memory limit, but not a request:

cat << EOF > memory-defaults-pod-2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: default-mem-demo-2
spec:
  containers:
  - name: default-mem-demo-2-ctr
    image: nginx
    resources:
      limits:
        memory: "1Gi"
EOF

Create the Pod:

kubectl create -f memory-defaults-pod-2.yaml --namespace=default-mem-example
pod "default-mem-demo-2" created

View detailed information about the Pod:

kubectl get pod default-mem-demo-2 --output=yaml --namespace=default-mem-example
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: 2019-01-04T10:34:53Z
  name: default-mem-demo-2
  namespace: default-mem-example
  resourceVersion: "239100"
  selfLink: /api/v1/namespaces/default-mem-example/pods/default-mem-demo-2
  uid: 5f3b79d3-100c-11e9-8810-42010a8000ba
spec:
  containers:
    - image: nginx
      imagePullPolicy: Always
      name: default-mem-demo-2-ctr
      resources:
        limits:
          memory: 1Gi
        requests:
          memory: 1Gi
      terminationMessagePath: /dev/termination-log
      terminationMessagePolicy: File
      volumeMounts:
        - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
          name: default-token-r77l2
          readOnly: true
  dnsPolicy: ClusterFirst
  nodeName: gke-admatic-cluster-default-pool-e5aae271-9tk6
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
    - effect: NoExecute
      key: node.kubernetes.io/not-ready
      operator: Exists
      tolerationSeconds: 300
    - effect: NoExecute
      key: node.kubernetes.io/unreachable
      operator: Exists
      tolerationSeconds: 300
  volumes:
    - name: default-token-r77l2
      secret:
        defaultMode: 420
        secretName: default-token-r77l2
status:
  conditions:
    - lastProbeTime: null
      lastTransitionTime: 2019-01-04T10:34:53Z
      status: "True"
      type: Initialized
    - lastProbeTime: null
      lastTransitionTime: 2019-01-04T10:34:57Z
      status: "True"
      type: Ready
    - lastProbeTime: null
      lastTransitionTime: 2019-01-04T10:34:53Z
      status: "True"
      type: PodScheduled
  containerStatuses:
    - containerID: docker://0b45113d59716f38dba3728c2c321b534de7d6ef0169d5744b08a748f1637e37
      image: nginx:latest
      imageID: docker-pullable://nginx@sha256:e2847e35d4e0e2d459a7696538cbfea42ea2d3b8a1ee8329ba7e68694950afd3
      lastState: {}
      name: default-mem-demo-2-ctr
      ready: true
      restartCount: 0
      state:
        running:
          startedAt: 2019-01-04T10:34:57Z
  hostIP: 10.128.0.2
  phase: Running
  podIP: 10.4.0.29
  qosClass: Burstable
  startTime: 2019-01-04T10:34:53Z

The output shows that the Container’s memory request is set to match its memory limit. Notice that the Container was not assigned the default memory request value of 256Mi.

containers:
  - image: nginx
    imagePullPolicy: Always
    name: default-mem-demo-2-ctr
    resources:
      limits:
        memory: 1Gi
      requests:
        memory: 1Gi

What if you specify a Container’s request, but not its limit?

Here’s the configuration file for a Pod that has one Container. The Container specifies a memory request, but not a limit:

cat << EOF > memory-defaults-pod-3.yaml
apiVersion: v1
kind: Pod
metadata:
  name: default-mem-demo-3
spec:
  containers:
  - name: default-mem-demo-3-ctr
    image: nginx
    resources:
      requests:
        memory: "128Mi"
EOF

Create the Pod:

kubectl create -f memory-defaults-pod-3.yaml --namespace=default-mem-example
pod "default-mem-demo-3" created

View the Pod’s specification:

kubectl get pod default-mem-demo-3 --output=yaml --namespace=default-mem-example
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubernetes.io/limit-ranger:
      "LimitRanger plugin set: memory limit for container
      default-mem-demo-3-ctr"
  creationTimestamp: 2019-01-04T10:36:39Z
  name: default-mem-demo-3
  namespace: default-mem-example
  resourceVersion: "239359"
  selfLink: /api/v1/namespaces/default-mem-example/pods/default-mem-demo-3
  uid: 9e479aa0-100c-11e9-8810-42010a8000ba
spec:
  containers:
    - image: nginx
      imagePullPolicy: Always
      name: default-mem-demo-3-ctr
      resources:
        limits:
          memory: 512Mi
        requests:
          memory: 128Mi
      terminationMessagePath: /dev/termination-log
      terminationMessagePolicy: File
      volumeMounts:
        - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
          name: default-token-r77l2
          readOnly: true
  dnsPolicy: ClusterFirst
  nodeName: gke-admatic-cluster-default-pool-e5aae271-0b3v
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
    - effect: NoExecute
      key: node.kubernetes.io/not-ready
      operator: Exists
      tolerationSeconds: 300
    - effect: NoExecute
      key: node.kubernetes.io/unreachable
      operator: Exists
      tolerationSeconds: 300
  volumes:
    - name: default-token-r77l2
      secret:
        defaultMode: 420
        secretName: default-token-r77l2
status:
  conditions:
    - lastProbeTime: null
      lastTransitionTime: 2019-01-04T10:36:39Z
      status: "True"
      type: Initialized
    - lastProbeTime: null
      lastTransitionTime: 2019-01-04T10:36:41Z
      status: "True"
      type: Ready
    - lastProbeTime: null
      lastTransitionTime: 2019-01-04T10:36:39Z
      status: "True"
      type: PodScheduled
  containerStatuses:
    - containerID: docker://46e66e00b4d9c5743cb35722150dd214b4df4816a0f3c879d399ea04fa168f43
      image: nginx:latest
      imageID: docker-pullable://nginx@sha256:e2847e35d4e0e2d459a7696538cbfea42ea2d3b8a1ee8329ba7e68694950afd3
      lastState: {}
      name: default-mem-demo-3-ctr
      ready: true
      restartCount: 0
      state:
        running:
          startedAt: 2019-01-04T10:36:40Z
  hostIP: 10.128.0.3
  phase: Running
  podIP: 10.4.2.32
  qosClass: Burstable
  startTime: 2019-01-04T10:36:39Z

The output shows that the Container’s memory request is set to the value specified in the Container’s configuration file. The Container’s memory limit is set to 512Mi, which is the default memory limit for the namespace.

containers:
  - image: nginx
    imagePullPolicy: Always
    name: default-mem-demo-3-ctr
    resources:
      limits:
        memory: 512Mi
      requests:
        memory: 128Mi

Motivation for default memory limits and requests

If your namespace has a resource quota, it is helpful to have a default value in place for memory limit. Here are two of the restrictions that a resource quota imposes on a namespace:

  • Every Container that runs in the namespace must have its own memory limit.
  • The total amount of memory used by all Containers in the namespace must not exceed a specified limit.

If a Container does not specify its own memory limit, it is given the default limit, and then it can be allowed to run in a namespace that is restricted by a quota.

Clean up

kubectl delete namespace default-mem-example
namespace "default-mem-example" deleted

results matching ""

    No results matching ""