skip to content

Workload Networking Model

How a packet reaches a workload and how it gets back out: the private address it is given, the hop that publishes it, and the rules that permit each one. Asked because local habits break here.

on this pageshow

questions

28

Inside a container, a worker connects to localhost to reach a database in another container - why does that fail?

level: juniorimportance: must knowfreq 80%

answer

  1. laptop habit, not a host process
  2. each container gets its own view
  3. loopback is per view
  4. localhost means this container only
  5. address the neighbour by name

basics

~20 s

Each container normally gets its own network view: its own interface, its own address and its own loopback. So localhost inside a container means that container itself, and nothing is listening there. Reach the other container by its address or its name.

solid answer

~40 s

A containerised process is not just another process on the host's network. The platform normally builds each container a private network view holding one virtual interface, one address drawn from a workload range, its own loopback and its own port space. `localhost` and `127.0.0.1` resolve inside that view, so a call to `localhost:7000` is a call to *this* container's loopback, where only what this container bound is listening. The database sits on a different loopback in a different view, so the call is refused straight away rather than routed anywhere. The fix is to address the neighbour properly: the name the platform resolves to it, or its own address. The trap is pure local-machine habit - on a laptop every process shares one loopback, so `localhost` happened to work for everything.

go deeper

for a junior

Recall that a container normally has its own address and its own loopback, so localhost inside it means that container. Reach a neighbour by the name that resolves to it, not by localhost.

for a middle

Explain what the private view holds - one interface, one address, one loopback, one port space - and why the call is refused locally rather than routed to the host or to a neighbour.

for a senior

Recognise this as an incident symptom: configuration carried over from a developer machine still says localhost, and the failure looks like a dead dependency. Be able to separate refused-here from unreachable-there.

for a principal

State the trade-off plainly: per-workload views buy free port choice, a portable workload identity and one place to apply rules, at the cost of invalidating every local-machine assumption in inherited configuration.

