Kubernetes部署与运维02 Nerdctl Rootful部署

322 阅读12分钟

Kubernetes目前大约每年发布三次,由于迭代速度快,目前市场上绝大部分的教程相对陈旧。更重要的是,从Kubernetes 1.20开始,Kubernetes官方宣布逐步弃用Docker作为容器运行时,并计划在Kubernetes 1.24版本中完全移除对Docker作为容器运行时的支持。这意味着,从Kubernetes 1.24版本开始,将不能使用Docker作为容器运行时来运行Kubernetes节点上的Pods。因此,市场上关于直接使用containerd容器运行时的新版Kubernetes教程几乎没有,更重要的是因为的Kubernetes涉及到镜像需要单独配置才能获取,这无疑拉高了初学者门槛。本教程采用互联网的形式进行发布,便于保持与Kubernetes最新版的同步,尽量自包含,便于读者学习、实践。

关键字Kubernetes 1.32; containerd; nerdctl; debain 12

Kubernetes部署与运维v3.png

整体规划

为方便后续内容学习,本部分基于【Kubernetes部署与运维01 Debian 12部署】中的环境开展Nerdctl的部署与学习。整体规划如下:

虚拟机名称软件环境IP地址主机名域名
K8s_Nerdctl1.7.7_Basenerdctl v1.7.7192.168.152.4nerdctlnerdctl.rz

虚拟机K8s_Nerdctl1.7.7_Base将基于K8s_Debian12.08_BaseDocker安装完成快照克隆。克隆关系如下:

源虚拟机克隆机
K8s_Debian12.08_BaseK8s_Nerdctl1.7.7_Base

基础环境配置信息:

软件版本
OSWindows 11
VMware Workstation Pro17.6.1 build-24319023
MobaXtermProfessional Edition v24.0
Nerctlv1.7.1full
nerdctl官网:https://github.com/containerd/nerdctl

理论知识

nerdctl‌是一个用于containerd的命令行工具,旨在提供与Docker CLI相似的用户体验。nerdctlcontainerd的一个子项目,兼容Docker CLI的习惯,特别适合从Docker转到containerd的用户使用。

nerdctl的主要功能和特性:

  • 兼容Docker CLI‌nerdctl的设计初衷是为了提供与Docker CLI相似的用户体验,使得用户可以无缝地从Docker迁移到containerd
  • 可选的高级功能‌:包括rootless模式(普通用户模式)、延迟拉取、加密镜像、P2P镜像分发、容器镜像签名和验证等。

nerdctlDockercontainerd的关系:nerdctl是专门为containerd设计的命令行工具,虽然它的操作界面与Docker CLI相似,但实际上它操作的是containerd而非Docker。这意味着nerdctl展示的内容和Docker CLI有所不同,但它保留了Docker CLI的操作习惯,使得用户可以更容易地从Docker迁移到containerd

案例实践

前期准备

K8s_Debian12.08_Base虚拟机作为源虚拟机,克隆虚拟机K8s_Nerdctl1.7.7_Base,并根据【整体规划】配置对应的IP地址与主机名等。

1)假定已经具有最小化安装的Debian12系统,具体参考【Kubernetes部署与运维01 Debian 12部署】。选中K8s_Debian12.08_Base虚拟机。克隆虚拟机,选择菜单虚拟机(M)->管理(M)->克隆(C)

Pasted image 20250127174039.png

2)在克隆虚拟机导向克隆源 页面,在现有快照(仅限关闭的虚拟机)(S)中选择之前拍摄好的快照系统配置完成

Pasted image 20250127174140.png

3)在克隆虚拟机导向新虚拟机名称 页面,虚拟机名称整体方案中规划,填入K8s_Nerdctl1.7.7_Base

Pasted image 20250127174403.png

虚拟机K8s_Nerctl1.7.7_Base克隆完成。由于默认是创建链接克隆,因此该虚拟机与源虚拟机K8s_Debian12.08_Base是存在着关联的,不可以删除虚拟机K8s_Debian12.08_Base,否则将影响虚拟机K8s_Nerctl1.7.7_Base

4)开启虚拟机K8s_Nerdctl1.7.7_Base,根据【整体规划】,修改IP地址为192.168.152.4,具体参考【Kubernetes部署与运维01 Debian 12部署-静态IP配置】。后续将以root身份登录系统。

5)根据【整体规划】,修改主机名为nerdctl,参考【Kubernetes部署与运维01 Debian 12部署-主机名配置】。

