天天看點

符合OCI規範的容器運作時 & kubernetes CRI

螞蟻金服kubernetes方向招聘

參考前一篇文章

目前的docker已經不是之前的docker了,技術棧進行了分層。

docker cli -> dockerd -> containerd -> oci implementation

OCI規範,簡單來說,包含容器規範和鏡像規範,具體參考:

link

由于引入了OCI,我們可以近乎透明無縫的替換 “docker run”指令 之下的具體實作。

根據自己業務場景的需求,可以選擇高性能的容器運作時,也可以選擇性能不那麼高但安全性更好的運作時。

目前符合OCI規範的容器運作時有:

  • runc, docker預設的運作時,與主控端共享核心,利用cgroup做資源隔離,安全性不是很高,由于核心共享,性能最好
  • runv,基于hypervisor的容器運作時,有自己單獨的核心,安全性好很多
  • kata,被螞蟻收了,号稱“容器的速度,虛拟機的安全”,貌似是基于runv做的
  • gvisor,谷歌搞的,比runc安全,比VM性能要好。有一個使用者空間的核心,會攔截應用程式的系統調用,目前沒有實作所有的系統調用,是以不是所有的應用都可以運作

目前docker預設使用的容器運作時runc。

docker指令行有一個參數:runtime,可以制定底層的容器運作時,如

docker run --runtime=runc hello-world
           

runc官方有一個執行個體,介紹如何用runc運作一個容器

EXAMPLE:
  To run docker's hello-world container one needs to set the args parameter
in the spec to call hello. This can be done using the sed command or a text
editor. The following commands create a bundle for hello-world, change the
default args parameter in the spec from "sh" to "/hello", then run the hello
command in a new hello-world container named container1:

    mkdir hello
    cd hello
    docker pull hello-world
    docker export $(docker create hello-world) > hello-world.tar
    mkdir rootfs
    tar -C rootfs -xf hello-world.tar
    runc spec
    sed -i 's;"sh";"/hello";' config.json
    runc run container1
           

網上有一個runc 和 runv 運作示例的文章,參考: 連結

說回到kubernetes,k8s抽象出了一個CRI接口。

kubelet 通過該接口與底層不同的容器運作時進行互動,進而實作解耦。

其中的關系如下圖

符合OCI規範的容器運作時 & kubernetes CRI

kubelet通過gRPC方式調用CRI的相關接口,CRI shim是該接口的一個實作。

kubelet有一個選項“–container-runtime”,

預設為docker,可以了解為非CRI模式。

設定為remote的時候,可以認為是啟用了CRI模式,通過另外一個選項

–container-runtime-path-endpoint=

來指定CRI服務的位址,一般是一個Linux 本地Socket。

kubelet會通過指定的CRI位址來進行容器的管理。

這個圖看着可能會比較清楚

符合OCI規範的容器運作時 & kubernetes CRI

繼續閱讀