二十九、K8s最小服务漏洞3-gVisor沙箱

2024-04-27 15:08

本文主要是介绍二十九、K8s最小服务漏洞3-gVisor沙箱,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、为什么需要使用沙箱运行容器

首先,我们来看看整个K8s调用容器的架构:

1.架构概述
在这里插入图片描述
架构分为3个部分,分别时High-level container management、High-level conatiner runtime、Low-level contianer runtime。

专注于运行容器的实际容器运行时通常被称为“Low-level contianer runtime”。支持更多高级功能的运行时,如图像管理和 gRPC/Web API,通常被称为"high-level container tools", “high-level container runtimes” 或者通常简称为 “container runtimes”

容器是使用Linux 命名空间和cgroups 实现的。命名空间让我们可以为每个容器虚拟化系统资源,例如文件系统或网络。Cgroups 提供了一种方法来限制每个容器可以使用的资源量,例如 CPU 和内存。低级运行时负责为容器设置这些命名空间和 cgroup,然后在这些命名空间和 cgroup 中运行命令。

通常,想要在容器中运行应用程序的开发人员需要的不仅仅是低级运行时提供的功能。他们需要有关图像格式、图像管理和共享图像的 API 和功能。这些功能由高级运行时提供。低级运行时只是没有为这种日常使用提供足够的功能。

最后K8s作为容器编排工具,调用高级进行时完成整个环境的容器部署。

2.Low-level contianer runtime
首先,低级别的容器运行时都需要遵循OCI开放容器标准,方便高级别容器运行时进行调用。此外,相比于高级容器运行时,它不具备如下功能:

  1. 创建了一个容器的网络;
  2. 管理容器镜像;
  3. 准备容器的环境;
  4. 管理本地/持久存储。

目前,我们有三个主要的低级容器运行时,其实现的工作有所不同:

  1. runc,这是大多数高级容器运行时(例如 Docker、Podman和contained)的默认设置。这是基于 Docker 最初捐赠的代码;
  2. kata-run来自“Kata Containers”项目,该项目旨在通过在轻量级 VM 中运行每个容器来提供更好的安全性和容器之间的隔离。它是runv和Intel Clear Containers项目的合并;
  3. gVisor由谷歌创建。它通过在严密的安全沙箱中运行每个容器来提供更好的隔离。

3.High-level contianer runtime
高级运行时负责容器镜像的传输和管理、解包镜像以及使用OCI传递给低级运行时来运行容器。通常,高级运行时提供一个守护程序应用程序和一个 API,远程应用程序可以使用它们来逻辑运行容器并监视它们。

同时,希望与 Kubernetes 集成的高级容器运行时需要实现 CRI。CRI 在 Kubernetes 1.5 中引入,充当kubelet和容器运行时之间的桥梁,具体对于每一个高级容器运行时,使用shim(垫片)完成。

目前三个主要的高级容器运行时:

  1. containerd是一个 CRI 兼容的容器运行时,由 Docker 捐赠给 CNCF。它目前是许多 Kubernetes 发行版中的默认设置,例如ad Canonical’s Charmed Kubernetes。它支持所有 OCI 兼容的运行时,并有一个特殊的 shim 用于kata-run;
  2. CRI-O是 Kubernetes 和 Red Hat 创建的符合 OCI 的运行时之间的桥梁。它的一大优势是它可以与 Kubernetes 本身同步发布。每个 CRI-O 版本都与具有相同版本号的 Kubernetes 版本兼容。此运行时是 OpenShift 中的默认值;
  3. Docker 本身也可以用作 CRI 兼容的容器运行时,使用docker-shim。然而,由于 Docker 增加了不必要的复杂性,许多 Kubernetes 分销商正在放弃这种解决方案。

4.High-level container management
本文中指的是K8s。Kubernetes 项目定义了许多标准。与本文相关的是CRI:容器运行时接口。此接口定义了 Kubernetes 如何与高级容器运行时对话。

