Skip to main content

Kubernetes

CronJobs

Do not create cron jobs with intervals of less than 10 minutes. The resource savings do not apply here, and the overhead for cold starts is too high.

Alternative: Deploy a continuous process with fewer resources.

Logging

Be sparing with unnecessary logging, as it causes significant costs. Enable debug/info/trace logs via flag or environment variable.

Standard Environments

  • dev: Auto-deployment from main/master. Mainly serves as an integration test (Does deployment work? Do migrations work? Does the API start?). The pipeline must ALWAYS be functional. If the pipeline is red, NOTHING may be merged that does not contribute to fixing the pipeline. Automatically deleted after 12 hours without deployment (data is retained).

  • test: For internal tests, demos of unmerged or in-progress features allowed. Pushing without review permitted. Automatically deleted after 7 days without deployment (data is retained).

  • staging: For customer acceptance. Serves as the base for future production deployments. Only master/main may be reset here (= only reviewed code). Permanently operational (= features can be tested here, demo content maintained, etc.).

  • prod: Manual deployment from staging.

Replicas

TLDR: Everything on non-prod runs with one replica; everything on prod runs with at least 2 replicas.

Why? On non-prod, we focus on cost-efficiency, so minor interruptions are not a problem. On prod, everything must be highly available. Cluster auto-scaler events or node upgrades MUST NOT interrupt application availability. Consequence: Every microservice needs to be designed to handle multiple replicas (= stateless).

Resources

Request

Amount of memory/CPU guaranteed for your container.

Limit

Amount of memory/CPU your container cannot exceed.

  • Exceed CPU → Process throttled
  • Exceed RAM → Process killed, exit code 137 (OOM Killed)

Containers are always scheduled based on the Request.

Which values for request/limit?

  • DO NOT over-commit memory (limit higher than request).
  • DO NOT limit CPU (we set 2 because we almost always use NodeJS, which is single-threaded).
  • CPU-Request: Used CPU at average load.
  • RAM-Request: Used RAM at average load + safety margin.

Example

resources:
requests:
cpu: 50m
memory: 512Mi
limits:
cpu: 2
memory: 512Mi

Why set the CPU Limit to 2 instead of 1?

Previously, we set the cpu limit for our single threaded NodeJS applications to 1. But in kubernetes even single threaded applications can benefit from more than 1 cpu core. This way processes like garbage collections or kubernetes processes can be offloaded to an additional core, keeping the main core free for the NodeJS application.

We did some tests and came to the conclusion that a cpu limit of 2 is the sweet spot.