ArchitectMind
  1. Home
  2. Tutorials
  3. Book 9 · Cloud, Containers, DevOps & Production Architecture
  4. Volume III
  5. Containers vs Virtual Machines
Book 9 · Volume III — Containers & Kubernetes · Topic 1.2

Containers vs Virtual Machines

Kernel sharing versus hardware virtualisation

11 min readStage 4 · Production & architecture10 interview questions
Chapter
Chapter 1 — Container Fundamentals
Prerequisites
Topic 1.1; Volume I Chapter 5.1
You will be able to
Compare containers and VMs precisely on isolation, performance, density, operations and security, explain why containers usually run inside VMs in the cloud, choose sandboxed or microVM runtimes when isolation matters, and justify runtime choices for different workloads
Covers
Containers vs virtual machines
On this page
  1. 1. Concept / Definition
  2. 2. Why It Exists
  3. 3. Core Concepts — Containers vs VMs
  4. 4. How It Works Internally — Isolation Spectrum
  5. 4A. Deep Dive — Choosing Runtimes for ShopNow and PayGrid
  6. 4B. Deep Dive — Same Service, Three Runtimes (checkout, 2 vCPU/4 GiB equivalent)
  7. 5. APIs / Features / Syntax
  8. 6. Practical Examples
  9. 7. Common Problems & Mistakes
  10. 8. Performance & Production Considerations
  11. 9. Architecture & Design Considerations
  12. 10. Interview Questions & Answers

1Concept / Definition

A virtual machine virtualises hardware: a hypervisor gives each VM virtual CPUs, memory and devices, and each VM runs its own operating system kernel. A container virtualises the operating system: all containers on a host share the host kernel, isolated by namespaces and cgroups. The difference drives everything else — speed, density, isolation and operations.

Containers vs virtual machines
Figure 1 — Containers vs virtual machines
Stacks compared
Figure 2 — Stacks compared
VocabularyMeaning
HypervisorSoftware/hardware layer running VMs (Nitro, KVM)
Guest kernelOS kernel inside a VM
MicroVMMinimal VM optimised for fast start (Firecracker)
Sandboxed containerContainer with an extra isolation layer (gVisor, Kata)
Table 1 — Terms

2Why It Exists

NeedBetter fit
Many small services, fast deploysContainers
Different OS kernels / Windows + LinuxVMs
Untrusted multi-tenant codeMicroVMs / sandboxes
Legacy apps expecting full OSVMs
Table 2 — Why both exist

3Core Concepts — Containers vs VMs

DimensionContainersVMs
IsolationProcess-level, shared kernelHardware-level, separate kernels
StartupMilliseconds–secondsTens of seconds–minutes
Image sizeMBs–hundreds of MBsGBs
DensityTens–hundreds per hostFew–tens per host
PatchingRebuild image; host kernel patched separatelyPatch each guest OS
PortabilitySame image across hosts with compatible kernel/archImage tied to hypervisor formats
OverheadNear nativeSmall (Nitro) to moderate
Table 3 — Comparison
Startup time comparison
Figure 3 — Startup time comparison

4How It Works Internally — Isolation Spectrum

Isolation spectrum
Figure 4 — Isolation spectrum
RuntimeHowAWS example
runcNamespaces/cgroups on host kernelEKS on EC2 nodes
gVisorUser-space kernel intercepts syscallsSandboxing untrusted code
Kata ContainersLightweight VM per podStrong isolation on K8s
FirecrackerMicroVM per function/taskLambda, Fargate
Table 4 — Runtimes

4ADeep Dive — Choosing Runtimes for ShopNow and PayGrid

WorkloadRuntimeReason
60 internal Java servicesContainers on EKS EC2 nodes (runc)Trusted code, density, cost
Seller-uploaded image processingLambda (Firecracker)Untrusted input, per-invocation isolation
Partner sync jobsECS Fargate (microVM per task)No node management, isolation
PayGrid CDE servicesContainers on dedicated node pool (EC2), strict policiesPCI scope isolation at node level
Legacy Windows reportingEC2 Windows VMWindows-specific stack
Table 5 — Mixed estate by risk and workload

4BDeep Dive — Same Service, Three Runtimes (checkout, 2 vCPU/4 GiB equivalent)

MetricEC2 VM (m7g.large)Container on EKS nodeFargate task
Time to serve after scale event~75 s~8 s (node exists)~45 s
Monthly cost per replica~₹5,300~₹2,900 (bin-packed)~₹6,800
Isolation boundaryHypervisorKernel (shared)MicroVM
Ops effortAMI, patchingPlatform teamMinimal
Best forLegacyMany servicesFew services, isolation
Table 6 — Measured trade-offs

