Kubernetes Overview · Part 0707

Docker Deprecation in KubernetesIs Docker really deprecated?

What does “Docker is deprecated in Kubernetes” actually mean? Kubernetes only removed the built-in dockershim. CRI, containerd, cri-dockerd, and why Docker images and Docker skills are still fully relevant, explained simply.

Translated from the original Bangla with AI. If anything reads oddly, the Bangla version is the reference.

Before and after dockershim removal: kubelet went through dockershim and Docker Engine to containerd; since Kubernetes v1.24 it talks to containerd directly through CRI, while Docker still builds the images
FIG. 07 Before: kubelet → dockershim → Docker Engine → containerd. Since v1.24: kubelet → CRI → containerd. Docker still builds the images.

A common confusion comes up when you are learning Docker and Kubernetes.

We often hear:

Docker is deprecated in Kubernetes.

Hearing this, many people assume Docker is no longer used, that there is no point learning Docker, or that Kubernetes no longer supports Docker images.

But that is not the reality at all.

Docker the technology has not been deprecated. Kubernetes only removed its built-in runtime integration with Docker Engine, that is, dockershim.

Docker is still a very important technology for building, testing, containerizing and running applications locally.

What changed is mainly the architecture of how Kubernetes executes containers internally.

Let's understand the whole thing step by step.

1. "Docker is deprecated" — Where did this confusion come from?

Say you started learning Kubernetes after learning Docker.

In a tutorial, you read:

Kubernetes no longer supports Docker as its built-in container runtime.

Naturally, a question comes up:

If Kubernetes does not use Docker, why learn Docker at all?

To answer this, we need to separate two things.

Docker as a Development Platform

Here, Docker is used to:

  • Containerize applications
  • Build Docker images
  • Set up a local development environment
  • Test applications
  • Run multiple services with Docker Compose
  • Push container images to a registry

Docker Engine as a Kubernetes Container Runtime

This is a completely different matter.

Kubernetes used to rely on a special component, called dockershim, to integrate directly with Docker Engine.

Kubernetes removed that built-in integration.

In other words:

Docker Development Tools       → Still Supported ✅

Docker Images                  → Still Supported ✅

Docker CLI                     → Still Useful ✅

Docker Compose                 → Still Useful ✅

Built-in Kubernetes Dockershim → Removed ❌

So learning Docker is still fully relevant.

2. What is Docker actually made of?

Docker is not just a container runtime.

It is a complete containerization platform in which several components work together.

Docker Platform
│
├── Docker CLI
│
├── Docker API
│
├── Docker Engine (dockerd)
│
├── BuildKit / Buildx
│
├── Docker Images
│
├── Container Registry Integration
│
├── Volumes
│
├── Networking
│
├── Authentication
│
├── Security
│
└── Container Runtime
    │
    ├── containerd
    │
    ├── containerd-shim
    │
    └── runc

Each of Docker's components has its own responsibility.

ComponentMain job
Docker CLIRuns Docker commands from the terminal
Docker APICommunication with Docker Engine
Docker EngineManages Docker containers, images and resources
BuildKitBuilds Docker images
Docker VolumesManages persistent data
Docker NetworkingContainer communication
AuthenticationRegistry access and credentials management
SecurityContainer isolation and permissions
containerdContainer runtime lifecycle management
runcCreates and starts the actual container process

Kubernetes does not need this whole Docker platform.

What Kubernetes mainly wants is a container runtime that can run containers through Kubernetes' standardized interface.

This is where containerd becomes important.

3. What does Kubernetes actually need?

Kubernetes is a container orchestration platform.

Its job is not just to run containers.

Kubernetes manages much more:

  • Application deployment
  • Container scheduling
  • Scaling
  • Service discovery
  • Load balancing
  • Self-healing
  • Rolling updates
  • Resource allocation

But Kubernetes does not create Linux container processes directly.

For that, Kubernetes uses a container runtime.

