Running Stateless Applications¶
The most common type of application run on Kubernetes is a stateless application. These applications, such as web servers, APIs, and many microservices, do not store persistent data or session state within the container. They can be stopped, started, and scaled horizontally without any loss of data.
This guide covers the best practices for running stateless applications on the
platform using the standard Kubernetes Deployment resource, and how to ensure
they remain highly available during planned maintenance.
Using a Deployment for Stateless Workloads¶
The primary tool for managing a stateless application in Kubernetes is the
Deployment. A Deployment provides declarative updates for your application's
Pods. You describe the desired state in a Deployment manifest, and the
Deployment Controller works to change the actual state to the desired state at a
controlled rate.
Deployments are ideal for stateless applications because they manage
ReplicaSets, which ensure that a specified number of replica Pods are running
at any given time.
Example Deployment Manifest¶
Here is an example of a Deployment for a stateless application, incorporating
platform-specific best practices.
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-stateless
labels:
app.kubernetes.io/name: hello-stateless
netic.dk/network-rules-egress: "hello-stateless"
netic.dk/network-rules-ingress: "hello-stateless"
spec:
# Run at least 2 replicas to ensure high availability.
replicas: 2
revisionHistoryLimit: 5
selector:
matchLabels:
app.kubernetes.io/name: hello-stateless
strategy:
# Use rolling updates to perform zero-downtime deployments.
type: RollingUpdate
rollingUpdate:
maxSurge: "25%"
maxUnavailable: "25%"
template:
metadata:
labels:
app.kubernetes.io/name: hello-stateless
# Allows ingress traffic from the shared ingress controller.
netic.dk/network-ingress: "contour"
spec:
containers:
- name: app
image: ghcr.io/neticdk/kubernetes-debug-image:v0.0.8 # Replace with your application image
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080
# Set requests and limits to ensure predictable performance.
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
# Mandatory security settings to reduce attack surface.
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 30001
# Determines the importance of the pod for scheduling and preemption.
priorityClassName: "secure-cloud-stack-tenant-namespace-application-non-critical"
Key Configuration Best Practices¶
- Replicas: Always run at least
replicas: 2to ensure your application remains available if one pod fails or is rescheduled. - Rolling Updates: The
RollingUpdatestrategy ensures zero-downtime deployments.maxUnavailablecontrols how many old pods can be removed, whilemaxSurgecontrols how many new pods can be added during an update. - Resource Requests and Limits:
- See best practices for resource limits for more information.
- Security Context: Setting a
securityContextmay be enforced by platform policies. You must configure your pods to run as non-root users (runAsNonRoot: true) and drop all Linux capabilities (capabilities: drop: ALL). This significantly improves the security of your application. - Priority Class: The
priorityClassNameinfluences the Kubernetes scheduler's decisions. For most applications, the default value ofsecure-cloud-stack-tenant-namespace-application-non-criticalis appropriate.
Ensuring High Availability with PodDisruptionBudget¶
A Deployment with multiple replicas protects against unexpected failures.
However, you also need to protect against planned, voluntary disruptions, such
as when a cluster node is drained for maintenance.
A PodDisruptionBudget (PDB) is a Kubernetes resource that limits the number of
pods of a given application that can be down simultaneously from voluntary
disruptions.
Example PodDisruptionBudget Manifest¶
This PDB should be deployed alongside your Deployment. It uses a label
selector to target the pods managed by the hello-stateless deployment.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: hello-stateless-pdb
spec:
# Ensures that at least 75% of your desired replicas are available during a node drain.
# This value should be coordinated with your deployment strategy.
minAvailable: 75%
selector:
matchLabels:
app.kubernetes.io/name: hello-stateless
Replicas vs. Disruption Budget
It is crucial that your PDB's availability requirements can be met. For
example, if you set minAvailable: 2 but your Deployment only has
replicas: 2, a node drain will stall because evicting even one pod would
violate the budget. Always ensure your replica count is high enough to
satisfy the PDB during maintenance.