gVisor Kubernetes 实战:基于 GKE Sandbox 的沙箱化 WordPress 部署指南
2026/9/13 15:45:29 网站建设 项目流程

gVisor Kubernetes 实战:基于 GKE Sandbox 的沙箱化 WordPress 部署指南

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

本文基于 gVisor 仓库自带的 Kubernetes 教程(tutorials/kubernetes.md),演示如何借助 GKE Sandbox 在 Kubernetes 集群中部署一个受 gVisor 沙箱保护的 WordPress 站点:从启用 gVisor 节点池、验证 RuntimeClass 生效,到修改 Deployment 清单、创建 Secret 并部署前后端两个 Pod 的完整流程。读完本文,你可以独立完成一套 gVisor 沙箱化 Web 应用的 Kubernetes 部署,并理解 gVisor 在安全与性能之间做取舍的生产实践依据。

前置准备

本教程的运行环境是 Google Kubernetes Engine(GKE)中的 GKE Sandbox。开始之前需要完成两步:

  1. 在 Google Cloud 控制台中进入 Kubernetes Engine 页面,启用 Kubernetes Engine API;
  2. 创建或选择一个用于部署的 GCP 项目。

完成这两步后,你的项目即具备了创建 gVisor 节点池的条件。

创建启用 gVisor 的节点池

gVisor 节点池的核心区别在于节点上预装了runsc运行时,并自动注册了一个名为gvisorRuntimeClass。有两种方式可以创建。

方式一:gcloud 命令行

在创建节点池的命令中加入--sandbox type=gvisor参数:

gcloud container node-pools create gvisor \ --cluster=${CLUSTER_NAME?} \ --sandbox type=gvisor \ --machine-type=e2-standard-2

参数说明:

  • --cluster:目标集群名称,${CLUSTER_NAME?}写法表示变量未设置时命令直接报错退出;
  • --sandbox type=gvisor:声明该节点池使用 gVisor 沙箱运行时,这是唯一区别于普通节点池的关键选项;
  • --machine-type:节点机型,本例选用 2 vCPU 的e2-standard-2,可按需调整。

方式二:GKE 控制台

在控制台中选择目标集群,点击ADD NODE POOL按钮:

然后在新建节点池页面的左侧切换到Security选项卡,勾选Enable sandbox with gVisor选项,其余配置(机型、节点数等)按需选择即可。

节点创建后发生了什么

gVisor 的RuntimeClass资源是在节点创建过程中实例化的。这一点可以从仓库的 Kubernetes 测试框架中得到印证:testcluster.go 中定义了常量gvisorRuntimeClass = "gvisor",表示 GKE Sandbox Pod 统一使用该名称的 RuntimeClass;而 objects.go 中的ApplyPodSpec方法在把测试 Pod 配置为 gVisor 运行时时,执行的核心操作正是podSpec.RuntimeClassName = proto.String(gvisorRuntimeClass)——即把 Pod 规格的runtimeClassName字段设置为gvisor

也就是说,Kubernetes 层面整个集成路径可以概括为:节点池声明--sandbox type=gvisor→ 节点上注册gvisorRuntimeClass → Pod 通过runtimeClassName: gvisor声明使用沙箱运行时

验证 gVisor 已启用

节点池就绪后,用以下命令确认gvisorRuntimeClass已经存在:

$ kubectl get runtimeclass/gvisor NAME HANDLER AGE gvisor gvisor 1h

输出中HANDLER列的值就是 kubelet 用来调度沙箱运行的 handler 名称。如果该命令返回 not found,说明节点池尚未创建完成或没有真正启用 gVisor 选项。

WordPress 部署:架构与关键设计决策

WordPress 站点需要两个 Pod 协同工作:

  • 前端 Web 服务器wordpress:4.8-apache):面向公网,攻击面最大;
  • 后端 MySQL 数据库mysql:5.6):存储站点数据,I/O 密集。

两者都使用PersistentVolumeClaim持久化数据,并通过 Kubernetes Secret(mysql-pass)共享 MySQL 密码。

生产环境的关键取舍:本示例只对前端 Web 服务器启用 gVisor 沙箱,而沙箱化 MySQL 后端。原因是 gVisor 存在 I/O 开销:I/O 密集型工作负载(如数据库)在沙箱中性能损耗明显,而前端 Web 服务器是对外攻击面最大的组件,在这里使用 gVisor 的安全/性能权衡收益最大。这一原则在仓库的生产环境指南中有系统论述:gVisor 通过拦截并用户态模拟系统调用来隔离宿主机内核,可以防御绝大多数 Linux CVE、容器逃逸和远程提权攻击;但I/O 密集(数据库)和网络密集(负载均衡器)负载会感知到性能下降,CPU 密集型负载(API 服务器、非静态 Web 服务器、数据处理管道)则几乎无损。因此建议"先缩减外部攻击面,再对高价值入口点沙箱化",而不是把所有应用都沙箱化。

准备部署清单

首先下载 Kubernetes 官方的 WordPress 示例清单(分别位于 k8s.io 官方文档站点的examples/application/wordpress/目录下):

curl -LO https://k8s.io/examples/application/wordpress/wordpress-deployment.yaml curl -LO https://k8s.io/examples/application/wordpress/mysql-deployment.yaml

然后在两个文件的spec.template.spec下各添加一行runtimeClassName: gvisor,这是让 Pod 落入 gVisor 沙箱的唯一改动。

wordpress-deployment.yaml

