天天看點

K8s 棄用 Docker!一文介紹 containerd ctr、crictl 使用

作者:LinkSLA智能運維管家

containerd 是一個進階容器運作時,又名 容器管理器。簡單來說,它是一個守護程序,在單個主機上管理完整的容器生命周期:建立、啟動、停止容器、拉取和存儲鏡像、配置挂載、網絡等。

containerd 旨在輕松嵌入到更大的系統中。Docker 在底層使用 containerd 來運作容器。Kubernetes 可以通過 CRI 使用 containerd 來管理單個節點上的容器。但是較小的項目也可以從與 containerd 的輕松內建中受益——例如,faasd 使用 containerd(我們需要更多的 d!)在獨立伺服器上啟動一個服務。

K8s 棄用 Docker!一文介紹 containerd ctr、crictl 使用

但是,以程式設計方式使用 containerd 并不是唯一的選擇。它還可以通過可用用戶端之一從指令行使用。由此産生的容器 UX 可能不像 docker 用戶端提供的那樣全面和使用者友好,但它仍然是有用的,例如,用于調試或學習目的。

K8s 棄用 Docker!一文介紹 containerd ctr、crictl 使用

如何在 ctr 中使用 containerd

ctr 是作為 containerd 項目的一部分提供的指令行用戶端。如果您在機器上運作了 containerd,則 ctr 二進制檔案很可能也在那裡。

該 ctr 界面 與 Docker CLI 不相容,乍一看,可能看起來不那麼使用者友好。顯然,它的主要閱聽人是測試守護程序的容器開發人員。但是,由于它是最接近實際 containerd API 的東西,是以它可以作為一種很好的探索手段——通過檢查可用指令,您可以大緻了解 containerd 可以做什麼和不能做什麼。

ctr 也非常适合學習的能力低級别的使用人員,因為 ctr + containerd 是更接近實際的容器比 docker + dockerd。

使用 ctr 處理容器鏡像

拉取鏡像,似乎是必需和完全合規的,但是你不能忽略系統資料庫或标簽部分:

$ ctr images pull docker.io/library/nginx:1.21
$ ctr images pull docker.io/kennethreitz/httpbin:latest
$ ctr images pull docker.io/kennethreitz/httpbin:latest
$ ctr images pull quay.io/quay/redis:latest
           

要列出本地鏡像,可以使用:

$ ctr images ls
           

令人驚訝的是,containerd 不提供開箱即用的鏡像建構支援。但是 containerd 經常被更進階别的工具用來建構鏡像。

ctr 您可以導入使用 docker build 或其他 OCI 相容軟體建構的現有鏡像,而不是使用建構鏡像:

$ docker build -t my-app .
$ docker save -o my-app.tar my-app

$ ctr images import my-app.tar
           

使用 ctr,您還可以學習和探索下挂載鏡像:

$ mkdir /tmp/httpbin
$ ctr images mount docker.io/kennethreitz/httpbin:latest /tmp/httpbin

$ ls -l /tmp/httpbin/
total 80
drwxr-xr-x 2 root root 4096 Oct 18  2018 bin
drwxr-xr-x 2 root root 4096 Apr 24  2018 boot
drwxr-xr-x 4 root root 4096 Oct 18  2018 dev
drwxr-xr-x 1 root root 4096 Oct 24  2018 etc
drwxr-xr-x 2 root root 4096 Apr 24  2018 home
drwxr-xr-x 3 root root 4096 Oct 24  2018 httpbin
...

$ ctr images unmount /tmp/httpbin
           

要使用删除鏡像 ctr,請運作:

$ ctr images remove docker.io/library/nginx:1.21
           

使用 ctr 處理容器

你可以運作一個容器用ctr run image-ref container-id。例如:

$ ctr run --rm -t docker.io/library/debian:latest cont1

請注意,ctr 與使用者友好地 docker run 為您生成唯一容器 ID 不同,您必須自己提供唯一容器 ID。該 ctr run 指令還隻支援一些熟悉的 docker run 标志:--env,-t,--tty,-d,--detach,--rm等,但沒有端口指定或自動重新開機容器--restart=always。

與鏡像類似,您可以使用以下指令列出現有容器:

$ ctr containers ls

有趣的是,該 ctr run 指令實際上是快捷方式ctr container create + ctr task start:

$ ctr container create -t docker.io/library/nginx:latest nginx_1
$ ctr container ls
CONTAINER    IMAGE                              RUNTIME
nginx_1      docker.io/library/nginx:latest     io.containerd.runc.v2

$ ctr task ls
TASK    PID    STATUS        # Empty!

