關(guān)注 k8s 的小伙伴們都知道在 k8s1.24版 Dockershim 代碼正式的從 k8s 移除了。這也就意味著k8s 與 docker 的對接再也不像以前那么絲滑了。這篇文檔記錄一下我在使用 docker 作為 CRI 插件時部署 k8s 的步驟。我依然借助kubeadm來部署 k8s,關(guān)于 kubeadm 的使用可以參考我前面的文檔,和這篇文檔重復(fù)的步驟我就不在這兒寫了,我們只關(guān)注和docker 相關(guān)的部分。
配置 dnf 源
OpenEuler 的包管理工具使用的是 rpm,可以配置 centos 的 docker yum 源,這里我們使用阿里云的 yum 源。
創(chuàng)建文件 /etc/yum.repos.d/docker-ce.repo 并填入以下內(nèi)容:
[docker]name=Docker CE Stablebaseurl=https://download.docker.com/linux/centos/7/x86_64/stableenabled=1gpgcheck=0[extra]name=Extrabaseurl=http://mirrors.aliyun.com/centos/7/extras/x86_64/enabled=1gpgcheck=0
配置好 yum 源,執(zhí)行 dnf 命令安裝:
dnf makecachednf install docker-ce -y
注意:這里有兩個源組成,在 centos 下使用只需要配置第一個源就可以了,但是因為我使用的系統(tǒng)是openEuler,只用第一個源的話會缺很多依賴包。安裝時會報下面這些錯誤:
Last metadata expiration check: 0:00:22 ago on Wed 31 Aug 2022 04:37:29 PM CST.Error:Problem: package docker-ce-3:20.10.17-3.el7.x86_64 requires docker-ce-rootless-extras, but none of the providers can be installed- cannot install the best candidate for the job- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.0-3.el7.x86_64- nothing provides slirp.NETns >= 0.4 needed by docker-ce-rootless-extras-20.10.0-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.1-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.1-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.10-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.10-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.11-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.11-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.12-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.12-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.13-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.13-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.14-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.14-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.15-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.15-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.16-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.16-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.17-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.17-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.2-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.2-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.3-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.3-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.4-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.4-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.5-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.5-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.6-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.6-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.7-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.7-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.8-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.8-3.el7.x86_64- nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.9-3.el7.x86_64- nothing provides slirp4netns >= 0.4 needed by docker-ce-rootless-extras-20.10.9-3.el7.x86_64(try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages)
配置 docker 加速cat >/etc/docker/daemon.json << EOF"exec-opts": ["native.cgroupdriver=systemd"],"registry-mirrors" : ["https://8xpk5wnt.mirror.aliyuncs.com"EOF
systemctl restart docker
下載并配置 cri-dockered
下載地址:https://github.com/Mirantis/cri-dockerd/releases
這是比 1.24 之前多的關(guān)鍵步驟,k8s 把 dockershim 的代碼移除后,需要額外安裝 cri-dockered 充當(dāng)之前 dockershim 的角色。
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.2.5/cri-dockerd-0.2.5.amd64.tgz
注意:v0.2.5 是我寫這篇文檔是的最新的 cri-dockerd,大家在安裝的時候要注意調(diào)整這個版本號到最新。
下載完成后解壓并 copy 的 /usr/bin 目錄
tar -xf cri-dockerd-0.2.5.amd64.tgzcp cri-dockerd/cri-dockerd /usr/bin/chmod +x /usr/bin/cri-dockerd
配置 service 文件[Unit]Description=CRI Interface for Docker Application Container EngineDocumentation=https://docs.mirantis.comAfter=network-online.target firewalld.service docker.serviceWants=network-online.targetRequires=cri-docker.socket[Service]Type=notifyExecStart=/usr/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.7ExecReload=/bin/kill -s HUP $MAINPIDTimeoutSec=0RestartSec=2Restart=alwaysStartLimitBurst=3StartLimitInterval=60sLimitNOFILE=infinityLimitNPROC=infinityLimitCORE=infinityTasksMax=infinityDelegate=yesKillMode=process[Install]WantedBy=multi-user.target
注意:這里的參數(shù) --pod-infra-container-image,這個值要根據(jù)實際情況調(diào)整,如果你的安裝環(huán)境不能訪問互聯(lián)網(wǎng),那你就需要配置為內(nèi)部鏡像倉庫。
創(chuàng)建 socket 文件
創(chuàng)建一個 socker 文件以便 kubelet 與 cri-dockerd 通信
cat <<"EOF" > /usr/lib/systemd/system/cri-docker.Socket[Unit]Description=CRI Docker Socket for the APIPartOf=cri-docker.service[Socket]ListenStream=%t/cri-dockerd.sockSocketMode=0660SocketUser=rootSocketGroup=docker[Install]WantedBy=sockets.target
啟動 cri-docker
systemctl daemon-reloadsystemctl start cri-docker
使用 kubeadm 部署 k8s
這部分可以參考我之前的文檔 的部分章節(jié)初始化環(huán)境和安裝 flannel 網(wǎng)絡(luò)插件,這里就不過多贅述了。
總結(jié):在 k8是1.24 版以后我們需要額外安裝 cri-dockerd 來彌補(bǔ) k8s 中原來 dockershim 完成的功能。
k8s 為什么移除 dockershim
在之前的文章多維度聊一聊 k8s 和 openstack,我吐槽過 k8s 對 docker 的渣男行為。
當(dāng)然這只是純粹的吐槽哈,那么我們接下來就執(zhí)行探討一下 docker 移除 dockershim 的原因。
我們先來看一看 kubelet 使用 docker 作為 cri 插件創(chuàng)建容器的步驟:
- Kubelet 通過CRI 接口(gRPC) 調(diào)用 dockershim, 請求創(chuàng)建一個容器.
- dockershim 收到請求后, 轉(zhuǎn)化成 Docker Daemon 能聽懂的請求, 發(fā)到 Docker Daemon 上請求創(chuàng)建一個容器;
- Docker Daemon 早在 1.12 版本中就已經(jīng)將針對容器的操作移到另一個守護(hù)進(jìn)程: containerd 中了, 因此 Docker Daemon 仍然不能幫我們創(chuàng)建容器, 而是要請求 containerd 創(chuàng)建一個容器;
- containerd 收到請求后, 并不會自己直接去操作容器, 而是創(chuàng)建一個叫做 containerd-shim 的進(jìn)程, 讓 containerd-shim 去操作容器.
- containerd-shim 在這一步需要調(diào)用 runc 這個命令行工具, 來啟動容器;
- runc 啟動完容器后本身會直接退出, containerd-shim 則會成為容器進(jìn)程的父進(jìn)程, 負(fù)責(zé)收集容器進(jìn)程的狀態(tài), 上報給 containerd, 并在容器中 pid 為 1 的進(jìn)程退出后接管容器中的子進(jìn)程進(jìn)行清理, 確保不會出現(xiàn)僵尸進(jìn)程;
我們可以看到第 2 步和第 3 步只是起到了翻譯的工作,沒有做任何實質(zhì)操作,而且還多了一個 Docker Daemon 服務(wù)在運(yùn)行。把第 2 步和第 3 步去掉,kubelet 之間和 containerd 通信是 k8s 一直想做的事,只不過之前 containerd 還不是很成熟,使用的人也不少很多在加上 docker 本身的知名度所以 k8s 一直保留著 dockershim,k8s 做出遺棄 dockershim 的決定也是經(jīng)過深思熟慮的,同時也表明了 containerd已經(jīng)足夠成熟了。