Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild
Back to Blog Explainer

Kubernetes for Developers: The Part You Actually Need to Know

Sean

Platform Writer

Jul 14, 2026
8 min read

Most Kubernetes material is written for the people who run clusters, and if you are a developer who merely deploys to one, that is the wrong syllabus. You do not need to understand etcd, the scheduler’s bin-packing algorithm, or CNI plugins. You need to know why your pod is in CrashLoopBackOff, what a readiness probe does to your rollout, why the ingress returns 502, and what happens when you set the memory limit too low. That is a much shorter list, and it is the one that will actually come up.

Kubernetes for Developers: The Part You Actually Need to Know

Table of contents

The five objects you will touch

There are dozens of Kubernetes resource types. You will interact with roughly five.

Pod - one or more containers scheduled together. You rarely create these directly, but you spend your life debugging them.

Deployment - manages a set of identical pods and handles rolling updates. This is what you actually write. Change the image tag, apply, and the Deployment replaces pods gradually.

Service - a stable internal address and load balancer for a set of pods. Pods come and go with new IPs; the Service name does not change. http://api:8080 inside the cluster resolves through it.

Ingress - routes external HTTP traffic to Services by hostname and path. This is where TLS terminates.

ConfigMap and Secret - configuration and credentials, injected as environment variables or mounted files. A Secret is base64-encoded, not encrypted - anyone with read access to Secrets in your namespace can read them in plaintext, which surprises people who assume the name implies protection.

That is the working set. StatefulSets, DaemonSets, and Jobs exist and you will meet them, but the five above cover the daily reality of shipping an application.

CrashLoopBackOff and the diagnostic sequence

Your pod is not running. Here is the sequence, and it is nearly always sufficient.

kubectl get pods
kubectl describe pod <name>
kubectl logs <name>
kubectl logs <name> --previous

describe shows the events at the bottom - image pull failures, scheduling failures, probe failures, OOM kills. Read the events first; they usually contain the answer verbatim.

logs --previous is the one people miss. In CrashLoopBackOff the container is dead, so kubectl logs shows you the fresh, empty attempt. --previous shows the output of the run that actually crashed, which is where the stack trace is.

The common causes, in rough order of frequency:

  • The app exits immediately. A missing environment variable, an unreachable database, a config file that is not where the code expects. The logs will say so.
  • OOMKilled. The container exceeded its memory limit and the kernel killed it. describe shows Reason: OOMKilled and the exit code is 137. Raise the limit or fix the leak.
  • The readiness probe never passes. The container is alive but Kubernetes will not send it traffic, and if it is a liveness probe it will be killed and restarted forever.
  • ImagePullBackOff. Wrong tag, wrong registry, or missing pull credentials. This one is not a crash loop, but it looks similarly broken.

Requests and limits are the setting that matters most

This is the single most consequential thing a developer configures, and it is routinely set by copying whatever was in the last YAML file.

resources:
  requests:
    memory: "256Mi"
    cpu: "100m"
  limits:
    memory: "512Mi"
    cpu: "500m"

Requests are what the scheduler reserves. A pod requesting 256Mi will only be placed on a node with 256Mi free, and that reservation is held whether the pod uses it or not.

Limits are the ceiling. Exceed the memory limit and the container is killed - OOMKilled, immediately, with no grace. Exceed the CPU limit and the container is throttled, not killed, which is more insidious: the app just gets slow, and nothing in the logs says why.

The two failure modes:

Requests too high. The pod reserves 2GB, uses 200MB, and the node fills up with reservations while sitting almost idle. You add nodes you do not need. This is how a cluster bill doubles for no reason.

Memory limit too low. The container gets OOMKilled under load, at 3am, under exactly the traffic conditions you did not test.

Measure with kubectl top pods under real load, set requests near the observed steady state, and set the memory limit with genuine headroom. Do not copy the numbers from a tutorial.

Probes decide whether your deploy is a rollout or an outage

Kubernetes has three probes and confusing them causes real incidents.

readinessProbe - is this pod ready for traffic? If it fails, the pod is removed from the Service’s endpoints but is not restarted. This is the one that protects your users during a deploy.

livenessProbe - is this pod alive? If it fails, the pod is killed and restarted. This is dangerous when misconfigured.

