最小化微服务漏洞

主要内容

❖ Pod安全上下文

❖ Pod安全策略

❖ Secret存储敏感数据

❖ 安全沙箱运行容器

Pod安全上下文

安全上下文(Security Context):K8s对Pod和容器提供的安全机制,可以设置Pod特权和访问控制。

安全上下文限制维度:

  • 自主访问控制(Discretionary Access Control):基于用户ID(UID)和组ID(GID),来判定对对象(例如文件) 的访问权限。
  • 安全性增强的 Linux(SELinux): 为对象赋予安全性标签。
  • 特权模式或者非特权模式运行。
  • Linux Capabilities: 为进程赋予 root 用户的部分特权而非全部特权。
  • AppArmor:定义Pod使用AppArmor限制容器对资源访问限制
  • Seccomp:定义Pod使用Seccomp限制容器进程的系统调用
  • AllowPrivilegeEscalation: 禁止容器中进程(通过 SetUID 或 SetGID 文件模式)获得特权提升。当容器以特权模式 运行或者具有CAP_SYS_ADMIN能力时,AllowPrivilegeEscalation总为True。
  • readOnlyRootFilesystem:以只读方式加载容器的根文件系统。

案例实施

案例1:设置容器以普通用户运行

背景:容器中的应用程序默认以root账号运行的,这个root与宿主机root账号是相同的, 拥有大部分对Linux内核的系统调用权限,这样是不安全的,所以我们应该将容器以普 通用户运行,减少应用程序对权限的使用。

可以通过两种方法设置普通用户:

  1. Dockerfile里使用USER指定运行用户
  2. K8s里指定spec.securityContext.runAsUser,指定容器默认用户UID
spec:securityContext:runAsUser: 1000 # 镜像里必须有这个用户UIDfsGroup: 1000 # 数据卷挂载后的目录属组设置为该组containers:- image: lizhenliang/flask-demo:rootname: websecurityContext:allowPrivilegeEscalation: false # 不允许提权

创建Pod使用安全上下文测试是否改为uuid运行容器:

[root@master01:~] # cat pod-test.yamlapiVersion: v1kind: Podmetadata:name: testspec:securityContext:runAsUser: 1000fsGroup: 1000containers:- image: lizhenliang/flask-demo:rootname: testsecurityContext:allowPrivilegeEscalation: false

执行yaml之后进入容器查看当前的uuid:

[root@master01:~]# kubectl exec -it test -- bashpython@test:/data/www$ iduid=1000(python) gid=1000(python) groups=1000(python)
案例2:避免使用特权容器

背景:容器中有些应用程序可能需要访问宿主机设备、修改内核等需求,在默认情况下, 容器没这个有这个能力,因此这时会考虑给容器设置特权模式。

启用特权模式:

containers:- image: lizhenliang/flask-demo:rootname: websecurityContext:privileged: true / false 

启用特权模式就意味着,你要为容器提供了访问Linux内核的所有能力,这是很危险的, 为了减少系统调用的供给,可以使用Capabilities为容器赋予仅所需的能力。

Linux Capabilities:Capabilities 是一个内核级别的权限,它允许对内核调用权 限进行更细粒度的控制,而不是简单地以 root 身份能力授权。 Capabilities 包括更改文件权限、控制网络子系统和执行系统管理等功能。在 securityContext 中,可以添加或删除 Capabilities,做到容器精细化权限控制。

案例3:取消挂载文件系统

容器默认没有挂载文件系统能力,添加SYS_ADMIN增加这个能力

apiVersion: v1kind: Podmetadata:name: busybox spec:containers:- image: busyboxname: testcommand: - sleep- 24hsecurityContext:capabilities:add: ["SYS_ADMIN"]

创建进入容器测试挂载权限:

[root@master01:~]# kubectl exec -itbusybox -- sh/ # mount /data/ /tmp/mount: mounting /data/ on /tmp/ failed: Permission denied
案例4:只读挂载权限

只读挂载容器文件系统,防止恶意二进制文件创建

apiVersion: v1kind: Podmetadata:name: busyboxspec:containers:- image: busyboxname: testcommand: - sleep- 24hsecurityContext:readOnlyRootFilesystem: true

