Apr. 21, 2026

Kubernetes for Developers in 2026: A Practical Guide.

Picture of By Pablo Zarauza
By Pablo Zarauza
Picture of By Pablo Zarauza
By Pablo Zarauza

21 minutes read

Kubernetes for Developers: What You Need to Know in 2026

Article Contents.

Share this article

Last Updated July 2026

Most developers do not choose Kubernetes. They inherit it. A platform team stands up a cluster, wires a pipeline, and hands over a repository with a folder of YAML in it. From then on, whether your code runs correctly in production depends less on framework knowledge and more on whether you understand the contract Kubernetes enforces on every process it schedules.

That contract is the subject of this guide. Not cluster administration, not control plane internals, not certification prep. This is the slice of Kubernetes that changes what a developer types, tests, and gets paged for: the objects that matter, the two configuration mistakes behind most production surprises, where your responsibility ends, and the platform team’s begins, and the cases where adopting Kubernetes is the wrong call.

Why Kubernetes literacy became a developer skill

Containers are no longer a specialization. The 2025 Stack Overflow Developer Survey found that Docker is used by 73.8% of professional developers, up from 59% the previous year, which the survey notes was the largest single-year usage increase of any technology it tracked. Kubernetes itself sits at 30.1% among professional developers, and 58% of respondents who have worked with it want to continue doing so.

The gap between those numbers is the interesting part. Roughly three in four professional developers build containers; fewer than one in three work directly with the system that runs them at scale. That gap is where production incidents live. A container that starts cleanly on a laptop still has to survive health probing, eviction under memory pressure, rolling replacement, secret rotation, and network policy enforcement. Kubernetes does not hide those conditions. It makes them explicit and enforces them without negotiation.

Meanwhile, the operational layer has consolidated. The 2025 DORA report, based on a global survey run between June and July 2025, found that 90% of organizations have adopted at least one internal platform, 76% have a dedicated platform team, and 29% operate multiple platforms. The question for a developer is no longer whether you will ship onto an orchestrated runtime. It is whether you understand that runtime well enough to debug your own service at 2 a.m.

Kubernetes vs. Docker: the distinction that still trips teams up

The confusion persists because both tools appear in the same sentence constantly, and because many teams use Docker for years before touching Kubernetes. The clean framing: Docker is how you build and run one container. Kubernetes is how you declare what should be true about many containers, continuously, across many machines.

Docker is imperative: you tell it to run something, and it runs. Kubernetes is declarative: you submit a desired state and controllers work indefinitely to reconcile reality against it. When you delete a pod by hand, and it comes back, that is not a bug. That is a Deployment controller doing exactly what you asked.

DimensionDockerKubernetes
Unit of workA single container or a small local compositionA cluster of nodes running many replicas of many workloads
Interaction styleImperative commands you runDeclarative state you submit, and controllers reconcile
Failure handlingContainer exits and stays exited unless a restart policy appliesFailed pods are rescheduled and replaced continuously
NetworkingBridge networks on one host, ports published manuallyCluster-wide service discovery, stable virtual IPs, policy enforcement
ScalingManual, or scripted per hostHorizontal autoscaling based on metrics, plus cluster autoscaling of nodes
Where developers spend timeDockerfile, image size, local build speedManifests, resource budgets, probes, rollout behavior

The two are sequential rather than competing. You still write a Dockerfile and still build an image. Kubernetes takes that image and answers a different set of questions: how many copies, on which nodes, with what CPU and memory, reachable at which address, replaced in what order during a deploy, and restarted under what conditions. Teams that get container fundamentals right first have a far easier time with orchestration.

The five objects that change your daily work

Kubernetes has a large API surface. A developer shipping a stateless service needs fluency in five things. Everything else can be learned on demand.

1. Pod

The Pod is the smallest deployable unit and the thing that actually gets scheduled. It wraps one or more containers that share a network namespace and storage volumes. You will rarely create one directly, but you read Pod status constantly, because every diagnostic conversation about your service starts there. Learning to interpret Pending, CrashLoopBackOff, OOMKilled, and ImagePullBackOff is the fastest debugging skill you can acquire, since each points at a different owner: scheduling capacity, application startup, memory budget, and registry access respectively. The Kubernetes documentation on Pods is worth reading end to end once.

2. Deployment

A Deployment declares how many replicas of a pod template should exist and how replacements are sequenced during an update. This is where rollout behavior lives. The maxUnavailable and maxSurge settings determine whether a deploy can briefly reduce capacity and whether it can temporarily exceed it. Getting these wrong produces the classic pattern where a deploy succeeds, the dashboard turns green, and latency spikes for ninety seconds because too many healthy replicas were replaced at once.