apiVersion: v1 kind: Service metadata: name: wordpress labels: app: wordpress spec: ports: - port: 80 selector: app: wordpress tier: frontend type: LoadBalancer --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: wp-pv-claim labels: app: wordpress spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: wordpress labels: app: wordpress spec: selector: matchLabels: app: wordpress tier: frontend strategy: type: Recreate template: metadata: labels: app: wordpress tier: frontend spec: runtimeClassName: gvisor # ADD THIS LINE containers: - image: wordpress:4.8-apache name: wordpress env: - name: WORDPRESS_DB_HOST value: wordpress-mysql - name: WORDPRESS_DB_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password ports: - containerPort: 80 name: wordpress volumeMounts: - name: wordpress-persistent-storage mountPath: /var/www/html volumes: - name: wordpress-persistent-storage persistentVolumeClaim: claimName: wp-pv-claim

要点解析:

  • runtimeClassName: gvisor加在spec.template.spec层级(即 Pod 模板的规格下),这是 RuntimeClass 的标准挂载位置;
  • Servicetype: LoadBalancer会让 GKE 分配一个外部 IP,用于浏览器访问;
  • strategy.type: Recreate保证数据库卷切换时新旧 Pod 不并发竞争同一个ReadWriteOncePVC;
  • WORDPASS_DB_HOST指向名为wordpress-mysql的 Service(见下文的 headless service)。

mysql-deployment.yaml

apiVersion: v1 kind: Service metadata: name: wordpress-mysql labels: app: wordpress spec: ports: - port: 3306 selector: app: wordpress tier: mysql clusterIP: None --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pv-claim labels: app: wordpress spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: wordpress-mysql labels: app: wordpress spec: selector: matchLabels: app: wordpress tier: mysql strategy: type: Recreate template: metadata: labels: app: wordpress tier: mysql spec: #runtimeClassName: gvisor # Uncomment this line if you want to sandbox the database. containers: - image: mysql:5.6 name: mysql env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pv-claim

要点解析:

  • clusterIP: None使wordpress-mysql成为 headless Service,前端通过该 DNS 名直连数据库 Pod(配合WORDPRESS_DB_HOST=wordpress-mysql);
  • MySQL 的runtimeClassName: gvisor被注释掉了——这正对应前文的生产建议:示例默认只沙箱化前端。注释中还给出了明确提示,如需对数据库沙箱化可取消该行注释,但这会引入 gVisor 的文件 I/O 开销,仅建议在功能验证而非生产场景下进行。

runtimeClassName之外,两个 Deployment 与原官方示例完全一致——这正是 RuntimeClass 机制的价值:应用清单几乎零侵入,仅一行声明即可切换容器运行时。

部署与验证

创建存储 MySQL 密码的 Secret,然后依次应用两份清单:

$ kubectl create secret generic mysql-pass --from-literal=password=${YOUR_SECRET_PASSWORD_HERE?} $ kubectl apply -f mysql-deployment.yaml $ kubectl apply -f wordpress-deployment.yaml

等待两个 Deployment 就绪,并观察 WordPress Service 被分配外部 IP:

$ watch kubectl get service wordpress NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE wordpress LoadBalancer 10.120.16.63 35.203.179.216 80:31025/TCP 1m

将输出的EXTERNAL-IP粘贴到浏览器地址栏,即可看到并配置你的 WordPress 站点——此刻承载该站点的前端容器正在 gVisor 沙箱内运行,其系统调用由runsc在用户态模拟,而非直接到达宿主机内核。

想确认某个 Pod 确实在沙箱内运行,可参考仓库 containerd 快速入门 中的验证手段,例如在容器内执行dmesg并检索 gVisor 相关输出。

其他接入方式与进阶参考

本教程展示的是 GKE Sandbox 这一"托管、免调优"的路径。gVisor 接入 Kubernetes 还有其他集成点,仓库文档中均有对应章节:

  • Minikube:启用 gVisor 插件后,设置gvisorRuntimeClass 的 Pod 即由runsc执行,见 Kubernetes 快速入门;
  • 自建集群 + containerd:通过 gVisor 的 containerd shim(实现 containerd shim v2 接口,兼容 containerd 1.3 及以上)接入,并在自建RuntimeClass中将handler设为runsc,完整步骤见 Containerd 快速入门。该文档中给出的最小 RuntimeClass 清单如下,可用于对比理解 GKE 自动创建的gvisorRuntimeClass 的构成:
apiVersion: node.k8s.io/v1 kind: RuntimeClass metadata: name: gvisor handler: runsc

此外,仓库还内置了配套的 Kubernetes 测试与验证资产,可作为深入阅读的入口:

  • test/kubernetes/ 下的testcluster框架封装了节点池创建、RuntimeClass 管理及 Pod 运行时选择(objects.go 中ApplyPodSpec/ApplyNodepool),是 gVisor 在 GKE 上做运行时对比测试的基础;
  • 性能指南 提供了各平台(KVM、ptrace、systrap 等)下沙箱开销的数据与分析;
  • 生产环境指南 系统回答了"哪些工作负载值得沙箱化、如何为性能调优平台与 I/O、网络"的问题——把 WordPress 这类部署推上生产之前,建议先通读该指南。

至此,你已完整走完"启用 gVisor 节点池 → 验证 RuntimeClass → 单行改动清单 → 沙箱化 WordPress 上线"的全流程,并掌握了 gVisor 在 Kubernetes 中安全/性能取舍的生产决策框架。

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询