创建进入容器测试文件权限:

[root@master01:~]# kubectl exec -itbusybox-- sh/ # mkdir amkdir: can't create directory 'a': Read-only file system

Pod安全策略(PSP)

PodSecurityPolicy(简称PSP):Kubernetes中Pod部署时重要的安全校验手段,能够 有效地约束应用运行时行为安全。 使用PSP对象定义一组Pod在运行时必须遵循的条件及相关字段的默认值,只有Pod满足这 些条件才会被K8s接受。

Pod安全策略限制维度

启用准入控制器

Pod安全策略实现为一个准入控制器,默认没有启用,当启用后会强制实施 Pod安全策略,没有满足的Pod将无法创建。因此,建议在启用PSP之前先添加 策略并对其授权。

启用Pod安全策略:

vi /etc/kubernetes/manifests/kube-apiserver.yaml

–enable-admission-plugins=NodeRestriction,PodSecurityPolicy

systemctl restart kubelet

如何使用PSP资源

用户使用SA (ServiceAccount)创建了一个Pod,K8s会先验证这个SA是否 可以访问PSP资源权限,如果可以进一步验证Pod配置是否满足PSP规则,任 意一步不满足都会拒绝部署。

因此,需要实施需要有这几点:

  1. 创建SA服务账号
  2. 该SA需要具备创建对应资源权限,例如创建Pod、Deployment
  3. SA使用PSP资源权限:创建Role,使用PSP资源权限,再将SA绑定Role

案例实施

示例1:禁止创建特权模式的Pod

创建Pod安全策略资源如下:

  • 不允许特权Pod
  • 运行seLinux的规则
  • 指定容器启动的用户ID和主组ID位任何人或者禁止没指定普通用户运行的容器(runAsUser)
  • 允许使用挂载类型数据卷
[root@master01:~]# cat psp.yamlapiVersion: policy/v1beta1kind: PodSecurityPolicymetadata:name: psp-examplespec:privileged: false # 不允许特权Pod# 下面是一些必要的字段seLinux:rule: RunAsAnysupplementalGroups:rule: RunAsAnyrunAsUser:rule: RunAsAny /MustRunAsNonRootfsGroup:rule: RunAsAnyvolumes:- '*'

执行之后查看当前的PSP资源情况:

在后续的1.25之后的版本里面,将会完全废弃Pod安全策略,采用安全上下文 的方式。

[root@master01:~]# kubectl apply -f psp.yamlWarning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+podsecuritypolicy.policy/psp-example created[root@master01:~]# kubectl get pspWarning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+NAMEPRIVCAPS SELINUXRUNASUSER FSGROUPSUPGROUP READONLYROOTFS VOLUMESpsp-example falseRunAsAny RunAsAnyRunAsAny RunAsAny false*
示例2:禁止创建特权模式流程
# 创建SA$ kubectl create serviceaccount aliang# 将SA绑定到系统内置Role$ kubectl create rolebinding aliang --clusterrole=edit --serviceaccount=default:aliang# 创建使用PSP权限的Role$ kubectl create role psp:unprivileged --verb=use --resource=podsecuritypolicy --resource-name=psp-example# 将SA绑定到Role$ kubectl create rolebinding aliang:psp:unprivileged --role=psp:unprivileged --serviceaccount=default:aliang# 创建pod测试$ kubectl --as=system:serviceaccount:default:psp-sa run nginx --image=nginx

OPA Gatekeeper

OPA介绍

PSP不足与状况:

  • 将再1.21版本弃用PSP,在1.25版本删除PSP
  • 仅支持Pod策略
  • 使用复杂,权限模型存在缺陷,控制不明确

️弃用文章

️替代提案

OPA(Open Policy Agent):是一个开源的、通用策略引擎,可以将策略编写为代码。提供 一个种高级声明性语言-Rego来编写策略,并把决策这一步骤从复杂的业务逻辑中解耦出来。

OPA可以用来做什么?

  1. 拒绝不符合条件的YAML部署
  2. 允许使用哪些仓库中的镜像
  3. 允许在哪个时间段访问系统
  4. 等…
