十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

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

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 集群。原文档给出了两条典型路径GKE Sandbox 集群在 Google Cloud 上使用启用了 GKE SandboxgVisor的节点池gvisor 的RuntimeClass会在节点创建时自动实例化。验证方式$ kubectl get runtimeclass/gvisor NAME HANDLER AGE gvisor gvisor 1h自建集群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/cli的Main函数shim 主体逻辑容器生命周期管理、与 runsc 的交互位于 pkg/shim/v1/ 下的runsc/、proc/、runtimeoptions/等子包。shim 的示例配置文件见 shim/runsc.toml更多运行参数如log_path、[runsc_config]透传给 runsc 的 flag可参考 Containerd Advanced Configuration。注册完运行时后为集群安装gvisor的RuntimeClasshandler 指向 runsc 运行时cat EOF | kubectl apply -f - apiVersion: node.k8s.io/v1 kind: RuntimeClass metadata: name: gvisor handler: runsc EOF安装 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 的部署 ConfigMapkubectl edit configmap config-deployment -n knative-serving该配置项的语义是“按 Pod 标签选择器label selector配置 Pod 的runtimeClassName字段”。原文档给出两种典型写法。写法一强制所有 Knative Pod 使用 gVisorapiVersion: 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 不使用 gVisorapiVersion: 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 及其runtimeClassNamekubectl get pods -ocustom-columnsNAME:.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 仓库可以佐证每一环kubelet / CRIkubelet 将 Pod 交给容器运行时运行时名对应 containerd 配置中的 handlerrunsc/io.containerd.runsc.v1containerd shimcontainerd 依据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.go、container.go等runsc 沙箱shim 通过 pkg/shim/v1/runsccmd/ 调用 runsc 二进制真正创建 Sentry 沙箱Pod 内所有容器的应用进程都在沙箱内执行运行时参数如需给 runsc 传 flag可通过 shim/runsc.toml 所示的[runsc_config]段配置flag value会被转换为runsc --flagvalue配置文件默认路径为/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 RuntimeClassGKE Sandbox 节点池或按 Containerd Quick Start 配置的自建节点config-deployment的runtime-class-name写法取决于 Knative Serving 版本对“可选择 RuntimeClass”特性的支持以你所用 Knative 版本的部署配置文档为准。【免费下载链接】gvisorApplication Kernel for Containers项目地址: https://gitcode.com/GitHub_Trending/gv/gvisor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表