In Kubernetes, how do a Deployment and a Service work together to let a microservice be released and scaled without breaking the services that call it?
answer
- Deployment = desired state + rollout
- Service = stable virtual IP/DNS
- pods are ephemeral, IPs change
- label selector links them
- readiness probes gate traffic
basics
~10 sA Deployment manages the running copies of a service and replaces them gradually during updates, while a Service gives callers one stable address that always points at whichever copies are currently healthy.
solid answer
~50 sA Deployment is a declarative desired-state controller: it manages a set of pod replicas for one service, handles rolling updates by gradually replacing old-version pods with new ones, and can roll back if health checks fail. Pods are ephemeral — they get new IPs whenever they're rescheduled or replaced — so callers can't hardcode pod addresses. A Service sits in front of the Deployment's pods and provides a stable virtual IP and DNS name; it continuously tracks which pods are currently ready (via label selectors and readiness probes) and load-balances traffic only to those. This separation is what lets a team deploy a new version of one microservice — scaling pod count up/down, replacing pods one at a time — without any consumer needing to know or care, because the consumer only ever talks to the Service's stable endpoint, not to individual pod instances.
go deeper
Should know a Deployment runs the app's pods and a Service gives a stable way to reach them.
Should explain rolling updates and why a stable Service endpoint matters for decoupling deploys from consumers.
Should bring in readiness probes, connection draining, and how this enables safe independent per-service releases at scale.
Should connect this to org-level outcomes — this pattern is what lets dozens of teams ship independently without a shared release train, and should note where it breaks down (e.g., breaking API changes still need contract versioning, not just infra decoupling).
## What a Deployment does A Kubernetes Deployment and a Service solve two different problems that together produce zero-downtime, independently-releasable microservices, and it's worth separating what each one actually does. A `Deployment` is a controller that manages a set of identical pod replicas for one service: you declare a desired state — 'run image v2 of order-service, three replicas' — and the Deployment continuously reconciles the running pods toward that state. When you push a new image version, the Deployment doesn't replace all pods at once; by default it performs a **rolling update**: 1. creating a few new-version pods, 2. waiting for them to pass their readiness checks, 3. then terminating a corresponding number of old-version pods, 4. repeating until all replicas run the new version. If the new pods never become ready (a bad build, a missing config value, a crash loop), the rollout can be halted or automatically rolled back, so a broken release doesn't fully replace a working one. ## What a Service adds The problem this alone doesn't solve is **addressability**: pods are ephemeral by design — they get a new internal IP address every time they're created, whether from a rollout, a crash-restart, or the autoscaler adding replicas — so nothing that calls this service can hardcode a pod IP and expect it to keep working. A `Service` solves that by providing a stable virtual IP address and DNS name that sits in front of a Deployment's pods. - It **doesn't point at specific pods directly**; instead it uses a **label selector** to continuously discover which currently-running pods match the service's labels. - Critically, it **filters that set down to only pods whose readiness probe is currently passing**, so a pod that's starting up, unhealthy, or draining during termination is automatically excluded from receiving traffic even though it may still technically exist. - Callers only ever address the Service's stable name; the Service transparently load-balances across whichever real pods are healthy at that instant. | Object | What it owns | |---|---| | Deployment | desired state, replica count, the rolling update, and rolling back a broken release | | Service | a stable virtual IP and DNS name, the label selector, and traffic only to pods whose readiness probe is passing | ## Why the split decouples releases This division of labor is precisely what decouples releasing a service from breaking its callers, which is the whole point in a microservices system. A team can trigger a rolling update on their own Deployment — changing replica count, pushing a new version, tuning resource limits — at any time, on their own release schedule, without notifying or coordinating with every team whose service calls theirs, because the calling code's only dependency is the unchanging Service name, never the pod-level details underneath it. That's the mechanism that makes 'deploy this one service independently, right now, without a maintenance window' operationally real rather than aspirational. ## The trade-off The trade-off is added indirection and reliance on probes being configured correctly. - The whole safety property — 'traffic only reaches healthy pods' — depends entirely on the **readiness probe** accurately reflecting whether a pod can actually serve traffic; a probe that just checks 'is the process running' rather than 'can this instance serve a real request' will happily route traffic to a pod that's up but broken (e.g., its database connection pool hasn't initialized yet), producing errors the Kubernetes layer had every mechanism to prevent. - There's also a well-known **timing race** during termination: Kubernetes starts removing a terminating pod from the Service's endpoint list and sends it a termination signal roughly in parallel, not strictly endpoint-removal-then-signal, so without a short `preStop` hook or grace period, a pod can receive its shutdown signal and stop accepting connections microseconds before some in-flight requests have finished being routed to it, producing a small burst of connection errors during otherwise-healthy rolling updates. ## A concrete illustration A concrete illustration: an e-commerce platform running a checkout-service behind a Service, called synchronously by a cart-service. When the checkout team ships a fix, their Deployment rolls three new pods in one at a time, each one only joining the Service's routable set after passing a readiness probe that actually calls a lightweight internal health endpoint verifying its database connection is live. cart-service never sees a version number, a pod IP, or a deploy notification — it just keeps calling checkout-service's stable name throughout the rollout, and (assuming the probe and shutdown grace period are configured correctly) sees no errors. This is the pattern — Deployment for controlled rollout, Service for a stable address that only ever exposes ready instances — that lets an organization run dozens of teams' services on independent release cadences without a shared deploy freeze.
- What happens to in-flight requests to a pod that a rolling update is about to terminate?Kubernetes sends the pod a termination signal and, if configured, waits for a grace period while the Service stops routing new traffic to it; the pod is expected to finish in-flight requests during that window. If the service doesn't handle the termination signal and drain connections properly, in-flight requests can be dropped mid-update, which is a common source of transient errors during deploys.
- Why can't consumers just cache a Service's resolved IP for performance instead of doing a fresh lookup each time?A Service's virtual IP is stable, but caching it isn't the risk — bypassing the Service's load-balancing and readiness tracking is. If a client caches an individual pod IP instead of using the Service, it will keep sending traffic to a pod that's been terminated or is failing health checks, since only the Service layer knows which pods are currently ready.
- How does this pattern specifically support independent deployability across many microservices?Because every service's callers depend only on its Service's stable name, one team can roll a new Deployment revision for their service at any time without coordinating with teams that consume it — the contract point (the Service) doesn't move even though the underlying pods do.
Like a restaurant's public phone number (the Service) staying the same even as staff (pods) rotate shifts, quit, or get replaced (Deployment rollout) — callers never need the direct line of whoever happens to be on duty.
saying these in an interview costs you the question
- Says pods have stable IPs
- Doesn't distinguish Deployment (rollout/replica management) from Service (stable network identity)
- Thinks Service and Deployment are the same object
- Ignores readiness probes when explaining zero-downtime updates