$ ctr task start -d nginx_1  # -d for --detach
$ ctr task list
TASK     PID      STATUS
nginx_1  10074    RUNNING
           

我喜歡 container 和 task 子指令的這種分離,因為它反映了 OCI 容器經常被遺忘的性質。盡管普遍認為容器不是程序 -容器是資源被隔離和執行受限制的程序。

使用 ctr task attach,您可以重新連接配接到在容器内運作的現有任務的 stdio 流:

$ ctr task attach nginx_1
2021/09/12 15:42:20 [notice] 1#1: using the "epoll" event method
2021/09/12 15:42:20 [notice] 1#1: nginx/1.21.3
2021/09/12 15:42:20 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
2021/09/12 15:42:20 [notice] 1#1: OS: Linux 4.19.0-17-amd64
2021/09/12 15:42:20 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1024:1024
2021/09/12 15:42:20 [notice] 1#1: start worker processes
2021/09/12 15:42:20 [notice] 1#1: start worker process 31
...
           

與 docker 非常相似,您可以在現有容器中執行指令:

$ ctr task exec -t --exec-id bash_1 nginx_1 bash

# From inside the container:
$ root@host:/# curl 127.0.0.1:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
...
           

在删除容器之前,必須停止其所有任務:$ ctr task kill -9 nginx_1

或者,您可以使用以下标志--force 删除正在運作的任務:

$ ctr task rm -f nginx_1

最後,要删除容器,請運作:

$ ctr container rm nginx_1

如何在 nerdctl 中使用 containerd

nerdctl 是一個相對較新的 containerd 指令行用戶端。與 ctr,nerdctl 旨在使用者友好且與 Docker 相容。在某種程度上,nerdctl + containerd可以無縫替換docker + dockerd. 但是,這似乎不是該項目的目标:

nerdctl 其目标是促進試驗 Docker 中不存在的 containerd 的尖端功能。此類功能包括但不限于延遲拉取 (stargz) 和圖像加密 (ocicrypt)。預計這些功能最終也将在 Docker 中可用,但是,這可能需要幾個月甚至幾年的時間,因為 Docker 目前被設計為僅使用容器子系統的一小部分。重構 Docker 以使用整個 containerd 是可能的,但并不簡單。是以我們決定建立一個完全使用 containerd 的新 CLI,但我們不打算用 Docker 來完成。我們一直在為 Docker/Moby 以及 containerd 做出貢獻,并将繼續這樣做。

從基本使用的角度來看,與 相比 ctr,nerdctl 支援:

  • 鏡像管理 nerdctl build
  • 容器網絡管理
  • Docker 與 nerdctl compose up

最酷的部分是 nerdctl 嘗試提供與 docker(和 podman)相同的指令行使用者體驗。是以,如果您熟悉 docker(或 podman)CLI,那麼您已經熟悉 nerdctl.

如何在 crictl 中使用 containerd

crictl 是 Kubernetes CRI 相容容器運作時的指令行用戶端。

引入了 Kubernetes 容器運作時接口 (CRI)以使 Kubernetes 容器運作時充滿魔法。Kubernetes 節點代理 kubelet 實作了 CRI 用戶端 API,可以使用任何實作 CRI 伺服器 API 的容器運作時來管理其節點上的容器和 pod。
K8s 棄用 Docker!一文介紹 containerd ctr、crictl 使用

從 1.1 版開始,containerd 帶有一個内置的 CRI 插件。是以,containerd 是一個相容 CRI 的容器運作時。是以,它可以與 crictl 共存.

crictl 建立用于檢查和調試 Kubernetes 節點上的容器運作時和應用程式。它支援以下操作:

attach: Attach to a running container
create: Create a new container
exec: Run a command in a running container
version: Display runtime version information
images, image, img: List images
inspect: Display the status of one or more containers
inspecti: Return the status of one or more images
imagefsinfo: Return image filesystem info
inspectp: Display the status of one or more pods
logs: Fetch the logs of a container
port-forward: Forward local port to a pod
ps: List containers
pull: Pull an image from a registry
run: Run a new container inside a sandbox
runp: Run a new pod
rm: Remove one or more containers
rmi: Remove one or more images
rmp: Remove one or more pods
pods: List pods
start: Start one or more created containers
info: Display information of the container runtime
stop: Stop one or more running containers
stopp: Stop one or more running pods
update: Update one or more running containers
config: Get and set crictl client configuration options
stats: List container(s) resource usage statistics
           

這裡有趣的部分是,通過 crictl + containerdbundle 可以了解 pod 是如何實作的,但是這個話題值得自己去探索。