修改/etc/hosts,文件内容如下:

127.0.0.1       localhost
127.0.1.1       nerdctl
192.168.152.4   nerdctl.rz

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

root身份登录系统,配置/root/.bashrc文件:

   9   │ export LS_OPTIONS='--color=auto'
  10   │ eval "$(dircolors)"
  11   │ alias ls='ls $LS_OPTIONS'
  12   │ alias ll='ls $LS_OPTIONS -l'
  13   │ alias l='ls $LS_OPTIONS -lA'
  14   │ #
  15   │ # Some more alias to avoid making mistakes:
  16   │ # alias rm='rm -i'
  17   │ # alias cp='cp -i'
  18   │ # alias mv='mv -i'
  19   │
  20   │ export HISTTIMEFORMAT="%F %T "

加载配置,使更改生效:

root@debase:~# source ~/.bashrc

6)创建software目录,本部分所有软件包均下载至该目录:

root@debase:~# mkdir software

root@debase:~# ll
total 4
drwxr-xr-x 2 root root 4096 Jan 27 18:02 software

Nerdctl完整包部署

【实践01-Nerdctl完整包部署】

使用nerdctl-full-1.7.7-linux-amd64.tar.gz部署包括containerd在内的相关容器工具与环境。

1)从官网下载nerdctl-full-1.7.7-linux-amd64.tar.gz/root/software目录下:

root@debase:~# ll ~/software/
total 253760
-rw-r--r-- 1 root root 259844835 Jan 27 18:05 nerdctl-full-1.7.7-linux-amd64.tar.gz

若无法下载,请查看本教程最后的百度网盘下载链接,其中提供了本教程所涉及到的相关文件与资源。

2)解压nerdctl-full-1.7.7-linux-amd64.tar.gz/usr/local

root@debase:~# tar Cxzvf /usr/local/ ~/software/nerdctl-full-1.7.7-linux-amd64.tar.gz
bin/
...
share/doc/nerdctl-full/
share/doc/nerdctl-full/README.md
share/doc/nerdctl-full/SHA256SUMS

nerdctl-full-1.7.7-linux-amd64.tar.gz包含各组件与版本如下:

- nerdctl: v1.7.7
- containerd: v1.7.22
- runc: v1.1.14
- CNI plugins: v1.5.1
- BuildKit: v0.15.2
- Stargz Snapshotter: v0.15.1
- imgcrypt: v1.1.11
- RootlessKit: v2.3.1
- slirp4netns: v1.3.1
- bypass4netns: v0.4.1
- fuse-overlayfs: v1.13
- containerd-fuse-overlayfs: v1.0.8
- Kubo (IPFS): v0.29.0
- Tini: v0.19.0
- buildg: v0.4.1

3)设置containerd以服务形式启动:

root@debase:~# systemctl enable --now containerd
Created symlink /etc/systemd/system/multi-user.target.wants/containerd.service → /usr/local/lib/systemd/system/containerd.service.

4)查看ctr版本:

root@debase:~# ctr version
Client:
  Version:  v1.7.22
  Revision: 7f7fdf5fed64eb6a7caf99b3e12efcf9d60e311c
  Go version: go1.23.1

Server:
  Version:  v1.7.22
  Revision: 7f7fdf5fed64eb6a7caf99b3e12efcf9d60e311c
  UUID: e3c42486-76a2-46c2-ab5d-4db55b14a772

5)生成containerd配置:

root@debase:~# mkdir -p /etc/containerd/

root@debase:~# containerd config default > /etc/containerd/config.toml

Containerd镜像加速配置

【实践02-Containerd镜像加速配置】

nerdctlRootful模式下,镜像加速是由containerd处理的,由于中国大陆与海外资源服务器网络不稳定等因素限制,需要设置containerd的镜像加速。

1)containerd镜像仓库配置建议放在一个单独的文件夹当中,并且在/etc/containerd/config.toml配置文件当中打开config_path配置,指向镜像仓库配置目录即可。仅在第一次修改/etc/containerd/config.toml文件打开config_path配置时需要重启containerd,后续增加镜像仓库配置则无需重启containerd。修改/etc/containerd/config.toml文件:

 ...
 161   │     [plugins."io.containerd.grpc.v1.cri".registry]
 162   │       config_path = "/etc/containerd/certs.d"
 ...