kubelet 是一个代理,位于 Kubernetes 集群中的每个工作节点上。kubelet 负责管理其节点的容器工作负载。在实际运行工作负载时,kubelet 使用 CRI 与在同一节点上运行的容器运行时进行通信。通过这种方式,CRI 只是一个抽象层或 API,它允许我们切换容器运行时实现,而不是将它们内置到 kubelet 中。
在这里插入图片描述
5.为什么需要使用沙箱运行容器
最后,再回到最开始的问题,为什么需要使用沙箱运行容器?目前我们1.22.0版本,还可以使用docker作为容器运行时,今后将变为containerd。但是,无论时docker还是containerd,默认都时通过runc这个低级别容器运行时实现的。而在前面的笔记中,我们看到了,如果使用runc来部署容器,会共享宿主机的各种空间,比如进程空间、内核空间。那么,如果我们容器的进程也会存在于宿主机上。那么,如果容器运行的进程存在漏洞,一旦被入侵,就会有一定可能性对我们宿主机造成损坏。所以,我们可以用沙箱的方式运行容器,隔离容器与宿主机的环境,在宿主机内,也就看到不容器内的进程了。

而runc部署的容器时不持支持沙箱的,所以我们需要使用另外一个低级别的容器进行时gVisor来完成操作。

Google gVisor 是支持 Google 计算平台 (GPC) App Engine、Cloud Functions 和 CloudML 的沙箱技术。谷歌意识到在公共云基础设施中运行不受信任的应用程序的风险以及使用虚拟机沙箱应用程序的效率低下,并开发了一个用户空间内核用来对不受信任的应用程序进行沙箱处理。gVisor 沙箱通过拦截从应用程序到主机内核的所有系统调用,并在用户空间中使用 gVisor 的内核实现Sentry进行处理这些系统调用。那么就算容器的恶意代码对内核破坏也是容器的内核,而非宿主机的内核。
在这里插入图片描述

二、配置docker使用gVisor做为runtime

使用一台单独的ubuntu设备作为宿主机即可。

1.安装docker

apt-get update
apt-get install -y docker-ce

如果需要加速,可以添加镜像加速器:

cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://frz7i079.mirror.aliyuncs.com"],
}
EOF

重启进程并设置docker开机启动。

systemctl daemon-reload ; systemctl restart docker; systemctl enable docker

可以看到,目前docker支持的runtime为runc:


root@vms75:~# docker info | grep runtime
WARNING: No swap limit supportRuntimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc

2.安装gVisor

安装最新的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

3.将gVisor设置为docker的runtime

命令如下:

/usr/local/bin/runsc install
sudo systemctl reload docker

再次查看/etc/docker/daemon.json文件,可以看到其中已经添加了runtimes的新路径,runsc为新runtime的名称,可以修改,最终路径指向了gvisor。

root@vms75:~# cat /etc/docker/daemon.json
{"runtimes": {"runsc": {"path": "/usr/local/bin/runsc"}}
}

可以通过如下的命令测试能够使用runsc运行容器:

docker run --rm --runtime=runsc hello-world

结果如下,说明runsc安装成功:

root@vms75:~# docker run --rm --runtime=runsc hello-worldHello from Docker!
This message shows that your installation appears to be working correctly.To generate this message, Docker took the following steps:1. The Docker client contacted the Docker daemon.2. The Docker daemon pulled the "hello-world" image from the Docker Hub.(amd64)3. The Docker daemon created a new container from that image which runs theexecutable that produces the output you are currently reading.4. The Docker daemon streamed that output to the Docker client, which sent itto your terminal.To try something more ambitious, you can run an Ubuntu container with:$ docker run -it ubuntu bashShare images, automate workflows, and more with a free Docker ID:https://hub.docker.com/For more examples and ideas, visit:https://docs.docker.com/get-started/

接着查看docker infor,可以看到如下信息:

 Runtimes: runc runscDefault Runtime: runc

现在docker存在两个低等级容器运行时,默认是runc,我们可以通过如下的命令其修改为runsc(即gvisor)。

vim /lib/systemd/system/docker.service

接着在ExecStart处设置–default-runtime runsc。

ExecStart=/usr/bin/dockerd --default-runtime runsc  -H fd:// --containerd=/run/containerd/containerd.sock

重启docke进程:

systemctl daemon-reload ; systemctl restart docker