5APIs / Features / Syntax

BASH
# Compare kernel versions: containers share the host kernel
uname -r                                         # host: 6.1.x
docker run --rm alpine uname -r                  # same kernel 6.1.x
docker run --rm ubuntu:24.04 cat /etc/os-release # different userland, same kernel
YAML
# Kubernetes RuntimeClass for sandboxed workloads (gVisor/Kata)
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata: { name: gvisor }
handler: runsc
---
apiVersion: v1
kind: Pod
metadata: { name: untrusted-renderer }
spec:
  runtimeClassName: gvisor
  containers:
    - name: app
      image: 123456789012.dkr.ecr.ap-south-1.amazonaws.com/renderer:1.4
YAML
# EKS Fargate profile: each pod in its own microVM boundary
fargateProfiles:
  - name: sandbox
    selectors:
      - namespace: untrusted-jobs

6Practical Examples

6.1 Consolidation savings

ShopNow's 40 services on 40 small VMs averaged 12% CPU. Moving to containers on 14 larger nodes raised utilisation to 55% and cut compute cost by 48%.

6.2 Kernel vulnerability exposure

A Linux kernel CVE affecting namespaces required patching nodes. Because containers share the kernel, the fix was node AMI replacement (Karpenter drift) — not image rebuilds.

6.3 Untrusted code isolated

User-supplied image transformations run in Lambda (Firecracker microVMs) rather than shared cluster pods, containing any exploit to a disposable microVM.

6.4 Worked example — startup impact on scaling

UnitTime to serve traffic
New EC2 VM from AMI60–90 s
New pod on existing node5–10 s (Java with CDS)
New pod needing new node60–90 s
Table 7 — Containers scale faster when capacity exists

6.5 Worked example — patching models

LayerContainersVMs
App librariesRebuild imagePatch in place or rebuild AMI
OS userlandRebuild image (base update)Patch guest
KernelPatch host nodesPatch each guest
Table 8 — Different responsibilities

6.6 Worked example — licensing

Software licensed perEffect
VM/coreContainers may need dedicated nodes to count cores
Table 9 — Licensing can drive design

6.7 Worked example — interview whiteboard

PromptAnswer outline
"Containers or VMs?""VMs virtualise hardware with separate kernels — strong isolation, heavier, slower. Containers share the host kernel with namespaces/cgroups — light, fast, dense, weaker isolation. In AWS, containers usually run on VMs (EKS nodes) or in microVMs (Fargate, Lambda). Choose containers for trusted microservices, VMs for different kernels/Windows/legacy, microVMs or gVisor/Kata for untrusted or multi-tenant workloads."
Table 10 — Structured answer

6.8 Worked example — PayGrid isolation layers

LayerIsolation
AccountCDE separate
Node poolDedicated, tainted
PodRestricted security context
NetworkPolicies default deny
Table 11 — Defence in depth instead of relying on containers alone

6.9 Worked example — anti-patterns

Anti-patternEffect
Running untrusted tenant code in shared podsEscape risk
Treating containers as VMsOperational mess
One VM per microserviceLow utilisation
Table 12 — Common mistakes

6.10 Worked example — Windows containers

FactDetail
Need Windows host kernelWindows nodes in EKS
Larger imagesSlower pulls
Table 13 — Special case

6.11 Worked example — performance overhead

WorkloadContainer vs bare metal
CPU-bound Java~0–2%
Network-heavySmall overhead (veth/CNI)
Storage via overlayUse volumes for heavy I/O
Table 14 — Near-native performance

6.12 Worked example — nested virtualisation

CaseNote
Kata on EC2Needs bare-metal or nested virtualisation support
FirecrackerBare metal instances
Table 15 — Constraints for sandboxes

6.13 Worked example — cost model

ModelBilling
EC2 nodes for containersPer instance (bin-packing matters)
FargatePer task vCPU/memory
LambdaPer request/duration
Table 16 — Isolation choice changes billing

6.14 Worked example — debugging differences

TaskContainersVMs
Shell accesskubectl exec / ephemeral containersSSM Session Manager
LogsstdoutFiles/agents
Table 17 — Different operations

6.15 Worked example — decision table

CriterionChoose
Trusted code, many servicesContainers on nodes
Untrusted/multi-tenantMicroVMs or sandboxed runtimes
Need full OS controlVMs
Short, event-drivenLambda
Table 18 — Quick guide