## What a container is given, network-wise When a platform starts a container it normally does not run the process directly on the host's networking. It builds that container a **private network view** and runs the process inside it. The view is a small but complete version of a machine's networking, and it usually contains: - one **virtual interface** - one end of a virtual interface pair, with the other end left on the host so traffic has somewhere to go; - one **address** on that interface, taken from a range the platform manages for workloads; - its own **loopback** interface, the one reachable as `localhost` and `127.0.0.1`; - its own **port space**, its own routing table, and its own idea of what is listening. Nothing in that list is shared with the container beside it. Network-wise, two containers on one host behave like two machines that happen to sit in the same box. ## Why localhost is the first habit to break On a developer machine every process shares one loopback. The application, the database and the cache all bind there, and `localhost:<port>` reaches any of them, because the machine has exactly one loopback and one port space. Move those same processes into containers and that single loopback splits into one per view. `localhost` stops meaning *this machine* and starts meaning **this view**. The worker's call is delivered to the worker's own loopback, where the only listeners are the ones the worker itself bound. The database is listening on a different loopback inside a different view, and the packet never goes near it. That is why configuration copied straight off a laptop fails on its first run in a container, and why the failure reads as a dependency outage: nothing is down, nothing is wrong on the database side, and the address looks correct. ## Reading the failure | The call | Where it is delivered | Result | |---|---|---| | `localhost:7000` from the worker | the worker's own loopback | refused - nothing is bound there | | the database container's address, port 7000 | the database container's interface | connects, if a route and the rules permit | | the host's address, port 7000 | the host's own network view | reaches only what the host itself has listening; making a container's port answer there is a separate mechanism | The difference between **refused** and **timed out** is worth internalising. A refusal is an answer: the local stack checked its own port space, found nothing bound, and said so immediately. A timeout means the packet left and nobody replied - a wrong address, a missing route, or a rule that dropped it. A `localhost` mistake produces the first, almost instantly, which is a strong hint that the process is talking to itself. ## Reaching the other container Three shapes, in rough order of how often they are the right one: 1. **Use the name the platform resolves.** Platforms hand workloads names that resolve to an address, so a caller never needs to know where anything landed. How that name keeps working while replicas are replaced is its own subject. 2. **Use the neighbour's address.** This works, but the address is assigned by the platform and changes when the container is replaced, so it belongs in a debugging session rather than in a configuration file. 3. **Put both containers in one shared network view.** They then genuinely share a loopback and `localhost` works again - at the price of one shared port space between them. What never works is keeping `localhost` and hoping. No platform rewrites a loopback call into a call to a neighbour, because it cannot know which neighbour was meant. ## Why the model is built this way A per-container view costs one broken habit and buys three things: - **Free port choice.** Every workload binds whatever port it likes, because the number is scoped to its own view rather than to the machine. - **A workload-shaped identity.** The unit that has an address is the workload, not the host, so a caller's target does not change meaning when the workload lands on a different host. - **A boundary worth writing rules about.** Traffic in and out of a view is a place where the platform can apply permission rules, because there is exactly one door. The escape hatches exist on purpose. A container can be placed in the **host's own network view**, in which case `localhost` really does mean the host and port choice starts colliding with everything else on the machine. Several containers can be placed in **one shared view**, which is exactly how a helper reaches an endpoint that is bound to loopback. Both are deliberate choices, and both trade the isolation described above for a specific convenience.

  • The call fails instantly with a refusal rather than hanging - what does that tell you?
    That something answered. The container's own stack looked in its own port space, found nothing bound on that port, and refused immediately. A hang or timeout would mean the packet left and got no reply, which points at a wrong address, a missing route or a rule dropping it. An instant refusal on a loopback address usually means the process is talking to itself.
  • Does a container always get a network view of its own?
    No. A platform can run a container in the host's own network view, where it shares the host's interfaces, addresses and port space - `localhost` then does mean the host, and port choice collides with everything else on the machine. Platforms can also place several containers in one shared view deliberately, so that they see one loopback between them.
  • Why is hardcoding the neighbour's address a bad fix even though it works once?
    Because the address belongs to that container instance, not to the workload. When the container is replaced the address usually changes, and the configuration now points at something that no longer exists. A name the platform resolves survives replacement; an address written into a config file does not.

Two offices in one building each run their own internal phone system. Dialling extension 100 from one office reaches that office's own front desk, never the neighbour's - the number means 'here', not 'this building'.

saying these in an interview costs you the question

  • Thinks localhost inside a container reaches services on the host
  • Believes every container on one host shares a single loopback
  • Reads the refusal as the other container being down
  • Blames a firewall rule for a call that never left the container
  • Expects the platform to redirect a loopback call to a neighbour
open as a page

Two containers on one host both listen on port 8080 internally, so why can only one publish host port 8080?

level: juniorimportance: must knowfreq 60%

basics

~20 s

A host port is an exclusive claim on a host address, so only one mapping can hold it there. Inside, each container has its own network view, so both processes can hold 8080 without ever meeting.

open as a page

A container's process listens on port 8080 but nothing off the host reaches it — what does publishing a host port do?

level: juniorimportance: must knowfreq 74%

basics

~20 s

Publishing claims a port on the host and installs an address-translation rule, so traffic arriving at that host port is rewritten and delivered to the container's own address and port. The process inside binds nothing on the host and is unchanged.

open as a page

A containerised report renderer must be reachable from partner browsers — which entry shapes can publish it, and what does each trade?

level: middleimportance: must knowfreq 62%

basics

~20 s

Four entry shapes: internal-only, a port reserved on every host, a balancer provisioned for that one workload, or a shared edge routing many hostnames and paths. They trade cost per external address against routing power and blast radius.

open as a page

A search indexer binds its status endpoint to the container's loopback address - why can nothing outside reach it?

level: middleimportance: must knowfreq 62%

basics

~20 s

The bind address decides which interfaces a listener will accept traffic on. Bound to loopback, it accepts only what arrives on that view's loopback; traffic from outside arrives on the container's other interface and is never delivered to it.

open as a page

