前景提要
Docker 技術使用 Linux 內核和內核功能(例如 Cgroups 和 namespaces)來分隔進程,以便各進程相互獨立運行。這種獨立性正是采用容器的目的所在;它可以獨立運行多種進程、多個應用,更加充分地發揮基礎設施的作用,同時保持各個獨立系統的安全性。
docker 對容器的管理和操作基本都是通過 containerd 完成的。 那么,containerd 是什么呢?
Containerd 是一個工業級標准的容器運行時,它強調簡單性、健壯性和可移植性。Containerd 可以在宿主機中管理完整的容器生命周期:容器鏡像的傳輸和存儲、容器的執行和管理、存儲和網絡等。詳細點說,Containerd 負責干下面這些事情:
- 管理容器的生命周期(從創建容器到銷毀容器)
- 拉取/推送容器鏡像
- 存儲管理(管理鏡像及容器數據的存儲)
- 調用 runC 運行容器(與 runC 等容器運行時交互)
- 管理容器網絡接口及網絡
containerd 跟 docker 調用關系
配置參數區別
- 日志配置
對比項 | docker | containerd |
---|---|---|
存儲路徑 | docker作為k8s容器運行時的情況下,容器日志的落盤由docker來完成, 保存在類似/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服務需要單獨配置:
[plugins.cri]
stream_server_address = "127.0.0.1"
stream_server_port = "0"
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