You attach a debug container sharing a shell-less workload's process and network view — why can it still not read the workload's config file?
answer
- two views joined, one not
- tools come from the other image
- separate roots on purpose
- the config file is not on your path
- reach it via the per-process entry
basics
~20 sBecause the filesystem root is not one of the views being shared. The debug container sees its own image's files; the target's files are reachable only through the operating system's per-process entry for the target process, which the shared process view makes identifiable.
solid answer
~50 sJoining shares the views you asked for and no others. Sharing the **process view** means the debug container's tools see the target's process table with the same identifiers the target itself sees, can read per-process state, and can signal it. Sharing the **network view** means the same addresses, the same loopback and the same interfaces, so you can connect to the target's listening port from inside its own view. The **filesystem root is normally kept separate**, and that separation is the point: it is what lets the debug container carry a shell and tools the target has never contained. So the target's configuration is not on any path you would expect. The route in is the operating system's per-process entry for a running process, which exposes that process's own root view — and you know which process to ask for precisely because the process view is shared.
code
pseudocode · 14 linesdebugContainer = {
image: toolsImage, // where the shell and tools come from
joinProcessView: target, // same process table, same identifiers
joinNetworkView: target, // same addresses, loopback, capture point
joinFilesystemRoot: false // its own files, not the target's
}
// wrong: there is no such path in the debug container's own root
open("/etc/worker.conf") -> not found
// right: go through the shared process view
firstPid = processTable.firstProcessOf(target)
targetRoot = perProcessEntry(firstPid).rootView
open(targetRoot + "/etc/worker.conf") -> the file the image shipsgo deeper
Remember that a debug container is a separate container carrying its own tools, and that it shares only the views it was asked to share — the target's files are not among them by default.
Explain what each shared view provides: identifiers, arguments and signalling from the process view; loopback, capture and resolution from the network view; and the per-process route to the target's filesystem root.
Demonstrate you use the views as evidence: say which question each one answers before attaching, use the loopback test to split 'not listening' from 'dropped in between', and know the technique needs a live process.
Own whether the capability exists in practice: whether on-call holds the permission, whether adding a container disturbs the running group on your platform, and what the maintained tool image contains.
## What "joining a view" actually means The operating system gives each container its own view of several things at once: the process table, the network stack, the filesystem root, user identities, the hostname. A **debug container** is an ordinary container with one difference — instead of receiving fresh views of its own, some of its views are pointed at an existing container's. Which views, and how you ask for it, differ between designs: a single-host runtime typically lets you start a container that joins another's views, while a cluster platform typically adds a container into the already-running group so that it inherits the group's views. The mechanism underneath is the same, and so is the reasoning. ## What the process view buys you - The **same process table**, with the same identifiers the target itself uses — so a stack dump, a wait-state read or a signal all address the process you mean. - The exact **argument vector and environment** the first process was started with, which settles a surprising share of "it behaves differently here" questions on its own. - The **child processes** the workload spawned, and whether any are lingering. - The route to the target's filesystem, described below. ## What the network view buys you - **Loopback and the same addresses**, so you can open a connection to the workload's port from inside its own view. That single test splits "the process is not listening" from "something between the caller and it is dropping traffic" — two diagnoses that look identical from outside. - A **capture point on the same interfaces**, which shows what actually arrives and leaves. - **Name resolution as the workload performs it**, which is often where an environment-only failure lives. One honest limit: a capture begins when you start it. Traffic that already passed the interface before the debug container existed was never recorded by anything. ## What stays separate, and why that is the whole point | View | Shared by default | What that gives you | |---|---|---| | Process table | yes, when asked for | identifiers, arguments, environment, signalling | | Network stack | yes, when asked for | loopback access, capture, name resolution as the target sees it | | Filesystem root | no | the debug container keeps its own tools — which is the reason the technique works | If the filesystem root were joined, the debug container would find itself in the same empty image the target ships and would have lost the tools that made it worth starting. The separation is deliberate, not an oversight. The consequence is that the target's configuration file, its executable and its data directory are not where you would type them. The route in is the **operating system's per-process entry for a running process**, which exposes that process's own root view as a path reachable from the debug container. Because the process view is shared, you already know the identifier to use. From there the target's shipped files read normally — with your tools, not its own. ## The limits worth knowing before an incident 1. **The target must be running.** Joining is a live-process technique; against an instance that has ended there is nothing to attach to, and the evidence is whatever the platform retained. 2. **The capability is often gated.** Designs differ on whether a container can be added to an already-running group without disturbing it, or whether any change to the group's declaration replaces it — and many estates put the whole capability behind a policy an on-call engineer may not hold. Find out which applies to you while nothing is on fire. 3. **It is a real container on a real host.** It occupies the host and does real work; it is not free, and it is meant to be thrown away when you are done. 4. **It does not change the target.** The workload keeps serving; nothing about it is restarted by your reading it. That is precisely why this is the preferred move over a restart that destroys the state you came to look at. ## The reasoning to show The interviewer is not testing whether you remember how to ask for a debug container. They are testing whether you know *what each shared view is evidence about*: the process view answers "what is this process actually doing and how was it started", the network view answers "who can reach whom from here", and neither of them answers "what is in the file on disk" until you go through the process entry. Naming the view you need before you attach is the difference between a five-minute diagnosis and half an hour of guessing at paths.
- What does sharing the network view let you establish that a probe from another host cannot?Whether the process is listening at all. From inside the shared view you connect over loopback, which bypasses every hop, rule and address translation between the workload and an outside caller. If that succeeds and the outside probe fails, the process is fine and the path to it is not; if it fails too, stop looking at the network.
- Why not just add a shell to the shipped image for the duration of the incident?The shipped image is what runs on every copy, everywhere, until it is replaced — so a tool layer added for one incident widens what a compromised process can execute for all of them, and puts something in production that was never tested there. A throwaway debug container gives the same tools, scoped to one host and one session.
- The target has already exited. Does joining still work?No. Every shared view is a view held open by a running process, so with no process there is nothing to join and the technique is simply unavailable. What remains is the output the platform captured from that instance, its recorded exit status, and anything the process wrote to a path that outlives the container.
saying these in an interview costs you the question
- Thinks joining a target's views also mounts the target's filesystem.
- Expects the target's executable to be on the debug container's path.
- Believes the debug container's tools run inside the target's boundary.
- Thinks a container that has already exited can still be joined.
- Assumes attaching a debug container restarts or disturbs the target.
- Expects a capture to show traffic that passed before it was started.