In a cluster with no network rules written, which workloads can one compromised worker reach, and why?

level: middleimportance: must knowfreq 66%

basics

~20 s

A compromised workload can reach every other workload on the cluster network, in any grouping, on any port they are listening on. Most container platforms ship an allow-everything default, so reachability stays universal until a rule narrows it.

open as a page

When a workload's packet is wrapped inside host-to-host traffic to cross the fleet, what does that wrapper cost?

level: middleimportance: must knowfreq 50%

basics

~20 s

Wrapping costs bytes and work: an outer host-to-host header rides on every packet and leaves fewer usable bytes inside it, both hosts spend processor time adding and stripping it, and the network between them sees only host addresses.

open as a page

Why do container platforms give every workload its own fleet-routable address instead of sharing each host's address?

level: middleimportance: must knowfreq 62%

basics

~20 s

Giving each workload its own fleet-routable address lets any workload dial any other directly, with no port bookkeeping and no rewritten source address, so callers reach a workload rather than the host it happens to sit on.

open as a page

A scoring service's replicas are replaced many times a day; what does its stable service name resolve to, and why does that survive the churn?

level: middleimportance: must knowfreq 74%

basics

~20 s

It resolves to a virtual address allocated to the service declaration itself, not to any replica. Replica churn changes only the member set behind that address, so the name and address a caller holds stay valid for as long as the service exists.

open as a page

Forty services each took a platform-provisioned external balancer and the bill jumped — what is being charged, and what consolidates it?

level: seniorimportance: must knowfreq 55%

basics

~20 s

Each workload's own balancer holds an allocated external address and a managed balancer instance, both charged for as long as they exist, with traffic on top — forty times over. A shared edge routing by hostname and path collapses forty addresses into one.

open as a page

A nightly reconciliation batch is switched to default-deny outbound — what stops working first, and why?

level: seniorimportance: must knowfreq 56%

basics

~10 s

Name resolution stops working first. The resolver is itself reached over the network, so unless the outbound allowlist permits it, every lookup fails and each dependency appears to be down rather than blocked.

open as a page

A workload is published by reserving one port number on every host in the fleet — what does that buy, and why cap it?

level: middleimportance: should knowfreq 46%

basics

~20 s

It buys external reachability with nothing allocated and no per-workload bill. It costs a fleet-scarce, exclusive port number, a client that must be handed host addresses which change on every resize, and every host listening on that number.

open as a page

Why can two containers on one host both listen on port 8080 without the second bind failing?

level: middleimportance: should knowfreq 50%

basics

~20 s

A port number is scoped to a network view, not to the machine. Each container normally has its own view and therefore its own port space, so port 8080 in one is a different port from 8080 in the other.

open as a page

An allow rule written against one replica's address stopped working after that replica moved — what should it have selected instead?

level: middleimportance: should knowfreq 50%

basics

~20 s

Select by label, not by address. A workload's address is a short-lived lease from a per-host pool: a rescheduled replica returns with a different one, so an address-pinned rule silently stops matching, or later matches whoever inherits that address.

open as a page

When would you run a container on the host's own network view instead of publishing a mapped port?

level: middleimportance: should knowfreq 42%

basics

~20 s

Running on the host's own network view removes the mapping entirely: the process binds host ports directly, sees client addresses unrewritten, and pays no translation cost — at the price of host-wide port collisions and a lost network boundary.

open as a page

A replica stops reporting ready but keeps running — what happens to its membership of the set behind the service's virtual address?

level: middleimportance: should knowfreq 58%

basics

~20 s

Its address is removed from the member set, so no new connections are dispatched to it, while the process itself keeps running untouched. When it reports ready again the address is added back silently, with no caller involvement and no event a caller sees.

open as a page

Each of forty workloads renews its own certificate at its own entry point — what changes when a shared edge holds them instead?

level: seniorimportance: should knowfreq 40%

basics

~20 s

One party then holds and renews certificates covering every hostname the edge answers for, instead of forty teams each remembering their own. That concentrates the expiry risk into one estate-wide incident and concentrates the ability to fix it in one place.