For example:

  • containerd
  • CRI-O
  • Docker Engine, through the external cri-dockerd adapter

Kubernetes container runtime architecture

Kubernetes Cluster
        │
        ▼
    API Server
        │
        ▼
     Kubelet
        │
        ▼
Container Runtime Interface (CRI)
        │
        ▼
     containerd
        │
        ▼
  containerd-shim
        │
        ▼
       runc
        │
        ▼
   Linux Kernel
        │
        ▼
 Running Containers

One thing needs to be clear here.

Kubernetes' kubelet is the agent running on every node. It talks to the container runtime according to each Pod's desired state.

For that communication, Kubernetes uses the Container Runtime Interface (CRI).

What is CRI?

CRI stands for:

Container Runtime Interface

It is a standardized interface through which Kubernetes can talk to different compatible container runtimes.

Say Kubernetes is saying:

A container needs to be started for this Pod.

Kubernetes does not need to know the implementation details of how the container runtime creates the process internally.

As long as there is a CRI-compatible runtime, Kubernetes can request standardized operations.

A simple example:

Kubernetes
     │
     ▼
    CRI
     │
     ├── containerd
     │
     └── CRI-O

containerd usually provides CRI integration, but it has to be enabled and properly configured to work with Kubernetes.

4. How did Kubernetes use Docker before?

In Kubernetes' earlier architecture, Docker Engine was a common container runtime.

But there was a technical problem.

Docker Engine did not implement Kubernetes' CRI itself.

So an adapter was needed for communication between Kubernetes' kubelet and Docker Engine.

That adapter was called dockershim.

The old Kubernetes architecture

Kubernetes
    │
    ▼
  Kubelet
    │
    ▼
 Dockershim
    │
    ▼
Docker Engine
    │
    ▼
 containerd
    │
    ▼
containerd-shim
    │
    ▼
   runc
    │
    ▼
Linux Container

Notice that Docker Engine itself uses containerd internally.

So starting a container from Kubernetes meant maintaining an extra integration layer.

The architecture worked, but it created an additional maintenance responsibility for the Kubernetes maintainers.

That is because Kubernetes had to maintain Docker-specific integration code.

5. Why did Kubernetes remove dockershim?

The Kubernetes team mainly wanted to simplify the architecture.

Since containerd can work with Kubernetes through CRI on its own, there is no need to reach containerd through Docker Engine.

In other words, before:

Kubernetes
    ↓
 Kubelet
    ↓
 Dockershim
    ↓
Docker Engine
    ↓
 containerd
    ↓
   runc
    ↓
 Container

And now, in a typical containerd-based setup:

Kubernetes
    ↓
 Kubelet
    ↓
   CRI
    ↓
 containerd
    ↓
containerd-shim
    ↓
   runc
    ↓
 Container

This brings a few benefits.

1. Simpler Architecture

No extra Docker-specific integration layer is needed.

2. Lower Maintenance Overhead

Kubernetes maintainers no longer have to maintain the built-in dockershim.

3. Standardized Runtime Integration

Any CRI-compatible runtime can be used.

4. Reduced Runtime Overhead

With the Docker Engine integration layer gone, the system architecture is simpler and some operational overhead can go down.

That does not mean performance will automatically improve a lot for every workload, though.

6. The actual Docker deprecation timeline

This change did not happen overnight.

The Kubernetes community prepared developers and administrators for the migration well in advance.

Kubernetes VersionWhat changed
v1.20 — December 2020Built-in dockershim deprecation announced
v1.21–v1.23Dockershim still available, but deprecated
v1.24 — May 2022Built-in dockershim removed
v1.24+Kubernetes needs a CRI-compatible runtime or an external Docker adapter

In other words, since the Kubernetes v1.24 release in May 2022, the built-in dockershim is no longer part of Kubernetes.

This is not a deprecation of the Docker project.

Official Kubernetes documentation:

https://kubernetes.io/blog/2022/02/17/dockershim-faq/

7. Do Docker images still work in Kubernetes?

Yes, absolutely.

This is the most important part of the whole topic.

Container images built with Docker can be used in Kubernetes.

That is because the modern container ecosystem uses standardized image formats.

The key standard here is:

OCI — Open Container Initiative

OCI defines the container image format and runtime specifications.

As a result, a compatible image can be executed by different container runtimes.

Example: building an image with Docker

Say you have a Python application.

Dockerfile:

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["python", "app.py"]

Now build the image with Docker:

docker build -t my-python-app:1.0 .

To test it locally:

docker run --rm my-python-app:1.0

Now you can push the image to a registry.

Example:

docker tag my-python-app:1.0 \
  registry.example.com/my-python-app:1.0

docker push registry.example.com/my-python-app:1.0

The same image can now be used in a Kubernetes Deployment.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: python-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: python-app
  template:
    metadata:
      labels:
        app: python-app
    spec:
      containers:
        - name: python-app
          image: registry.example.com/my-python-app:1.0

Then:

kubectl apply -f deployment.yaml

Kubernetes will pull the image and run the container using its configured container runtime.

For a private registry, you need to configure the appropriate image pull credentials in Kubernetes.

Complete workflow

Developer Machine
       │
       ▼
   Source Code
       │
       ▼
    Dockerfile
       │
       ▼
   docker build
       │
       ▼
 Container Image
       │
       ▼
 Container Registry
       │
       ▼
 Kubernetes Cluster
       │
       ▼
      Kubelet
       │
       ▼
       CRI
       │
       ▼
    containerd
       │
       ▼
      runc
       │
       ▼
  Running Application

Here, Docker is used to build the application.

And in the Kubernetes environment, containerd is used to run it.

Important: building an image on a developer machine does not mean a remote Kubernetes cluster can see it. You have to push the image to a registry or use a local, cluster-specific image loading mechanism.

8. So why should you still learn Docker?

Say you are a software developer, data engineer or AI engineer.

You have a Python FastAPI application.

Now you want to deploy it to Kubernetes.

Even before learning Kubernetes, you need to understand:

  • How to write a Dockerfile
  • How a Docker image is built
  • How a container runs
  • How to configure environment variables
  • How port mapping works
  • How to use volumes
  • How to view container logs
  • How an image registry works

Docker is very convenient for learning these fundamental concepts.

A real development workflow

Development
    │
    ▼
Write Python Application
    │
    ▼
Create Dockerfile
    │
    ▼
Build Docker Image
    │
    ▼
Run Local Container
    │
    ▼
Test Application
    │
    ▼
Push Image to Registry
    │
    ▼
Deploy to Kubernetes

This workflow is still completely valid.

The removal of dockershim from Kubernetes does not require any change to a Docker-based development workflow.

9. How do you work with containerd when Docker isn't there?

Say you are working on a Linux server or a Kubernetes node.

Docker Engine is not installed there.

But containerd is.

If you want to use Docker-like commands, you can use nerdctl.

nerdctl is a Docker-compatible CLI for containerd.

Docker CLI example

docker run nginx

The nerdctl equivalent

nerdctl run nginx

Some more examples:

Docker Commandnerdctl Equivalent
docker psnerdctl ps
docker imagesnerdctl images
docker pull nginxnerdctl pull nginx
docker run nginxnerdctl run nginx
docker logs nginxnerdctl logs nginx
docker stop nginxnerdctl stop nginx

Many common commands look the same, but Docker and nerdctl do not have identical features.

And nerdctl may need to be installed and configured separately.

What is containerd's native CLI?

containerd's native low-level CLI is:

ctr

Example:

sudo ctr containers list

To inspect the Kubernetes namespace:

sudo ctr -n k8s.io containers list

For troubleshooting Kubernetes-managed containers, though, crictl is usually more appropriate.

Example:

sudo crictl ps

And for managing Kubernetes workloads, kubectl is the right approach.

10. Docker vs containerd — Comparison

TopicDockercontainerd
Technology TypeFull Container PlatformContainer Runtime
Main PurposeBuild, develop, run and manage containersContainer lifecycle management
Developer FriendlyYesMore infrastructure-focused
Image BuildingBuildKit / Buildx supportNot its primary responsibility
Container ExecutionYesYes
Kubernetes CRIDocker Engine does not implement CRI itselfCRI integration supported
Kubernetes IntegrationNeeds the cri-dockerd adapterDirect CRI integration
Common CLIdockerctr, nerdctl
Local DevelopmentVery commonPossible
Production RuntimeYesVery common
Dockerfile SupportYesPossible with nerdctl/BuildKit-based workflows
Kubernetes Node RuntimePossible with an external adapterDirectly supported

The most important difference:

Docker is a broader container development and management platform.

containerd is a lower-level container runtime.

Docker itself uses containerd internally.

11. Can Docker Engine not be used in Kubernetes at all?

A technical detail matters a lot here.

Many people say:

Kubernetes no longer supports Docker Engine.

But that statement is not entirely accurate.

The built-in dockershim has been removed from Kubernetes. But Docker Engine can still be integrated with Kubernetes using an external CRI adapter.

That adapter is called:

cri-dockerd

It is an external replacement for Kubernetes' old built-in dockershim.

Docker Engine with cri-dockerd

Kubernetes
    │
    ▼
  Kubelet
    │
    ▼
    CRI
    │
    ▼
 cri-dockerd
    │
    ▼
Docker Engine
    │
    ▼
 containerd
    │
    ▼
containerd-shim
    │
    ▼
   runc
    │
    ▼
 Container

In other words, Kubernetes can still use Docker Engine, as long as the right adapter is installed and configured.

For a typical modern Kubernetes cluster, though, using containerd or another CRI-compatible runtime directly is more straightforward.

Official Kubernetes documentation:

https://kubernetes.io/docs/setup/production-environment/container-runtimes/

12. How do you check which runtime a Kubernetes node uses?

Say you maintain a Kubernetes cluster.

You want to know which container runtime the cluster's nodes are using.

Run this command:

kubectl get nodes -o wide

The runtime can appear in the CONTAINER-RUNTIME column of the output.

For more detail:

kubectl describe node <node-name>

Here you can check the Container Runtime Version field.

To see the runtime version of all nodes at once:

kubectl get nodes \
  -o custom-columns=NAME:.metadata.name,RUNTIME:.status.nodeInfo.containerRuntimeVersion

Example output:

NAME       RUNTIME
worker-1   containerd://2.x.x
worker-2   containerd://2.x.x
worker-3   containerd://2.x.x

In this example, the worker nodes use containerd.

Runtime-specific troubleshooting

If the node runs containerd:

sudo crictl ps

To see images:

sudo crictl images

To see runtime-level information about Pods:

sudo crictl pods

Lifecycle operations for Kubernetes workloads should generally be done with kubectl, though.

That is because runtime-level changes can conflict with Kubernetes' desired state.

13. Docker vs Kubernetes — A simple real-life analogy

Now let's understand the whole thing with a real-life example.

Imagine Docker is a complete restaurant.

The restaurant has:

  • Menu
  • Waiter
  • Kitchen
  • Storage
  • Payment System
  • Delivery Service

We can compare the restaurant's kitchen to containerd.

Now, Kubernetes is a large food delivery and restaurant orchestration system.

Kubernetes' job is to distribute work across many restaurants or kitchens.

How many orders go to which kitchen, where there is capacity, where something is going wrong: Kubernetes manages all of that.

Kubernetes does not need its own menu, waiter or complete restaurant infrastructure.

What it needs is a kitchen interface through which it can send instructions to prepare food.

For container runtimes, that standardized interface is CRI.