OPA工作流程

Gatekeeper 是基于 OPA的一个 Kubernetes 策略解决方案,可替代PSP或者部分RBAC功能。

当在集群中部署了Gatekeeper组件,APIServer所有的创建、更新或者删除操作都会触发 Gatekeeper来处理,如果不满足策略则拒绝。

部署OPA Gatekeeper

Gatekeeper的策略由两个资源对象组成:

  • Template:策略逻辑实现的地方,使用rego语言
  • Contsraint:负责Kubernetes资源对象的过滤或者为Template提供输入参数
[root@master01:~/cks/opa]# kubectl apply -f https://pic1.xuehuaimg.com/proxy/raw.githubusercontent.com/open-policy-agent/gatekeeper/release-3.7/deploy/gatekeeper.yaml[root@master01:~/cks/opa]# kubectl get pods -n gatekeeper-systemNAME READY STATUSRESTARTS AGEgatekeeper-controller-manager-66f474f785-kn5fl 1/1 Running 032sgatekeeper-controller-manager-66f474f785-xgz7s 1/1 Running 032sgatekeeper-controller-manager-66f474f785-xxwdm 1/1 Running 032s

案例实施

案例1:禁止容器启用特权
  • 需要创建ConstraintTemplate的资源
  • 使用rego的语言编写对启用特权的资源发出警告
  • 需要指定类型为privileged模式
[root@master01:~/cks/opa]# cat privileged_tpl.yamlapiVersion: templates.gatekeeper.sh/v1beta1kind: ConstraintTemplatemetadata:name: privilegedspec:crd:spec:names:kind: privilegedtargets:- target: admission.k8s.gatekeeper.shrego: |package admissionviolation[{"msg": msg}] {# 如果violation为true说明违反约束containers = input.review.object.spec.template.spec.containersc_name := containers[0].namecontainers[0].securityContext.privileged # 如果返回false或者没获取到值说明通过msg := sprintf("提示:'%v'容器禁止启用特权!",[c_name])}[root@master01:~/cks/opa]# kubectl get ConstraintTemplateNAME AGEprivileged 32m

创建约束、如下是约束资源类型:

  • Deployment
  • DaemonSet
  • StatefulSet
[root@master01:~/cks/opa]# cat privileged_constraints.yamlapiVersion: constraints.gatekeeper.sh/v1beta1kind: privilegedmetadata:name: privilegedspec:match:# 匹配的资源kinds:- apiGroups: ["apps"]kinds:- "Deployment"- "DaemonSet"- "StatefulSet"[root@master01:~/cks/opa]# kubectl get constraintsNAME AGEprivileged 31m

创建Deployment开启特权模式再执行创建会发出警告。

apiVersion: apps/v1kind: Deploymentmetadata:labels:app: nginxname: nginxspec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- image: nginxname: nginxsecurityContext:privileged: true[root@master01:~/cks/opa]# kubectl apply -f deployment.yamlError from server ([privileged] 提示:'nginx'容器禁止启用特权!): error when creating "dp.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [privileged] 提示:'nginx'容器禁止启用特权!
案例2:只允许使用特定的镜像仓库
  • 需要创建ConstraintTemplate的资源
  • 使用rego的语言编写对镜像仓库的信任
  • 需要指定类型为image-check模式
[root@master01:~/cks/opa]# cat image-check_tpl.yamlapiVersion: templates.gatekeeper.sh/v1beta1kind: ConstraintTemplatemetadata:name: image-checkspec:crd:spec:names:kind: image-checkvalidation:openAPIV3Schema:properties:# 需要满足条件的参数prefix:type: stringtargets:- target: admission.k8s.gatekeeper.shrego: |package imageviolation[{"msg": msg}] {containers = input.review.object.spec.template.spec.containersimage := containers[0].imagenot startswith(image, input.parameters.prefix)msg := sprintf("提示:'%v'镜像地址不在可信任仓库!", [image])}[root@master01:~/cks/opa]# kubectl get constrainttemplateNAMEAGEimage-check 77sprivileged35m

这里需要配置传递OPA的参数为: “lizhenliang/”