6.16 Worked example — compliance view

Auditor questionAnswer
How are tenants isolated?Accounts, node pools, policies, microVMs where needed
Table 19 — Explain layered isolation

6.17 Worked example — Firecracker facts

MetricValue
Boot~125 ms
Memory overhead< 5 MiB per microVM
Table 20 — MicroVM efficiency

6.18 Worked example — checklist

Item✔
Isolation need assessed✔
Runtime chosen per workload✔
Node patching plan✔
Licensing checked✔
Table 21 — Before choosing

6.19 Worked example — migration path VM → container

StepDetail
Externalise config and stateEnv, S3, DB
Log to stdoutCollector-friendly
Containerise with multi-stage buildSmall image
Run on EKS with same health checksParity
Decommission VMsCost saving
Table 22 — Typical replatform

6.20 Worked example — "lift and shift" into containers

RiskMitigation
App writes local filesVolumes or S3
Background cron inside app VMKubernetes CronJobs
Hard-coded hostnamesService discovery
Table 23 — Containers expose hidden VM assumptions

6.21 Worked example — observability differences

SignalContainersVMs
Host metricsNode exporter per nodePer VM agent
App logsstdout → Fluent BitFiles → agent
Lifecycle eventsKubernetes eventsEC2 state changes
Table 24 — Different telemetry sources

6.22 Worked example — security scanning scope

TargetContainersVMs
Image/AMI CVEsImage scanning (ECR/Inspector)AMI scanning
RuntimeGuardDuty EKS runtimeGuardDuty EC2 runtime
Table 25 — Both need coverage

6.23 Worked example — density risk

RiskMitigation
Noisy neighbour on shared nodeRequests/limits, QoS classes, topology spread
Node failure takes many podsReplicas across nodes/AZs, PDBs
Table 26 — Density needs discipline

6.24 Worked example — hybrid estate map

WorkloadRuntime
60 Java servicesEKS containers
12 partner jobsECS Fargate
200 event functionsLambda
3 legacy appsEC2 VMs
1 Windows toolEC2 Windows
Table 27 — Most estates mix runtimes

6.25 Worked example — exam-style comparison questions

QuestionAnswer
Which has its own kernel?VM
Which packs more per host?Containers
Which isolates untrusted tenants best?VMs/microVMs
Table 28 — Quick recall

6.26 Worked example — interview follow-up

Follow-upAnswer
"Is Docker a VM?"No — it manages isolated processes on the host kernel
"Why is Fargate more isolated than EKS on EC2?"Each task runs in its own microVM
Table 29 — Common probes

7Common Problems & Mistakes

MistakeFix
Assuming VM-level isolationAdd sandboxes/microVMs
Ignoring kernel patchingNode AMI pipeline
Over-isolating trusted appsContainers are fine
Table 30 — Mistakes and fixes

The most common container mistake is treating a container as if it were a VM-strength security boundary. Teams run tenant code or third-party plugins in shared pods and assume namespaces will hold; for untrusted workloads use microVMs or sandboxed runtimes instead. The second is forgetting that containers moved kernel patching rather than removing it: if nobody owns node AMI updates, a kernel CVE stays open on every node regardless of how clean the image scans are. The opposite error also happens: putting each trusted internal service in its own VM or Fargate task for isolation it does not need, which multiplies cost and slows scaling. Match isolation to the trust level of the code, and write that rule down per workload class.

8Performance & Production Considerations

ConsiderationPractice
Node sizingBin-packing efficiency
Cold startsImage size, caching
Isolation overheadMeasure sandboxes
Table 31 — Operating runtimes

Container efficiency depends on bin-packing, so size nodes and pod requests deliberately. Requests set too high waste capacity; set too low, pods are throttled or evicted under load. For Java, set memory limits that cover heap, metaspace, thread stacks and direct buffers, and let the JVM size its heap as a percentage of the limit. Scale-out speed depends on image size and caching: small JRE base images, layered jars and images pre-pulled on new nodes keep it fast. Sandboxed runtimes are not free, so measure gVisor or Kata overhead on the real workload, especially syscall-heavy I/O, before mandating them. Finally, make node replacement routine, so that kernel patching and AMI updates never become emergency work.

9Architecture & Design Considerations

GuidelineDetail
Match isolation to trustRisk-based
Containers on VMs is normalLayers
Serverless for untrusted burstsMicroVMs
Table 32 — Design guidance

10Interview Questions & Answers