Analogy architecture

                    Developer
                        │
                        ▼
                 Docker Restaurant
                        │
                  Build & Package
                        │
                        ▼
                 Container Image
                        │
                        ▼
                  Image Registry
                        │
                        ▼
                    Kubernetes
                        │
                 Workload Scheduling
                        │
                        ▼
                       CRI
                        │
                        ▼
                 containerd Kitchen
                        │
                        ▼
                 Running Container

Docker is still useful for preparing and packaging applications.

Kubernetes has simply made its own runtime integration more standardized.

14. Common misconceptions — True or false?

StatementCorrect?Explanation
Docker is dead❌ FalseDocker is still used as a container development platform
Docker images no longer work in Kubernetes❌ FalseOCI-compatible images are supported
Kubernetes removed built-in dockershim✅ TrueRemoved in Kubernetes v1.24
Kubernetes directly requires Docker Engine❌ FalseIt uses a CRI-compatible runtime
Kubernetes can use containerd✅ TrueA common runtime choice
Docker Engine can never work with Kubernetes❌ FalseIt can, with cri-dockerd
Docker is still useful for developers✅ TrueUseful for image building and local testing
nerdctl can work directly with containerd✅ TrueA Docker-like CLI
Kubernetes and Docker are the same❌ FalseOne is an orchestration platform, the other a container platform
Kubernetes can use CRI-O✅ TrueA CRI-compatible runtime

15. Full architecture — From Docker development to Kubernetes production

For a developer or AI engineer, understanding this full workflow is important.

                 DEVELOPER MACHINE
                        │
                        ▼
                   Source Code
                        │
                        ▼
                    Dockerfile
                        │
                        ▼
                 Docker BuildKit
                        │
                        ▼
                   Docker Image
                        │
                        ▼
                 Local Docker Test
                        │
                        ▼
                 Container Registry
                        │
                        │ Push / Pull Image
                        ▼
                 KUBERNETES CLUSTER
                        │
                        ▼
                    API Server
                        │
                        ▼
                    Scheduler
                        │
                        ▼
                    Worker Node
                        │
                        ▼
                      Kubelet
                        │
                        ▼
                        CRI
                        │
                        ▼
                    containerd
                        │
                        ▼
                  containerd-shim
                        │
                        ▼
                       runc
                        │
                        ▼
                   Linux Kernel
                        │
                        ▼
                  Running Container

In this architecture, Docker and Kubernetes are used together, but their responsibilities are different.

Docker helps create the image.

Kubernetes orchestrates the application.

containerd and runc help execute the container.

16. Final takeaway — What should we remember?

The whole topic can be summed up in a few key points.

Docker has not been deprecated

Docker is still relevant for containerized application development.

Kubernetes removed the built-in dockershim

Since Kubernetes v1.24, the built-in Docker Engine integration is gone.

Kubernetes uses CRI

Through CRI, Kubernetes talks to compatible container runtimes.

containerd can integrate with Kubernetes directly

With proper CRI configuration, Docker Engine is not needed as a middle layer.

Docker images work in Kubernetes

OCI-compatible, Docker-built images can be used in Kubernetes workloads.

Learning Docker still matters

Docker is an excellent learning platform for understanding container images, Dockerfiles, volumes, networking, registries and local testing.

Docker Engine is not banned from Kubernetes

If needed, Docker Engine can be integrated using the cri-dockerd adapter.

Official References

One-line summary

Docker is still important for building, testing and containerizing applications. Kubernetes only removed its built-in Docker Engine integration, because containers can be run directly with a CRI-compatible runtime such as containerd.

As an AI engineer, DevOps engineer or Kubernetes administrator, it is important to understand what both Docker and containerd do.

Docker teaches you how to containerize an application. And Kubernetes teaches you how to deploy, scale, monitor and manage those containerized applications on production infrastructure.

Was this guide helpful?

Search the archive

Press Esc to close