做者 | 易立 阿里雲資深技術專家html
containerd 是一個開源的行業標準容器運行時,關注於簡單、穩定和可移植,同時支持 Linux 和 Windows。node
containerd 從 1.1 版本開始就已經內置了 Container Runtime Interface (CRI) 支持,進一步簡化了對 Kubernetes 的支持。其架構圖以下:nginx
在 Kubernetes 場景下,containerd 與完整 Docker Engine 相比,具備更少的資源佔用和更快的啓動速度。git
圖片來源:containerdgithub
紅帽主導的 cri-o 是與 containerd 競爭的容器運行時管理項目。containerd 與 cri-o 項目相比,在性能上具有優點,在社區支持上也更加普遍。api
圖片來源:ebay 的分享安全
更重要的是 containerd 提供了靈活的擴展機制,支持各類符合 OCI(Open Container Initiative)的容器運行時實現,好比 runc 容器(也是熟知的 Docker 容器)、KataContainer、gVisor 和 Firecraker 等安全沙箱容器。微信
在 Kubernetes 環境中,能夠用不一樣的 API 和命令行工具來管理容器 / Pod、鏡像等概念。爲了便於你們理解,咱們能夠用下圖說明如何利用不一樣層次的 API 和 CLI 管理容器生命週期管理。網絡
Minikube 是體驗 containerd 做爲 Kubernetes 容器運行時的最簡單方式,咱們下面將其做爲 Kubernetes 容器運行時,並支持 runc 和 gvisor 兩種不一樣的實現。架構
早期因爲網絡訪問緣由,不少朋友沒法直接使用官方 Minikube 進行實驗。在最新的 Minikube 1.5 版本中,已經提供了完善的配置化方式,能夠幫助你們利用阿里雲的鏡像地址來獲取所需 Docker 鏡像和配置,同時支持 Docker/Containerd 等不一樣容器運行時。咱們建立一個 Minikube 虛擬機環境,注意須要指明 --container-runtime=containerd
參數設置 containerd 做爲容器運行時。同時 registry-mirror 也要替換成本身的阿里雲鏡像加速地址。
$ minikube start --image-mirror-country cn \ --iso-url=https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.5.0.iso \ --registry-mirror=https://XXX.mirror.aliyuncs.com \ --container-runtime=containerd Darwin 10.14.6 上的 minikube v1.5.0 Automatically selected the 'hyperkit' driver (alternates: [virtualbox]) ️ 您所在位置的已知存儲庫都沒法訪問。正在將 registry.cn-hangzhou.aliyuncs.com/google_containers 用做後備存儲庫。 正在建立 hyperkit 虛擬機(CPUs=2,Memory=2000MB, Disk=20000MB)... ️ VM is unable to connect to the selected image repository: command failed: curl -sS https://k8s.gcr.io/ stdout: stderr: curl: (7) Failed to connect to k8s.gcr.io port 443: Connection timed out : Process exited with status 7 正在 containerd 1.2.8 中準備 Kubernetes v1.16.2… 拉取鏡像 ... 正在啓動 Kubernetes ... ⌛ Waiting for: apiserver etcd scheduler controller 完成!kubectl 已經配置至 "minikube" $ minikube dashboard Verifying dashboard health ... Launching proxy ... Verifying proxy health ... Opening http://127.0.0.1:54438/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ in your default browser...
咱們經過 Pod 部署一個 nginx 應用:
$ cat nginx.yaml apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx $ kubectl apply -f nginx.yaml pod/nginx created $ kubectl exec nginx -- uname -a Linux nginx 4.19.76 #1 SMP Fri Oct 25 16:07:41 PDT 2019 x86_64 GNU/Linux
而後,咱們開啓 minikube 對 gvisor 支持:
$ minikube addons enable gvisor gvisor was successfully enabled $ kubectl get pod,runtimeclass gvisor -n kube-system NAME READY STATUS RESTARTS AGE pod/gvisor 1/1 Running 0 60m NAME CREATED AT runtimeclass.node.k8s.io/gvisor 2019-10-27T01:40:45Z $ kubectl get runtimeClass NAME CREATED AT gvisor 2019-10-27T01:40:45Z
當 gvisor
pod 進入 Running
狀態的時候,能夠部署 gvisor 測試應用。
咱們能夠看到 K8s 集羣中已經註冊了一個 gvisor
的「runtimeClassName」。以後,開發者能夠經過在 Pod 聲明中的 「runtimeClassName」 來選擇不一樣類型的容器運行時實現。好比,以下咱們建立一個運行在 gvisor 沙箱容器中的 nginx 應用。
$ cat nginx-untrusted.yaml apiVersion: v1 kind: Pod metadata: name: nginx-untrusted spec: runtimeClassName: gvisor containers: - name: nginx image: nginx $ kubectl apply -f nginx-untrusted.yaml pod/nginx-untrusted created $ kubectl exec nginx-untrusted -- uname -a Linux nginx-untrusted 4.4 #1 SMP Sun Jan 10 15:06:54 PST 2016 x86_64 GNU/Linux
咱們能夠清楚地發現:因爲基於 runc 的容器與宿主機共享操做系統內核,runc 容器中查看到的 OS 內核版本與 Minikube 宿主機 OS 內核版本相同;而 gvisor 的 runsc 容器採用了獨立內核,它和 Minikube 宿主機 OS 內核版本不一樣。
正是由於每一個沙箱容器擁有獨立的內核,減少了安全攻擊面,具有更好的安全隔離特性。適合隔離不可信的應用,或者多租戶場景。注意:gvisor 在 minikube 中,經過 ptrace 對內核調用進行攔截,其性能損耗較大,此外 gvisor 的兼容性還有待加強。
咱們如今能夠進入進入 Minikube 虛擬機:
$ minikube ssh
containerd 支持經過名空間對容器資源進行隔離,查看現有 containerd 名空間:
$ sudo ctr namespaces ls NAME LABELS k8s.io
# 列出全部容器鏡像 $ sudo ctr --namespace=k8s.io images ls ... # 列出全部容器列表 $ sudo ctr --namespace=k8s.io containers ls
在 Kubernetes 環境更加簡單的方式是利用 crictl
對 pods 進行操做。
# 查看pod列表 $ sudo crictl pods POD ID CREATED STATE NAME NAMESPACE ATTEMPT 78bd560a70327 3 hours ago Ready nginx-untrusted default 0 94817393744fd 3 hours ago Ready nginx default 0 ... # 查看名稱包含nginx的pod的詳細信息 $ sudo crictl pods --name nginx -v ID: 78bd560a70327f14077c441aa40da7e7ad52835100795a0fa9e5668f41760288 Name: nginx-untrusted UID: dda218b1-d72e-4028-909d-55674fd99ea0 Namespace: default Status: Ready Created: 2019-10-27 02:40:02.660884453 +0000 UTC Labels: io.kubernetes.pod.name -> nginx-untrusted io.kubernetes.pod.namespace -> default io.kubernetes.pod.uid -> dda218b1-d72e-4028-909d-55674fd99ea0 Annotations: kubectl.kubernetes.io/last-applied-configuration -> {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"nginx-untrusted","namespace":"default"},"spec":{"containers":[{"image":"nginx","name":"nginx"}],"runtimeClassName":"gvisor"}} kubernetes.io/config.seen -> 2019-10-27T02:40:00.675588392Z kubernetes.io/config.source -> api ID: 94817393744fd18b72212a00132a61c6cc08e031afe7b5295edafd3518032f9f Name: nginx UID: bfcf51de-c921-4a9a-a60a-09faab1906c4 Namespace: default Status: Ready Created: 2019-10-27 02:38:19.724289298 +0000 UTC Labels: io.kubernetes.pod.name -> nginx io.kubernetes.pod.namespace -> default io.kubernetes.pod.uid -> bfcf51de-c921-4a9a-a60a-09faab1906c4 Annotations: kubectl.kubernetes.io/last-applied-configuration -> {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"nginx","namespace":"default"},"spec":{"containers":[{"image":"nginx","name":"nginx"}]}} kubernetes.io/config.seen -> 2019-10-27T02:38:18.206096389Z kubernetes.io/config.source -> api
不少同窗都關心 containerd 與 Docker 的關係,以及是否 containerd 能夠取代 Docker?
containerd 已經成爲容器運行時的主流實現,也獲得了 Docker 社區和 Kubernetes 社區的大力支持。Docker Engine 底層的容器生命週期管理也是基於 containerd 實現。
可是 Docker Engine 包含了更多的開發者工具鏈,好比鏡像構建。也包含了 Docker 本身的日誌、存儲、網絡、Swarm 編排等能力。此外,絕大多數容器生態廠商,如安全、監控、開發等對 Docker Engine 的支持比較完善,對 containerd 的支持也在逐漸補齊。
因此在 Kubernetes 運行時環境,對安全和效率和定製化更加關注的用戶能夠選擇 containerd 做爲容器運行時環境;對於大多數開發者,繼續使用 Docker Engine 做爲容器運行時也是一個不錯的選擇。
在阿里雲 Kubernetes 服務 ACK,咱們已經採用 containerd 做爲容器運行時管理,來支撐安全沙箱容器和 runc 容器的混合部署。在現有產品中,咱們和阿里雲操做系統團隊、螞蟻金服一塊兒支持了基於輕量虛擬化的 runV 沙箱容器,4Q 也將和操做系統團隊、安全團隊合做發佈基於 Intel SGX 的可信加密沙箱容器。
具體產品信息能夠參考該文檔。
Serverless Kubernetes(ASK)中,咱們也利用 containerd 靈活的插件機制定製和剪裁了面向 nodeless 環境的容器運行時實現。
「 阿里巴巴雲原生微信公衆號(ID:Alicloudnative)關注微服務、Serverless、容器、Service Mesh等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,作最懂雲原生開發者的技術公衆號。」