Ubuntu下替换docker—Containerd + nerdctl

安装过程需要使用root用户进行安装

1、安装containerd

apt update && sudo apt upgrade -y
apt install -y apt-transport-https ca-certificates curl

#配置http代理
export http_proxy="http://127.0.0.1:7897" 
export https_proxy="http://127.0.0.1:7897" 

# 添加GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 添加仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

apt update
apt install -y containerd.io

containerd --version

2、containerd配置

查看containerd的配置文件是否存在(/etc/containerd/config.toml),如果不存在则生成默认配置

mkdir -p /etc/containerd

# 生成默认配置并保存
containerd config default | sudo tee /etc/containerd/config.toml

为了让containerd与使用systemd作为cgroup驱动的主机(如Ubuntu)更好地集成,并确保Kubernetes的稳定性,需要 将SystemdCgroup设置为true

# 将配置文件中的 SystemdCgroup = false 替换为 true
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

变更sandbox的镜像地址

    [plugins.'io.containerd.cri.v1.images'.pinned_images]
      sandbox = 'registry.aliyuncs.com/google_containers/pause:3.10.1'

3、配置nerdctl

apt update
apt install -y uidmap rootlesskit

#根据containerd --version命令返回的版本下载对应的nerdctl的版本,下载https://github.com/containerd/nerdctl/releases
nerdctl-2.2.1-linux-amd64.tar.gz

# 解压并将二进制文件移动到系统路径
tar Cxzvf /usr/local/bin nerdctl-2.2.1-linux-amd64.tar.gz

nerdctl --version

4、安装CNI插件和BuildKit

如果你计划使用nerdctl来构建镜像或需要完整的容器网络功能,建议同时安装CNI插件和BuildKit。

安装 CNI 插件
CNI(容器网络接口)插件负责为容器创建网络,是运行容器所必需的。

# 下载最新版 CNI 插件,这里以 v1.6.2 为例
CNI_VERSION="1.9.0"
wget https://github.com/containernetworking/plugins/releases/download/v${CNI_VERSION}/cni-plugins-linux-amd64-v${CNI_VERSION}.tgz

# 创建目录并解压
mkdir -p /opt/cni/bin
tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v${CNI_VERSION}.tgz

安装BuildKit

# 下载最新版 BuildKit,以 v0.27.1 为例
BUILDKIT_VERSION="0.27.1"
wget https://github.com/moby/buildkit/releases/download/v${BUILDKIT_VERSION}/buildkit-v${BUILDKIT_VERSION}.linux-amd64.tar.gz

# 解压到系统目录
tar Cxzvf /usr buildkit-v${BUILDKIT_VERSION}.linux-amd64.tar.gz
/usr/bin/buildctl --version

配置systemd守护buildkit的服务

# 创建 systemd 服务文件
tee /etc/systemd/system/buildkit.service > /dev/null << EOF
[Unit]
Description=BuildKit
Documentation=https://github.com/moby/buildkit

[Service]
ExecStart=/usr/bin/buildkitd --oci-worker=false --containerd-worker=true

[Install]
WantedBy=multi-user.target
EOF

# 启动并设置开机自启
systemctl daemon-reload
systemctl start buildkit
systemctl enable buildkit

5、配置CNI插件

使用nerdctl创建网络,尽量不要手动写

nerdctl network create bridge

检查cni配置是否成功

grep -A 20 -B 5 "cni" /etc/containerd/config.toml

重新启动containerd服务

systemctl start buildkit

检查cni服务是否随containerd服务启动

journalctl -u containerd | grep -i cni

6、设置containerd代理

一定要注意有些docker的公开源已经变更,尽可能使用私有的轩辕镜像地址,下面的地址测试通过

#配置docker.io的镜像下载地址
mkdir -p /etc/containerd/certs.d/docker.io
tee /etc/containerd/certs.d/docker.io/hosts.toml > /dev/null << 'EOF'
server = "https://docker.io"

[host."https://docker.m.daocloud.io"]
  capabilities = ["pull", "resolve"]

[host."https://registry.cn-hangzhou.aliyuncs.com"]
  capabilities = ["pull", "resolve"]

[host."https://docker.nju.edu.cn"]
  capabilities = ["pull", "resolve"]

EOF

配置完上面的代理后下载镜像需要使用下面的命令下载

nerdctl pull docker.io/library/nginx:alpine

但是如果不想指定镜像的详细下载地址,需要再配置下面的镜像源代理

#配置registry-1.docker.io的镜像下载地址
mkdir -p /etc/containerd/certs.d/registry-1.docker.io
tee /etc/containerd/certs.d/registry-1.docker.io/hosts.toml > /dev/null << 'EOF'
server = "https://registry-1.docker.io"

[host."https://docker.m.daocloud.io"]
  capabilities = ["pull", "resolve"]

[host."https://registry.cn-hangzhou.aliyuncs.com"]
  capabilities = ["pull", "resolve"]

[host."https://docker.nju.edu.cn"]
  capabilities = ["pull", "resolve"]

EOF

测试下载镜像

nerdctl pull nginx:alpine

7、配置cni网络

# 创建 CNI 配置目录
sudo mkdir -p /etc/cni/net.d

# 创建默认的 bridge 网络配置
sudo tee /etc/cni/net.d/10-bridge.conf > /dev/null << 'EOF'
{
  "cniVersion": "1.0.0",
  "name": "mynet",
  "type": "bridge",
  "bridge": "cni0",
  "isGateway": true,
  "ipMasq": true,
  "ipam": {
    "type": "host-local",
    "ranges": [
      [{"subnet": "10.88.0.0/16"}]
    ],
    "routes": [
      {"dst": "0.0.0.0/0"}
    ]
  }
}
EOF

# 创建 loopback 配置
sudo tee /etc/cni/net.d/99-loopback.conf > /dev/null << 'EOF'
{
  "cniVersion": "1.0.0",
  "name": "lo",
  "type": "loopback"
}
EOF

重新启动containerd

systemctl restart containerd

检查是否存在其他的一些错误

journalctl -u containerd --no-pager -n 100 | grep -i "error\|fail\|mount\|denied"