2)创建/etc/containerd/certs.d目录,并重启containerd服务,使配置生效:

root@debase:~# mkdir -p /etc/containerd/certs.d

root@debase:~# systemctl restart containerd.service

root@debase:~# systemctl status containerd.service
● containerd.service - containerd container runtime
     Loaded: loaded (/usr/local/lib/systemd/system/containerd.service; enabled; >
     Active: active (running) since Mon 2025-01-27 18:18:50 CST; 6s ago
       Docs: https://containerd.io
    Process: 9505 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUC>
   Main PID: 9507 (containerd)
      Tasks: 8
     Memory: 12.9M
        CPU: 66ms
     CGroup: /system.slice/containerd.service
             └─9507 /usr/local/bin/containerd

3)设置docker hubdocker.io)的镜像加速器,创建目录/etc/containerd/certs.d/docker.io

root@debase:~# mkdir -p /etc/containerd/certs.d/docker.io

4)创建/etc/containerd/certs.d/docker.io/hosts.toml文件,内容如下:

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

[host."https://docker.1panel.live"]
  capabilities = ["pull", "resolve"]

[host."https://hub.rat.dev"]
  capabilities = ["pull", "resolve"]

server:被加速的服务器访问地址; host:镜像加速器地址; capabilities:镜像加速器提供的加速服务类型。

5)拉取镜像,使用containerd自带的ctr命令拉取镜像时,需要指定--hosts-dir=/etc/containerd/certs.d参数:

root@debase:~# ctr images pull --hosts-dir=/etc/containerd/certs.d --platform linux/amd64 docker.io/library/busybox:latest
docker.io/library/busybox:latest:                                                 resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:a5d0ce49aa801d475da48f8cb163c354ab95cab073cd3c138bd458fc8257fbf1:    done           |++++++++++++++++++++++++++++++++++++++|
...
elapsed: 3.3 s                                                                    total:  1.0 Mi (313.6 KiB/s)
unpacking linux/amd64 sha256:a5d0ce49aa801d475da48f8cb163c354ab95cab073cd3c138bd458fc8257fbf1...
done: 101.188187ms

root@debase:~# ctr images pull --hosts-dir=/etc/containerd/certs.d --platform linux/amd64 docker.io/library/ubuntu:20.04
docker.io/library/ubuntu:20.04:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:8e5c4f0285ecbb4ead070431d29b576a530d3166df73ec44affc1cd27555141b:    done           |++++++++++++++++++++++++++++++++++++++|
...
elapsed: 29.6s                                                                    total:  25.0 M (865.1 KiB/s)
unpacking linux/amd64 sha256:8e5c4f0285ecbb4ead070431d29b576a530d3166df73ec44affc1cd27555141b...
done: 1.693066662s

root@debase:~# ctr image list -q
docker.io/library/busybox:latest
docker.io/library/ubuntu:20.04

--platform linux/amd64用于指定镜像硬件平台是amd64

6)拉取镜像,使用nerdctl

root@debase:~# nerdctl pull hello-world
docker.io/library/hello-world:latest:                                             resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:d715f14f9eca81473d9112df50457893aa4d099adeb4729f679006bf5ea12407:    done           |++++++++++++++++++++++++++++++++++++++|
...
elapsed: 3.0 s                                                                    total:  13.9 K (4.6 KiB/s)

root@debase:~# nerdctl pull mysql:8.0.40-debian
docker.io/library/mysql:8.0.40-debian:                                            resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:8da93b1d48d62b4869a5f8116590e284e35bfc40c86dffb247369e2d702c063f:    done           |++++++++++++++++++++++++++++++++++++++|
...
elapsed: 45.5s                                                                    total:  174.8  (3.8 MiB/s)

root@debase:~# nerdctl images
REPOSITORY     TAG              IMAGE ID        SIZE         BLOB SIZE
busybox        latest           a5d0ce49aa80    4.2 MiB      2.1 MiB
hello-world    latest           d715f14f9eca    16.0 KiB     16.3 KiB
mysql          8.0.40-debian    8da93b1d48d6    599.1 MiB    174.8 MiB
ubuntu         20.04            8e5c4f0285ec    77.9 MiB     26.2 MiB

Nerdctl自动补全配置

【实践03-nerdctl命令自动补全配置】

配置nerdctl命令,支持使用tab键自动参数补全。

nerdctl支持bash环境命令参数自动补全:

root@debase:~# mkdir /etc/bash_completion.d/

