CMPE273 · Module 2

Service Boundaries, Runtime Isolation, and Containers

Examine what makes services independently deployable, how containers create repeatable runtime boundaries, and how partial failure appears when services run separately.

Learning Objectives

  1. Explain the difference between a process boundary and a service boundary.
  2. Describe why independently deployable services improve isolation and operational flexibility.
  3. Distinguish container images from running containers.
  4. Containerize two independently running services.
  5. Configure services using environment variables rather than hardcoded values.
  6. Explain container networking, ports, host mappings, and service names.
  7. Demonstrate partial failure by stopping one service while another remains available.
  8. Explain health checks, restart policies, and basic resource limits.
  9. Identify common container security risks.
  10. Review AI-generated Dockerfiles and container configuration critically.

Core Concepts

Process Boundary

A runtime separation between operating system processes. Processes have separate memory and can fail independently, but they may still be deployed and operated as one unit.

Service Boundary

A design and operational boundary where a component has clear ownership, configuration, deployment, health, and failure behavior.

Deployment Unit

The artifact that is built, released, rolled back, monitored, and operated independently.

Container Image

An immutable package containing application code, runtime dependencies, metadata, and a default command.

Running Container

A live process created from an image with runtime configuration, networking, storage, limits, and environment variables.

Container Network

A network namespace where containers can reach each other by service name instead of assuming localhost.

Runtime Configuration

Values supplied outside the image, commonly through environment variables, so the same image can run in different environments.

Failure Isolation

The ability for one service to stop, restart, or degrade while other services remain observable and available.

Diagrams

Two Services Running as Processes on One Host

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.

Two Services Running in Separate Containers

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.

Image Build to Container Runtime Lifecycle

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.

Host Port to Container Port Mapping

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.

Service A Calls Service B Through a Container Network

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.

Configuration and Secret Boundaries

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.

Service B Fails While Service A Remains Running

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.

Health Check Failure Followed by Container Restart

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.

Persistent Volume Versus Ephemeral Container Storage

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.

Key Takeaways

Lab Links