作者 | 易立 阿里云资深技术专家
containerd 是一个开源的行业标准容器运行时,关注于简单、稳定和可移植,同时支持 Linux 和 Windows。

* 2016 年 12 月 14 日,Docker 公司宣布将 Docker Engine 的核心组件 containerd 捐赠到一个新的开源社区独立发展和运营。阿里云、AWS、 Google、IBM 和 Microsoft 作为初始成员,共同建设 containerd 社区;
* 2017 年 3 月,Docker 将 containerd 捐献给 CNCF(云原生计算基金会)。containerd 得到了快速的发展和广泛的支持;
* Docker 引擎已经将 containerd 作为容器生命周期管理的基础,Kubernetes 也在 2018 年 5 月,正式支持 containerd 作为容器运行时管理器;
* 2019 年 2 月,CNCF 宣布 containerd 毕业,成为生产可用的项目。
containerd 从 1.1 版本开始就已经内置了 Container Runtime Interface (CRI) 支持,进一步简化了对 Kubernetes 的支持。其架构图如下:

在 Kubernetes 场景下,containerd 与完整 Docker Engine 相比,具有更少的资源占用和更快的启动速度。


图片来源:[containerd](https://yq.aliyun.com/go/articleRenderRedirect?url=https%3A%2F%2Fkubernetes.io%2Fblog%2F2018%2F05%2F24%2Fkubernetes-containerd-integration-goes-ga%2F)
红帽主导的 cri-o 是与 containerd 竞争的容器运行时管理项目。containerd 与 cri-o 项目相比,在性能上具备优势,在社区支持上也更加广泛。

图片来源:[ebay 的分享](https://yq.aliyun.com/go/articleRenderRedirect?url=https%3A%2F%2Fwww.infoq.cn%2Farticle%2FodSLClSjvO8BNx)
更重要的是 containerd 提供了灵活的扩展机制,支持各种符合 OCI(Open Container Initiative)的容器运行时实现,比如 runc 容器(也是熟知的 Docker 容器)、KataContainer、gVisor 和 Firecraker 等安全沙箱容器。

在 Kubernetes 环境中,可以用不同的 API 和命令行工具来管理容器 / Pod、镜像等概念。为了便于大家理解,我们可以用下图说明如何利用不同层次的 API 和 CLI 管理容器生命周期管理。

* Kubectl:是集群层面的命令行工具,支持 Kubernetes 的基本概念
* [crictl](https://yq.aliyun.com/go/articleRenderRedirect?spm=a2c4e.11153940.0.0.60875022IQ6dSV&url=https%3A%2F%2Fgithub.com%2Fcontainerd%2Fcri%2Fblob%2Fmaster%2Fdocs%2Fcrictl.md):是针对节点上 CRI 的命令行工具
* [ctr](https://yq.aliyun.com/go/articleRenderRedirect?spm=a2c4e.11153940.0.0.60875022IQ6dSV&url=https%3A%2F%2Fgithub.com%2Fcontainerd%2Fcontainerd%2Fblob%2Fmaster%2Fdocs%2Fman%2Fctr.1.md):是针对 containerd 的命令行工具
体验
--
Minikube 是体验 containerd 作为 Kubernetes 容器运行时的最简单方式,我们下面将其作为 Kubernetes 容器运行时,并支持 runc 和 gvisor 两种不同的实现。
早期由于网络访问原因,很多朋友无法直接使用官方 Minikube 进行实验。在最新的 Minikube 1.5 版本中,已经提供了完善的配置化方式,可以帮助大家利用阿里云的镜像地址来获取所需 Docker 镜像和配置,同时支持 Docker/Containerd 等不同容器运行时。我们[创建](https://yq.aliyun.com/articles/221687?spm=a2c4e.11153940.0.0.60875022IQ6dSV)一个 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 的兼容性还有待增强。
使用 ctl 和 crictl 工具
------------------
我们现在可以进入进入 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?
containerd 已经成为容器运行时的主流实现,也得到了 Docker 社区和 Kubernetes 社区的大力支持。Docker Engine 底层的容器生命周期管理也是基于 containerd 实现。

但是 Docker Engine 包含了更多的开发者工具链,比如镜像构建。也包含了 Docker 自己的日志、存储、网络、Swarm 编排等能力。此外,绝大多数容器生态厂商,如安全、监控、开发等对 Docker Engine 的支持比较完善,对 containerd 的支持也在逐渐补齐。
所以在 Kubernetes 运行时环境,对安全和效率和定制化更加关注的用户可以选择 containerd 作为容器运行时环境;对于大多数开发者,继续使用 Docker Engine 作为容器运行时也是一个不错的选择。
阿里云容器服务对 containerd 的支持
-----------------------
在阿里云 Kubernetes 服务 ACK,我们已经采用 containerd 作为容器运行时管理,来支撑安全沙箱容器和 runc 容器的混合部署。在现有产品中,我们和阿里云操作系统团队、蚂蚁金服一起支持了基于轻量虚拟化的 runV 沙箱容器,4Q 也将和操作系统团队、安全团队合作发布基于 Intel SGX 的可信加密沙箱容器。

具体产品信息可以参考[该文档](https://help.aliyun.com/document_detail/140541.html?spm=a2c4e.11153940.0.0.60875022IQ6dSV)。
Serverless Kubernetes(ASK)中,我们也利用 containerd 灵活的插件机制定制和剪裁了面向 nodeless 环境的容器运行时实现。
[原文链接](https://yq.aliyun.com/articles/727308?utm_content=g_1000089999)[containerd 与安全沙箱的 Kubernetes 初体验](https://yq.aliyun.com/articles/727308?utm_content=g_1000089999)[原文链接](https://yq.aliyun.com/articles/727308?utm_content=g_1000089999)
本文为云栖社区原创内容,未经允许不得转载。
分享到:
相关推荐
四、安全沙箱的挑战与限制 尽管Flash安全沙箱提供了许多保护,但它并非无懈可击。过去,许多安全漏洞被发现,允许攻击者绕过沙箱限制,执行恶意代码。随着HTML5等现代技术的兴起,Flash逐渐被淘汰,许多浏览器已经...
### FLEX安全沙箱实用指南 #### 一、引言 在进行FLEX开发时,了解和掌握FLEX的安全沙箱机制对于确保应用程序的安全性至关重要。本文将详细介绍FLEX安全沙箱的相关概念及其应用场景,帮助开发者更好地理解如何在...
Edge Kubernetes 是一种边缘计算场景下的解决方案,可以提供安全沙箱容器和 Kubernetes 集群管理。 安全沙箱容器 @edge 方案可以提供以下特点: 1. 云边端相互协同,提供统一的交付、运维、管控标准。 2. 云端统一...
总的来说,这个组件的目的是为了解决AS3应用在与服务器通信时遇到的安全沙箱限制。通过正确配置和使用提供的工具,开发者能够创建跨越沙箱限制的安全通信链路,实现Flash内容的网络功能,同时确保用户系统的安全性。...
这个概念是在Flex 4之后尤其受到关注,因为当时在Internet Explorer中出现了与安全沙箱相关的挑战。沙箱模型类似于浏览器的同源策略,确保不同来源的内容不会未经授权地相互交互。 Flex安全沙箱主要分为两类:远程...
1.安全沙箱容器 2.EdgeKubernetes 3.安全沙箱容器@edge方案 4.新探索 随着云计算边界不断向边缘侧延展,5G 和物联网技术的蓬勃发展给边缘计算带来了巨大机遇的同时,也带来了极大的挑战,传统 runc 容器已无法满足...
当我们面临“Java, C#, Delphi 解决 Flash 安全沙箱问题”的场景时,这意味着我们需要在这些编程语言中处理与 Flash 沙箱相关的安全问题,以确保应用程序的安全性和合规性。 首先,让我们深入了解一下 Flash 的安全...
用户可以在要要安全沙箱环境中运行浏览器,软件等程序,沙箱中运行和程序不会对系统和电脑产生任何的实际的更改和影响,程序运行所产生的变化会在结束程序束后后删除,快来下载体验吧。 无痕上网功能: 要要安全沙箱...
网上的方法很多,我看了好多,但是就是不管用,我的情况是,在程序没发布时,直接运行没错误,但是当发布时,访问就错了,提示SecurityError: Error #2048: 安全沙箱冲突:http://localhost:8086/index.swf 不能从 ...
在IT领域,尤其是在Flash开发中,安全沙箱是一个至关重要的概念。它是一种设计机制,用于限制ActionScript(AS)代码的执行权限,以保护用户的计算机系统免受恶意代码的侵害。安全沙箱允许Flash内容在特定的安全环境...
至于“工具”标签,意味着可能有实用的工具或脚本与这个话题相关,可能是用于检测、测试沙箱安全性的工具,或者是辅助绕过沙箱的工具。 由于没有具体的压缩包内容,我们无法提供更深入的分析。但是,通常情况下,...
Kubernetes游乐场 这个项目是一个游乐场,您可以在一个安全的沙箱中使用Kubernetes。 它提供: 在集群虚拟机(VM)上的Kubernetes全自动安装。 群集的虚拟机由Vagrant管理。 Kubernetes Playground与主要的操作系统...
在使用ArcGIS API for Flex开发WebGIS应用时,安全沙箱问题是一个重要的考虑因素,它涉及到数据的安全性和应用程序的跨域访问控制。Flex是Adobe Flash平台的一部分,用于创建丰富的互联网应用,而ArcGIS API for ...
《Flex与.NET基于Socket的网络连接 收藏 .txt》和《Flex flash_player9 沙箱安全解决方案.txt》可能讨论了Flex应用程序与.NET服务通过Socket通信时如何处理安全沙箱问题,以及在Flash Player 9中如何解决这些问题的...
3. 受信任的本地沙箱:注册为受信任的本地SWF文件放置在此沙箱中,它们可以与其他任何SWF文件交互,并且可以从任何位置读取数据,用户和系统管理员可以根据安全需求调整文件的沙箱分配。 理解并正确运用这些安全...
在这个场景中,我们关注的是ActionScript(AS)与Java之间的Socket通信,以及如何在面临安全沙箱限制时找到解决方案。Socket编程是实现客户端-服务器通信的基础,它允许两个或多个应用程序通过网络交换数据。 首先...
QQ电脑管家的安全沙箱功能是一种高级的保护技术,旨在为用户提供一个隔离的环境来执行可能存在风险的程序,如浏览可疑网站、观看不安全的视频或试用未经验证的软件。这个功能的核心理念在于,它创建了一个虚拟空间,...
安全沙箱确保了各应用程序与操作系统、文件系统、网络以及其他应用之间的隔离,甚至对同一Flash Player实例的不同沙箱也是如此。沙箱的安全控制涉及管理员、用户、网络设置和作者设置等利益相关方,他们分别控制权限...
Sandboxie(英译“沙盘”)允许你在...可用来保护浏览网页时真实系统的安全,也可以用来清除上网、运行程序的痕迹,还可以用来测试软件,测试病毒等用途。即使在沙盘进程中下载的文件,也可以随着沙盘的清空而删除。
本文主要讨论的是一个关于SAE(Sina App Engine)云服务中的安全问题,涉及Java安全沙箱的绕过。SAE是新浪提供的一个云服务平台,为用户提供PHP和JAVA等环境来构建网站。为了保护云上的用户免受恶意攻击,如DDoS...