Q1BasicConcept

Main difference between containers and VMs?

The isolation boundary is different. A virtual machine virtualises hardware: a hypervisor such as Nitro or KVM gives each VM virtual CPUs, memory and devices, and each VM boots its own operating system kernel. A container virtualises the operating system: containers are ordinary processes on one shared host kernel, isolated by namespaces, which control what they can see, and cgroups, which limit what they can use. Everything else follows. Containers start in milliseconds to seconds, images are megabytes rather than gigabytes and dozens fit on a host, but a kernel flaw affects them all. VMs are heavier and slower, but give stronger isolation and can run different kernels, including Windows.

Q2BasicConcept

Which starts faster?

Containers start much faster, typically in milliseconds to a few seconds, while a new VM takes tens of seconds to minutes. Starting a container only creates namespaces and cgroups and launches a process on a kernel that is already running; booting a VM involves firmware, a guest kernel, init and agents. For scaling, what users feel is time to serve traffic. In the note's figures, a new pod on an existing node served in 5 to 10 seconds for Java with CDS, mostly JVM startup, while a new EC2 instance took 60 to 90 seconds. A pod that needs a new node pays the VM cost as well, which is why spare node capacity matters.

Q3IntermediateInternals

Why are containers less isolated?

Because all containers on a host share one kernel, and the kernel is a very large attack surface. Namespaces and cgroups are kernel features, so isolation is only as strong as the kernel code enforcing it. A container calls the host kernel directly through hundreds of system calls, and a vulnerability in any of them, or in namespace handling, can let a process escape and reach every other container on the node. Misconfiguration widens the gap: privileged containers, host mounts, broad capabilities or running as root. A VM talks to a much smaller hypervisor interface instead. Mitigations include seccomp profiles, dropped capabilities, non-root users, read-only filesystems and sandboxed runtimes.

Q4IntermediateConcept

What is a microVM?

A microVM is a minimal virtual machine designed to start almost as fast as a container while keeping hardware-level isolation. Firecracker, the open-source virtual machine monitor that AWS built on KVM, is the main example. It removes legacy devices and emulation and exposes only a few virtio devices, so a microVM boots in about 125 milliseconds with under 5 MiB of memory overhead. Each microVM runs its own small guest kernel, so one tenant's kernel exploit does not reach another tenant. AWS runs every Lambda execution environment and each Fargate task in its own Firecracker microVM, which is how it can safely place many customers' workloads on the same physical servers.

Q5Senior EngineerInternals

What are gVisor and Kata?

gVisor and Kata Containers are sandboxed container runtimes that add an extra isolation layer while keeping the normal container interface. gVisor, through its runsc runtime, runs a user-space kernel written in Go that intercepts the container's system calls and implements them itself, so the application never talks directly to the host kernel; it costs some performance on syscall-heavy and I/O-heavy workloads. Kata Containers runs each pod inside a lightweight VM with its own guest kernel, giving hardware-backed isolation, but needs bare-metal or nested virtualisation support. In Kubernetes you select either through a RuntimeClass, so only untrusted workloads, such as a renderer for user-supplied files, pay the overhead.

Q6Senior EngineerTricky

How is the kernel patched for containers?

By patching or replacing the host nodes, not by rebuilding container images. An image contains only userland, libraries and the application; the kernel belongs to the node, so a kernel CVE is fixed at the node layer. On EKS this usually means publishing a new node AMI, such as an updated Bottlerocket or EKS-optimised image, and letting Karpenter drift or managed node group updates replace nodes gradually, with pod disruption budgets keeping services available. ShopNow handled a namespace-related kernel CVE exactly this way. Image rebuilds are still needed for library and base-image vulnerabilities, so patching responsibility splits between the platform team for nodes and service teams for their images.

Q7Technical ArchitectInternals

Why run containers inside VMs in the cloud?

In the public cloud the hypervisor is the isolation boundary between customers, and containers add density and fast deployment inside one customer's boundary. A provider cannot let two customers share a kernel, because a single kernel exploit would expose the other, so customer workloads always sit inside VMs on Nitro, either EC2 instances or Firecracker microVMs. Inside your own nodes, containers pack many trusted services onto each VM, giving high utilisation and quick scaling. ShopNow moved 40 services from 40 small VMs averaging 12% CPU to containers on 14 larger nodes at 55%, cutting compute cost by 48%. You get both layers: VM isolation between tenants and container efficiency within one.

Q8Technical ArchitectTrade-off

When choose Fargate over EC2 nodes?