[root@master01:~/cks/opa]# cat image-check_constraints.yamlapiVersion: constraints.gatekeeper.sh/v1beta1kind: image-checkmetadata:name: image-checkspec:match:kinds:- apiGroups: ["apps"]kinds:- "Deployment"- "DaemonSet"- "StatefulSet"parameters:# 传递给opa的参数prefix: "lizhenliang/"[root@master01:~/cks/opa]# kubectl get constraintsNAMEAGEimage-check.constraints.gatekeeper.sh/image-check 77s

执行测试时使用docker官方的镜像仓库:

  1. 由于我们开启了镜像仓库的信任 所以对docker仓库不支持
  2. 只能从lizhenliang该仓库进行拉取镜像
[root@master01:~/cks/opa]# kubectl create deployment test --image=nginxerror: failed to create deployment: admission webhook "validation.gatekeeper.sh" denied the request: [image-check] 提示:'nginx'镜像地址不在可信任仓库!

Secret存储敏感数据

Secret是一个用于存储敏感数据的资源,所有的数据要经过base64编码,数据实际会存储在K8s中Etcd, 然后通过创建Pod时引用该数据。

应用场景:凭据

Pod使用secret数据有两种方式:

  • 变量注入
  • 数据卷挂载
secret的类型

kubectl create secret 支持三种数据类型:

  • docker-registry:存储镜像仓库认证信息
  • generic:从文件、目录或者字符串创建,例如存储用户名密码
  • tls:存储证书,例如HTTPS证书
secret的使用

一个 Secret 可以包含 Pod 访问数据库所需的用户凭证。 例如,由用户名和密码组成的数据库连接字符串。 你 可以在本地计算机上,将用户名存储在文件 ./username.txt 中,将密码存储在文件 ./password.txt 中。

[root@master01:~]# echo -n 'admin' > username.txt[root@master01:~]# echo -n '1a2b3c4d' > password.txt

在这些命令中, -n 标志确保生成的文件在文本末尾不包含额外的换行符。 这一点很重要,因为当 kubectl 读 取文件并将内容编码为 base64 字符串时,多余的换行符也会被编码。

kubectl create secret 命令将这些文件打包成一个 Secret 并在 API 服务器上创建对象。

[root@master01:~]# kubectl create secret generic db-user-pass --from-file=username.txt --from-file=password.txtsecret/db-user-pass created[root@master01:~]# kubectl get secrets db-user-pass -o yamlapiVersion: v1data:password.txt: MWEyYjNjNGQ=username.txt: YWRtaW4=kind: Secretmetadata:creationTimestamp: "2022-04-13T06:43:03Z"name: db-user-passnamespace: defaultresourceVersion: "100098"uid: 440fa829-0135-4ef2-b8dc-9f06f5a2f2a3type: Opaque
解码 Secret

要查看创建的 Secret 的内容,运行以下命令:

[root@master01:~]# kubectl get secrets db-user-pass -o jsonpath='{.data}'{"password.txt":"MWEyYjNjNGQ=","username.txt":"YWRtaW4="}[root@master01:~]# echo 'MWEyYjNjNGQ=' | base64 -d1a2b3c4d[root@master01:~]# echo 'YWRtaW4=' | base64 -dadmin

案例实施

示例:将Mysql用户密码保存到Secret中存储

创建secret,mysql-root-password的键值是1a2a3a4a

[root@master01:~]# kubectl create secret generic mysql --from-literal=mysql-root-password=1a2a3a4asecret/mysql created[root@master01:~]# kubectl get secrets mysql -o yamlapiVersion: v1data:mysql-root-password: MWEyYTNhNGE=kind: Secretmetadata:creationTimestamp: "2022-04-13T07:06:21Z"name: mysqlnamespace: defaultresourceVersion: "102066"uid: 3104256b-5b46-43a4-85ed-acc66be7ccbatype: Opaque

创建Pod测试,使用env从secret中引用变量

[root@master01:~]# cat pod.yamlapiVersion: v1kind: Podmetadata:labels:run: mysqlname: mysqlspec:nodeName: master01containers:- image:mysql:5.6name: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mysqlkey: mysql-root-password[root@master01:~]# kubectl get podsNAMEREADY STATUSRESTARTS AGEmysql 1/1 Running 021s

