Files
2020-07-26 17:14:57 +03:00

3.2 KiB
Raw Blame History

Set memory limits using Docker only



One Paragraph Explainer

A memory limit tells the process/container the maximum allowed memory usage - a request or usage beyond this number will kill the process (OOMKill). Applying this is a great practice to ensure one citizen doesn't drink alone all the juice and leave other components to starve. Memory limits also allow the runtime to place a container in the right instance - placing a container that consumes 500MB in an instance with 300MB memory available will lead to failures. Two different options allow configuring this limit: V8 flags (--max-old-space-size) and the Docker runtime. There is confusion around which of those to set: Ensure to always configure the Docker runtime limits as is has a much wider perspective for making the right decisions. First, given this limit, the runtime knows how to scale and create more resources. It can also make a thoughtful decision on when to crash - if a container has a short burst in memory request and the hosting instance is capable of supporting this, Docker will let the container stay alive. Docker also measures the actually used memory and not the allocated part (unlike v8 --max-old-space-size) so it can get Killed only when really needed. Last, With Docker the Ops experts can set various production memory configurations that can be taken into account like memory swap.



Code Example Memory limit with Docker

Bash
docker run --memory 512m my-node-app



Code Example Memory limit with Kubernetes

Kubernetes deployment yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-node-app
spec:
  containers:
  - name: my-node-app
    image: my-node-app
    resources:
      requests:
        memory: "400Mi"
      limits:
        memory: "500Mi"
    command: ["node index.js"]



Code Example Anti-Pattern Setting memory limit using V8 flags

Kubernetes deployment yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-node-app
spec:
  containers:
  - name: my-node-app
    image: my-node-app
    command: ["node index.js --max-old-space-size=400"]



Kubernetes documentation: "If you do not specify a memory limit"

From K8S documentation

The Container has no upper bound on the amount of memory it uses. The Container could use all of the memory available on the Node where it is running which in turn could invoke the OOM Killer. Further, in case of an OOM Kill, a container with no resource limits will have a greater chance of being killed.



Docker documentation: "it throws an OOME and starts killing processes "

From Docker official docs

It is important not to allow a running container to consume too much of the host machines memory. On Linux hosts, if the kernel detects that there is not enough memory to perform important system functions, it throws an OOME, or Out Of Memory Exception, and starts killing processes to free up memory.