root@debase:~# nerdctl completion bash > /etc/bash_completion.d/nerdctl

root@debase:~# source /etc/bash_completion.d/nerdctl

BuildKit配置

【实践04-BuildKit镜像构建工具配置】

nerdctl build以及nerdctl compose build依赖于BuildKit,在使用它们之前,需要配置Buildkit。配置 BuildKit镜像构建工具,支持构建镜像。

BuildKit有两种类型的后端:

  • containerd workerBuildKit通过containerd管理容器与镜像,containerd需要设置为随主机启动而自动运行;
  • OCI worker:不需要containerdBuildKit直接管理容器与镜像。但是OCI worker依赖于runc用于容器执行。

需要设置BuildKit使用两种类型后端中的任何一种。

需要强调的是OCI worker无法访问由containerd管理的基础镜像(在DockerfileFROM字段指定的镜像)。因此,无法让nerdctl build使用那些由containerd管理的镜像,以其作为基础镜像,(这些不能使用的基础镜像,也包括之前由nerdctl build命令构建,但是由containerd管理的镜像)。

1)配置BuildKit使用containerd worker后端,设置buildkit开机自启动:

root@debase:~# systemctl enable --now buildkit
Created symlink /etc/systemd/system/multi-user.target.wants/buildkit.service → /usr/local/lib/systemd/system/buildkit.service.

root@debase:~# systemctl status buildkit.service
● buildkit.service
     Loaded: loaded (/usr/local/lib/systemd/system/buildkit.service; enabled; pr>
     Active: active (running) since Mon 2025-01-27 18:51:46 CST; 8s ago
    Process: 21384 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SU>
   Main PID: 21385 (buildkitd)
      Tasks: 8
     Memory: 21.0M
        CPU: 62ms
     CGroup: /system.slice/buildkit.service
             └─21385 /usr/local/bin/buildkitd

2)创建/etc/buildkit/,以存放buildkit.toml配置文件。

root@debase:~# mkdir -p /etc/buildkit/

3)创建/etc/buildkit/buildkitd.toml文件,内容如下:

[worker.oci]
  enabled = false

[worker.containerd]
  enabled = true
  # namespace should be "k8s.io" for Kubernetes (including Rancher Desktop)
  namespace = "default"

BuildKit的配置文件完整版可以参考https://github.com/moby/buildkit/blob/v0.15/docs/buildkitd.toml.md

4)由于BuildKit是以后台的形式提供服务,为使配置生效,需要重启buildkit.service服务。

root@debase:~# systemctl restart buildkit.service

5)测试配置环境。在家目录中创建buildkit_test目录,在其中创建Dockerfilesources.list

root@debase:~# mkdir ~/buildkit_test

root@debase:~# touch ~/buildkit_test/Dockerfile

root@debase:~# touch ~/buildkit_test/sources.list

root@debase:~# tree ~/buildkit_test/
/root/buildkit_test/
├── Dockerfile
└── sources.list

1 directory, 2 files

Dockerfile内容如下:

FROM ubuntu:20.04
ADD sources.list /etc/apt/
RUN apt update
RUN apt install -y tree
CMD touch /root/hello && tree /root/

sources.list内容如下:

deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse

6)尝试使用nerdctl build构建镜像:

root@debase:~/buildkit_test# nerdctl build -t ubuntu:test .
[+] Building 94.5s (9/9) FINISHED
 => [internal] load build definition from Dockerfile                        0.0s
 => => transferring dockerfile: 158B                                        0.0s
 => [internal] load metadata for docker.io/library/ubuntu:20.04            42.1s
 => [internal] load .dockerignore                                           0.0s
 => => transferring context: 2B                                             0.0s
 => [internal] load build context                                           0.0s
 => => transferring context: 388B                                           0.0s
 => [1/4] FROM docker.io/library/ubuntu:20.04@sha256:8e5c4f0285ecbb4ead07  42.1s
 => => resolve docker.io/library/ubuntu:20.04@sha256:8e5c4f0285ecbb4ead07  42.1s
 => [2/4] ADD sources.list /etc/apt/                                        0.0s
 => [3/4] RUN apt update                                                    4.9s
 => [4/4] RUN apt install -y tree                                           2.1s
 => exporting to image                                                      3.2s
 => => exporting layers                                                     2.4s
 => => exporting manifest sha256:e3b6ecea95eaadb5b73475db9f6e9eac443bcf550  0.0s
 => => exporting config sha256:b214bd0bc24498ff05672e7be9c8c102bbcf1d39332  0.0s
 => => naming to docker.io/library/ubuntu:test                              0.0s
 => => unpacking to docker.io/library/ubuntu:test                           0.8s

