k8s笔记28--快速在ubuntu上基于二进制和源码安装containerd
介绍
Containerd是一个工业标准的容器运行时,它强调简单、健壮和可移植性。它可作为Linux和Windows的守护进程,能管理主机系统上完整容器生命周期: 镜像传输和存储、容器执行和管理、容器底层存储和网络等。它是CNCF下"毕业"的项目,旨在嵌入到更大的系统中,而不是由开发人员或最终用户直接使用。
作为IT行业的人员最熟悉的容器产品大多是docker,可是docker较新的版本底层也在使用containerd来管理容器; k8s 早期大力支持docker作为其底层容器运行时,把相关代码都hardcode到组件中,指导1.24版本开始逐步废除kubelet中的 dockershim,转而通过cri来适配更多类型的容器运行时,包括知名的containerd和 CRI-O。
containerd作为知名、稳定、可靠的容器运行时,从事容器云领域的小伙伴都有必要了解一下它的基本原理和常见的安装部署方式,以便于解决工作、学习中遇到的相关问题...
containerd 安装方法
在安装之前我们可以想象一下运行起来一个容器需要哪些基础组件,类比docker run启动一个容器,我们 containerd 需要哪些基础工具组件呢?
首先, 需要命令行工具 nerdctl或者ctr来实现类似于docker run的功能(即docker-cli项目);其次, nerdctl等工具是需要和containerd的进行通信的,因此需要containerd组件;除此之外还需要一个low-level的运行时工具,它可以通过namespace隔离、cgroup限制来运行起一个实际的容器进程,这个组件就是runc了(当然可以用其它的low-level运行时工具,例如 youki);最后,容器运行是需要相关网络组件的,因此需要cni网络组件。
了解上述基础内容后,我们就能明白: 通过 runc、containerd、nerdctl、cni等4个主要模块就能玩转containerd容器运行时了,下面我们基于这4个模块分别用二进制和源码的方法安装containerd。
二进制文件安装
-
runc
在 github.com/opencontainers/runc/releases 下载指定系统和版本的 runc
-
containerd
在 github.com/containerd/containerd/releases 下载指定系统和版本的 containerd,笔者使用ubuntu比较多,下载 cri-containerd-cni-1.6.30-linux-amd64.tar.gz 版本,cri表示包含low-level的runc可执行文件,cni表示包含了常见的容器网络组件(例如bridge)。
-
nerdctl
在 github.com/containerd/nerdctl/releases 下载containerd的client程序,可以用来执行 nerdctl run|images|ps 等等价于docker的命令。
-
cni
在 github.com/containernetworking/plugins/releases 下载常见的容器网络组件可执行文件。
bash如果不设置cni的话,新建容器会出现网络相关报错 root@xg:/home/xg# nerdctl run -d --name=test-busybox busybox:1.32 sleep 3600 FATA[0000] failed to verify networking settings: failed to create default network: needs CNI plugin "bridge" to be installed in CNI_PATH ("/opt/cni/bin"), see https://github.com/containernetworking/plugins/releases: exec: "/opt/cni/bin/bridge": stat /opt/cni/bin/bridge: no such file or directory
此处以cri-containerd-cni-1.6.30-linux-amd64.tar.gz 和 nerdctl-2.0.0-beta.2-linux-amd64.tar.gz 为例,将文件拷贝文件到指定目录,按照如下步骤即可运行期containerd容器服务:
bash安装containerd $ tar -zxvf cri-containerd-cni-1.6.30-linux-amd64.tar.gz # mv usr/local/bin/* /usr/local/bin/ # mv opt/cni /opt/ # mv usr/local/sbin/runc /usr/local/sbin/ # mv etc/systemd/system/containerd.service /etc/systemd/system/containerd.service # systemctl daemon-reload # systemctl start containerd 安装nerdctl $ tar -zxvf nerdctl-2.0.0-beta.2-linux-amd64.tar.gz # mv nerdctl /usr/local/bin/
测试containerd
测试nerdctl
至此,我们已经通过二进制文件成功的运行起了containerd服务,并用nerdctl测试了容器运行时的可用性。如果后续碰到了内网机器无法访问公网的情况,大胆的使用这种二进制的方法安装containerd服务吧。
源码构建安装
-
runc
在github clone containerd 源码,checkout到指定的版本,make all 编译生成二进制文件。bash$ git clone https://github.com/opencontainers/runc.git $ git checkout release-1.1 $ make all 命令执行成功后会在当前目录生产对应的runc文件,将其同步到目标机器上,然后mv 到 /usr/local/sbin/ 目录下即可
如下图:
-
containerd
在github clone containerd 源码,checkout到指定的版本,make all 编译生成二进制文件。bash$ git clone https://github.com/containerd/containerd.git $ git checkout release/1.6 $ make all make all执行成功后就会在bin目录下生成一系列containerd相关的二进制文件,将bin文件打包后同步到指定的机器上,mv 到 /usr/local/bin/ 目录, 将 containerd.service mv到/etc/systemd/system/目录, 然后通过 systemctl 即可启动服务 containerd.service放在项目的根目录下(截至2024-03-2日,分支release/1.6)
如下图:
-
nerdctl
在github clone nerdctl 源码,checkout到指定的版本,make all 编译生成二进制文件。bash$ git clone https://github.com/containerd/nerdctl.git $ git checkout release/1.7 $ make all make all执行成功后就会在当前目录/_output下生成nerdctl二进制文件,将其同步到目标机器上,mv到 /usr/local/bin/ 下即可
如下图:
-
cni
在github clone containerd 源码,checkout到指定的版本,make all 编译生成二进制文件。bash$ git clone $ git checkout release-1.1 $ bash build_linux.sh $ ls bin bandwidth bridge dhcp firewall host-device host-local ipvlan loopback macvlan portmap ptp sbr static tuning vlan vrf 执行成功后会在当前目录下bin文件夹下生成一系列的网络插件二进制文件,将bin文件打包后同步到指定的机器上,将二进制文件 mv 到 /opt/cni/bin 目录即可
如下图:
注意事项
-
编译containerd报错的时候可能需要安装libbtrfs-dev
bash报错信息: btrfs/ioctl.h: No such file or directory 部分网友推荐 apt-get -y install btrfs-progs ,实测在ubuntu22.04及之后的系统上无效 解决方法: 有效: apt install libbtrfs-dev 参考: https://ubuntu.pkgs.org/20.04/ubuntu-main-arm64/libbtrfs-dev_5.4.1-2_arm64.deb.html 方法2: 编译的时候忽略 btrfs make all BUILDTAGS=no_btrfs
-
编译runc报错的时候可能需要安装 pkg-config 和 libseccomp-dev
bash报错信息1: # pkg-config --cflags -- libseccomp pkg-config: exec: "pkg-config": executable file not found in $PATH 解决方法: apt install pkg-config 报错信息2: go build github.com/seccomp/libseccomp-golang: # pkg-config --cflags -- libseccomp Package libseccomp was not found in the pkg-config search path. Perhaps you should add the directory containing `libseccomp.pc' to the PKG_CONFIG_PATH environment variable Package 'libseccomp', required by 'virtual:world', not found pkg-config: exit status 1 解决方法: apt install libseccomp-dev
-
在新的server上执行 runc -v报错 GLIBC_2.38 not found
bash报错: # /usr/local/sbin/runc -v /usr/local/sbin/runc: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by /usr/local/sbin/runc) 解决方法: 确保编译系统的glibc版本和运行系统的glibc相同,或者比运行系统低一点。 笔者最开始在ubuntu23.10 Desktop 上编译,在 ubuntu 22.04 server上运行, 而23.10 使用GLIBC 2.38,22.04使用的是GLIBC 2.35, 因此调整到22.04版本的系统上重新编译就可以正常使用了。 可以通过 strings /lib/x86_64-linux-gnu/libc.so.6 |grep GLIBC_ 查看当前系统上的glibc版本 通过 ldd --version 查看当前系统正在使用的glibc版本
说明
软件环境:
ubuntu 22.04 server
nerdctl-2.0.0-beta.2
cri-containerd-cni-1.6.30
runc 1.1.0
参考文档:
containerd -> BUILDING.md
Docker、Containerd、RunC分别是什么
功能解释:containerd.io、docker-ce、docker-ce-cli、docker-buildx-plugin、docker-compose-plugin、docker.io
ubuntu docker离线安装docker
How to install the Containerd runtime engine on Ubuntu Server 22.04
Containerd shim 原理深入解读
Containerd组件 -- containerd-shim-runc-v2作用
Understanding the Container Runtime Containerd in one article