再次查看docker info,可以看到默认的runtime已经修改为runsc了,后续使用gVisor运行容器时,不需要再使用–runtime=runsc指定了:

 Default Runtime: runsc

4.检查沙箱功能
创建一个nginx镜像,然后在宿主机中查看是否有对应的进程:

docker run -dit --name=web1 --restart=always nginx

查看宿主机进程:

root@vms75:~# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
2eda45493c41   nginx     "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   80/tcp    web1
root@vms75:~# ps aux | grep -v grep | grep nginx

可以看到,虽然我们创建了nginx容器,但是宿主机上并没有对应的进程。

三、配置containerd使用gVisor做为runtime

使用一台单独的ubuntu设备作为宿主机即可。

1.安装containerd

apt-get update
apt-get install containerd.io cri-tools -y
systemctl enable containerd --now
containerd config default > /etc/containerd/config.toml

/etc/containerd/config.toml为containerd的配置文件,我们可以修改如下的内容:

  1. 搜索mirrors,修改加速器https://frz7i079.mirror.aliyuncs.com
  2. 搜索sandbox_image 修改为registry.aliyuncs.com/google_containers/pause:3.5
  3. 搜索runc.options修改为SystemdCgroup = true

containerd 客户端工具有ctr 和crictl 两个,如果想要执行crictl命令则需要使用如下命令:

crictl config runtime-endpoint unix:///var/run/containerd/containerd.sock

完成后重启contianerd:

systemctl restart containerd ; systemctl enable containerd

现在可以使用ctr或者crictl做一些镜像管理操作,例如:

  1. ctr i list/crictl images:查看镜像
  2. crictl pull xxx/ctr i pull xxx:下载镜像

需要注意的是,containerd 和docker 相比多了命名空间的概念。当使用crictl 命令的时候,都是在k8s.io这个命名空间里的,而ctr 默认是在default 这个命名空间里。所以当crictl 下载镜像之后,会自动创建一个k8s.io,而下载的镜像就是放在k8s.io 里的。

例如,现在我们使用crictl下载镜像:

crictl pull docker.io/nginx

使用ctr i list命令无法查看镜像,而crictl images则可以:

root@vms74:~# ctr i list
REF TYPE DIGEST SIZE PLATFORMS LABELS
root@vms74:~# crictl images
IMAGE                     TAG                 IMAGE ID            SIZE
docker.io/library/nginx   latest              f652ca386ed13       56.7MB

我们可以查看命名空间:

root@vms74:~# ctr ns list
NAME   LABELS
k8s.io

可以看到,这里创建了一个k8s.io的命名空间。如果想要切换命名空间到k8s.io,可以使用如下的命令:

export CONTAINERD_NAMESPACE=k8s.io

可以看到无论是ctr或者crictl的命令都和docker中格式不一致。当习惯使用docker后,为了方便使用containerd,我们可以安装nerdctl工具,让我们containerd的命令格式和docker一致。最新的二进制版本nerdctl可以从如下连接下载:https://github.com/containerd/nerdctl/releases,这里下载nerdctl-0.15.0-linux-amd64.tar.gz即可。

接着下载其依赖的CNI插件,下载地址为:https://github.com/containernetworking/plugins/releases,这里下载即可。

下载完成后,在ubuntu宿主机中通过如下的命令解压:

tar zxvf nerdctl-0.15.0-linux-amd64.tar.gz
mkdir -p /opt/cni/bin/
tar zxf cni-plugins-linux-amd64-v1.0.1.tgz -C /opt/cni/bin/

完成后,将当前目录下的nerdctl拷贝到/bin目录下即可:

mv nerdctl /bin/

然后启动nerdctl的补全功能,在/etc/profile里添加source <(nerdctl completion bash),最后再使用如下命令即可:

source /etc/profile

现在,我们就可以像使用docker一样的使用containerd了,只需要把docker命令中的docker修改为nerdctl即可。例如,查看镜像:

root@vms74:~# nerdctl images
REPOSITORY    TAG                                                                 IMAGE ID        CREATED           PLATFORM       SIZE
nginx         latest                                                              9522864dd661    22 minutes ago    linux/amd64    149.1 MiB
nginx         <none>                                                              9522864dd661    22 minutes ago    linux/amd64    149.1 MiB
sha256        f652ca386ed135a4cbe356333e08ef0816f81b2ac8d0619af01e2b256837ed3e    9522864dd661    22 minutes ago    linux/amd64    149.1 MiB

删除镜像:

root@vms74:~# nerdctl rmi nginx:latest
Untagged: docker.io/library/nginx:latest@sha256:9522864dd661dcadfd9958f9e0de192a1fdda2c162a35668ab6ac42b465f0603
Deleted: sha256:9321ff862abbe8e1532076e5fdc932371eff562334ac86984a836d77dfb717f5
Deleted: sha256:0664b7821b6050b321b14cdede97c2079ae45aff22beb4a42f7595294f5be62d
Deleted: sha256:c9fcd9c6ced8b793a0ad4f93820c1d51d94c3b1fca93000d93e9e8eefa6fdb38
Deleted: sha256:d3e1dca44e8225cdd06b6bf7cdfc847e3ab9f09ab6aeefb006e2e8f02f0dd26c
Deleted: sha256:82caad489ad7bc7e1ae6f17bb1e9ade2bca44a41a07cc8c5587af8a2de2f536a
Deleted: sha256:2bed47a66c07ecddfea2bc9c128d81b31272d99b69aff1fb4edc079c4dbf56e7

部署nginx容器和查看容器:

root@vms74:~# nerdctl run -d --name=web1 --restart=always nginx
docker.io/library/nginx:latest:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:9522864dd661dcadfd9958f9e0de192a1fdda2c162a35668ab6ac42b465f0603:    done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:4424e31f2c366108433ecca7890ad527b243361577180dfd9a5bb36e828abf47: done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:f652ca386ed135a4cbe356333e08ef0816f81b2ac8d0619af01e2b256837ed3e:   done           |++++++++++++++++++++++++++++++++++++++|
elapsed: 1.1 s                                                                    total:   0.0 B (0.0 B/s)
a03b306cc186ab6e15024d460e8e281d5551f53aa5a1a8f87783e355faaaf535
root@vms74:~# nerdctl ps
CONTAINER ID    IMAGE                             COMMAND                   CREATED           STATUS    PORTS    NAMES
a03b306cc186    docker.io/library/nginx:latest    "/docker-entrypoint.…"    31 seconds ago    Up                 web1

2.安装gVisor

安装最新的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

3.将gVisor设置为containerd的runtime
更新/etc/containerd/config.toml。确保选中containerd-shim-runsc-v1是 ${PATH}或在同一目录中containerd的二进制文件。这里的runsc也就是gvisor。

cat <<EOF | sudo tee /etc/containerd/config.toml
version = 2
[plugins."io.containerd.runtime.v1.linux"]shim_debug = true
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runsc]runtime_type = "io.containerd.runsc.v1"
EOF

重新启动containerd:

systemctl daemon-reload ; systemctl restart containerd

查看containerd是否加载了gvisor:

root@vms74:~# crictl info | grep runtime"runtimes": {"runtimeType": "io.containerd.runc.v2","runtimeEngine": "","runtimeRoot": "","runtimeType": "io.containerd.runsc.v1","runtimeEngine": "","runtimeRoot": "",

可以看到,目前containerd已经支持了runsc。

4.检查沙箱功能

使用gvisor作为runtime:

run -d --name=web1 --restart=always --runtime=runsc nginx

查看宿主机上是否有对应的进程,可以看到,没有对应的进程。说明整个容器已经在沙箱中运行了。

root@vms74:~# ps aux | grep -v grep | grep nginx
root@vms74:~#

四、在K8s环境中,使用containerd(使用gVisor)做为runtime

注意:如果K8s使用docker作为high-level conatiner runtime,那么docker不支持使用gVisor作为low-level conatiner runtime。所以这里我们需要使用containerd作为K8s的high-level conatiner runtime。

1.k8s集群环境:
在这里插入图片描述
底层系统为ubuntu18.04,Master node的IP地址为192.168.26.71/24,三个Worker node的IP地址为192.168.26.72/24、192.168.26.73/24,192.168.26.74/24。网络通过calico来创建。

