news 2026/9/13 15:01:12

gVisor 与 Knative 集成:让 Kubernetes 上的 Serverless 工作负载运行在 gVisor 沙箱中

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
gVisor 与 Knative 集成:让 Kubernetes 上的 Serverless 工作负载运行在 gVisor 沙箱中

gVisor 与 Knative 集成:让 Kubernetes 上的 Serverless 工作负载运行在 gVisor 沙箱中

【免费下载链接】gvisorApplication Kernel for Containers项目地址: https://gitcode.com/GitHub_Trending/gv/gvisor

本文基于 gVisor 仓库中的 Knative 教程(g3doc/user_guide/tutorials/knative.md)展开,讲解如何让 Knative 创建的 Serverless 服务默认运行在 gVisor 沙箱中:从集群 RuntimeClass 准备,到 Knative 部署配置中runtime-class-name的完整写法与例外规则,再到服务部署与沙箱生效验证,并结合仓库中 containerd shim 的源码路径说明整条“RuntimeClass → runsc”的落地链路。读完本文,你可以将任意 Knative Serving 工作负载批量迁入 gVisor 隔离环境,并按标签粒度控制例外。

前提条件:一个能运行 gVisor 工作负载的集群

本教程假设你拥有一个能够运行 gVisor 工作负载的 Kubernetes 集群。原文档给出了两条典型路径:

  1. GKE Sandbox 集群:在 Google Cloud 上使用启用了 GKE Sandbox(gVisor)的节点池,gvisor 的RuntimeClass会在节点创建时自动实例化。验证方式:

    $ kubectl get runtimeclass/gvisor NAME HANDLER AGE gvisor gvisor 1h
  2. 自建集群(containerd + gVisor shim):在自建节点上通过 containerd 的 gVisor 运行时处理器接入,完整步骤见仓库内的 Containerd Quick Start。其核心是在/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"

    其中runtime_type = "io.containerd.runsc.v1"指向 gVisor 提供的 containerd shim 二进制containerd-shim-runsc-v1。该 shim 的入口即仓库中的 shim/main.go,它调用gvisor.dev/gvisor/shim/v1/cliMain函数;shim 主体逻辑(容器生命周期管理、与 runsc 的交互)位于 pkg/shim/v1/ 下的runsc/proc/runtimeoptions/等子包。shim 的示例配置文件见 shim/runsc.toml,更多运行参数(如log_path[runsc_config]透传给 runsc 的 flag)可参考 Containerd Advanced Configuration。

    注册完运行时后,为集群安装gvisorRuntimeClass(handler 指向 runsc 运行时):

    cat <<EOF | kubectl apply -f - apiVersion: node.k8s.io/v1 kind: RuntimeClass metadata: name: gvisor handler: runsc EOF
  3. 安装 Knative:按 Knative 官方的 YAML 安装指南在其 Serving 组件上安装 Knative(会创建knative-serving命名空间及config-deployment等 ConfigMap)。二进制与集群组件的安装细节另见 安装指南。

配置 Knative 的 runtime-class-name 部署项

Knative 允许通过部署配置(deployment configs,即knative-serving命名空间下的 ConfigMap)为它创建的 Pod 设置各种参数,其中runtime-class-name用于控制 Knative 生成的 Deployment 中的 Pod 运行在哪种运行时上。

编辑 Knative 的部署 ConfigMap:

kubectl edit configmap config-deployment -n knative-serving

该配置项的语义是“按 Pod 标签选择器(label selector)配置 Pod 的runtimeClassName字段”。原文档给出两种典型写法。

写法一:强制所有 Knative Pod 使用 gVisor

apiVersion: v1 kind: ConfigMap metadata: name: config-deployment namespace: knative-serving data: runtime-class-name: | gvisor: {}

runtime-class-name的值是一个 YAML 映射:键为运行时类名,值为匹配的标签选择器。这里gvisor: {}表示空选择器(无标签约束),即所有经 Knative 创建的 Pod 都会被强制使用gvisor作为 Runtime Class。

写法二:按标签允许例外 Pod 不使用 gVisor

apiVersion: v1 kind: ConfigMap metadata: name: config-deployment namespace: knative-serving data: runtime-class-name: | "": selector: no-isolation-here: "true" gvisor: {}

这里引入了两个条目:

  • ""(空字符串键)表示使用集群默认运行时(即不设置 gVisor Runtime Class),并只在 Pod 带有no-isolation-here: "true"标签时才命中;
  • gvisor: {}仍然是兜底规则,命中其余所有 Pod。

因此,带有no-isolation-here: "true"标签的 Knative 服务可以绕过沙箱直接跑在默认运行时上(例如某些与沙箱兼容性不佳、或 I/O 密集的工作负载),其余服务仍然全部进入 gVisor。注意选择器按“更具体者优先”的方式匹配,兜底规则应放在无法被具体选择器命中的位置(本文档示例中即空选择器条目)。

部署 Knative Service

设置好 Runtime Class 部署配置后,就可以创建 Knative Service 了。原文档使用经典的helloworld-go示例镜像,并通过TARGET环境变量定制输出内容:

cat <<EOF | kubectl apply -f - apiVersion: serving.knative.dev/v1 kind: Service metadata: name: helloworld-go spec: template: spec: containers: - image: gcr.io/knative-samples/helloworld-go env: - name: TARGET value: "gVisor User" EOF

注意整个 Service 定义中没有任何 gVisor 相关的显式字段——沙箱归属完全由上一步config-deployment中的runtime-class-name规则决定。这正是 Knative 集成方式的价值:无需修改业务服务清单,平台层配置即可全局生效。

验证 Pod 的 Runtime Class

用自定义列查看 Pod 及其runtimeClassName

