Kubernetes Foundations

Containers vs Virtual Machines: The Infrastructure View

Kubernetes runs containers, not traditional virtual machines. To understand Kubernetes, you need to understand what containers are, what virtual machines are, and why they solve different infrastructure problems.

What this lesson covers

This lesson explains the difference between virtual machines and containers from an infrastructure perspective.

By the end, you should understand:

  • What a virtual machine is
  • What a container is
  • Why containers start faster than virtual machines
  • Why containers are not the same as tiny VMs
  • Why Kubernetes is built around containers
  • How to run and inspect a simple container locally
Field note: The goal is not to decide that containers are better than virtual machines. The goal is to understand when each model makes sense.

The short version

A virtual machine virtualizes a full computer. It has its own operating system, kernel, services, patches, users, and processes.

A container packages an application process with the files and dependencies it needs to run. It shares the host operating system kernel.

That difference matters because Kubernetes manages containers as application workloads. It does not manage each workload like a full server.

What is a virtual machine?

A virtual machine is a software-defined computer running on top of a physical host or cloud hypervisor.

A VM usually includes:

  • A virtual CPU allocation
  • Virtual memory
  • Virtual disks
  • Virtual network adapters
  • A full guest operating system
  • System services
  • Applications running inside that guest operating system

If you run ten virtual machines, you are generally running ten guest operating systems.

This gives strong isolation and familiar server management boundaries, but it also adds overhead. Each VM needs operating system patching, configuration, monitoring, disk space, and security management.

What is a container?

A container is a packaged and isolated application process.

A container usually includes:

  • The application
  • Runtime dependencies
  • Libraries
  • Configuration defaults
  • A filesystem view built from a container image

A container does not boot a full guest operating system the way a virtual machine does. It runs as a process on the host and shares the host kernel.

This is why containers usually start quickly and use fewer resources than full virtual machines.

Field note: A container is not a tiny VM. It is closer to a packaged process with isolation around it.

Side-by-side comparison

Virtual Machine:
Physical host or cloud host
  Hypervisor
    VM
      Guest operating system
        Application

Container:
Physical host or cloud host
  Host operating system
    Container runtime
      Containerized application process

This is the core difference. A VM carries a full guest operating system. A container shares the host kernel and runs as an isolated process.

Why this matters for Kubernetes

Kubernetes is designed to schedule and manage containers across a cluster of machines.

Instead of thinking:

I need to log into a server, install the app, configure services, and manage the OS.

Kubernetes pushes you toward thinking:

I need to define the workload, the image, the configuration, the number of replicas, the network exposure, and the health checks.

That shift is one of the biggest mental changes for infrastructure people learning Kubernetes.

Containers are built from images

A container image is the packaged template used to create containers.

You can think of it like this:

  • Image: the packaged artifact
  • Container: a running instance of that image

If you have used virtual machines, it may be tempting to compare an image to a VM template. That comparison is useful at a high level, but not perfect.

A VM template usually represents a full machine. A container image usually represents an application and its runtime dependencies.

Containers should be disposable

In traditional server operations, a server may live for months or years. People log into it, patch it, change configuration, install tools, and troubleshoot directly on the box.

In a container model, the running container should be disposable. If you need to change the application, you build a new image and deploy a new container.

You generally should not treat a running container as something to manually nurse back to health.

Field note: If a container is broken, the normal answer is often to fix the image, configuration, or deployment definition — not to remote into the container and hand-edit it.

What containers are good at

Containers are useful when you need application packaging and repeatability.

  • Packaging an application with its dependencies
  • Running the same image across environments
  • Starting workloads quickly
  • Scaling multiple copies of an application
  • Supporting automated deployment pipelines
  • Reducing environment drift between development, test, and production

What virtual machines are good at

Virtual machines are still useful. Kubernetes does not make them irrelevant.

  • Strong operating system boundaries
  • Running different operating systems on the same host
  • Traditional server workloads
  • Legacy applications that expect a full server
  • Domain controllers, management servers, and infrastructure appliances
  • Workloads that are not designed for container packaging

In many production environments, Kubernetes itself runs on virtual machines. The nodes are VMs, and the workloads running on those nodes are containers.

Security differences