3. Service

A Service provides a stable name and virtual IP in front of pods that are constantly created and destroyed. Without it nothing could reliably call your application, because pod IPs change on every replacement. The developer-relevant detail: Service membership is driven by label selectors, and endpoint membership is gated by readiness. A pod that is running but not ready receives no traffic. That one rule explains a large share of confusing deploy-time outages.

4. ConfigMap and Secret

These separate configuration from image content, which makes one artifact promotable across environments. The discipline they enforce is worth more than the mechanism. Credentials in an image or a committed manifest are a durable liability: GitHub reported that more than 39 million secrets were leaked across its platform in 2024 alone. Secrets belong in a managed store, injected at runtime, rotated without a rebuild. Treat any credential appearing in a Git diff as already compromised, and consider how it fits a broader zero trust posture rather than as isolated hygiene.

5. Probes and resource specifications

Grouping these is deliberate: they are the two fields most often left blank and the two that most often cause incidents. Probes tell Kubernetes whether your container is alive and whether it is ready for traffic. Requests and limits tell the scheduler what your container needs and what it may consume. Both are covered below, because getting them right is most of the difference between a service that behaves and one that flaps.

A developer Kubernetes competency ladder

Kubernetes onboarding stalls when teams treat it as a binary: either you know Kubernetes, or you do not. It is more useful to name five distinct levels and be explicit about which one a role requires. Most application developers should be solidly at level two and comfortable at level three. Levels four and five belong to platform engineers.

LevelWhat you can doTypical owner
1. ConsumerDeploy through a pipeline, read logs, roll back a bad releaseJunior developer, first month
2. PractitionerWrite and review manifests, set requests, limits, and probes, debug pod states, interpret eventsApplication developer, expected baseline
3. ContributorTune rollout strategy and autoscaling, instrument for observability, reason about network policy and pod security standardsSenior developer, tech lead
4. Platform userBuild reusable charts and overlays, define GitOps promotion paths, set cluster-wide defaults and quotasPlatform engineer
5. OperatorManage control plane, upgrades, capacity, multi-tenancy, and cluster-level securitySRE or infrastructure engineer

Naming the ladder helps with hiring and planning. It stops teams from over-training application developers on cluster administration they will never perform, and from under-training them on the manifest fields that decide whether their service survives a Tuesday afternoon. If your engineering managers cannot say which level each role needs, the training budget goes to the wrong place.

Resource requests and limits: the field developers get wrong most

Requests and limits are two different promises, and conflating them causes both wasted spend and unexplained restarts. The request is what the scheduler reserves, and it determines placement. The limit is the ceiling the runtime enforces. Omit both, and your container is scheduled with no reservation and no ceiling: first to be evicted under pressure, and able to starve neighbors before that happens.

Enforcement differs sharply by resource type, and this is the detail most developers miss. Exceeding a CPU limit gets you throttled: the process keeps running with fewer scheduler slices, so latency degrades quietly. Exceeding a memory limit kills the container outright with OOMKilled status, because memory cannot be compressed. So aggressive CPU limits produce mysterious tail latency, while sloppy memory limits produce restart loops.

Here is a concrete way to set them. Suppose you run a Java service and observe, over two weeks of production traffic, a median heap usage of 480 MiB, a p99 of 720 MiB, and steady-state CPU of 0.15 cores with peaks to 0.6 during batch imports.

  1. Set the memory request at or slightly above the p99 observed usage, so 768 MiB. Requesting the median guarantees eviction during normal peaks.
  2. Set the memory limit equal to the request for anything latency-sensitive, so 768 MiB. Equal request and limit places the pod in the Guaranteed quality of service class, which makes it the last to be evicted under node pressure.
  3. Set the CPU request near steady-state usage, so 200m. This is a scheduling hint, not a cap, and overstating it wastes reserved capacity across the cluster.
  4. Set the CPU limit generously, or leave it unset for latency-sensitive services, because throttling a service that briefly needs more CPU is usually worse than letting it borrow idle capacity.
  5. Revisit both numbers after any significant change in traffic shape or dependency behavior, treating them as configuration that ages rather than a one-time decision.

The asymmetry surprises people: be precise with memory, generous with CPU. Memory limits are a hard kill, so they need headroom above real p99. CPU limits are a soft throttle, so tight ones buy little and cost latency. The Kubernetes guide to managing container resources documents the mechanics; the judgment above is what turns mechanics into a working configuration.