root@debase:~/buildkit_test# nerdctl images
REPOSITORY     TAG              IMAGE ID        SIZE         BLOB SIZE
busybox        latest           a5d0ce49aa80    4.2 MiB      2.1 MiB
hello-world    latest           d715f14f9eca    16.0 KiB     16.3 KiB
mysql          8.0.40-debian    8da93b1d48d6    599.1 MiB    174.8 MiB
ubuntu         20.04            8e5c4f0285ec    77.9 MiB     26.2 MiB
ubuntu         test             e3b6ecea95ea    131.5 MiB    62.7 MiB

若构建时输出如下信息:

[+] Building 21.1s (2/2) FINISHED
 => [internal] load build definition from Dockerfile                        0.0s
 => => transferring dockerfile: 158B                                        0.0s
 => ERROR [internal] load metadata for docker.io/library/ubuntu:20.04      21.1s
------
 > [internal] load metadata for docker.io/library/ubuntu:20.04:
------
Dockerfile:1
--------------------
   1 | >>> FROM ubuntu:20.04
   2 |     ADD sources.list /etc/apt/
   3 |     RUN apt update
--------------------
error: failed to solve: ubuntu:20.04: failed to resolve source metadata for docker.io/library/ubuntu:20.04: failed to do request: Head "https://registry-1.docker.io/v2/library/ubuntu/manifests/20.04": dial tcp 104.244.46.5:443: connect: connection refused
FATA[0021] no image was built

以上信息表示BuildKit无法直接使用containerd的镜像加速器拉取镜像。因此,需要单独为BuildKit配置镜像加速。

7)修改/etc/buildkit/buildkitd.toml文件,参考https://github.com/moby/buildkit/blob/v0.15/docs/buildkitd.toml.md,增加镜像部分配置:

[worker.oci]
  enabled = false

[worker.containerd]
  enabled = true
  # namespace should be "k8s.io" for Kubernetes (including Rancher Desktop)
  namespace = "default"

[registry."docker.io"]
  mirrors = ["docker.m.daocloud.io", "docker.1panel.live", "hub.rat.dev" ]
  http = false

8)重启buildkit.service服务。

root@debase:~/buildkit_test# systemctl restart buildkit.service

9)现在可以重新构建镜像了。

root@debase:~/buildkit_test# nerdctl build -t ubuntu:test .
[+] Building 94.5s (9/9) FINISHED
...
 => => unpacking to docker.io/library/ubuntu:test             0.8s

root@debase:~/buildkit_test# nerdctl images
REPOSITORY     TAG              IMAGE ID        SIZE         BLOB SIZE
...
ubuntu         test             e3b6ecea95ea    131.5 MiB    62.7 MiB

收尾工作

1)删除~/buildkit_test目录:

root@debase:~# cd

root@debase:~# rm -rf ~/buildkit_test/

2)删除系统内镜像:

root@debase:~# nerdctl images -q
a5d0ce49aa80
d715f14f9eca
8da93b1d48d6
8e5c4f0285ec
e3b6ecea95ea

root@debase:~# nerdctl rmi $(nerdctl images -q)
Untagged: docker.io/library/busybox:latest@sha256:a5d0ce49aa801d475da48f8cb163c354ab95cab073cd3c138bd...

root@debase:~# nerdctl images
REPOSITORY    TAG    IMAGE ID    CREATED    PLATFORM    SIZE    BLOB SIZE

3)使用poweroff关闭K8s_Nerdctl1.7.7_Base虚拟机。

root@debase:~# poweroff

4)为K8s_Nerdctl1.7.7_Base虚拟机拍摄快照Nerctl v1.7.7部署完成,以备后续在克隆时使用。

5)AI时代背景之下,运维将从传统CPU服务器切入到GPU服务器与端边设备,对于运维开发人员,技术玩家而言,也同步需要跟上新的技术栈。本学习内容涉及到的软件包、配置文件等资源,可以直接从百度网盘下载获取:

  • 百度网盘分享文件:Kubernetes1.32
  • 链接:https://pan.baidu.com/s/18XeGQ28BDPjHh8JKj0uZFQ?pwd=6x17 提取码:6x17