Choose Fargate when you want each task or pod isolated in its own microVM and do not want to manage nodes at all: no AMIs, patching, node scaling or bin-packing decisions. It suits a modest number of services, partner jobs or workloads that need stronger isolation, like ShopNow's partner sync jobs. Choose EC2 nodes when you run many services at scale: bin-packing on EC2, especially with Graviton and Spot, is cheaper, roughly ₹2,900 against ₹6,800 per replica in the note's comparison, and pods start faster on existing nodes. EC2 nodes also support DaemonSets, GPUs, custom kernels and privileged agents, which Fargate does not. Many estates sensibly use both.

Q9Solution ArchitectScenario

How would you run untrusted customer code?

Never in plain containers sharing a kernel with other tenants or with your own services. Put each execution inside a hardware-isolated boundary: Lambda or Fargate, which run on Firecracker microVMs, or a Kubernetes RuntimeClass using Kata Containers or gVisor on dedicated, tainted nodes. Then add defence in depth, because the sandbox is only one layer: no network egress by default, no credentials or a minimal IAM role per execution, CPU, memory and time limits, read-only filesystems, and inputs and outputs passed through queues or S3. Make each environment disposable after a single job. ShopNow runs seller-uploaded image transformations in Lambda, so any exploit stays inside a short-lived microVM.

Q10Solution ArchitectTrade-off

When stick with VMs?

Stay with VMs when the workload needs something containers cannot provide cleanly. Examples are a different kernel or operating system, such as Windows-specific stacks; legacy software that expects a full OS with init systems, local state, cron jobs and agents; vendor software certified only on VMs; licensing counted per VM or per core, where containers would force dedicated nodes anyway; and isolation requirements a shared kernel cannot meet. ShopNow keeps a legacy Windows reporting tool on an EC2 Windows instance and three legacy applications on EC2. Moving such workloads into containers often costs more than it saves, so revisit the decision when the software is replaced or the vendor supports containers.

Newsletter

Get new tutorials every week

New ArchitectMind tutorials and interview questions, once a week. No spam, unsubscribe anytime.

Almost done! Check your inbox and click the confirmation link to complete your subscription.
Keep going in Book 9

Cloud, Containers, DevOps & Production Architecture

Volume I · Topic 1.1

What Is Cloud Computing?

Cloud Computing & Cloud Architecture Fundamentals

Volume I · Topic 1.2

Cloud Service Models

Cloud Computing & Cloud Architecture Fundamentals

Volume I · Topic 1.3

Cloud Deployment Models

Cloud Computing & Cloud Architecture Fundamentals

Volume II · Topic 1.1

Regions

AWS & Cloud Services

Volume II · Topic 1.2

Availability Zones

AWS & Cloud Services

Volume II · Topic 1.3

Edge Locations

AWS & Cloud Services

Volume III · Topic 1.1

Containers

Containers & Kubernetes

Volume III · Topic 1.3

Container Lifecycle

Containers & Kubernetes

Volume IV · Topic 1.1

IaC Fundamentals

Infrastructure as Code & Platform Engineering

Volume IV · Topic 1.2

Declarative vs Imperative

Infrastructure as Code & Platform Engineering

Volume IV · Topic 1.3

Immutable Infrastructure

Infrastructure as Code & Platform Engineering

Volume V · Topic 1.1

DevOps

CI/CD & DevOps Architecture

Volume V · Topic 1.2

Development + Operations

CI/CD & DevOps Architecture

Volume V · Topic 1.3

Continuous Integration

CI/CD & DevOps Architecture

Volume VI · Topic 1.1

Production Readiness Review

Production Architecture & Reliability Engineering

Volume VI · Topic 1.2

Operational Requirements

Production Architecture & Reliability Engineering

Volume VI · Topic 1.3

Capacity

Production Architecture & Reliability Engineering

Volume VII · Topic 1.1

Cloud-Native Principles

Cloud-Native Architecture & Multi-Region Systems

Volume VII · Topic 1.2

Twelve-Factor Applications

Cloud-Native Architecture & Multi-Region Systems

Volume VII · Topic 1.3

Immutable Infrastructure

Cloud-Native Architecture & Multi-Region Systems

Volume VIII · Topic 1.1

Architecture Drivers

Cloud Architecture Design, Cost & Migration

Volume VIII · Topic 1.2

Cloud Service Selection

Cloud Architecture Design, Cost & Migration

Volume VIII · Topic 1.3

Managed vs Self-Managed

Cloud Architecture Design, Cost & Migration