安全沙箱运行容器

gVisor介绍

所知,容器的应用程序可以直接访问Linux内核的系统调用,容器在安全隔离上还是比较弱,虽然 内核在不断地增强自身的安全特性,但由于内核自身代码极端复杂,CVE 漏洞层出不穷。 所以要想减少这方面安全风险,就是做好安全隔离,阻断容器内程序对物理机内核的依赖。 Google开源的一种gVisor容器沙箱技术就是采用这种思路,gVisor隔离容器内应用和内核之间访 问,提供了大部分Linux内核的系统调用,巧妙的将容器内进程的系统调用转化为对gVisor的访问。

gVisor兼容OCI,与Docker和K8s无缝集成,很方面使用。

项目地址:https://github.com/google/gvisor

gVisor内核交互

gVisor架构

gVisor与Docker集成

gVisor内核要求:

Linux 3.17+ 如果用的是CentOS7则需要升级内核,Ubuntu不需要。

CentOS7内核升级步骤:

[root@master01 ~]# rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org[root@master01 ~]# rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm[root@master01 ~]# yum --enablerepo=elrepo-kernel install kernel-ml-devel kernel-ml –y[root@master01 ~]# grub2-set-default 0[root@master01 ~]# reboot[root@master01 ~]# uname -r[root@master01 ~]# 5.17.2-1.el7.elrepo.x86_64

gVisor集成Docker配置

参考文档:https://gvisor.dev/docs/user_guide/install/

已经测试过的应用和工具:https://gvisor.dev/docs/user_guide/compatibility/

1、准备gVisor二进制文件[root@master01 ~]# sha512sum -c runsc.sha512[root@master01 ~]# rm -f *.sha512[root@master01 ~]# chmod a+x runsc [root@master01 ~]# chmod a+x containerd-shim-runsc-v1[root@master01 ~]# mv runsc containerd-shim-runsc-v1 /usr/local/bin2、Docker配置使用gVisor[root@master01 ~]# runsc install # 查看加的配置/etc/docker/daemon.json[root@master01 ~]# systemctl restart docker使用runsc运行容器:[root@master01 ~]# docker run -d --runtime=runsc nginx使用dmesg验证:[root@master01 ~]# docker run --runtime=runsc -it nginx dmesg
gVisor与Containerd集成

如果这里是Docker的环境,需要切换到Containerd容器引擎。

仍然需要将runsc 、containerd-shim-runsc-v1工具移到/usr/local/bin下面

1.准备配置

开启ipv4路由转发配置,重新生效系统配置

[root@master01 ~]# cat > /etc/sysctl.d/99-kubernetes-cri.conf << EOFnet.bridge.bridge-nf-call-iptables = 1net.ipv4.ip_forward = 1net.bridge.bridge-nf-call-ip6tables = 1EOF[root@master01 ~]# sysctl -system

2、安装Containerd

如果默认安装了docker-ce会自动安装containerd的依赖,没有则需要安装containerd。

ubuntu添加docker-ce的repo源之后apt-get install的方式安装

[root@master01 ~]# cd /etc/yum.repos.d[root@master01 ~]# wget http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo[root@master01 ~]# yum install -y containerd.io

3、修改配置文件

  1. pause镜像地址
  2. Cgroup驱动改为systemd
  3. 增加runsc容器运行时
  4. 配置docker镜像加速器

修改配置文件默认的containerd的配置文件是空的,所以需要重新生成一个完整的配置文件。

containerd的目录是在 /etc/containerd

[root@master01 ~]# cd /etc/containerd/[root@master01 containerd]# containerd configdefault > config.toml[root@master01 containerd]# vim config.toml 43 [plugins."io.containerd.grpc.v1.cri"] ···· # 修改镜像为国内的镜像 56 sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.2"····# 添加一个runsc,指定类型为runsc,这里是跟runc同级 90[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runsc] 91 runtime_type = "io.containerd.runsc.v1" # 修改systemd驱动为true 94[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] 103[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]··· 114SystemdCgroup = true# 添加docker仓库的镜像源,配置阿里镜像加速 139 [plugins."io.containerd.grpc.v1.cri".registry.mirrors] 140[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] 141endpoint = ["https://b9pmyelo.mirror.aliyuncs.com"]