Also check what defaults your cluster applies. Many platform teams set namespace-level LimitRange defaults, so a manifest with no resource fields still gets values, just not values chosen with your service in mind.

Probes: the difference between liveness, readiness, and startup

Kubernetes offers three probe types, and using the wrong one is a common way to turn a slow dependency into a cascading outage.

  1. A readiness probe controls traffic. When it fails, the pod is removed from Service endpoints but is left running. This is the correct probe for temporary inability to serve, such as a saturated connection pool.
  2. A liveness probe controls restarts. When it fails, the container is killed and restarted. This is only correct for unrecoverable states, such as a deadlock that no amount of waiting will resolve.
  3. A startup probe protects slow-starting applications. While it is running, liveness checks are suspended, which prevents a JVM with a long warm-up from being killed before it ever becomes healthy.

The failure mode to internalize: never point a liveness probe at an endpoint that checks downstream dependencies. If your liveness check queries the database and the database slows down, Kubernetes restarts every replica simultaneously, removing all capacity at exactly the moment the system was already struggling. A dependency check belongs in readiness, where the consequence is withheld traffic rather than a coordinated restart. This distinction is worth reading in the upstream documentation on configuring probes.

Two details cause real incidents. Probe timeouts should reflect the actual latency distribution of the checked endpoint, not a default guess: a one-second timeout on an endpoint with a p99 of 900 ms will fail intermittently for no reason. And probe traffic is real traffic, hitting your service on a schedule forever, which matters for anything that scales toward zero or bills per running instance.

The inner development loop: what to run locally and what not to

One unproductive extreme is running a full local cluster to test a one-line change. The other is having no way to exercise your code against cluster semantics until it reaches a shared environment. The workable answer is tiering: run the fastest tool that can falsify the change you just made.

ApproachBest forMain tradeoff
Plain container runBusiness logic, unit and component testsNo cluster semantics at all, so manifests go untested
Local cluster (kind or minikube)Validating manifests, probes, service wiring, RBACSlow image build and load cycle, no production-like data or scale
Remote development against a shared clusterIntegration behavior, real dependencies, realistic networkingRequires namespace isolation and discipline to avoid disrupting others
Ephemeral preview environment per pull requestReviewing behavior, not just diffsHighest platform investment, needs strong teardown automation

Two rules keep this manageable. Never let a manifest reach a shared environment without applying it somewhere first, because a manifest rejected in a pipeline is a much slower feedback loop than one rejected locally. And keep the templating layer thin: Helm for packaging, Kustomize for overlays. A manifest layer that needs its own onboarding document is a defect, not a feature.

GitOps and where developer responsibility ends

GitOps treats a Git repository as the single declarative source of truth for cluster state, with an in-cluster controller continuously reconciling toward that description. For developers, deployment stops being an action you perform and becomes a state you propose: you open a pull request, and a controller such as Argo CD or Flux notices the merge and converges the cluster. The principles are documented by the OpenGitOps project. The shift is more cultural than technical, since kubectl apply against production becomes a break in the chain of custody rather than a normal workflow.

This is where a clear responsibility boundary matters most. When 90% of organizations run at least one internal platform, and 76% have a dedicated platform team, the failure mode is rarely missing capability. It is unstated ownership. A split that works:

  1. Developers own the application manifest surface: image reference, replica count, resource requests and limits, probe definitions, and environment configuration references.
  2. Platform teams own cluster-wide concerns: ingress, certificates, node pools, policy enforcement, base charts, quotas, and the reconciliation controllers themselves.
  3. Both share ownership of the promotion path, because the definition of a deployable change is a joint contract rather than a handoff.

Write that split down. Ambiguity produces the two worst outcomes: developers blocked on trivial changes because everything routes through a platform ticket, or developers granted cluster-wide permissions they neither want nor understand. Teams that get this right treat the platform as an internal product with real users, consistent with DORA’s finding that platforms designed around developer experience produce measurably better returns.

Kubernetes for AI inference, batch, and GPU workloads

Kubernetes is increasingly the substrate for model serving, not just web services, and the differences are substantial enough that habits from stateless HTTP work poorly.

GPUs are scheduled as extended resources, not fractional shares by default. A pod either receives whole devices or waits. That reshapes cost behavior, because an idle GPU pod is dramatically more expensive than an idle web replica, and because autoscaling on CPU utilization tells you almost nothing about whether a model server is saturated. Queue depth and request concurrency are the signals that matter, which is why event-driven autoscaling is common here rather than the default CPU-based horizontal autoscaler.

