Investigation 017 · Node Execution Principles

Three containers are running.
Why is one application still broken?

INV-016 already separated decisions from execution mechanics. We inherit that boundary unchanged. The mystery now is smaller and sharper: what exact unit should the scheduler and node treat as indivisible when one application needs tightly-coupled processes?

Begin the investigation ↓
Independent ContainersRUNNING · DISCONNECTED GUARANTEES

Author's Note

Keep runtime delegation inherited, unchanged.

This investigation does not reopen who owns execution mechanics. The node still decides that assigned work should run and delegates how to the runtime.

We are only discovering the workload boundary that runtime delegation receives: what must be placed, started, addressed, and evicted together.

Separating responsibilities solved execution mechanics. It did not define the application's indivisible execution boundary.

Prologue

The helper process asks one dangerous question.

A web service requests two companions: one process fetches configuration before startup, another ships logs while the service runs.

Request 1

Run the web service process.

Request 2

Add a log helper that is useful only beside that web service.

Request 3

Add a precondition process that must succeed before web startup.

Consequence

Three healthy containers can still fail to behave as one application.

The puzzle is not "how to run three containers." It is "how to express one application boundary across them."

First Principles

One process is simple. Two processes expose boundary questions.

The first time a second process appears, architecture must answer co-location, startup order, identity, and fate. None belong to a process in isolation.

Container question

Can one process run correctly?

A container already answers this: one process, one isolation boundary, one lifecycle.

Application question

Can several processes stay correct together?

This requires shared guarantees that no single process can declare or enforce alone.

When correctness depends on several processes together, the orchestration unit can no longer be one process by default.

Naive Architecture

One workload equals one container.

If every application is self-sufficient as one process, the inherited architecture is complete: one scheduling decision, one runtime request, one lifecycle.

Schedulerwhere
Node agentthat
Runtimehow

The Architecture That Almost Worked

One application represented by three independently scheduled containers.

Configuration, web, and logging all run, each by a valid local decision. The platform still has no enforceable concept that they are one indivisible unit.

Config container

Precondition worker

Must complete before web startup.

Web container

Main process

Serves traffic only after config exists.

Log container

Helper process

Useful only when co-located with that specific web process.

Every container can be healthy while the application contract is still missing.

Breaking Our Design

Four pressures expose one missing boundary.

EPISODE 01

The Helper Process Problem

Pressure. A log helper separated from the web process is healthy but useless.

Prediction. If independent placement is enough, helper usefulness should survive separate node decisions.

Experiment

Place web and helper separately, then compare atomic co-location.

Observation

Separated helper cannot perform its job.

Failure

Useful relationship is not guaranteed.

Discovery

Tightly-coupled members need atomic placement.

Next pressure

Placement alone does not control startup sequencing.

Boundary delta

Group-level placement guarantee is required.

Compare separate placement against atomic co-location.

Webunplaced
Log helperunplaced
Resultunknown

Choose a placement mode and inspect helper usefulness.

Next pressure: even co-location does not guarantee preconditions complete before startup.

EPISODE 02

The Startup Order Problem

Pressure. Web startup races before configuration completion.

Prediction. If independent startup is acceptable, retries should be equivalent to a platform guarantee.

Experiment

Start unordered, then enforce platform-declared order.

Observation

Unordered startup flails; ordered startup is stable.

Failure

Application code absorbs deployment sequencing burden.

Discovery

Ordering belongs to the shared execution boundary.

Next pressure

Ordered members still appear as separate network identities.

Boundary delta

Declared startup order must be enforceable.

Run unordered startup, then compare with enforced ordering.

Config preconditionpending
Web startupnot attempted
Outcomeunknown

Observe whether startup correctness is accidental or guaranteed.

Next pressure: co-located, ordered members still look like unrelated endpoints.

EPISODE 03

The Shared Identity Problem

Pressure. Separate addresses and localhost scopes split one application into three network identities.

Prediction. If independent identities are harmless, helper-to-web communication should remain trivial.

Experiment

Compare separate identities with shared abstract identity.

Observation

Separate identities break localhost expectations.

Failure

One application appears as fragmented network targets.

Discovery

The group needs one shared abstract identity guarantee.

Next pressure

Identity alone does not settle eviction behavior.

Boundary delta

Identity ownership is group-scoped.

Test separate localhosts versus one shared abstract identity.

Address modelseparate addresses
localhost testnot tested
Resultunknown

Validate whether helper and main process behave as one logical host.

Next pressure: health and eviction still happen per fragment, not per application.

EPISODE 04

The Fate-Sharing Problem

Pressure. Independent eviction leaves healthy but useless fragments running.

