CKA [Installation] – Container Runtime Interface (CRI) 的讲解
✅ 什么是CRI

我们需要运行一个Pod的话,通常都是Kubectl 下达命令到 MasterNode的api server , 接着ApiService 就通知WorkerNode的Kubelet , 然后Kubectl 就通知CRI , CRI才来拉取image然后创建Pod。

按照这个流程的话,Kubelet 是不直接参与Pod的创建的而是CRI。CRI是Kubernetes 指定的标准,好让Kubelet能够直接的Container Runtime来沟通。所以市面上Container Runtime 有好几种,比如Containerd , CRI-O , Docker Engine 等等。
✅ 什么是CRICTL
crictl 是一个直接和kubernetes CRI 沟通的命令工具,他就类似和docker命令行有点像。
【拉最新的nginx image到WorkerNode】
crictl pull nginx:latest
【查看当下这台WorkerNode的Pod】
crictl pods
【查看当下这台WorkerNode已经存在的images】
crictl images

✅ 什么是cri-dockerd?

Docker Engine是不支持Kubernetes标准版的CRI , 所以必须改成使用cri-dockerd 那么kubelet 才能够和docker engine沟通。
🔧 实践使用 cri-dockerd (使用ubuntu 通过kubeadm安装MasterNode)
✅ 安装Docker
1. 执行以下的3个命令行来安装docker
sudo su root
sudo apt update && apt upgrade
sudo apt install -y docker.io golang-go
sudo systemctl enable --now docker
2. 安装完之后测试
docker info

✅ 安装CRI-Docker
1. 可以从github上找出最新的安装包 ,然后进行下载
https://github.com/Mirantis/cri-dockerd

wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.20/cri-dockerd_0.3.20.3-0.ubuntu-jammy_amd64.deb
2. 安装deb包
dpkg -i cri-dockerd_0.3.20.3-0.ubuntu-jammy_amd64.deb
3. 启动和查看cri-dockerd的状态
systemctl enable cri-docker
systemctl status cri-docker

✅ 设置linux Kernel
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sudo sysctl --system
modprobe overlay
modprobe br_netfilter
✅ 配置仓库 & 安装 Kubernetes 组件
这步骤有点类似于部署MasterNode的文章:https://www.pangzai.win/cka-installation-ubuntu%e5%ae%89%e8%a3%85master-node/
1. 更新 apt 包缓存 , 安装 https 支持、证书、curl、gpg 等基础工具
sudo apt-get update
apt-get install -y apt-transport-https ca-certificates curl gpg
2. 导入 Kubernetes 仓库的 GPG key,并添加 apt 源
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.34/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.34/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
3. 查看该版本支持哪些版本(用于确认可安装版本)
apt-cache madison kubeadm

4. 安装Kubernetes组件
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
5. 启用并启动 kubelet 服务(kubelet 是节点上运行的核心组件)
sudo systemctl enable --now kubelet
6. 使用Kubeadm初始化集群, 需要等一个几十秒才能完成
这一步和创建MasterNode文章的有点不一样,这个我改用了cri-dockerd,而不是默认标准的K8s CRI
kubeadm init --pod-network-cidr=192.168.0.0/16 --cri-socket=unix:///var/run/cri-dockerd.sock
【初始化完整之后就会得到这东西, 需要保存好以便让worker node加进来使用】
kubeadm join 52.0.12.43:6443 --token 42j4sm.cw3fvwle48hq8azt \
--discovery-token-ca-cert-hash sha256:166b5ad4ff0784b3710855685a08d9db70bb5c856a4a7539206a0d3c2ccfa92e
7. 把已经设置好的Kubeconfig copy 到master node本机内,以便master node 宿主机能够访问到k8s cluster
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
8. 安装完毕测试一下
kubectl get node

✅ 移除 Taint(使 master 也能调度 Pod,可选)
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
- 默认情况下,control-plane(master)节点会被打上一个 taint,禁止普通 Pod 调度到其上
- 这条命令是移除这个 taint,让控制面节点也能承载普通工作负载(适合单节点 / 小规模集群)
- 在生产环境中,通常你不会这么做,而是保持 master 只做控制面职责,不跑普通 Pod
✅ 安装CNI网络插件(Calico)
1. 下载并 kubectl create Calico 的 operator 和自定义资源清单,以部署 Calico 网络插件
Calico 负责 Pod 之间的网络互连、网络策略、安全控制等
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.30.3/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.30.3/manifests/custom-resources.yaml
2. 必须安装CNI 之后node status 才能变成Ready , 如果是刚安装的话必须等2-3分钟来反映状态
kubectl get nodes

✅ 测试cri-docker
1. 我们特地的停掉cri-docker
systemctl stop cri-docker
systemctl status cri-docker

2. 我们执行一个pod , 我们发现pod的状态卡在pending
kubectl run pod1 --image=nginx
kubectl get pod

3. 我们可以查看pod的情况, 从pod的情况来看,kubelet找不到可用的worker node
kubectl describe pod pod1

4. 我们可以查看kubelet的log , 我们可以看到kubelet和cri-dockerd 是连不上的
-u 就是从systemctl unit的kubelet查看log
-n 就是最新50条记录
journalctl -u kubelet -n 50

5. 我们重启cri-docker , 就能看拿到pod1 创建成功了
systemctl start cri-docker

![]()