ContainerdvsDocker:誰才是K8s叢集的最佳容器執行時

前景提要

Docker 技術使用 Linux 核心和核心功能(例如 Cgroups 和 namespaces)來分隔程序,以便各程序相互獨立執行。這種獨立性正是採用容器的目的所在;它可以獨立執行多種程序、多個應用,更加充分地發揮基礎設施的作用,同時保持各個獨立系統的安全性。
為了防止docker一家獨大,docker當年的實現被拆分出了幾個標準化的模組,標準化的目的是模組是可被其他實現替換的,不由任何一個廠商控制。
docker由 docker-client ,dockerd,containerd,docker-shim,runc組成,所以containerd是docker的基礎元件之一,docker 對容器的管理和操作基本都是透過 containerd 完成的。那麼,containerd 是什麼呢?
Containerd 是一個工業級標準的容器執行時(Container Runtime Interface),它強調簡單性、健壯性和可移植性。Containerd 可以在宿主機中管理完整的容器生命週期:容器映象的傳輸和儲存、容器的執行和管理、儲存和網路等。詳細點說,Containerd 負責幹下面這些事情:
  • 管理容器的生命週期(從建立容器到銷燬容器)
  • 拉取/推送容器映象
  • 儲存管理(管理映象及容器資料的儲存)
  • 呼叫 runC 執行容器(與 runC 等容器執行時互動)
  • 管理容器網路介面及網路 
從k8s的角度看,可以選擇 containerd 或 docker 作為執行時元件:Containerd 呼叫鏈更短,元件更少,更穩定,佔用節點資源更少呼叫鏈

containerd 跟 docker 呼叫關係

配置引數區別

  • 日誌配置
對比項 docker containerd
儲路徑
docker作為k8s容器執行時的情況下,容器日誌的落盤由docker來完成,

儲存在類似/var/lib/docker/containers/CONTAINERID目錄下。

kubelet會在/var/log/pods和/var/log/containers下面建立軟連結,

指向/var/lib/docker/containers/CONTAINERID目錄下。

kubelet會在/var/log/pods和/var/log/containers下面建立軟連結,

指向/var/lib/docker/containers/CONTAINERID目錄下的容器日誌檔案
containerd作為k8s容器執行時的情況下, 容器日誌的落盤由kubelet來完成,儲存到/var/log/pods/$CONTAINER_NAME目錄下,同時在/var/log/containers目錄下建立軟連結,指向日誌檔案
配置引數 在docker配置檔案中指定:"log-driver": "json-file", "log-opts": {"max-size": "100m","max-file": "5"} 方法一:在kubelet引數中指定:–container-log-max-files=5 –container-log-max-size="100Mi" 方法二:在KubeletConfiguration中指定:"containerLogMaxSize": "100Mi","containerLogMaxFiles": 5,
把容器日誌儲存到資料盤 把資料盤掛載到"data-root"(預設是/var/lib/docker)即可 建立一個軟連結/var/log/pods指向資料盤掛載點下的某個目錄在TKE中選擇"將容器和映象儲存在資料盤",會自動建立軟連結/var/log/pods
  • stream server

    kubectl exec/logs等命令需要在apiserver跟容器執行時之間建立流轉發通道。

    docker API本身提供stream服務,kubelet內部的docker-shim會透過docker API做流轉發。

    containerd的stream服務需要單獨配置:
  1. [plugins.cri]
  2. stream_server_address "127.0.0.1"
  3. stream_server_port "0"
  4. enable_tls_streaming false
在k8s 1.11之前,kubelet並不會做stream proxy, 只會做redirect。也就是把containerd暴露的stream server地址告訴apiserver, 讓apiserver直接來訪問containerd的stream server。這種情況下,需要給stream server使能tle認證來做安全防護。
從k8s1.11引入了kubelet stream proxy (https://github.com/kubernetes/kubernetes/pull/64006), 從而使得containerd stream server只需要監聽本地地址即可。
  • CNI網路
對比項 docker containerd
誰負責呼叫CNI kubelet內部的docker-shim containerd內建的cri-plugin(containerd 1.1以後)
如何配置CNI kubelet引數 –cni-bin-dir 和 –cni-conf-dir containerd配置檔案(toml):plugins.cri.cni bin_dir = "/opt/cni/bin" conf_dir = "/etc/cni/net.d"
  • 命令對比
containerd不支援docker API和docker CLI, 但是可以透過cri-tool實現類似的功能。
映象相關功能 docker containerd
顯示本地映象列表 docker images crictl images
下載映象 docker pull crictl pull
上傳映象 docker push
刪除本地映象 docker rmi crictl rmi
檢視映象詳情 docker inspect crictl inspecti
容器相關功能 docker containerd
顯示容器列表 docker ps crictl ps
建立容器 docker create crictl create
啟動容器 docker start crictl start
停止容器 docker stop crictl stop
刪除容器 docker rm crictl rm
檢視容器詳情 docker inspect crictl inspect
attach docker attach crictl attach
exec docker exec crictl exec
logs docker logs crictl logs
stats docker stats crictl stats
POD相關功能 docker containerd
顯示POD列表 crictl pods
檢視POD詳情 crictl inspectp
執行POD crictl runp
停止POD crictl stopp

拓展閱讀

接下來就是crictl的的常見命令,其中能完全替代docker命令的參照下列表格
crictl對容器生命週期的管理基本已經覆蓋,不過在crictl我們不能完成操作也比較多,比如對映象的管理就不屬於它的管理範圍。這部分還得依靠ctr來實現,操作方式同樣可以參照下表

需注意的是,由於Containerd也有namespaces的概念,對於上層編排系統的支援,主要區分了3個名稱空間分別是k8s.io、moby和default,以上我們用crictl操作的均在k8s.io名稱空間完成如檢視映象列表就需要加上-n引數

ctr -n k8s.

io

images list

連結:https://www.cnblogs.com/xiexun/p/18268677
(版權歸原作者所有,侵刪)


相關文章