Prediction. If independent fates are acceptable, partial eviction should preserve meaningful service behavior.

Experiment

Evict one member independently, then compare group eviction.

Observation

Independent eviction preserves fragments, not application correctness.

Failure

No group-level health or termination boundary exists.

Discovery

Group eviction and termination need one boundary, while members may still restart individually inside it.

Next pressure

The contract is now visible and can be formalized.

Boundary delta

Eviction and health must be group-scoped.

Compare independent eviction with shared-fate group eviction.

Webrunning
Helpersrunning
Outcomehealthy

Observe whether eviction semantics preserve application correctness.

Next pressure: the platform now needs one explicit application boundary contract.

Optional compact review carousel

The Turning Point

Schedule one application boundary.
Not accidental container adjacency.

Placement, startup, identity, storage intent, and fate must be owned together by one generic boundary before any platform-specific name appears.

Application Boundary Contract

A generic contract earned before platform terms.

The smallest tightly-coupled process group must be placed, initialized, addressed, and terminated as one indivisible unit.

GuaranteeWhat must hold
Atomic placementAll declared members land through one scheduling decision, or none does.
Declared startup orderingPrecondition members run to completion successfully before application members can start.
Shared abstract network identityThe group is reachable as one logical host identity; members can communicate with local-host semantics at the group boundary.
Shared declared storage guaranteeGroup-declared storage is consistently available to every member that mounts it.
Shared fateGroup eviction and termination apply to the boundary as one unit; individual members may still restart within that boundary.
Policy exclusionsThe contract does not define retry intervals, replica counts, CPU/memory apportionment, or health-check cadence.

Only Now: Kubernetes

Kubernetes names the generic boundary.

Kubernetes calls this indivisible application boundary a Pod. Containers that must complete before application startup are init containers.

These names implement the earned contract. They do not replace it.

A container runs one process. A Pod owns the guarantees that make tightly-coupled processes one application.

Engineering Reflection

The timeless principle is boundary honesty.

When correctness belongs to a group, orchestration must treat the group as one unit. Containers remain the process unit; the application boundary remains the coupling unit.

Intellectual Lineage

Borg to Kubernetes

Borg's alloc lineage documented helper companions and the operational inconvenience of allowing app containers to escape shared grouping, leading Kubernetes to regularize grouping for every app container.

Architectural honesty

A single-container boundary remains the default. Use several containers together only when permanent coupling makes separation incorrect; genuinely independent containers belong in separate boundaries.

Transferable lesson

Any orchestration system needs a smallest indivisible execution boundary once tightly-coupled processes appear.

Costs Accepted

Concrete placement cost

A helper needing about 50 MB can no longer be scheduled alone on a node with 50 MB free if its multi-GB companion cannot fit there. Placement eligibility becomes the combined footprint.

No independent scaling

Members in one boundary scale together even when one member would need fewer replicas.

Shared failure domain

Group-level eviction or termination affects healthy and unhealthy members together.

Cognitive cost

Engineers must reason about process-level behavior and boundary-level guarantees at the same time.

Investigation Exercise

Run the synthesis trace and stop it midway.

01 · Place

Predict helper usefulness under separate placement.

02 · Order

Predict startup behavior before precondition completion.

03 · Identity

Predict localhost behavior under separate identities.

04 · Fate

Predict outcomes for independent and shared eviction.

● ● ●
Run the synthesis trace after making predictions.

Bridge

Shared identity is earned.
Why not borrow the node's identity?

This investigation requires one group identity. It does not establish why that identity must be distinct from the machine that executes the group.

Tightly coupled processes share one application boundary while the need for an identity distinct from the node remains unresolved
We know the application boundary needs one identity. We have not earned why it cannot share the node's identity.

Next Investigation

INV-018 — The Node Networking Problem

Why does every application boundary receive its own IP instead of sharing the network identity of its node?

Deliberate Simplifications Ledger

Shared abstract network identity is guaranteed but not mechanizedINV-018
Infrastructure container treated only as one possible namespace-holder implementationINV-018
Identity allocation and cluster-wide uniqueness are assumedINV-018 / INV-020
Shared declared storage guarantee is named, not implementedINV-025–027
Per-member resource partitioning remains policyOpen backlog
Communication between application boundaries on different nodesINV-020–024

Sources

  • Kubernetes - Pods
  • Kubernetes - Init Containers
  • Burns, B., Grant, B., Oppenheimer, D., Brewer, E., Wilkes, J. "Borg, Omega, and Kubernetes: Lessons learned from three container-management systems over a decade." ACM Queue 14(1), 2016.
  • Verma, A. et al. "Large-scale cluster management at Google with Borg." EuroSys, 2015.