open as a page

A helper container must scrape a worker's endpoint bound to loopback - what must be true of both containers?

level: seniorimportance: should knowfreq 38%

basics

~20 s

They must be placed in one shared network view, not merely on the same host. Sharing the view gives them one interface, one address, one loopback and one port space, so the helper's call to loopback reaches the worker instead of itself.

open as a page

After a workload overlay is introduced, small requests succeed but large responses hang between hosts - why?

level: seniorimportance: should knowfreq 46%

basics

~20 s

Almost certainly a packet-size mismatch. The workload interface still advertises the link's full size, so once the host adds its wrapper the frame exceeds what the link carries and is dropped. Small exchanges never fill a packet, so they survive.

open as a page

A host with idle processors accepts no more workloads because its address range is full - why, and what fixes it?

level: seniorimportance: should knowfreq 44%

basics

~20 s

Addresses are a capacity dimension of their own. One pool is carved into fixed per-host ranges, so a host whose range is used up places nothing more, whatever its spare processor. The fix is re-planning the ranges or enlarging the pool.

open as a page

After a partner's traffic is published into a container, why does every request log the same internal source address?

level: seniorimportance: should knowfreq 52%

basics

~20 s

The publishing hop rewrites the destination so packets reach the container and, in most implementations, rewrites the source too so replies return through the host to be un-translated. The application therefore sees one internal address for every client.

open as a page

A queue consumer's pooled connections keep reaching a replaced replica of a scoring service — why did the stable name not protect it?

level: seniorimportance: should knowfreq 52%

basics

~20 s

Because a member is chosen when a connection is established, not when a request is sent. A pool holds its connections for hours, so the choice made at open time is never revisited, and the abstraction only helps callers that open new connections.

open as a page

You must set one external-entry standard for an estate of forty containerised services — how do you decide, and what do you exempt?

level: principalimportance: should knowfreq 36%

basics

~20 s

Set a default most workloads never have to argue with — internal-only inside, one shared edge outside — then write the exemption test: traffic the edge cannot route, a blast radius that cannot be shared, volume that would distort the edge. Then fund the edge's owner.

open as a page

How would you move a shared cluster carrying dozens of teams from allow-everything to default-deny without causing an outage?

level: principalimportance: should knowfreq 28%

basics

~20 s

Derive the real dependency graph from observed traffic, restrict inbound before outbound, stage it workload by workload starting with the highest-value receivers, and let each team own its own rule. Label hygiene and enforcement coverage are the prerequisites.

open as a page

How would you choose between an encapsulated overlay and a natively routed workload network for a large estate?

level: principalimportance: should knowfreq 34%

basics

~20 s

Decide on control of the network, the address budget and what you need to see - not on benchmarks. An overlay needs no cooperation and lets pools repeat per cluster; native routing costs real addresses and agreement, and returns headroom and workload-level visibility.

open as a page

When a platform starts a workload, what creates its network interface and gives it an address?

level: middleimportance: nice to knowfreq 28%

basics

~20 s

Not the platform itself. It defines a small contract and calls a pluggable attachment driver before the workload's first process starts, handing it the workload's private network view; the driver builds the interface, takes an address from the host's range and returns it.

open as a page

A network rule was accepted and stored, yet the traffic it forbids still flows — what is missing?

level: seniorimportance: nice to knowfreq 30%

basics

~20 s

An enforcing component on the host where the workload runs. A stored rule is only a declaration; something local to each host must translate it into packet filtering; if nothing does, the rule is stored without error and enforces nothing.

open as a page

Teams keep asking to address individual replicas directly instead of through the service's virtual address — how do you decide which requests to grant, and what do you require of the ones you do?

level: principalimportance: nice to knowfreq 28%

basics

~20 s

Grant it only where the caller genuinely must reach a particular member rather than any member: replicas forming a group among themselves, a caller that must reach the instance holding a given piece of state, or per-instance collection. Everything else keeps the virtual address.

open as a page