kubectl get pods -o=custom-columns='NAME:.metadata.name,RUNTIME CLASS:.spec.runtimeClassName,STATUS:.status.phase'

输出应类似:

NAME RUNTIME CLASS STATUS helloworld-go-00002-deployment-646c87b7f5-5v68s gvisor Running

两个需要留意的现象:

  • 缩容到零:Knative 的核心特性是空闲时把副本缩到 0,因此执行命令时可能看不到任何 Pod;通过其 URL 访问服务会触发一个全新 Pod 被拉起,该 Pod 同样会带有gvisorRuntime Class。
  • 版本后缀:Pod 名中的00002是 Knative 的 Revision 序号,每次模板变更都会产生新 Revision,新 Pod 的运行时归属仍由 ConfigMap 规则决定。

看到RUNTIME CLASS列为gvisor且状态Running,即表示 Knative 服务已运行在 gVisor 沙箱中。

底层链路:runtimeClassName 如何一路到达 runsc

从源码结构看,Knative 配置中的runtime-class-name最终落到 Pod 的spec.runtimeClassName字段,后续链路与普通 Kubernetes Pod 完全一致,gVisor 仓库可以佐证每一环:

  1. kubelet / CRI:kubelet 将 Pod 交给容器运行时,运行时名对应 containerd 配置中的 handler(runsc/io.containerd.runsc.v1);
  2. containerd shim:containerd 依据runtime_type = "io.containerd.runsc.v1"启动containerd-shim-runsc-v1。该 shim 实现 containerd v2 shim API(兼容 v1 任务服务),仓库中 pkg/shim/v1/manager.go 负责沙箱内多容器的生命周期管理,pkg/shim/v1/runsc/ 封装对 runsc 的调用(api.gocontainer.go等);
  3. runsc 沙箱:shim 通过 pkg/shim/v1/runsccmd/ 调用 runsc 二进制真正创建 Sentry 沙箱,Pod 内所有容器的应用进程都在沙箱内执行;
  4. 运行时参数:如需给 runsc 传 flag,可通过 shim/runsc.toml 所示的[runsc_config]段配置(flag = "value"会被转换为runsc --flag="value"),配置文件默认路径为/etc/containerd/runsc.toml,机制说明见 Containerd Advanced Configuration。

也就是说,Knative 教程只是在这条通用链路的“源头”换了一个配置入口:由 Knative Serving 控制面统一给每个 Revision 的 Pod 打上runtimeClassName: gvisor,而不是要求每个开发者在 Service 清单里手写。

生产环境注意事项

  • I/O 开销:gVisor 的沙箱机制会带来一定的 I/O 开销,仓库的 Production Guide 对生产部署给出了系统性的建议;同样的取舍在 WordPress 教程 中也有体现——沙箱化对外暴露面最大的前端组件收益最大,而数据库类组件通常不建议放入沙箱。Knative 场景下,可借助上文“按标签例外”的写法,为少数不适合沙箱的 Service 打上no-isolation-here标签放行。
  • 冷启动与缩容到零:Knative 的 scale-to-zero 意味着首次请求会额外承担沙箱创建(runsc 启动、Sentry 初始化)的开销,容量规划时应结合访问模式评估。
  • 适用范围:本教程的前提是集群节点已具备 gvisor RuntimeClass(GKE Sandbox 节点池或按 Containerd Quick Start 配置的自建节点);config-deploymentruntime-class-name写法取决于 Knative Serving 版本对“可选择 RuntimeClass”特性的支持,以你所用 Knative 版本的部署配置文档为准。

【免费下载链接】gvisorApplication Kernel for Containers项目地址: https://gitcode.com/GitHub_Trending/gv/gvisor

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 15:00:55

Slew与Skew:高速电路中的边沿速率与时间偏移深度解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 15:00:53

PLC硬件联调与信号验证:产线故障定位实战指南

1. 这不是“学PLC”&#xff0c;而是“从产线旁站稳脚跟”的第一步我带过37期PLC实操班&#xff0c;学员里有刚毕业的机械专业本科生&#xff0c;也有干了十五年电工、第一次摸电脑的老师傅。开班第一天&#xff0c;我从不讲梯形图&#xff0c;而是把所有人拉到实训台前&#x…

作者头像 李华
网站建设 2026/9/13 15:00:33

GJK碰撞检测算法原理与MATLAB实现详解

简介&#xff1a;这是一份基于MATLAB的GJK碰撞检测算法实现包&#xff0c;面向计算机图形学、物理模拟及机器人路径规划等领域的开发者与学习者。GJK算法通过支撑向量与Minkowski差快速判断三维物体是否相交&#xff0c;项目完整实现了支撑向量计算、Minkowski差构造、迭代求解…

作者头像 李华
网站建设 2026/9/13 15:00:04

Hive、Presto与Druid:OLAP引擎选型与性能对比

1. OLAP引擎选型的关键考量因素 在大数据领域&#xff0c;OLAP&#xff08;在线分析处理&#xff09;引擎的选择直接影响着数据分析的效率和成本。面对Hive、Presto和Druid这三个主流选择&#xff0c;我们需要从多个维度进行系统评估。 首先明确一个基本认知&#xff1a;没有完…

作者头像 李华
网站建设 2026/9/13 14:59:18

Kronos K线预测完整指南:开源K线大模型本地快速上手

Kronos K线预测完整指南&#xff1a;开源K线大模型本地快速上手 【免费下载链接】Kronos Kronos: A Foundation Model for the Language of Financial Markets 项目地址: https://gitcode.com/GitHub_Trending/kronos14/Kronos 每天盯盘数小时&#xff0c;还要手工拉均线…

作者头像 李华