gVisor和KataContainers怎么使用

87次阅读
没有评论

共计 5511 个字符,预计需要花费 14 分钟才能阅读完成。

本篇内容介绍了“gVisor 和 KataContainers 怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让丸趣 TV 小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

目前的容器技术仍然有许多广为人知的安全挑战,其中一个主要的问题是,从单一共享内核获得效率和性能意味着容器逃逸可能成为一个漏洞。

所以在 2015 年,几乎在同一个星期,Intel OTC(Open Source Technology Center)和国内的 HyperHQ 团队同时开源了两个基于虚拟化技术的容器实现,分别叫做 Intel Clear Container 和 runV 项目。而在 2017 年,借着 Kubernetes 的东风,这两个相似的容器运行时项目在中立基金会的撮合下最终合并,就成了现在大家耳熟能详的 Kata Containers 项目。由于 Kata Containers 的本质就是一个精简后的轻量级虚拟机,所以它的特点,就是“像虚拟机一样安全,像容器一样敏捷”。

2018 年,Google 公司则发布了一个名叫 gVisor 的项目。gVisor 项目给容器进程配置一个用 Go 语言实现的、运行在用户态的、极小的“独立内核”。这个内核对容器进程暴露 Linux 内核 ABI,扮演着“Guest Kernel”的角色,从而达到了将容器和宿主机隔离开的目的。

KataContainers

首先,我们来看 KataContainers。它的工作原理可以用如下所示的示意图来描述。

Kata Containers 的本质,就是一个轻量化虚拟机。所以当你启动一个 Kata Containers 之后,你其实就会看到一个正常的虚拟机在运行。这也就意味着,一个标准的虚拟机管理程序(Virtual Machine Manager, VMM)是运行 Kata Containers 必备的一个组件。在我们上面图中,使用的 VMM 就是 Qemu。

Docker 使用 KataContainers

首先节点需要支持以下四种任意一种 cpu 虚拟化技术:

Intel VT-x technology

ARM Hyp mode

IBM Power Systems

IBM Z manframes 如果部署在 VMware 虚拟机中,需要在宿主机开启嵌套虚拟化的功能,开启步骤见链接:https://blog.51cto.com/11434894/2389180?source=dra

安装 kataContainer:

ARCH=$(arch)
BRANCH= ${BRANCH:-master} 
sudo sh -c  echo  deb http://download.opensuse.org/repositories/home:/katacontainers:/releases:/${ARCH}:/${BRANCH}/xUbuntu_$(lsb_release -rs)/ /    /etc/apt/sources.list.d/kata-containers.list 
curl -sL http://download.opensuse.org/repositories/home:/katacontainers:/releases:/${ARCH}:/${BRANCH}/xUbuntu_$(lsb_release -rs)/Release.key | sudo apt-key add -
sudo -E apt-get update
sudo -E apt-get -y install kata-runtime kata-proxy kata-shim

设置 docker 配置文件:

cat   /etc/docker/daemon.json   EOF 
  default-runtime :  kata-runtime ,
  runtimes : {
  kata-runtime : {
  path :  /usr/bin/kata-runtime 
 }
 }
systemctl daemon-reload
systemctl restart docker

运行一个容器,可以看到显示的内核版本和宿主机是不一样的:

root@cr7-ubuntu:~# docker run busybox uname -a

Kubernetes 使用 kataContainer

配置 containerd 使用 kataContainer:

cat   /etc/containerd/config.toml   EOF
disabled_plugins = [restart]
[plugins.linux]
 shim_debug = true
[plugins.cri.containerd.runtimes.kata] #kata 这个名字可以自己定义,和 runtimeClass 指定的名字要一样
 runtime_type =  io.containerd.kata.v2 