Virtual machines and containers both provide isolation, but they do not isolate in the same way.

VMs have a full guest operating system boundary. Containers share the host kernel, so the security model depends heavily on the container runtime, Linux kernel features, host hardening, image security, workload permissions, and Kubernetes policy.

This does not mean containers are unsafe. It means they require a different security mindset.

For Kubernetes, container security eventually includes:

  • Using trusted images
  • Scanning images for vulnerabilities
  • Running containers as non-root where possible
  • Limiting container privileges
  • Using read-only filesystems where appropriate
  • Restricting host access
  • Using Kubernetes RBAC and admission controls
  • Applying network policies
Field note: Do not assume container isolation is the same as VM isolation. Containers are powerful, but the shared-kernel model matters for security.

Hands-on lab: run and inspect a container

This lab assumes you completed the local lab setup and Docker Desktop is running.

First, confirm Docker is working:

docker version
docker ps

Now run a simple nginx container:

docker run --name nginx-container-lab -d -p 8080:80 nginx:latest

What this command does

  • docker run starts a new container.
  • --name nginx-container-lab gives the container a friendly name.
  • -d runs it in the background.
  • -p 8080:80 maps port 8080 on your machine to port 80 inside the container.
  • nginx:latest tells Docker which image to use.

Open a browser and go to:

http://localhost:8080

You should see the default nginx welcome page.

Inspect the running container

List running containers:

docker ps

View logs from the container:

docker logs nginx-container-lab

Inspect details about the container:

docker inspect nginx-container-lab

The inspect output is detailed. Do not try to memorize it. Notice that Docker knows the container image, network settings, port mappings, mounts, status, and runtime configuration.

Exec into the container

You can open a shell inside the running container:

docker exec -it nginx-container-lab /bin/sh

Once inside, run:

hostname
ps
ls

Then exit:

exit

This is useful for learning, but remember the field note from earlier: containers should be disposable. Avoid building operational habits around manually fixing containers from the inside.

Stop and remove the container

Stop the container:

docker stop nginx-container-lab

Remove it:

docker rm nginx-container-lab

Confirm it is gone:

docker ps
docker ps -a

What you just proved

In this lab, you:

  • Started a container from an image
  • Mapped a local port to a container port
  • Viewed the running container
  • Checked container logs
  • Inspected container details
  • Opened a shell inside the container
  • Stopped and removed the container

This is the basic unit Kubernetes builds on. Kubernetes does not remove the container model. It adds orchestration, scheduling, health checks, networking, configuration, and desired state management around it.

Bottom line: Virtual machines package servers. Containers package application processes. Kubernetes is built around managing those containerized application processes across a cluster.

Check your understanding

Use these questions to test whether the container and VM concepts made sense.

  1. What does a virtual machine virtualize?
  2. What does a container package?
  3. Why do containers usually start faster than virtual machines?
  4. Is a container the same thing as a tiny VM?
  5. What is the difference between a container image and a running container?
  6. Why should containers generally be treated as disposable?
  7. Why does Kubernetes care about containers?
  8. What does the -p 8080:80 part of the Docker command do?
  9. What command lists running containers?
  10. What command shows logs from a container?
  11. Why is container isolation not exactly the same as VM isolation?
  12. In many production environments, what are Kubernetes nodes often running on?
Answer key
  1. A virtual machine virtualizes a full computer, including virtual hardware and a guest operating system.
  2. A container packages an application process with the files and dependencies it needs to run.
  3. Containers usually start faster because they do not boot a full guest operating system.
  4. No. A container is better understood as an isolated packaged process, not a tiny VM.
  5. An image is the packaged template. A container is a running instance of that image.
  6. Because changes should usually come from rebuilding the image or changing the deployment configuration, not manually editing a running container.
  7. Kubernetes schedules, runs, monitors, exposes, and manages containerized workloads.
  8. It maps port 8080 on your machine to port 80 inside the container.
  9. docker ps.
  10. docker logs <container-name>.
  11. Containers share the host kernel, while VMs have a separate guest operating system boundary.
  12. They are often running on virtual machines provided by a cloud or virtualization platform.
← Previous: Local Lab Setup Series index Next: kubectl Basics →