目前,已经搭建好了master1、worker1和worker2的K8s集群环境。在master上查看集群信息:可以看到目前三台设备都使用docker作为runtime。

root@vms71:~# kubectl get nodes -o wide
NAME            STATUS   ROLES                  AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
vms71.rhce.cc   Ready    control-plane,master   15d   v1.22.0   192.168.26.71   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.11
vms72.rhce.cc   Ready    <none>                 15d   v1.22.0   192.168.26.72   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.11
vms73.rhce.cc   Ready    <none>                 15d   v1.22.0   192.168.26.73   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.11

现在,我们需要将worker node3,也就是将再上一步已经配置完成的以containerd作为runtime的设备加入到这个已经存在的集群中。

2.加入worker node3
在worker node3上,配置/etc/hosts,关闭swap:

swapoff -a ; sed -i '/swap/d' /etc/fstab

切换命名空间到k8s.io:

export CONTAINERD_NAMESPACE=k8s.io

设置加入集群所需要的参数并让其生效:

cat > /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOFmodprobe overlay
modprobe br_netfiltercat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOFsysctl -p /etc/sysctl.d/k8s.conf

在worker node3上下载calico所需要的镜像,首先下载对应的yaml文件:

curl https://docs.projectcalico.org/manifests/calico.yaml -O

然后使用如下命令,查看所需要的镜像,并下载到本地:

grep image calico.yaml

接着安装K8s:

apt-get install -y kubeadm=1.22.0-00 kubelet=1.22.0-00 kubectl=1.22.0-00
systemctl restart kubelet ; systemctl enable kubelet

在master上使用如下命令生成给worker node3加入集群的命令:

root@vms71:~# kubeadm token create --print-join-command
kubeadm join 192.168.26.71:6443 --token nvqate.m94p1pzp5obke6sq --discovery-token-ca-cert-hash sha256:8a808cf9415018407a86963ce4af14ce3b0c830c56eaa27ce9b52baa2504116a

复制加入集群的命令到worker node3上。等级一小段时间,然后回到master上,使用命令查看worker node3是否加入成功:

root@vms71:~# kubectl get nodes -owide
NAME            STATUS   ROLES                  AGE     VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
vms71.rhce.cc   Ready    control-plane,master   15d     v1.22.0   192.168.26.71   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.11
vms72.rhce.cc   Ready    <none>                 15d     v1.22.0   192.168.26.72   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.11
vms73.rhce.cc   Ready    <none>                 15d     v1.22.0   192.168.26.73   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.11
vms74.rhce.cc   Ready    <none>                 9m18s   v1.22.0   192.168.26.74   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   containerd://1.4.12

可以看到已经加入成功,状态为ready,且运行的high-level container runtime为containerd。

3.让k8s支持gVisor
在worker node3上,修改内核文件,让kubelet也能使用gVisor(runsc):

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"
EOFsystemctl daemon-reload ; systemctl restart kubelet.service

4.在k8s环境中部署使用runsc而非runc作为worker node3的low-level container runtime
在master上创建一个runtime class,yaml文件如下:

apiVersion: node.k8s.io/v1  
kind: RuntimeClass
metadata:name: myclass  
handler: runsc  

handler是对应的的 CRI (low-level container runtime)配置的名称,这里指定runsc。应用yaml文件后查看是否部署成功:

root@vms71:~# kubectl get runtimeclasses.node.k8s.io
NAME      HANDLER   AGE
myclass   runsc     12s

5.部署pod在worker node3中的沙箱中工作

在master上,为worker node3打一个标签,方便后续部署pod:

root@vms71:~# kubectl label nodes vms74.rhce.cc xx=xx
node/vms74.rhce.cc labeled
root@vms71:~# kubectl get nodes -l xx=xx
NAME            STATUS   ROLES    AGE   VERSION
vms74.rhce.cc   Ready    <none>   24m   v1.22.0

所使用的yaml文件如下,指定pod将部署在worker node3上,同时指定了runtime class为我们创建的myclass:

apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod1name: pod1
spec:terminationGracePeriodSeconds: 0runtimeClassName: myclassnodeSelector:xx: xxcontainers:- image: nginximagePullPolicy: IfNotPresentname: pod1resources: {}dnsPolicy: ClusterFirstrestartPolicy: Always
status: {}

接着使用如下yaml文件创建pod,并查看:

root@vms71:~# kubectl get pods -owide
NAME   READY   STATUS    RESTARTS   AGE   IP               NODE            NOMINATED NODE   READINESS GATES
pod1   1/1     Running   0          5s    10.244.183.193   vms74.rhce.cc   <none>           <none>

可以看到,pod1已经在worker node3上运行了。那么我们切换到worker node3,查看是否以沙箱的形式运行pod1。使用如下命令查看宿主机上是否存在nginx的进程:

root@vms74:~# ps aux | grep -v grep | grep nginx
root@vms74:~#

可以看到,pod1已经通过runsc以沙箱的形式运行了。

除此之外,KATA这个low-level container runtime也可以将容器环境和宿主机环境隔离,其使用和安装方法和gvisor十分相似。具体步骤请参考:https://github.com/kata-containers/documentation/blob/master/install/ubuntu-installation-guide.md

整理资料来源:
What’s up with CRI-O, Kata Containers and Podman?:https://merlijn.sebrechts.be/blog/2020-01-docker-podman-kata-cri-o/
Container Runtimes series:https://www.ianlewis.org/en/container-runtimes-part-1-introduction-container-r
Making Containers More Isolated: An Overview of Sandboxed Container Technologies: https://unit42.paloaltonetworks.com/making-containers-more-isolated-an-overview-of-sandboxed-container-technologies/
gvisor install:https://gvisor.dev/docs/user_guide/install/
runtimeclass:https://kubernetes.io/zh/docs/concepts/containers/runtime-class/#2-创建相应的-runtimeclass-资源
kata runtime ubuntu: https://github.com/kata-containers/documentation/blob/master/install/ubuntu-installation-guide.md
《老段CKS课程》

这篇关于二十九、K8s最小服务漏洞3-gVisor沙箱的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/940825

相关文章

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

poj 1734 (floyd求最小环并打印路径)

题意: 求图中的一个最小环,并打印路径。 解析: ans 保存最小环长度。 一直wa,最后终于找到原因,inf开太大爆掉了。。。 虽然0x3f3f3f3f用memset好用,但是还是有局限性。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#incl

hdu 1102 uva 10397(最小生成树prim)

hdu 1102: 题意: 给一个邻接矩阵,给一些村庄间已经修的路,问最小生成树。 解析: 把已经修的路的权值改为0,套个prim()。 注意prim 最外层循坏为n-1。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstri

90、k8s之secret+configMap

一、secret配置管理 配置管理: 加密配置:保存密码,token,其他敏感信息的k8s资源 应用配置:我们需要定制化的给应用进行配置,我们需要把定制好的配置文件同步到pod当中容器 1.1、加密配置: secret: [root@master01 ~]# kubectl get secrets ##查看加密配置[root@master01 ~]# kubectl get se

poj 2175 最小费用最大流TLE

题意: 一条街上有n个大楼,坐标为xi,yi,bi个人在里面工作。 然后防空洞的坐标为pj,qj,可以容纳cj个人。 从大楼i中的人到防空洞j去避难所需的时间为 abs(xi - pi) + (yi - qi) + 1。 现在设计了一个避难计划,指定从大楼i到防空洞j避难的人数 eij。 判断如果按照原计划进行,所有人避难所用的时间总和是不是最小的。 若是,输出“OPETIMAL",若

poj 2135 有流量限制的最小费用最大流

题意: 农场里有n块地,其中约翰的家在1号地,二n号地有个很大的仓库。 农场有M条道路(双向),道路i连接着ai号地和bi号地,长度为ci。 约翰希望按照从家里出发,经过若干块地后到达仓库,然后再返回家中的顺序带朋友参观。 如果要求往返不能经过同一条路两次,求参观路线总长度的最小值。 解析: 如果只考虑去或者回的情况,问题只不过是无向图中两点之间的最短路问题。 但是现在要去要回

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。