startupProbe - has this pod finished starting? While it is running, the other two are suspended. Use it for slow-starting applications.

readinessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 10

The classic self-inflicted outage: a liveness probe that hits an endpoint which checks the database. The database gets slow under load, the probe times out, Kubernetes kills every pod simultaneously, the app restarts into the same slow database, and now you have converted a degraded service into a total outage.

The rule: a liveness probe should test the process, not its dependencies. If the database is down, restarting your app does not help. A readiness probe may check dependencies - taking a pod out of rotation is a reasonable response to a broken downstream. Killing it is not.

Why the ingress is returning 502

A 502 from the ingress means it could not get a valid response from your pods, and the cause is nearly always one of four things.

  1. No ready pods behind the Service. Check kubectl get endpoints <service>. If the endpoint list is empty, the Service has nothing to route to - which usually means the readiness probe is failing, or the label selector does not match any pods.
  2. The label selector is wrong. The Service selects app: api but the Deployment labels its pods app: api-server. Everything looks healthy in isolation and nothing is connected. This is the most common one and the most maddening.
  3. A port mismatch. The Service targetPort does not match the port the container actually listens on.
  4. The app is bound to 127.0.0.1. Inside a container, listening on localhost means nothing outside the container can reach it. Bind to 0.0.0.0.

The fastest diagnostic is to skip the ingress entirely and port-forward straight to the pod:

kubectl port-forward pod/<name> 8080:8080

If that works, the app is fine and the problem is in the Service or Ingress layer. If it does not, the problem is the app. That one command splits the search space in half.

What you can genuinely ignore

The operator’s syllabus is not yours. You can safely defer, possibly forever:

  • etcd, the control-plane components, and how the scheduler makes decisions.
  • CNI plugins, the network fabric, and how pod-to-pod routing actually works.
  • RBAC beyond “my service account needs permission to read Secrets”.
  • Custom Resource Definitions and writing operators.
  • Cluster autoscaling, node pools, taints, and tolerations - until someone hands you a node-selection problem.
  • Helm chart authoring. Using a chart is fine; writing one is a different job.

What you should know cold: the five objects, the debugging sequence, requests and limits, the three probes, and how a Service finds its pods.

That is genuinely most of the developer-facing surface of Kubernetes. The rest of the iceberg is real, and it is someone’s full-time job - but if your job is shipping the application, the above will get you through the overwhelming majority of the days when the cluster is unhappy with you.

How this fits the rest of the stack

Whatever you decide here, the cost of the decision only shows up as a bill. The RunxBuild hosting calculator is the right place to model that before committing: the compute, the database, the storage, the bandwidth, the worker - each one is a separate line item, and the real cost of a platform is the sum, not the headline number. The RunxBuild dashboard is where the team sees the actual usage once it is running.

Useful related references:

FAQ

What is the minimum Kubernetes a developer needs to know?

Five objects (Pod, Deployment, Service, Ingress, ConfigMap/Secret), the debugging sequence (get, describe, logs, logs —previous), how requests and limits work, the difference between readiness and liveness probes, and how a Service selects pods by label. That covers most real situations.

Why is my pod in CrashLoopBackOff?

Run kubectl logs with —previous - in a crash loop the current container is dead, so plain logs shows an empty new attempt while —previous shows the run that actually crashed. The usual causes are a missing environment variable, an unreachable dependency, or an OOMKill from too low a memory limit.

What is the difference between a readiness probe and a liveness probe?

A failing readiness probe removes the pod from the Service so it stops receiving traffic, but does not restart it. A failing liveness probe kills and restarts the pod. Liveness probes should test the process only - if they check the database, a slow database will cause Kubernetes to kill every pod at once and turn a degradation into an outage.

What causes a 502 from a Kubernetes ingress?

Usually no ready pods behind the Service. Check kubectl get endpoints - an empty list means either the readiness probe is failing or the Service label selector does not match the Deployment’s pod labels. Also check for a port mismatch or an app bound to 127.0.0.1 instead of 0.0.0.0.

Are Kubernetes Secrets encrypted?

Not by default. They are base64-encoded, which is encoding rather than encryption, and anyone with read access to Secrets in the namespace can decode them trivially. Encryption at rest for Secrets is a cluster-level configuration that has to be enabled deliberately.

#kubernetes#k8s#containers#devops#dev-infra