CRI概述
容器運行時(Container Runtime):顧名思義就是容器從拉取鏡像到啟動運行再到中止的整個生命周期。 其中最知名的就是Docker了,除此之外市面上還有containerd,rkt等。
(類似於Web服務除了nginx還有apache...)
每個容器運行時都有特點,因此不少用戶希望Kubernetes能夠支持更多的容器運行時。為了更具擴展性,kubernetes引入了容器運行時插件API,即 Container Runtime Interface,簡稱CRI。
CRI中定義了容器和鏡像的服務的接口。因為容器運行時 與鏡像的生命周期是彼此隔離的,因此需要定義兩個服務。該接口使用Protocol Buffer, 基於gRPC. 這兩種服務定義在 kubernetes/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2/api.proto 中
Protocol Buffers API(一種更高效的類似json的數據格式)包含兩個gRPC服務:
ImageService和RuntimeService。
ImageService提供了從倉庫拉取鏡像、查看和移除鏡像的功能。
RuntimeService負責Pod和容器的生命周期管理,以及與容器的交互 (exec/attach/port-forward)。
rkt和Docker這樣的容器運行時可以使用一 個Socket同時提供兩個服務,在kubelet中可以用--container-runtime- endpoint和--image-service-endpoint參數設置這個Socket。
Docker的CRI實現, 在Kubernetes 1.6中被更新為Beta版本,並在kubelet啟動時默認啟動。
可替代的容器運行時支持在Kubernetes中的概念並非首次。在Kubernetes 1.3發布時,rktnetes項目同時發布,讓rkt容器引擎成為除Docker外的又一選擇。
不管是Docker還是rkt,都需要通過內部、不太穩定的接口直接集成到kubelet的源碼中,同kubelet源碼糾纏不清。
這種程度的集成需要對kubelet的內部機制有非常深入的了解,還會給社區帶來維護管理壓力,這就給新生代容器運行時造成了難於跨越的集成壁壘。
CRI的主要組件
CRI包含一組Protocol Buffers、gRPC API、運行庫支持! 及開發中的標准規范和工具。CRI目前是v1alpha2版本.
Container Runtime實現了CRI gRPC Server,包括RuntimeService 和ImageService。
該gRPC Server需要監聽本地的Unix socket,而kubelet則作為gRPC Client運行。
Kubelet與容器運行時通信(或者是CRI插件填充了容器運行時)時,Kubelet就像是客戶端,而CRI插件就像對應的服務器。如圖所示。(kubelet組件的主要功能:啟動和停止容器。)
kubelet使用 gRPC框架(google 遠程過程調用) 通過UNIX Socket與容器運行時(或CRI代 理)進行通信。
名詞解釋:RPC 注解:一種通過網絡從遠程計算機程序上請求服務,而不需要了解底層網絡技術的協議
CRI在Kubelet與docker之間實現了CRI shim中間層。
1:CRI shim的gRPC server監聽unix:///var/run/dockershim.sock,kubelet的gRPC client連接這個socket。
2: kubelet與CRI shim的數據傳輸使用gRPC、而數據格式采用protobuf。
3:CRI shim使用engine-api建立一個連接unix:///var/run/docker.sock的client,通過docker API控制容器生命周期以及鏡像管理。
Pod和容器的生命周期管理
podsandbox:共有環境
Pod由一組應用容器組成,其中包含共有的環境和資源約束。在CRI里,這個環境被稱為PodSandbox。
PodSandbox就是Pod的這個環境, 也就是說Pod這個抽象概念的表現就是PodSandbox<共有環境>、應用容器和一些資源約束.
Kubernetes有意為容器運行時 留下一些發揮空間,它們可以根據自己的內部實現來生成不同的PodSandbox:
1:對於基於Hypervisor的運行時,PodSandbox會具體化為一個虛擬機!!!。 2: 其他例如Docker,會是一個Linux命名空間!!!。
kubelet創建cgroup: 資源保障
在v1alpha1版API中,kubelet會創建Pod級別的cgroup 傳遞給容器運行時,並以此運行所有進程 來滿足PodSandbox對Pod的資源保障。
生命周期:
在啟動Pod之前,kubelet調用RuntimeService.RunPodSandbox來創建環境。這一過程包括為Pod設置網絡資源(分配IP等操作, 涉及CNI)。
PodSandbox被激活之后,就可以獨立地創建、啟動、停止和刪除不同的容器了。
kubelet會在停止和刪除PodSandbox之前首先停止和刪除其中的容器。
kubelet的職責在於通過RPC!!! 管理容器的生命周期,實現容器生命周期的鈎子,存活和健康監測,以及執行Pod的重啟策略等。