Model loading also breaks the usual startup assumptions. A container that must load a multi-gigabyte model before its first request will not pass a default liveness probe, which makes startup probes mandatory here. And for training or batch inference, Job and CronJob are the correct primitives. Running a finite workload as a Deployment produces a container that completes and is immediately restarted, forever.

One maturity gap is worth naming. Many organizations can technically run inference on Kubernetes long before they have a disciplined process for versioning, evaluating, and promoting models. Capability arrives before practice, and that gap is a common source of accumulating AI technical debt: a process problem, not an infrastructure one.

A developer-facing Kubernetes scorecard

Most Kubernetes metrics are written for cluster operators. These six are ones a development team can own and act on.

SignalWhat it tells youA healthy direction
OOMKilled events per service, per weekMemory limits are set below real p99 usageTrending to zero, investigated when nonzero
CPU throttling percentageLimits are tight enough to be degrading latencyLow and stable for latency-sensitive services
Requested vs. actually used CPU and memoryHow much reserved capacity is being wastedRequests within a predictable band of real usage
Time from merge to running in productionWhether the delivery path is actually automatedMinutes, not hours, without manual intervention
Rollback durationWhether reverting is a routine action or an incidentFast enough that rollback is the default response
Percentage of restarts explained within an hourWhether observability is sufficient to diagnose your own serviceHigh, and rising as instrumentation improves

The last row is the one teams skip and the one that matters most. If a developer cannot explain why their own pod restarted, no amount of cluster tooling compensates. That usually means missing structured logging, absent trace context, or metrics that stop at the ingress. Instrumenting with an open standard such as OpenTelemetry is the low-drama fix, and the payoff shows up in incident duration rather than in a dashboard.

The cost of leaving Kubernetes to someone else

Teams often defer Kubernetes learning on the reasoning that the platform team handles it. That has four predictable costs, worth naming because they rarely appear on any budget line.

The first is incident duration. When the developer who wrote the service cannot interpret its pod events, every restart becomes a cross-team investigation. Resolution time stretches not because the problem is hard but because the person who understands the code and the person who understands the runtime are two different people.

The second is infrastructure spend. Requests set by guesswork are almost always too high, because the safe guess is a generous one. Multiply a 3x over-request across a few hundred pods and the waste is material, permanent, and invisible, since nothing fails and no alert fires.

The third cost is design drift. Developers who do not understand eviction, rolling replacement, or readiness gating write applications that assume stable local state, in-memory sessions, and orderly shutdown. Those assumptions hold on a laptop and fail on a cluster, and the fixes are architectural rather than configurational. This is how a modernization program that looked like a deployment change becomes a rewrite, the same dynamic that undermines many legacy migration efforts.

The fourth cost is bottlenecked delivery. If every manifest change needs a platform ticket, the platform team becomes a queue and developer throughput becomes a function of someone else’s sprint capacity.

When Kubernetes is the wrong choice

Kubernetes is a poor default and a good deliberate decision. Skip it in these five situations.

  1. You run a small number of services with predictable, modest traffic. A managed container service or platform-as-a-service will cost less and demand less of your team’s attention.
  2. You have no one who can own the operational layer. Kubernetes shifts complexity rather than removing it, and an unowned cluster becomes a liability faster than an unowned VM.
  3. Your workload is genuinely event-driven and bursty with long idle periods. Serverless functions handle that shape more economically than a cluster with reserved capacity sitting idle.
  4. Your application cannot tolerate being restarted or rescheduled. If it depends on stable local disk, in-process state, or a fixed hostname, containerizing it first is a prerequisite, not a detail to sort out later.
  5. You are adopting it primarily to make hiring or architecture look modern. That reason produces the worst outcomes, because nobody can articulate what the cluster is for when it starts costing money.

The honest test is whether you can name the specific problem Kubernetes solves for you. Multi-team deployment isolation, sophisticated rollout control, heterogeneous workload scheduling, and portability across providers are all real answers. If none describes your situation, a simpler runtime is the better decision, and revisiting it later is entirely reasonable. The same discipline applies to deciding whether to split a monolith at all.

Five mistakes developers make most often

These recur across teams regardless of language or industry.

1. Treating a container like a small virtual machine

Long-lived local files, background cron loops inside the app container, and manual restarts to clear bad state all assume a permanence Kubernetes does not provide. Pods are replaced routinely. Externalize state, keep processes single-purpose, and make shutdown graceful and idempotent.

2. Omitting resource specifications

