前 言
Docker是我們常用的容器runtime,友好的CLI,豐富的社區資料,外加研發運維人員多年的經驗積累,使用Docker幾乎是沒有任何門檻的事。而k3s為了降低資源消耗,將默認的runtime修改為containerd,雖然containerd很早就已經是Docker的一部分,但是純粹使用containerd還是給大家帶來了諸多困擾。本文收集了一些社區常見的containerd問題,尋求到解決方案后整理成文,供大家需要時查閱。
入門簡介
我們都知道Kubernetes定義了自己運行時接口規范CRI,containerd雖然具備容器管理能力,但是不能被直接被Kubernetes使用。k3s作為Kubernetes的精簡版本,也是如此,k3s自身的kubelet通過cri-containerd plugin(https://github.com/containerd/cri)來驅動containerd創建Pod。
單純的Containerd沒有Docker CLI,對于經常使用Docker的用戶來說,一下就會感到不習慣。根據CRI規范,Kubernetes社區也定義了專門CLI工具crictl(https://github.com/kubernetes-sigs/cri-tools)。k3s中也內置了crictl,它被直接編譯到k3s binary中,你在安裝k3s時,會自動創建crictl的軟連接。crictl具備了和Docker CLI類似的功能:
除了crictl,k3s還內置了ctr(https://github.com/containerd/containerd/tree/master/cmd/ctr),ctr是containerd本身的CLI,更對容器和鏡像API的基本封裝:
目前k3s的containerd使用的runc-v2版本,這個版本有個巨大的優化就是針對每個Pod創建containerd-shim進程。以Traefik Pod為例,pause容器和traefik容器都是containerd-shim的子進程,這種進程劃分方式更加合理,對Kubernetes更加友好。
常用技巧
containerd相關的CLI確實沒有Docker CLI方便,比如筆者在使用containerd時碰到一個場景,期望實現對鏡像重新tag的操作,這在Docker下非常容易做到,但是在containerd下非常麻煩。crictl中并不支持這種操作,社區中也有相關issue解釋:
https://github.com/kubernetes-sigs/cri-tools/issues/438
所以我們只能使用其他方式,通常我會這樣做:
# 在一臺機去上使用docker tag轉換image
# 導出鏡像,并拷貝到k3s機器上
docker tag busybox busyboxaaa
docker save -o busybox.tar busyboxaaa
scp busybox.tar ubuntu@172.31.24.12:~/
# 用ctr導入
ctr image import busybox.tar
k3s集成的containerd的配置文件被存放在 /var/lib/rancher/k3s/agent/etc/containerd/config.toml 中,但是如果要修改其配置不能單純修改它,你需要通過模版修改它:
cd /var/lib/rancher/k3s/agent/etc/containerd
cp config.toml config.toml.tmpl
# update config.toml.tmpl
# reboot k3s to take affect
systemctl restart k3s
通常來說,我們都會在本地環境使用k3s,使用私有Registry也是不可避免的,Docker中配置私有registry是非常方便的,而在containerd中該如何配置?關于containerd的registry配置請參考:
https://github.com/containerd/cri/blob/master/docs/registry.md
值得一提的是一個特殊場景,通常你會在內網在用registry鏡像啟用一個鏡像倉庫服務,為了簡單方便,你可以不啟用tls證書而單純使用http模式。這種情況下,k3s有一個方便的配置方式,即編輯/etc/rancher/k3s/registries.yaml,比如:
$ cat /etc/rancher/k3s/registries.yaml
mirrors:
"172.31.7.129:5000":
endpoint:
- "http://172.31.7.129:5000”
$ systemctl restart k3s
重啟后,containerd的配置會出現變化,直接使用crictl命令即可拉取鏡像:
后 記
從業界的技術發展趨勢上看,Docker越來越被Kubernetes社區所拋棄,以實現CRI接口的各種容器runtime會與Kubernetes兼容性越發友好。Docker本身的迭代速度已經無法滿足容器的發展,k3s直接使用containerd可以很快跟蹤各種容器技術本身的新特性,對技術人員來說,盡早適應Docker以外的runtime,才能跟上社區主流的前進方向。