[plugins.cri.registry.mirrors. docker.io]
 endpoint = [https://frz7i079.mirror.aliyuncs.com]
systemctl daemon-reload 
systemctl restart containerd

配置 kubelet 使用 containerd 作为容器运行时:

cat   /etc/systemd/system/kubelet.service.d/0-cri-containerd.conf   EOF
[Service]
Environment= KUBELET_EXTRA_ARGS=--container-runtime=remote --runtime-request-timeout=15m -- container-runtime-endpoint=unix:///run/containerd/containerd.sock 
systemctl daemon-reload 
systemctl restart kubelet

kubernetes 创建 runtimeClass:

apiVersion: node.k8s.io/v1beta1 # RuntimeClass is defined in the node.k8s.io API group
kind: RuntimeClass
metadata:
 name: kata 
handler: kata #  这里与 containerd 配置文件中的  [plugins.cri.containerd.runtimes.{handler}]  匹配 

创建 pod:

apiVersion: v1
kind: Pod
metadata:
 name: kata-nginx
spec:
 runtimeClassName: kata
 containers:
 - name: nginx
 image: nginx
 ports:
 - containerPort: 80

gVisor

相比之下,gVisor 的设计其实要更加“激进”一些。它的原理,可以用如下所示的示意图来表示清楚。

gVisor 工作的核心,在于它为应用进程、也就是用户容器,启动了一个名叫 Sentry 的进程。而 Sentry 进程的主要职责,就是提供一个传统的操作系统内核的能力,即:运行用户程序,执行系统调用。所以说,Sentry 并不是使用 Go 语言重新实现了一个完整的 Linux 内核,而只是一个对应用进程“冒充”内核的系统组件。

Docker 使用 gVisor

查看原本的 runtime:

root@cr7-ubuntu:~# docker info
 Runtimes: runc
 Default Runtime: runc
...

安装 gVisor:

(
 set -e
 ARCH=$(uname -m)
 URL=https://storage.googleapis.com/gvisor/releases/release/latest/${ARCH}
 wget ${URL}/runsc ${URL}/runsc.sha512 \
 ${URL}/containerd-shim-runsc-v1 ${URL}/containerd-shim-runsc-v1.sha512
 sha512sum -c runsc.sha512 \
 -c containerd-shim-runsc-v1.sha512
 rm -f *.sha512
 chmod a+rx runsc containerd-shim-runsc-v1
 sudo mv runsc containerd-shim-runsc-v1 /usr/local/bin
)

设置 docker 配置文件:

cat   /etc/docker/daemon.json   EOF 
  registry-mirrors : [https://frz7i079.mirror.aliyuncs.com],
  runtimes : {
  gvisor : { # 这个名字可以自己制定,docker run 的时候 --runtime 使用
  path :  /usr/local/bin/runsc 
 }
 }
systemctl daemon-reload
systemctl restart docker

查看此时的 runtime:

root@cr7-ubuntu:~# docker info
Runtimes: runc gvisor
Default Runtime: runc
...

运行 gvisor 为 runtime 的容器:

docker run -itd --name web1 --runtime=gvisor nginx

在宿主机上是看不到这个进程的,如果是 runc 的容器是能看到进程的:

root@cr7-ubuntu:~/gvisor# ps -ef | grep nginx | grep -v grep
#没有输出 

Kubernetes 使用 gVisor

配置 containerd 使用 gvisor:

cat   /etc/containerd/config.toml   EOF
disabled_plugins = [restart]
[plugins.linux]
 shim_debug = true
[plugins.cri.containerd.runtimes.gvisor] #gvisor 这个名字可以自己定义,和 runtimeClass 指定的名字要一样
 runtime_type =  io.containerd.runsc.v1 
[plugins.cri.registry.mirrors. docker.io]
 endpoint = [https://frz7i079.mirror.aliyuncs.com]
systemctl restart containerd

配置 crictl 使用 containerd 作为作为容器运行时:

runtime-endpoint: unix:///var/run/containerd/containerd.sock
image-endpoint:  
timeout: 0
debug: false

配置 kubelet 使用 containerd 作为容器运行时:

cat   /var/lib/kubelet/kubeadm-flags.env   EOF
KUBELET_KUBEADM_ARGS= --network-plugin=cni --pod-infra-container- image=registry.aliyuncs.com/google_containers/pause:3.2 --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock 
systemctl daemon-reload 
systemctl restart kubelet

kubeadm join 将 node 加入 kubernetes 集群,master 使用 docker 作为容器运行时,node 使用 containerd 作为容器运行时。

创建 runtimeClass:

apiVersion: node.k8s.io/v1beta1
kind: RuntimeClass
metadata:
 name: gvisor
handler: gvisor # 对应 CRI 配置的名称 

创建 pod 使用 gvisor 作为 runtime:

apiVersion: v1
kind: Pod
metadata:
 name: nginx-gvisor
spec:
 runtimeClassName: gvisor
 containers:
 - name: nginx
 image: nginx
 nodeName: cks3

对比

在性能上,KataContainers 和 KVM 实现的 gVisor 基本不分伯仲,在启动速度和占用资源上,基于用户态内核的 gVisor 还略胜一筹。但是,对于系统调用密集的应用,比如重 I/O 或者重网络的应用,gVisor 就会因为需要频繁拦截系统调用而出现性能急剧下降的情况。此外,gVisor 由于要自己使用 Sentry 去模拟一个 Linux 内核,所以它能支持的系统调用是有限的,只是 Linux 系统调用的一个子集。

“gVisor 和 KataContainers 怎么使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注丸趣 TV 网站,丸趣 TV 小编将为大家输出更多高质量的实用文章!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计5511字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)