1 / 18
Sections
Module 2
Service Boundaries and Runtime Isolation
What makes two services truly independent rather than merely two pieces of code in the same project?
- Boundaries become real when they affect deployment, configuration, health, and failure.
- Containers are a tool for making runtime boundaries repeatable.
Slide 2
Why Independent Deployment Matters
Independent deployment lets teams change, scale, restart, and roll back one service without redeploying the whole system.
- Smaller blast radius for changes and failures.
- Different services can scale for different workloads.
- Operational ownership becomes visible.
Slide 3
Process Boundary Versus Service Boundary
Separate processes are a start, but a service boundary also needs independent operation.
- Processes have separate memory and lifetimes.
- Services need clear ownership, contracts, config, health, and release paths.
- A shared deploy script can still create tight coupling.
flowchart LR host[Host machine] procA[Service A process] procB[Service B process] shared[Shared runtime config] host --> procA host --> procB procA --> shared procB --> shared
Service A and Service B run as separate processes on the same host. They have process isolation, but they may still share a deployment script, filesystem, environment, and failure domain. This is not automatically a clean service boundary.
Slide 4
Process Isolation Versus Container Isolation
Containers package runtime dependencies and isolate network, filesystem, user, and resource settings.
- Containers still run processes.
- Isolation is practical, not magical.
- Runtime settings shape security and failure behavior.
flowchart LR runtime[Container runtime] net[Shared container network] containerA[Container for Service A] containerB[Container for Service B] imageA[Image A] imageB[Image B] runtime --> containerA runtime --> containerB imageA --> containerA imageB --> containerB containerA --> net containerB --> net
Service A and Service B run in separate containers with their own runtime dependencies, environment variables, ports, and filesystem views. The host still provides the container runtime, but each service can be built, started, stopped, and inspected independently.
Slide 5
Image Versus Container
An image is the packaged artifact; a container is a running instance created from that artifact.
- Build images from source and dependency metadata.
- Run containers with environment, network, storage, and limits.
- Rebuild artifacts deliberately instead of changing live containers by hand.
flowchart LR source[Source code] deps[Dependency file] dockerfile[Container definition] image[Container image] runtime[Container runtime] c1[Container instance one] c2[Container instance two] source --> image deps --> image dockerfile --> image image --> runtime runtime --> c1 runtime --> c2
Source code, dependency files, and a container definition produce an image. The runtime starts one or more containers from that image with environment variables, port mappings, networks, and storage configuration.
Slide 6
Ports and Host Mappings
Published ports connect traffic from the host to a port inside a container.
- Container ports are internal to the container network namespace.
- Host ports make a container reachable from outside the container network.
- A mapping like 8080 to 5000 does not change the app port.
flowchart LR browser[Browser] host[Host port 8080] container[Service A container] app[App listens on port 5000] browser --> host host --> container container --> app
The host receives traffic on port 8080 and forwards it to port 5000 inside the Service A container. Inside the container, the application still listens on port 5000.
Slide 7
Container Networking and Service Discovery
Containers on the same network can call each other by service name instead of localhost.
- Localhost means the current container.
- Service names resolve through the container network.
- Module 3 will go deeper into HTTP API design.
flowchart LR net[Shared container network] serviceA[Service A container] serviceB[Service B container] endpoint[service-b port 5001] serviceA --> net net --> endpoint endpoint --> serviceB
Service A reaches Service B using the name service-b on a shared container network. It does not call localhost, because localhost inside Service A points back to Service A itself.
Slide 8
Configuration Through Environment Variables
The same image should run in different environments without changing source code.
- Put endpoint URLs, ports, and modes in runtime config.
- Do not bake secrets into images.
- Keep configuration visible and reviewable.
flowchart TB image[Image with code and dependencies] env[Environment variables] secrets[Secret source] container[Running container] risk[Do not copy secrets into image] image --> container env --> container secrets --> container secrets -.-> risk
A container image contains code and dependencies. Runtime configuration supplies endpoint names and ports. Secrets should come from a secret source or protected runtime mechanism, not from committed code or the image build context.
Slide 9
Partial Failure in Containers
One service can stop while another remains running, observable, and responsible for graceful behavior.
- Stop Service B and keep Service A running.
- Service A should return a controlled degraded response.
- Logs should make the failure path visible.
flowchart LR client[Client] serviceA[Service A running] serviceB[Service B stopped] logs[Logs] client --> serviceA serviceA -. request fails .-> serviceB serviceA --> logs
Service A stays available after Service B stops. Requests that require Service B fail or degrade, while health checks and logs show that Service A itself is still running. This is partial failure in a small containerized system.
Slide 10
Health Checks and Restart Policies
A health check can detect an unhealthy container, and a restart policy can restart it.
- A restart is not the same as full recovery.
- Health checks must test useful behavior.
- Repeated restarts can hide deeper dependency or state problems.
flowchart LR runtime[Container runtime] check[Health check] unhealthy[Marked unhealthy] restart[Restart container] healthy[Healthy again or still failing] runtime --> check check --> unhealthy unhealthy --> restart restart --> healthy
The runtime checks a container health endpoint. If health checks fail, the runtime marks the container unhealthy and may restart it according to policy. The restarted process may still need dependencies and state to be healthy.
Slide 11
Resource Limits and Noisy Neighbors
Runtime isolation should include CPU, memory, and restart behavior, not only separate folders.
- One service can consume resources needed by another.
- Limits make failure behavior more predictable.
- Limits can also cause crashes if set without measurement.
Slide 12
Persistent and Ephemeral State
Container filesystems are disposable unless state is explicitly stored elsewhere.
- Logs and local files can disappear with the container.
- Volumes preserve selected state outside the container lifecycle.
- Service-owned state still needs clear ownership.
flowchart LR c1[Running container] temp[Ephemeral container storage] volume[Persistent volume] c2[Replacement container] c1 --> temp c1 --> volume temp -. lost on remove .-> c2 volume --> c2
Ephemeral container storage is lost when the container is removed. A persistent volume stores selected data outside the container lifecycle so it can be reused by a replacement container.
Slide 13
Container Security Basics
Container security is part of the service boundary, not a later checklist.
- Use small base images.
- Avoid running as root when practical.
- Do not copy secrets into images.
- Use .dockerignore.
- Pin dependencies where reasonable.
- Expose only required ports.
- Review build context carefully.
- Treat generated Dockerfiles as drafts.
Slide 14
Reviewing AI-Generated Container Configuration
Coding agents can accelerate setup, but they often miss operational and security constraints.
- Oversized images.
- Running as root.
- Copying secrets or local files.
- Missing .dockerignore.
- Unpinned dependencies.
- Unnecessary exposed ports.
- Incorrect health checks.
- Assuming localhost across containers.
- Mixing build and runtime dependencies.
Slide 15
Week 2 Lab
Containerize Service A and Service B, connect them on a shared network, and observe partial failure.
- Build separate images.
- Run services independently.
- Configure endpoints with environment variables.
- Stop one service and inspect behavior.
Slide 16
Failure Walkthrough
What should Service A do when Service B is stopped, slow, or restarting?
- Return a controlled error or degraded response.
- Log the dependency failure with a correlation ID.
- Avoid pretending that restart alone means recovery.
Slide 17
Key Takeaways
Containers help make service boundaries concrete, but the engineering goal is independent operation under change and failure.
- Boundaries include build, run, config, network, state, and ownership.
- Use service names on container networks.
- Health and restart are tools, not correctness guarantees.
- Review AI-generated configuration before trusting it.
Slide 18
What's Next: Network Communication with REST
Module 3 moves from running services independently to designing their synchronous network communication.
- REST will be the required baseline protocol.
- gRPC will be compared later as an instructor-guided or optional extension.
- The container lab gives us a runtime for communication experiments.