# Changing the Container Runtime on a Node from Docker Engine to containerd

LLMS index: [llms.txt](/llms.txt)

---

This task outlines the steps needed to update your container runtime to containerd from Docker. It
is applicable for cluster operators running Kubernetes 1.23 or earlier. This also covers an
example scenario for migrating from dockershim to containerd. Alternative container runtimes
can be picked from this [page](/docs/setup/production-environment/container-runtimes/).

## Before you begin

<div class="alert alert-secondary callout third-party-content" role="note"><strong>Note:</strong>&puncsp;This section links to third party projects that provide functionality required by Kubernetes. The Kubernetes project authors aren't responsible for these projects, which are listed alphabetically. To add a project to this list, read the <a href="/docs/contribute/style/content-guide/#third-party-content">content guide</a> before submitting a change. <a href="#third-party-content-disclaimer">More information.</a></div>


Install containerd. For more information see
[containerd's installation documentation](https://containerd.io/docs/getting-started/)
and for specific prerequisite follow
[the containerd guide](/docs/setup/production-environment/container-runtimes/#containerd).

## Drain the node 

```shell
kubectl drain <node-to-drain> --ignore-daemonsets
```

Replace `<node-to-drain>` with the name of your node you are draining.

## Stop the Docker daemon

```shell
systemctl stop kubelet
systemctl disable docker.service --now
```

## Install Containerd

Follow the [guide](/docs/setup/production-environment/container-runtimes/#containerd)
for detailed steps to install containerd.

<ul class="nav nav-tabs" id="tabs-tab-cri-containerd-installation" role="tablist"><li class="nav-item"><a data-bs-toggle="tab" class="nav-link active" href="#tabs-tab-cri-containerd-installation-0" role="tab" aria-controls="tabs-tab-cri-containerd-installation-0" aria-selected="true">Linux</a></li>
	  
		<li class="nav-item"><a data-bs-toggle="tab" class="nav-link" href="#tabs-tab-cri-containerd-installation-1" role="tab" aria-controls="tabs-tab-cri-containerd-installation-1">Windows (PowerShell)</a></li></ul>

<div class="tab-content" id="tabs-tab-cri-containerd-installation-content"><div class="tab-body tab-pane fadeshow active"
        id="tabs-tab-cri-containerd-installation-0" role="tabpanel" aria-labelledby="tabs-tab-cri-containerd-installation-0-tab" tabindex="tab-cri-containerd-installation"><ol>
<li>
<p>Install the <code>containerd.io</code> package from the official Docker repositories.
Instructions for setting up the Docker repository for your respective Linux distribution and
installing the <code>containerd.io</code> package can be found at
<a href="https://github.com/containerd/containerd/blob/main/docs/getting-started.md">Getting started with containerd</a>.</p>
</li>
<li>
<p>Configure containerd:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">sudo mkdir -p /etc/containerd
</span></span><span class="line"><span class="cl">containerd config default <span class="p">|</span> sudo tee /etc/containerd/config.toml
</span></span></code></pre></div></li>
<li>
<p>Restart containerd:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">sudo systemctl restart containerd
</span></span></code></pre></div></li>
</ol>
</div><div class="tab-body tab-pane fade"
        id="tabs-tab-cri-containerd-installation-1" role="tabpanel" aria-labelledby="tabs-tab-cri-containerd-installation-1-tab" tabindex="tab-cri-containerd-installation"><p>Start a Powershell session, set <code>$Version</code> to the desired version (ex: <code>$Version=&quot;1.4.3&quot;</code>), and
then run the following commands:</p>
<ol>
<li>
<p>Download containerd:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">curl</span><span class="p">.</span><span class="py">exe</span> <span class="n">-L</span> <span class="n">https</span><span class="err">:</span><span class="p">//</span><span class="n">github</span><span class="p">.</span><span class="n">com</span><span class="p">/</span><span class="n">containerd</span><span class="p">/</span><span class="n">containerd</span><span class="p">/</span><span class="n">releases</span><span class="p">/</span><span class="n">download</span><span class="p">/</span><span class="n">v</span><span class="nv">$Version</span><span class="p">/</span><span class="n">containerd</span><span class="p">-</span><span class="nv">$Version</span><span class="n">-windows-amd64</span><span class="p">.</span><span class="py">tar</span><span class="p">.</span><span class="py">gz</span> <span class="n">-o</span> <span class="nb">containerd-windows</span><span class="n">-amd64</span><span class="p">.</span><span class="py">tar</span><span class="p">.</span><span class="py">gz</span>
</span></span><span class="line"><span class="cl"><span class="n">tar</span><span class="p">.</span><span class="py">exe</span> <span class="n">xvf</span> <span class="p">.\</span><span class="nb">containerd-windows</span><span class="n">-amd64</span><span class="p">.</span><span class="py">tar</span><span class="p">.</span><span class="py">gz</span>
</span></span></code></pre></div></li>
<li>
<p>Extract and configure:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Copy-Item</span> <span class="n">-Path</span> <span class="s2">&#34;.\bin\&#34;</span> <span class="n">-Destination</span> <span class="s2">&#34;</span><span class="nv">$Env:ProgramFiles</span><span class="s2">\containerd&#34;</span> <span class="n">-Recurse</span> <span class="n">-Force</span>
</span></span><span class="line"><span class="cl"><span class="nb">cd </span><span class="nv">$Env:ProgramFiles</span><span class="p">\</span><span class="n">containerd</span><span class="p">\</span>
</span></span><span class="line"><span class="cl"><span class="p">.\</span><span class="n">containerd</span><span class="p">.</span><span class="py">exe</span> <span class="n">config</span> <span class="k">default</span> <span class="p">|</span> <span class="nb">Out-File</span> <span class="n">config</span><span class="p">.</span><span class="py">toml</span> <span class="n">-Encoding</span> <span class="n">ascii</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Review the configuration. Depending on setup you may want to adjust:</span>
</span></span><span class="line"><span class="cl"><span class="c"># - the sandbox_image (Kubernetes pause image)</span>
</span></span><span class="line"><span class="cl"><span class="c"># - cni bin_dir and conf_dir locations</span>
</span></span><span class="line"><span class="cl"><span class="nb">Get-Content</span> <span class="n">config</span><span class="p">.</span><span class="py">toml</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># (Optional - but highly recommended) Exclude containerd from Windows Defender Scans</span>
</span></span><span class="line"><span class="cl"><span class="nb">Add-MpPreference</span> <span class="n">-ExclusionProcess</span> <span class="s2">&#34;</span><span class="nv">$Env:ProgramFiles</span><span class="s2">\containerd\containerd.exe&#34;</span>
</span></span></code></pre></div></li>
<li>
<p>Start containerd:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="p">.\</span><span class="n">containerd</span><span class="p">.</span><span class="py">exe</span> <span class="p">-</span><span class="n">-register-service</span>
</span></span><span class="line"><span class="cl"><span class="nb">Start-Service</span> <span class="n">containerd</span>
</span></span></code></pre></div></li>
</ol>
</div></div>


## Configure the kubelet to use containerd as its container runtime

Edit the file `/var/lib/kubelet/kubeadm-flags.env` and add the containerd runtime to the flags;
`--container-runtime-endpoint=unix:///run/containerd/containerd.sock`.

Users using kubeadm should be aware that the kubeadm tool stores the host's CRI socket in the 

`/var/lib/kubelet/instance-config.yaml` file on each node. You can create this `/var/lib/kubelet/instance-config.yaml` file on the node.

The `/var/lib/kubelet/instance-config.yaml` file allows setting the `containerRuntimeEndpoint` parameter. 

You can set this parameter's value to the path of your chosen CRI socket (for example `unix:///run/containerd/containerd.sock`).

## Restart the kubelet

```shell
systemctl start kubelet
```

## Verify that the node is healthy

Run `kubectl get nodes -o wide` and containerd appears as the runtime for the node we just changed.

## Remove Docker Engine

<div class="alert alert-secondary callout third-party-content" role="note"><strong>Note:</strong>&puncsp;This section links to third party projects that provide functionality required by Kubernetes. The Kubernetes project authors aren't responsible for these projects, which are listed alphabetically. To add a project to this list, read the <a href="/docs/contribute/style/content-guide/#third-party-content">content guide</a> before submitting a change. <a href="#third-party-content-disclaimer">More information.</a></div>


If the node appears healthy, remove Docker.

<ul class="nav nav-tabs" id="tabs-tab-remove-docker-engine" role="tablist"><li class="nav-item"><a data-bs-toggle="tab" class="nav-link active" href="#tabs-tab-remove-docker-engine-0" role="tab" aria-controls="tabs-tab-remove-docker-engine-0" aria-selected="true">CentOS</a></li>
	  
		<li class="nav-item"><a data-bs-toggle="tab" class="nav-link" href="#tabs-tab-remove-docker-engine-1" role="tab" aria-controls="tabs-tab-remove-docker-engine-1">Debian</a></li>
		<li class="nav-item"><a data-bs-toggle="tab" class="nav-link" href="#tabs-tab-remove-docker-engine-2" role="tab" aria-controls="tabs-tab-remove-docker-engine-2">Fedora</a></li>
		<li class="nav-item"><a data-bs-toggle="tab" class="nav-link" href="#tabs-tab-remove-docker-engine-3" role="tab" aria-controls="tabs-tab-remove-docker-engine-3">Ubuntu</a></li></ul>

<div class="tab-content" id="tabs-tab-remove-docker-engine-content"><div class="tab-body tab-pane fadeshow active"
        id="tabs-tab-remove-docker-engine-0" role="tabpanel" aria-labelledby="tabs-tab-remove-docker-engine-0-tab" tabindex="tab-remove-docker-engine"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">sudo yum remove docker-ce docker-ce-cli
</span></span></code></pre></div></div><div class="tab-body tab-pane fade"
        id="tabs-tab-remove-docker-engine-1" role="tabpanel" aria-labelledby="tabs-tab-remove-docker-engine-1-tab" tabindex="tab-remove-docker-engine"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">sudo apt-get purge docker-ce docker-ce-cli
</span></span></code></pre></div></div><div class="tab-body tab-pane fade"
        id="tabs-tab-remove-docker-engine-2" role="tabpanel" aria-labelledby="tabs-tab-remove-docker-engine-2-tab" tabindex="tab-remove-docker-engine"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">sudo dnf remove docker-ce docker-ce-cli
</span></span></code></pre></div></div><div class="tab-body tab-pane fade"
        id="tabs-tab-remove-docker-engine-3" role="tabpanel" aria-labelledby="tabs-tab-remove-docker-engine-3-tab" tabindex="tab-remove-docker-engine"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">sudo apt-get purge docker-ce docker-ce-cli
</span></span></code></pre></div></div></div>


The preceding commands don't remove images, containers, volumes, or customized configuration files on your host.
To delete them, follow Docker's instructions to [Uninstall Docker Engine](https://docs.docker.com/engine/install/ubuntu/#uninstall-docker-engine).

<div class="alert alert-caution" role="note"><h4 class="alert-heading">Caution:</h4>Docker's instructions for uninstalling Docker Engine create a risk of deleting containerd. Be careful when executing commands.</div>


## Uncordon the node 

```shell
kubectl uncordon <node-to-uncordon>
```

Replace `<node-to-uncordon>` with the name of your node you previously drained.