配置kubelet使用containerd

配置完之后先重启containerd,再重启kubelet,最后如果pod出现报错,重启docker。

[root@master01 ~]# vi /etc/sysconfig/kubelet KUBELET_EXTRA_ARGS=--container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --cgroup-driver=systemd[root@master01 ~]# systemctl restart containerd[root@master01 ~]# systemctl restart kubelet[root@master01 ~]# systemctl restart docker

验证当前的Kubernetes容器基层

  1. 以上的步骤需要在所有集群配置
  2. 包括crictl连接containerd的配置也要在所有集群运行
[root@master01 ~]# kubectl getnode -o wide | awk'{print $1,$2,$5,$NF}' | column -tNAMESTATUSVERSIONCONTAINER-RUNTIMEmaster01Ready v1.22.1containerd://1.5.11master02Ready v1.22.1containerd://1.5.11master03Ready v1.22.1containerd://1.5.11

crictl连接containerd

containerd也有 ctr 管理工具,但功能比较简单,一般使用crictl工具检查和调试容器。

项目地址:https://github.com/kubernetes-sigs/cri-tools/

准备crictl连接containerd配置文件:

[root@master01 ~]# cat > /etc/crictl.yaml << EOFruntime-endpoint: unix:///run/containerd/containerd.sockEOF[root@master01 ~]# systemctl restartcontainerd 

下面是docker与crictl命令对照表:

案例实施

示例: K8s使用gVisor运行容器
  • 创建RuntimeClass
  • 绑定RuntimeClass

RuntimeClass 是一个用于选择容器运行时配置的特性,容器运行时配置用 于运行 Pod 中的容器。

创建RuntimeClass:

  • 这里创建一个名称为gvisor的runtimeclass资源
  • 可以创建多个runtimeclass资源,起到隔离的效果
  • handler一定是runsc,对应CSI的配置名称
[root@master01 ~]# cat runtime.yamlapiVersion: node.k8s.io/v1 # RuntimeClass 定义于 node.k8s.io API 组kind: RuntimeClassmetadata:name: gvisor # 用来引用 RuntimeClass 的名字handler: runsc # 对应的 CRI 配置的名称[root@master01 ~]# kubectl get runtimeclassesNAME HANDLER AGEgvisor runsc 72m

创建Pod测试gVisor:

这里使用runtimeClassName绑定

[root@master01 ~]# cat pod.yamlapiVersion: v1kind: Podmetadata:labels:run: podname: podspec:nodeName: "master01"runtimeClassName: gvisorcontainers:- image: nginxname: pod[root@master01 ~]# kubectl get podsNAME READY STATUSRESTARTS AGEpod1/1 Running 072m
  • 创建RuntimeClass
  • 绑定RuntimeClass

RuntimeClass 是一个用于选择容器运行时配置的特性,容器运行时配置用 于运行 Pod 中的容器。

创建RuntimeClass:

  • 这里创建一个名称为gvisor的runtimeclass资源
  • 可以创建多个runtimeclass资源,起到隔离的效果
  • handler一定是runsc,对应CSI的配置名称
[root@master01 ~]# cat runtime.yamlapiVersion: node.k8s.io/v1 # RuntimeClass 定义于 node.k8s.io API 组kind: RuntimeClassmetadata:name: gvisor # 用来引用 RuntimeClass 的名字handler: runsc # 对应的 CRI 配置的名称[root@master01 ~]# kubectl get runtimeclassesNAME HANDLER AGEgvisor runsc 72m

创建Pod测试gVisor:

这里使用runtimeClassName绑定

[root@master01 ~]# cat pod.yamlapiVersion: v1kind: Podmetadata:labels:run: podname: podspec:nodeName: "master01"runtimeClassName: gvisorcontainers:- image: nginxname: pod[root@master01 ~]# kubectl get podsNAME READY STATUSRESTARTS AGEpod1/1 Running 072m