containerd 与安全沙箱的 Kubernetes 初体验 虚拟机nginxlinux
程序员文章站
2022-07-15 13:00:27
...
作者 | 易立 阿里云资深技术专家
containerd 是一个开源的行业标准容器运行时,关注于简单、稳定和可移植,同时支持 Linux 和 Windows。
![1_jpeg](https://yqfile.alicdn.com/7bb34fd60db56373632b0c949a7090fc075ab456.jpeg)
* 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 的支持。其架构图如下:
![2_jpeg](https://yqfile.alicdn.com/cebd07a2f58c10144a8a459377aadd66278a5bec.jpeg)
在 Kubernetes 场景下,containerd 与完整 Docker Engine 相比,具有更少的资源占用和更快的启动速度。
![3_jpeg](https://yqfile.alicdn.com/f5ddfe8f88a9af1a2ebba8e56e94b61923bd3d1b.jpeg)
![4_jpeg](https://yqfile.alicdn.com/704e219fb0977b28efa990e7d0119966608cd02b.jpeg)
图片来源:[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 项目相比,在性能上具备优势,在社区支持上也更加广泛。
![5_jpeg](https://yqfile.alicdn.com/9cc0986cdfa64e596b355305d346da7ec72156fe.jpeg)
图片来源:[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 等安全沙箱容器。
![6_jpeg](https://yqfile.alicdn.com/205d974617757b8879d15a0587f8f14ae4ca8ab3.jpeg)
在 Kubernetes 环境中,可以用不同的 API 和命令行工具来管理容器 / Pod、镜像等概念。为了便于大家理解,我们可以用下图说明如何利用不同层次的 API 和 CLI 管理容器生命周期管理。
![7_jpeg](https://yqfile.alicdn.com/f4e80a56eb565ca847586e919b997bb0e7fc6476.jpeg)
* 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...
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
部署测试应用
------
我们通过 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
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
然后,我们开启 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
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
当 `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
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
我们可以清楚地发现:由于基于 runc 的容器与宿主机共享操作系统内核,runc 容器中查看到的 OS 内核版本与 Minikube 宿主机 OS 内核版本相同;而 gvisor 的 runsc 容器采用了独立内核,它和 Minikube 宿主机 OS 内核版本不同。
正是因为每个沙箱容器拥有独立的内核,减小了安全攻击面,具备更好的安全隔离特性。适合隔离不可信的应用,或者多租户场景。注意:gvisor 在 minikube 中,通过 ptrace 对内核调用进行拦截,其性能损耗较大,此外 gvisor 的兼容性还有待增强。
使用 ctl 和 crictl 工具
------------------
我们现在可以进入进入 Minikube 虚拟机:
```
$ minikube ssh
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
containerd 支持通过名空间对容器资源进行隔离,查看现有 containerd 名空间:
```
$ sudo ctr namespaces ls
NAME LABELS
k8s.io
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
```
# 列出所有容器镜像
$ sudo ctr --namespace=k8s.io images ls
...
# 列出所有容器列表
$ sudo ctr --namespace=k8s.io containers ls
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
在 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
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
containerd 与 Docker 的关系
-----------------------
很多同学都关心 containerd 与 Docker 的关系,以及是否 containerd 可以取代 Docker?
containerd 已经成为容器运行时的主流实现,也得到了 Docker 社区和 Kubernetes 社区的大力支持。Docker Engine 底层的容器生命周期管理也是基于 containerd 实现。
![8](https://yqfile.alicdn.com/ffdf214128393a709be44b6262ff1c8c683505a8.png)
但是 Docker Engine 包含了更多的开发者工具链,比如镜像构建。也包含了 Docker 自己的日志、存储、网络、Swarm 编排等能力。此外,绝大多数容器生态厂商,如安全、监控、开发等对 Docker Engine 的支持比较完善,对 containerd 的支持也在逐渐补齐。
所以在 Kubernetes 运行时环境,对安全和效率和定制化更加关注的用户可以选择 containerd 作为容器运行时环境;对于大多数开发者,继续使用 Docker Engine 作为容器运行时也是一个不错的选择。
阿里云容器服务对 containerd 的支持
-----------------------
在阿里云 Kubernetes 服务 ACK,我们已经采用 containerd 作为容器运行时管理,来支撑安全沙箱容器和 runc 容器的混合部署。在现有产品中,我们和阿里云操作系统团队、蚂蚁金服一起支持了基于轻量虚拟化的 runV 沙箱容器,4Q 也将和操作系统团队、安全团队合作发布基于 Intel SGX 的可信加密沙箱容器。
![9_jpeg](https://yqfile.alicdn.com/12914c04422a8330db2cd6e881427a65d2b9ef9b.jpeg)
具体产品信息可以参考[该文档](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)
本文为云栖社区原创内容,未经允许不得转载。
containerd 是一个开源的行业标准容器运行时,关注于简单、稳定和可移植,同时支持 Linux 和 Windows。
![1_jpeg](https://yqfile.alicdn.com/7bb34fd60db56373632b0c949a7090fc075ab456.jpeg)
* 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 的支持。其架构图如下:
![2_jpeg](https://yqfile.alicdn.com/cebd07a2f58c10144a8a459377aadd66278a5bec.jpeg)
在 Kubernetes 场景下,containerd 与完整 Docker Engine 相比,具有更少的资源占用和更快的启动速度。
![3_jpeg](https://yqfile.alicdn.com/f5ddfe8f88a9af1a2ebba8e56e94b61923bd3d1b.jpeg)
![4_jpeg](https://yqfile.alicdn.com/704e219fb0977b28efa990e7d0119966608cd02b.jpeg)
图片来源:[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 项目相比,在性能上具备优势,在社区支持上也更加广泛。
![5_jpeg](https://yqfile.alicdn.com/9cc0986cdfa64e596b355305d346da7ec72156fe.jpeg)
图片来源:[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 等安全沙箱容器。
![6_jpeg](https://yqfile.alicdn.com/205d974617757b8879d15a0587f8f14ae4ca8ab3.jpeg)
在 Kubernetes 环境中,可以用不同的 API 和命令行工具来管理容器 / Pod、镜像等概念。为了便于大家理解,我们可以用下图说明如何利用不同层次的 API 和 CLI 管理容器生命周期管理。
![7_jpeg](https://yqfile.alicdn.com/f4e80a56eb565ca847586e919b997bb0e7fc6476.jpeg)
* 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...
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
部署测试应用
------
我们通过 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
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
然后,我们开启 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
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
当 `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
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
我们可以清楚地发现:由于基于 runc 的容器与宿主机共享操作系统内核,runc 容器中查看到的 OS 内核版本与 Minikube 宿主机 OS 内核版本相同;而 gvisor 的 runsc 容器采用了独立内核,它和 Minikube 宿主机 OS 内核版本不同。
正是因为每个沙箱容器拥有独立的内核,减小了安全攻击面,具备更好的安全隔离特性。适合隔离不可信的应用,或者多租户场景。注意:gvisor 在 minikube 中,通过 ptrace 对内核调用进行拦截,其性能损耗较大,此外 gvisor 的兼容性还有待增强。
使用 ctl 和 crictl 工具
------------------
我们现在可以进入进入 Minikube 虚拟机:
```
$ minikube ssh
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
containerd 支持通过名空间对容器资源进行隔离,查看现有 containerd 名空间:
```
$ sudo ctr namespaces ls
NAME LABELS
k8s.io
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
```
# 列出所有容器镜像
$ sudo ctr --namespace=k8s.io images ls
...
# 列出所有容器列表
$ sudo ctr --namespace=k8s.io containers ls
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
在 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
```
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以移动")
containerd 与 Docker 的关系
-----------------------
很多同学都关心 containerd 与 Docker 的关系,以及是否 containerd 可以取代 Docker?
containerd 已经成为容器运行时的主流实现,也得到了 Docker 社区和 Kubernetes 社区的大力支持。Docker Engine 底层的容器生命周期管理也是基于 containerd 实现。
![8](https://yqfile.alicdn.com/ffdf214128393a709be44b6262ff1c8c683505a8.png)
但是 Docker Engine 包含了更多的开发者工具链,比如镜像构建。也包含了 Docker 自己的日志、存储、网络、Swarm 编排等能力。此外,绝大多数容器生态厂商,如安全、监控、开发等对 Docker Engine 的支持比较完善,对 containerd 的支持也在逐渐补齐。
所以在 Kubernetes 运行时环境,对安全和效率和定制化更加关注的用户可以选择 containerd 作为容器运行时环境;对于大多数开发者,继续使用 Docker Engine 作为容器运行时也是一个不错的选择。
阿里云容器服务对 containerd 的支持
-----------------------
在阿里云 Kubernetes 服务 ACK,我们已经采用 containerd 作为容器运行时管理,来支撑安全沙箱容器和 runc 容器的混合部署。在现有产品中,我们和阿里云操作系统团队、蚂蚁金服一起支持了基于轻量虚拟化的 runV 沙箱容器,4Q 也将和操作系统团队、安全团队合作发布基于 Intel SGX 的可信加密沙箱容器。
![9_jpeg](https://yqfile.alicdn.com/12914c04422a8330db2cd6e881427a65d2b9ef9b.jpeg)
具体产品信息可以参考[该文档](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)
本文为云栖社区原创内容,未经允许不得转载。
上一篇: Re: 酷似抓虾的ruby on rail网站-猫爪
下一篇: Java IO 核心操作(五)