01.kubernetes 中 containerd安装与配置
kubernetes 中 containerd安装与配置指南
Containerd作为k8s容器运行时,调用关系如下:
kubelet ==>cri plugin(在 containerd 进程中) ==> containerd ==> runc ==> cni runc 主要被containerd、 docker engine 调用。
一、kubernetes 离线安装containerd 运行时
1. 二进制安装containerd
- 安装包下载选择
包含ctr containerd
wget https://github.com/containerd/containerd/releases/download/v2.0.4/containerd-2.0.4-linux-amd64.tar.gz
包含ctr containerd cni runc 部署kubernetes优选
wget https://github.com/containerd/containerd/releases/download/v1.7.28/cri-containerd-cni-1.7.28-linux-amd64.tar.gz
https://github.com/containerd/containerd/releases 容器运行时
https://github.com/opencontainers/runc/releases runc 是 OCI 接口标准
https://github.com/containernetworking/plugins/releases k8s 网络接口插件
- 下载安装包并配置
wget https://github.com/containerd/containerd/releases/download/v2.0.4/containerd-2.0.4-linux-amd64.tar.gz
mkdir -p /opt/package/containerd
tar xf containerd-2.0.4-linux-amd64.tar.gz -C /opt/package/containerd
cp /opt/package/containerd/bin/* /usr/bin
- 安装依赖组件runc
wget https://github.com/opencontainers/runc/releases/download/v1.2.6/runc.amd64
mv runc.amd64 /usr/sbin/runc
chmod +x /usr/sbin/runc
#runc -v
runc version 1.1.12-0ubuntu2~22.04.1
spec: 1.0.2-dev
go: go1.21.1
libseccomp: 2.5.3
- 下载 cni plugins ( CNI网络插件安装)
CNI 网络接口插件一般用于K8S 网络解决方案. 这里安装为了后期安装K8S使用。
wget https://github.com/containernetworking/plugins/releases/download/v1.6.2/cni-plugins-linux-amd64-v1.6.2.tgz
mkdir /opt/cni/bin
tar xf cni-plugins-linux-amd64-v1.6.2.tgz -C /opt/cni/bin
chmod +x /opt/cni/bin/*
- 配置systemctl 服务
创建 systemd 服务文件
cat << EOF | sudo tee /etc/systemd/system/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target
[Service]
ExecStartPre=/sbin/modprobe overlay
ExecStart=/usr/bin/containerd
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
EOF
- 启动 containerd 服务
systemctl start containerd
systemctl status containerd
systemctl enable containerd --now
- 查看版本
containerd --version
2. 二进制安装containerd (优选)
mkdir -p /opt/package
wget https://github.com/containerd/containerd/releases/download/v1.7.28/cri-containerd-cni-1.7.28-linux-amd64.tar.gz
tar xf cri-containerd-cni-1.7.28-linux-amd64.tar.gz
包括 cni 插件 containerd runc crictl
mv opt/cni /opt/
mv usr/local/bin/* /usr/local/bin/
mv usr/local/sbin/* /usr/local/bin/
mv etc/systemd/system/containerd.service /etc/systemd/system/containerd.service
mv etc/crictl.yaml /etc/
启动
systemctl enable containerd
systemctl start containerd
systemctl status containerd
3. 配置containred
- 生成配置文件
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
- 修改Cgroup的管理者为systemd组件 (k8s使用)
sed -ri 's#(SystemdCgroup = )false#\1true#' /etc/containerd/config.toml
grep SystemdCgroup /etc/containerd/config.toml
- 修改pause的基础镜像名称 (k8s使用)
grep sandbox_image /etc/containerd/config.toml
sed -i 's#registry.k8s.io/pause:3.8#registry.aliyuncs.com/google_containers/pause:3.10#' /etc/containerd/config.toml
grep sandbox_image /etc/containerd/config.toml
systemctl restart containerd
- 指定crictl 调用containerd运行时
cat >/etc/crictl.yaml<<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 2
debug: false
pull-image-on-create: false
EOF
4. 配置镜像仓库
- 修改containerd 配置文件
(1)Containerd安装完成后,其自带的配置文件/etc/containerd/config.toml中的内容,需要用打印出的containerd默认配置替换。
(2)Containerd的Cgroup设为systemd,以和k8s默认的Cgroup保持一致,默认是 cgroupfs
(3)pause镜像路径改为国内源registry.aliyuncs.com/google_containers/pause:3.10。
mkdir -p /etc/containerd/certs.d
sudo sed -i '/\[plugins."io.containerd.grpc.v1.cri".registry\]/{n;s/config_path.*/config_path= "\/etc\/containerd\/certs.d"/}' /etc/containerd/config.toml
grep /etc/containerd/certs.d /etc/containerd/config.toml
{n;s/configpath.*/configpath= "\/etc\/containerd\/certs.d"/}: 在匹配行之后执行替换操作。n 命令用于读取下一行,s 命令用于替换字符串。
手动修改配置文件
vim /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"
重启服务
systemctl restart containerd
- containerd配置仓库加速
mkdir -p /etc/containerd/certs.d/registry.iotcloud.wl
mkdir -p /etc/containerd/certs.d/registry.iotcloud.wl:443
mkdir -p /etc/containerd/certs.d/registry.iotcloud.wl:8090
mkdir -p /etc/containerd/certs.d/registry.iotcloud.wl:5000
mkdir -p /etc/containerd/certs.d/docker.io
mkdir -p /etc/containerd/certs.d/quay.io
cat >/etc/containerd/certs.d/registry.iotcloud.wl/hosts.toml <<EOF
server = "https://registry.iotcloud.wl:443"
[host."https://registry.iotcloud.wl:443"]
capabilities = ["pull", "resolve", "push"]
skip_verify = true
EOF
cat >/etc/containerd/certs.d/registry.iotcloud.wl:443/hosts.toml <<EOF
server = "https://registry.iotcloud.wl:443"
[host."https://registry.iotcloud.wl:443"]
capabilities = ["pull", "resolve", "push"]
skip_verify = true
EOF
cat >/etc/containerd/certs.d/registry.iotcloud.wl:8090/hosts.toml <<EOF
server = "https://registry.iotcloud.wl:8090"
[host."https://registry.iotcloud.wl:8090"]
capabilities = ["pull", "resolve", "push"]
skip_verify = true
EOF
cat >/etc/containerd/certs.d/registry.iotcloud.wl:5000/hosts.toml <<EOF
server = "https://registry.iotcloud.wl:5000"
[host."https://registry.iotcloud.wl:5000"]
capabilities = ["pull", "resolve", "push"]
skip_verify = true
EOF
cat >/etc/containerd/certs.d/docker.io/hosts.toml<<EOF
server = "https://docker.io"
[host."https://dockerproxy.com"]
capabilities = ["pull", "resolve"]
[host."https://docker.m.daocloud.io"]
capabilities = ["pull", "resolve"]
[host."https://reg-mirror.qiniu.com"]
capabilities = ["pull", "resolve"]
[host."https://registry.docker-cn.com"]
capabilities = ["pull", "resolve"]
[host."http://hub-mirror.c.163.com"]
capabilities = ["pull", "resolve"]
EOF
cat >/etc/containerd/certs.d/quay.io/hosts.toml <<EOF
server = "https://quay.io"
[host."https://quay.m.daocloud.io"]
capabilities = ["pull", "resolve", "push"]
EOF
tree /etc/containerd
- 配置containerd http/https代理(可选)
mkdir -p /etc/systemd/system/containerd.service.d
cat >/etc/systemd/system/containerd.service.d/http-proxy.conf<<EOF
[Service]
Environment="HTTP_PROXY=http://172.16.4.39:11080"
Environment="HTTPS_PROXY=http://172.16.4.39:11080"
Environment="NO_PROXY=10.98.0.0/16,10.264.0.0/16,127.0.0.1,localhost,registry.mirror.local"
EOF
systemctl daemon-reload
systemctl status containerd
root@k8s-maste01:/opt/package# systemctl status containerd
● containerd.service - containerd container runtime
Loaded: loaded (/etc/systemd/system/containerd.service; enabled; preset: enabled)
Drop-In: /etc/systemd/system/containerd.service.d
└─http-proxy.conf
- 功能验证
systemctl restart containerd.service
systemctl status containerd.service
root@k8s-maste01:/opt/package# crictl pull busybox:1.28
Image is up to date for sha256:8c811b4aec35f259572d0f79207bc0678df4c736eeec50bc9fec37ed936a472a
root@k8s-maste01:/opt/package# crictl pull nginx:1.26
Image is up to date for sha256:64e5ac93d424ecf2fcdb60e508278d86d5e544d5a07ec0983fac0b2dc3c65ddf
- 查看安装文件
ls /usr/bin/containerd*
/usr/bin/containerd 这是 containerd 的主二进制文件,负责容器运行时管理
/usr/bin/containerd-shim 这个二进制文件是 containerd 的一个组件,用于作为容器和 containerd 之间的中间层,主要处理容器的生命周期事件
/usr/bin/containerd-shim-runc-v1 这个文件是与 runc 容器运行时版本 1 兼容的 containerd-shim 版本。runc 是 OCI(Open Container Initiative)标准的参考实现
/usr/bin/containerd-shim-runc-v2 类似于 containerd-shim-runc-v1,但这是为 runc 容器运行时版本 2 设计的
/usr/bin/containerd-stress 这个工具用于对 containerd 进行压力测试,帮助识别性能瓶颈或稳定性问题
二、kubernetes apt/yum安装containerd 运行时
1. YUM安装(CentOS7.9)
- 配置YUM源
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum clean all && yum repolist
查看可用安装包
yum list available|grep containerd
containerd.io.x86_64 1.6.33-3.1.el7 docker-ce-stable
- 安装containerd
yum install -y containerd.io
- 启动服务
systemctl enable --now containerd
systemctl status containerd
systemctl cat containerd
- 仓库等其它配置如上
2. apt安装(ubuntu24.0.4)
- 配置APT源
sed -i 's#archive.ubuntu.com#mirrors.aliyun.com#g' /etc/apt/sources.list
apt update
- 安装必要的依赖
安装containerd之前,需要安装一些必要的依赖:
apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates --assume-yes
- 添加阿里云的containerd GPG密钥
使用curl添加阿里云提供的containerd GPG密钥
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
- 添加阿里云的containerd仓库
将阿里云的containerd仓库添加到你的系统源列表。这里以Ubuntu 20.04为例,根据你的Ubuntu版本,focal可能需要替换为bionic、xenial等
ubuntu 18.04
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic stable"
ubuntu 20.04
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu focal stable"
ubuntu 22.04
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy stable"
- 新版本containerd源配置
创建一个新的仓库源列表文件,例如 /etc/apt/sources.list.d/containerd.list,并添加阿里云的 containerd 仓库地址
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/containerd.list
apt update
- 安装 containerd
apt install containerd.io
- 重启 containerd
sudo systemctl restart containerd
sudo systemctl status containerd
# containerd -v
containerd github.com/containerd/containerd v1.7.28 b98a3aace656320842a23f4a392a33f46af97866
三、验证与服务管理
1. 验证安装
ctr version # 查看客户端和服务端版本,ctr 为containerd 客户端工具
2. 服务管理命令
systemctl restart containerd # 重启服务
systemctl status containerd # 查看运行状态
3. 功能测试
crictl pull busybox:1.28
ctr image pull docker.io/library/nginx:1.26 --hosts-dir=/etc/containerd/certs.d
ctr images pull docker.io/library/hello-world:latest --hosts-dir=/etc/containerd/certs.d # 拉取测试镜像 :
ctr run --rm docker.io/library/hello-world:latest --name test # 运行容器 :
运行
ctr run -t -d docker.io/library/nginx:1.26 test2
ctr task list
ctr task exec -t --exec-id 6645 test2 /bin/bash
4. 查看 containerd 日志
journalctl -u containerd
5. 完全卸载重装 containerd
apt purge containerd.io # 卸载旧版本:
apt install containerd.io # 重新安装并配置
四、containred 工作原理
自 Kubernetes 1.24 版本起,Dockershim 组件被正式移除,kubelet 无法再直接与 Docker 进行交互。这意味着 Docker 不再是 Kubernetes 的内置容器运行时。
为替代 Docker,Kubernetes 社区推荐使用符合 CRI(Container Runtime Interface)标准的运行时,containerd 是其中的首选。
1、 containerd 的优势
containerd 之所以成为 Kubernetes 的推荐运行时,主要得益于以下几点:
- 符合 CRI 标准
containerd 是一个符合 CRI 标准的容器运行时,能够直接与 kubelet 交互,无需额外的适配层。这种设计使得 containerd 与 Kubernetes 的集成更加高效和稳定。 - 轻量级与高性能
containerd 专注于容器运行时的核心功能,去除了 Docker 中不必要的功能(如镜像构建、网络管理等),因此更加轻量级,性能也更高。 - 模块化设计
containerd 的模块化设计使其易于扩展和维护。它支持多种低级运行时(如 runc)和插件机制,能够灵活适应不同的使用场景。 - 镜像管理与安全性提升
containerd 提供了高效的镜像管理功能,并支持镜像安全扫描和验证。在最新版本(如 containerd 2.1)中,镜像安全性和性能得到了进一步优化。
2、containerd 的核心功能
containerd 是一个符合 CRI(Container Runtime Interface)标准的容器运行时,主要负责以下功能:
- 容器生命周期管理
containerd 负责容器的创建、启动、停止和销毁。它通过 CRI 接口接收来自 kubelet 的指令,并将这些指令转化为具体的操作。 - 镜像管理
containerd 提供镜像的拉取、存储和分发功能。它支持从镜像仓库(如 Docker Hub)中拉取镜像,并在本地缓存和管理这些镜像,以便快速创建容器。 - 存储与网络管理
containerd 管理容器的存储和网络资源。它通过插件机制支持多种存储驱动和网络模型,确保容器之间的资源隔离和通信。 - 低级运行时调用
containerd 并不直接运行容器,而是将具体的容器运行任务委托给低级运行时(如 runc)。runc 是符合 OCI(Open Container Initiative)标准的运行时工具,负责利用 Linux 内核的 cgroups 和 namespaces 实现容器的资源隔离和进程管理
3、containerd 的工作原理
containerd 在 Kubernetes 中的工作流程可以概括为以下几个步骤:
- kubelet 调用 CRI 接口
kubelet 通过 CRI 接口向 containerd 发送指令,例如创建容器、停止容器或拉取镜像。 - containerd 处理指令
containerd 接收到指令后,负责容器的生命周期管理(如创建、启动、停止容器)以及镜像的拉取和存储。 - 低级运行时执行任务
containerd 将具体的容器运行任务委托给低级运行时(如 runc)。runc 根据 OCI(Open Container Initiative)标准创建和运行容器。 - 资源管理与调度
containerd 通过插件机制管理容器的存储和网络资源,确保容器之间的资源隔离和通信。
4、containerd 与 Kubernetes 的集成方式
- CRI 接口的作用
CRI(Container Runtime Interface)是 Kubernetes 定义的一组标准接口,用于 kubelet 与容器运行时之间的通信。containerd 通过实现 CRI 接口与 Kubernetes 无缝集成。
2.containerd 的优势
containerd 相比 Docker 具有以下优势:
轻量级:containerd 是一个专注于容器运行时的工具,去除了 Docker 中不必要的功能,性能更高。
标准化:containerd 符合 CRI 和 OCI 标准,兼容性强,支持多种低级运行时。
模块化:containerd 的设计模块化,易于扩展和维护。
3.Kubernetes 对 containerd 的支持
自 Kubernetes 1.24 版本起,Docker 不再作为内置容器运行时支持,containerd 成为默认的容器运行时。这一变化进一步推动了 containerd 在 Kubernetes 生态中的普及
4. 总结
containerd 是 Kubernetes 中重要的容器运行时,其工作原理可以概括为:kubelet 通过 CRI 接口调用 containerd,containerd 负责容器的生命周期管理、
镜像管理和资源调度,并将具体的容器运行任务委托给 runc。这种分工明确、标准化的调用链,确保了 Kubernetes 集群的高效性和灵活性
5、 Kubernetes 与 runc 的调用流程
在 Kubernetes 中,容器运行时的调用关系可以清晰地描述为以下流程:
kubelet → containerd → runc → CNI
下面将详细解析每一层的作用及其在调用链中的角色:
1. 调用关系概述
kubelet:Kubernetes 的核心组件,负责管理 Pod 和容器的生命周期。
containerd:符合 CRI 标准的高性能容器运行时,负责容器和镜像的管理。
runc:低级容器运行时,用于创建和运行容器。
CNI(Container Network Interface):容器网络接口,负责为容器配置网络。
2. 各层详细解析
- kubelet 的作用
kubelet 是 Kubernetes 集群中每个节点上的核心组件,主要职责包括:
与 Kubernetes API Server 交互,获取 Pod 的定义。
调用容器运行时(如 containerd)来启动、停止和管理容器。
监控容器状态,并上报给 Kubernetes 控制平面。
kubelet 通过 CRI(Container Runtime Interface)与 containerd 交互。CRI 是 Kubernetes 定义的一套标准接口,允许 kubelet 与不同的容器运行时进行通信。
-
containerd 的作用
containerd 是一个符合 CRI 标准的容器运行时,主要负责:
容器生命周期管理:包括创建、启动、停止和删除容器。
镜像管理:拉取、存储和分发容器镜像。
存储管理:管理容器的存储卷。
containerd 在接收到 kubelet 的请求后,会将具体的容器运行任务委托给低级运行时(如 runc)。这种分层设计使得 containerd 更加轻量化和模块化。 -
runc 的作用
runc 是一个符合 OCI(Open Container Initiative)标准的低级容器运行时,主要负责:
根据容器的规范(如 OCI 规范)创建和运行容器。
管理容器的命名空间、控制组(cgroups)和文件系统。
确保容器与宿主机之间的隔离。
runc 是 containerd 的默认运行时,containerd 通过调用 runc 来完成容器的实际启动和运行。 -
CNI 的作用
CNI(Container Network Interface)是 Kubernetes 中用于配置容器网络的插件接口,主要负责:
为容器分配 IP 地址。
配置容器的网络路由和防火墙规则。
管理容器之间的网络通信。
在容器启动时,containerd 会调用 CNI 插件为容器配置网络。CNI 插件可以是 Calico、Flannel、Weave Net 等,用户可以根据需求选择不同的网络方案。
3. 调用流程示例
以下是一个 Pod 启动的完整调用流程:
-
kubelet 接收 Pod 定义:
kubelet 从 Kubernetes API Server 获取 Pod 的定义。
解析 Pod 的容器配置(如镜像、资源限制、网络配置等)。 -
kubelet 调用 containerd:
kubelet 通过 CRI 接口向 containerd 发送创建容器的请求。
containerd 接收请求并开始处理。 -
containerd 调用 runc:
containerd 根据容器配置生成 OCI 规范文件。
调用 runc 创建并启动容器。 -
runc 创建容器:
runc 根据 OCI 规范创建容器的命名空间、cgroups 和文件系统。
启动容器内的进程。 -
CNI 配置网络:
容器启动后,containerd 调用 CNI 插件为容器配置网络。
CNI 插件为容器分配 IP 地址并设置网络规则。
6.容器运行完成:
容器启动后,kubelet 监控容器状态并上报给 Kubernetes 控制平面。
- 总结
Kubernetes 中的容器运行时调用关系可以总结为:
1 .kubelet 通过 CRI 接口与 containerd 交互,管理容器的生命周期。 - containerd 调用 runc 来实际创建和运行容器。
- CNI 负责为容器配置网络,确保容器之间的通信。
这种分层设计使得 Kubernetes 的容器管理更加高效、灵活和模块化。containerd 作为中间层,既符合 CRI 标准,
又能通过 runc 实现低级别的容器运行,同时与 CNI 插件协同工作,为容器提供完整的运行环境
6、网络插件 cni
CNI(Container Network Interface)插件是一组用于配置容器网络接口的标准化工具和库。它们是由CoreOS公司发起的一个开源项目,旨在为容器化环境提供一种简单、可扩展的网络解决方案。以下是对CNI插件的基本说明:
1.CNI插件的目标:
标准化:为容器运行时提供一种标准的网络配置接口。
可插拔:允许不同的网络解决方案通过插件的方式集成到容器平台中。
灵活性:支持多种网络模型和需求,如桥接、覆盖网络、主机网络等。
2.CNI插件的主要组件:
CNI插件:实际执行网络配置的插件程序,例如bridge、host-local、loopback、macvlan等。
CNI配置文件:JSON格式的配置文件,用于指定网络配置参数。
CNI二进制文件:cnitool是一个用于测试和调试CNI插件的命令行工具。
3.常见的CNI插件:
bridge:创建一个Linux网桥,并将容器连接到该桥上。
host-local:一个IP地址管理(IPAM)插件,用于分配和跟踪IP地址。
loopback:为容器提供回环接口。
macvlan:允许容器拥有独立的MAC地址,从而在物理网络上作为独立的设备。
flannel:实现一个覆盖网络,允许跨主机容器通信。
calico:提供网络隔离、策略实施和跨主机通信。
weave:类似于flannel,提供跨主机容器网络的覆盖解决方案。
4.CNI插件的工作流程:
添加(ADD):当容器被创建时,容器运行时调用CNI插件来配置网络接口。
删除(DEL):当容器被删除时,容器运行时调用CNI插件来清理网络接口。
检查(CHECK):(可选)用于验证网络配置是否正确。
版本(VERSION):(可选)用于查询CNI插件支持的版本。
7、runc 工具
runc 是一个轻量级的工具,它是 OCI(Open Container Initiative)容器运行时规范的参考实现。它的主要作用是:
创建和运行容器:runc 负责创建容器命名空间、控制组(cgroups)、文件系统等,并最终启动容器内的进程。
OCI 兼容性:runc 遵循 OCI 规范,这意味着它可以运行任何符合 OCI 标准的容器镜像。
低层操作:runc 提供了直接与容器交互的低层操作接口,如启动、停止、暂停和删除容器。
简而言之,runc 是一个命令行工具,可以直接用于创建和运行容器,但它通常不直接被终端用户使用,而是被更高级别的工具和系统(如 containerd、Docker Engine 等)调用
更多推荐

所有评论(0)