前言
在 Kubernetes(K8s)的发展历程中,容器运行时从早期的 Docker 逐步向更轻量、更标准的 Containerd 演进。随着 K8s 1.24 版本正式移除对 Docker 的支持,Containerd 已成为生产环境中主流的容器运行时选择。相比 Docker,Containerd 更轻量、更专注于容器生命周期管理,且完全兼容 K8s 的 CRI(容器运行时接口)标准。
本文将从零开始,带你完整实践基于 Containerd 的 K8s 集群部署流程,涵盖环境准备、组件安装、集群初始化、网络插件配置等全流程,同时对比 Containerd 与 Docker 的常用命令差异,帮助你快速掌握 K8s 生产环境的部署与调试方法。
一、环境规划与基础配置
1. 主机规划
本次部署采用 3 节点集群架构,具体规划如下:
表格
| 主机名 | IP 地址 | 集群角色 |
|---|---|---|
| k8smaster | 192.168.38.137 | Master 控制节点 |
| k8swork1 | 192.168.38.141 | Worker 工作节点 |
| k8swork2 | 192.168.38.142 | Worker 工作节点 |
所有节点均使用 CentOS/RHEL 系统,后续所有操作若无特殊说明,均需在所有节点执行。
2. 加载必要内核模块
为满足 K8s 网络与转发需求,需加载overlay和br_netfilter模块:
tee /etc/modules-load.d/containerd.conf <<EOF overlay br_netfilter EOF modprobe overlay modprobe br_netfilter3. 开启 IPVS 支持(可选但推荐)
IPVS 提供更高效的负载均衡能力,创建配置文件加载相关模块:
cat >/etc/modules-load.d/ipvs.conf <<EOF ip_vs ip_vs_lc ip_vs_wlc ip_vs_rr ip_vs_wrr ip_vs_lblc ip_vs_lblcr ip_vs_dh ip_vs_sh ip_vs_fo ip_vs_nq ip_vs_sed ip_vs_ftp nf_conntrack EOF # 重启后验证模块加载 reboot lsmod | grep ip_vs4. 关闭防火墙、SELinux 与交换分区
# 关闭防火墙 systemctl stop firewalld && systemctl disable firewalld # 关闭SELinux setenforce 0 sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config grubby --update-kernel ALL --args selinux=0 # 关闭交换分区 swapoff -a cp /etc/fstab /etc/fstab.bak cat /etc/fstab.bak | grep -v swap > /etc/fstab5. 配置系统内核参数
修改/etc/sysctl.conf,开启桥接转发与 IP 转发:
cat >> /etc/sysctl.conf <<EOF vm.swappiness = 0 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-ip6tables = 1 EOF # 生效配置 sysctl -p6. 配置主机名解析
在所有节点的/etc/hosts文件中添加集群节点解析:
cat >> /etc/hosts <<EOF 127.0.0.1 localhost 172.16.213.221 k8smaster 172.16.213.222 k8swork1 172.16.213.223 k8swork2 EOF二、安装与配置 Containerd
1. 安装 Containerd
使用阿里云 Docker YUM 源安装 Containerd:
# 安装依赖工具 yum install -y yum-utils device-mapper-persistent-data lvm2 # 添加阿里云Docker源 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 安装Containerd dnf install containerd.io -y2. 生成并修改默认配置
# 生成默认配置文件 mkdir -p /etc/containerd containerd config default > /etc/containerd/config.toml # 修改配置:设置certs.d路径,用于镜像加速 sed -i 's/config_path = ""/config_path = "\/etc\/containerd\/certs.d"/g' /etc/containerd/config.toml3. 配置镜像加速器
为解决国内镜像拉取慢的问题,配置 Docker Hub 与 K8s 镜像加速:
# Docker Hub镜像加速 mkdir -p /etc/containerd/certs.d/docker.io cat > /etc/containerd/certs.d/docker.io/hosts.toml << EOF server = "https://docker.io" [host."https://hub.geekery.cn"] capabilities = ["pull", "resolve"] [host."https://docker.rainbond.cc"] capabilities = ["pull", "resolve"] EOF # registry.k8s.io镜像加速 mkdir -p /etc/containerd/certs.d/registry.k8s.io tee /etc/containerd/certs.d/registry.k8s.io/hosts.toml << 'EOF' server = "https://registry.k8s.io" [host."https://ghcr.geekery.cn"] capabilities = ["pull", "resolve", "push"] [host."https://k8s.chenby.cn"] capabilities = ["pull", "resolve", "push"] EOF4. 优化 Containerd 配置
修改配置文件,设置阿里云镜像源与 Systemd Cgroup 驱动:
# 替换K8s默认镜像源为阿里云 sed -i "s#registry.k8s.io#registry.aliyuncs.com/google_containers#g" /etc/containerd/config.toml # 启用Systemd Cgroup驱动 sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml # 启动并设置开机自启 systemctl daemon-reload && systemctl enable containerd && systemctl restart containerd三、安装 Kubeadm、Kubelet 与 Kubectl
1. 配置 Kubernetes YUM 源
使用阿里云官方 K8s 源:
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://pkgs.k8s.io/core:/stable:/v1.31/rpm/ enabled=1 gpgcheck=1 gpgkey=https://pkgs.k8s.io/core:/stable:/v1.31/rpm/repodata/repomd.xml.key exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni EOF2. 安装核心组件
yum install kubelet kubeadm kubectl cri-tools --disableexcludes=kubernetes # 设置kubelet开机自启 systemctl daemon-reload && systemctl enable kubelet && systemctl start kubelet3. 配置 crictl 工具
crictl是 CRI 兼容的容器运行时调试工具,配置其连接 Containerd:
cat > /etc/crictl.yaml <<EOF runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock timeout: 10 debug: false EOF四、初始化 K8s Master 节点
1. 查看与预下载镜像
# 查看初始化默认配置 kubeadm config print init-defaults # 查看需要的镜像列表(默认源) kubeadm config images list # 查看阿里云源的镜像列表 kubeadm config images list --image-repository registry.aliyuncs.com/google_containers2. 生成并修改初始化配置文件
# 导出默认配置 kubeadm config print init-defaults > kubeadm.yaml修改kubeadm.yaml,关键配置调整如下:
advertiseAddress:修改为 Master 节点 IP 192.168.38.137criSocket:修改为 Containerd 的 socket 路径unix:///run/containerd/containerd.sockimageRepository:修改为registry.aliyuncs.com/google_containerskubernetesVersion:修改为目标版本(如v1.31.3)
在文件末尾添加以下配置,启用 IPVS 模式与 Systemd Cgroup:
--- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: ipvs --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration cgroupDriver: systemd3. 执行集群初始化
kubeadm init --config=kubeadm.yaml初始化完成后,根据提示执行以下命令配置 kubectl:
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config # 启用kubectl自动补全 echo "source <(kubectl completion bash)" >> ~/.bashrc source ~/.bashrc五、加入 Worker 节点到集群
1. 获取集群加入命令
如果初始化时未保存 token,可在 Master 节点重新生成:
kubeadm token create --ttl 0 --print-join-command输出示例:
2. 在 Worker 节点执行加入命令
在k8swork1和k8swork2节点执行上述命令,加入集群:
kubeadm join 172.16.213.221:6443 --token bnefy8.d79yn6ylxlk7k8hr \ --discovery-token-ca-cert-hash sha256:eaa17f4b308e9406891f85f664c0d2c97a49bd9e963f64c9453b7042509e106c3. 验证节点状态
在 Master 节点执行:
kubectl get nodes此时节点状态为NotReady,因为尚未安装网络插件。
六、安装 Calico 网络插件
1. 下载并修改 Calico 配置文件
wget https://docs.projectcalico.org/manifests/calico.yaml为解决国内镜像拉取问题,修改配置文件中的镜像地址,例如:
sed -i 's#docker.io/calico#docker.m.daocloud.io/calico#g' calico.yaml也可手动提前拉取镜像:
crictl pull ghcr.geekery.cn/calico/cni:v3.25.0 crictl pull ghcr.geekery.cn/calico/node:v3.25.0 # 其他需要的镜像同理拉取2. 部署 Calico
kubectl apply -f calico.yaml3. 验证网络插件状态
# 查看节点状态,等待变为Ready kubectl get nodes # 查看kube-system命名空间下的Pod状态 kubectl get pods -n kube-system若节点长时间未就绪,可重启 kubelet 服务:
systemctl restart kubelet七、Containerd 调试工具:crictl 与 ctr
1. 工具介绍
ctr:Containerd 原生 CLI 工具,用于直接管理容器、镜像、命名空间等资源。crictl:K8s 社区定义的 CRI 兼容 CLI 工具,专为调试 K8s 容器运行时设计,支持 Pod、容器、镜像管理。
关键区别:Containerd 支持命名空间隔离,crictl默认使用k8s.io命名空间,而ctr默认使用default命名空间,因此ctr下载的镜像默认对crictl不可见。
2. 常用命令对比
以下是docker、crictl与ctr的常用命令对比:
| 功能 | Docker 命令 | crictl 命令 | ctr 命令(需指定命名空间) |
|---|---|---|---|
| 显示本地镜像列表 | docker images | crictl images | ctr -n k8s.io images list |
| 下载镜像 | docker pull | crictl pull | ctr -n k8s.io images pull |
| 上传镜像 | docker push | 无 | ctr -n k8s.io images push |
| 删除本地镜像 | docker rmi | crictl rmi | ctr -n k8s.io images rm |
| 查看镜像详情 | docker inspect IMAGE-ID | crictl inspecti IMAGE-ID | ctr -n k8s.io images info IMAGE-ID |
| 显示容器列表 | docker ps | crictl ps | ctr -n k8s.io containers list |
| 创建容器 | docker create | crictl create | ctr -n k8s.io containers create |
| 启动容器 | docker start | crictl start | ctr -n k8s.io containers start |
| 停止容器 | docker stop | crictl stop | ctr -n k8s.io containers stop |
| 删除容器 | docker rm | crictl rm | ctr -n k8s.io containers delete |
| 查看容器详情 | docker inspect | crictl inspect | ctr -n k8s.io containers info |
| attach 交互 | docker attach | crictl attach | ctr -n k8s.io tasks attach |
| exec 执行命令 | docker exec | crictl exec | ctr -n k8s.io tasks exec |
| 查看日志 | docker logs | crictl logs | 无 |
| 查看资源占用 | docker stats | crictl stats | 无 |
3. 镜像导入导出示例
crictl不支持镜像导入导出,需使用ctr工具:
# 标记镜像 ctr -n k8s.io i tag k8s.gcr.io/pause:3.2 registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2 # 导出镜像 ctr -n k8s.io i export pause.tar registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2 # 导入镜像 ctr -n k8s.io i import pause.tar结尾
本文完整演示了基于 Containerd 的 K8s 集群部署流程,从环境准备、组件安装到集群初始化、网络插件配置,再到 Containerd 调试工具的使用,覆盖了生产环境部署的核心步骤。相比传统的 Docker 方案,Containerd 更轻量、更贴合 K8s 的 CRI 标准,是当前及未来 K8s 集群的主流选择。
部署完成后,你可以通过kubectl命令管理集群资源,部署测试应用验证集群功能。后续你可以继续深入学习 K8s 的资源对象(如 Deployment、Service、Ingress 等),探索集群的高级特性与运维技巧。
如果在部署过程中遇到镜像拉取失败、节点状态异常等问题,可以通过crictl查看容器运行时日志,或通过kubectl describe命令排查 Pod 状态,快速定位问题根源。