The most common defect and the easiest to fix. Missing requests mean unpredictable scheduling and first-to-be-evicted status. Missing limits mean one bad deploy can degrade everything sharing a node.

3. Pointing a liveness probe at a dependency

Worth repeating because the consequences are severe: this converts a slow database into a simultaneous restart of every replica. Dependency health belongs in readiness.

4. Building excessive logic into the manifest layer

Deeply nested templates with conditionals across many environments become undebuggable. If reviewers cannot predict the rendered output from the source, the abstraction has failed. Prefer flat overlays over clever templates.

5. Deferring observability until after an incident

Structured logs, meaningful metrics, and propagated trace context are cheap to add during development and expensive to retrofit under pressure. A service without them cannot be debugged from outside the cluster, and that is where you will be debugging it.

Frequently Asked Questions

1. Do developers need to learn Kubernetes if a platform team manages the cluster?

Yes, but only to level two on the ladder above. You need to read and write manifests, set resource requests and limits deliberately, configure probes correctly, and interpret pod states well enough to diagnose your own service. You do not need to manage the control plane, plan upgrades, or design multi-tenancy. That is a real division of labor, not an excuse to skip the application-facing half.

2. Is Kubernetes only worth it for microservices?

No. Kubernetes is often valuable for a containerized monolith, because rolling updates, health-gated traffic, and horizontal scaling apply regardless of how many services you run. The relevant question is whether you need declarative, automated runtime management, not how finely your application is decomposed. Plenty of teams adopt Kubernetes for a single well-behaved application and get real value from it.

3. Should developers write raw YAML or use higher-level tooling?

Learn raw manifests first, then adopt tooling. Developers who start with an abstraction cannot debug what it generates, and every abstraction eventually leaks. Once fundamentals are solid, use Helm for packaging and Kustomize for overlays, keeping templating thin enough that a reviewer can predict the output.

4. How do you set memory limits without guessing?

Observe real usage over at least one full traffic cycle, including weekly batch or reporting peaks. Set the request at or slightly above observed p99, and set the limit equal to the request for latency-sensitive services so the pod lands in the Guaranteed quality of service class. Revisit when traffic shape changes, because these settings age.

5. When should a team adopt GitOps?

As soon as more than one person deploys, or as soon as any environment matters enough that an undocumented change would be a problem. GitOps is easier to adopt early than to retrofit, because retrofitting means reconciling accumulated manual drift before the controller can be trusted. If your cluster state and repository already disagree, that reconciliation is the first task, not the last.

Conclusion

Kubernetes rewards a narrow, deep slice of learning rather than broad coverage. Understand the five objects that shape your daily work. Set requests and limits from observed data rather than habit, precise with memory and generous with CPU. Use readiness for dependency health and liveness only for unrecoverable states. Know where your responsibility ends and the platform team’s begins, and write that boundary down. Instrument enough to explain your own restarts.

That short list covers most of the distance between a team that fights its cluster and a team that barely thinks about it. The rest is organizational rather than technical: clear ownership, a promotion path someone maintains, and the willingness to say a given workload does not belong on Kubernetes at all.

Related Reading:

Related Articles.

Picture of Pablo Zarauza<span style="color:#FF285B">.</span>

Pablo Zarauza.

Pablo is a Tech Lead at Coderio and a specialist in backend software development, enterprise application architecture, and scalable system design. He writes about software architecture, microservices, and software modernization, helping companies build high-performance, maintainable, and secure enterprise software solutions.

Picture of Pablo Zarauza<span style="color:#FF285B">.</span>

Pablo Zarauza.

Pablo is a Tech Lead at Coderio and a specialist in backend software development, enterprise application architecture, and scalable system design. He writes about software architecture, microservices, and software modernization, helping companies build high-performance, maintainable, and secure enterprise software solutions.

You may also like.

Dead Architecture Walking: How to Identify and Replace the Systems Quietly Blocking Your AI Strategy

Jul. 15, 2026

Dead Architecture Walking: How to Identify and Replace the Systems Quietly Blocking Your AI Strategy.

21 minutes read

Modernization Is Not a Project, It's a Posture: How Leading Engineering Teams Think Differently

Jul. 10, 2026

Modernization Is Not a Project, It’s a Posture: How Leading Engineering Teams Think Differently.

19 minutes read

Cloud-Native App Development in 2026: Principles, Benefits, and a Practical Adoption Strategy

Jul. 08, 2026

Cloud-Native App Development in 2026: Principles, Benefits, and a Practical Adoption Strategy.

18 minutes read

Contact Us.

Accelerate your software development with our on-demand nearshore engineering teams.