Docker, Kubernetes, OCI, CRI-O, containerd & runc:
它们是如何协同工作的?
Docker,Kubernetes 等工具来运行一个容器时会调用容器运行时(CRI)比如 containerd,CRI-O
通过容器运行时来完成容器的创建、运行、销毁等实际工作
Docker 使用的是 containerd 作为其运行时;Kubernetes 支持 containerd,CRI-O 等多种容器运行时
这些容器运行时都遵循了 OCI 规范,并通过 runc 来实现与操作系统内核交互来完成容器的创建和运行
Docker
Docker 可以轻松地构建容器镜像,从 Docker Hub 中拉取镜像,创建、启动和管理容器。实际上,当你用 Docker 运行一个容器时实际上是通过 Docker 守护程序、containerd 和 runc 来运行它。
- docker-cli:这是一个命令行工具,它是用来完成 docker pull, build, run, exec 等命令进行交互
- containerd:这是一个管理和运行容器的守护进程。它推送和拉动镜像,管理存储和网络,并监督容器的运行。
- runc:这是低级别的容器运行时间(实际创建和运行容器的东西)。它包括 libcontainer,一个用于创建容器的基于 Go 的本地实现。
containerd
containerd 是一个来自 Docker 的高级容器运行时,并实现了 CRI 规范。它是从 Docker 项目中分离出来,为容器社区提供创建新容器解决方案的基础。
所以 Docker 自己在内部使用 containerd,当你安装 Docker 时也会安装 containerd。
containerd 通过其 CRI 插件实现了 Kubernetes 容器运行时接口(CRI),它可以管理容器的整个生命周期,包括从镜像的传输、存储到容器的执行、监控再到网络。
kubernetes 1.24开始,dockershim已经从kubelet中移除,但因为历史问题docker却不支持kubernetes主推的CRI(容器运行时接口)标准,所以docker不能再作为kubernetes的容器运行时了,即从kubernetesv1.24开始不再使用docker了,而是 Containerd。
但是如果想继续使用docker的话,可以在kubelet和docker之间加上一个中间层cri-docker。cri-docker是一个支持CRI标准的shim(垫片)。一头通过CRI跟kubelet交互,另一头跟docker api交互,从而间接的实现了kubernetes以docker作为容器运行时。但是这种架构缺点也很明显,调用链更长,效率更低。
下面 演示 cri-docker的使用,但是更推荐使用containerd作为kubernetes的容器运行时
文章目录
所有节点安装docker-ce。
所有节点设置docker加速器
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://frz7i079.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
yum install docker-ce -y
systemctl enable docker --now
systemctl restart docker
安装cri-docker
到下面的链接下载最新版cri-docker
https://github.com/Mirantis/cri-dockerd/tags
tar zxf cri-dockerd-0.2.6.amd64.tgz && cp cri-dockerd/cri-dockerd /usr/bin/ &&
到下面的链接下载最新版cri-docker
https://github.com/Mirantis/cri-dockerd/tags
设置系统参数
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl -p /etc/sysctl.d/k8s.conf
https://github.com/Mirantis/cri-dockerd/tree/master/packaging/systemd
cat /usr/lib/systemd/system/cri-docker.service
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
Requires=cri-docker.socket
[Service]
Type=notify
ExecStart=/usr/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.7
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process
[Install]
WantedBy=multi-user.target
cat /usr/lib/systemd/system/cri-docker.socket
[Unit]
Description=CRI Docker Socket for the API
PartOf=cri-docker.service
[Socket]
ListenStream=%t/cri-dockerd.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker
[Install]
WantedBy=sockets.target
启动cri-docker并设置开机自动启动
systemctl daemon-reload ; systemctl enable cri-docker --now
systemctl is-active cri-docker
安装kubernetes
方法一 使用 kubeadm 安装
方法二 使用 kubekey 安装