用 R 与 plumber 构建 Knative Serving 服务:helloworld-rserver 实战指南 文档教程云原生【免费下载链接】docsUser documentation for Knative components.项目地址https://gitcode.com/gh_mirrors/docs1/docs点击查看免费下载helloworld-rserver是 Knative 文档仓库code-samples/community/serving/helloworld-rserver中由社区贡献并维护的一个 Serving 代码样例演示如何用 R 语言和 plumber 包编写一个纯 R 实现的 REST API并把它部署到 Knative 集群。通过本指南你将掌握 plumber 注解式路由的写法、TARGET/PORT环境变量的容器契约、多架构镜像的构建推送以及使用kubectl完成 Knative Service 的部署、验证与清理全流程。示例概览plumber 注解驱动的 R REST APIKnative 官方代码样例按用途分为 Serving 与 Eventing 两大类别参见 code-samples/README.md其中社区贡献样例统一放在 code-samples/community/serving/README.md 下。helloworld-rserver正是其中的一个 Serving 样例它不依赖任何外部 Web 框架而是直接用 R 生态的plumber包——plumber 通过在 R 函数上方书写# get ...形式的注解把普通 R 函数声明为 HTTP 端点从而让 R 脚本天然变成 REST API。整个样例目录只包含四个文件完整实现见 code-samples/community/serving/helloworld-rserver文件作用HelloWorld.R定义端点/读取环境变量TARGET并输出Hello ${TARGET}!server.R调用 plumber 把HelloWorld.R装载为 API 并监听端口Dockerfile基于 R 官方基础镜像构建运行环境并安装 plumberservice.yamlKnative Serving 的Service声明注入TARGET环境变量样例的核心逻辑很简单应用读取环境变量TARGET向访问者返回Hello ${TARGET}!如果未设置TARGET则默认使用World。这与其他语言的 Hello World 样例如 helloworld-nodejs/index.js 中的process.env.TARGET || World遵循完全一致的惯例便于横向对照。前置条件开始之前需要准备以下环境一个已安装 Knative 的 Kubernetes 集群Knative Serving 负责把下面的镜像变成可访问、可自动伸缩的 Serverless 服务。Docker 与容器镜像仓库账号本地 Docker 需正常运行并配置好 Docker Hub 账号本文以 Docker Hub 作为镜像仓库将镜像推送到docker.io。如果想直接拿到可运行的完整样例也可以克隆本仓库后在样例目录中操作git clone https://gitcode.com/gh_mirrors/docs1/docs.git knative-docs cd knative-docs/code-samples/community/serving/helloworld-rserver复现示例代码四个文件的逐行解读下面按原文档的复现步骤逐一创建四个文件。你也可以直接对照仓库中的现成文件例如 HelloWorld.R、server.R、Dockerfile 与 service.yaml。HelloWorld.R用 plumber 注解声明 REST 端点新建文件HelloWorld.R内容如下对应仓库源码 HelloWorld.R# HelloWorld function # get / # html function() { TARGET - Sys.getenv(TARGET, World) message paste(Hello , TARGET, !, sep ) print(message) }逐行拆解# get /plumber 的注解语法采用 roxygen2 风格的#注释。它告诉 plumber下面的函数需要注册为 HTTPGET方法路径为根路径/。只要调用这个函数即可处理一次对/的请求。# html声明响应的内容类型为 HTML 呈现。TARGET - Sys.getenv(TARGET, World)读取环境变量TARGETSys.getenv的第二个参数World是默认值即当环境变量未设置时回退为World。paste(Hello , TARGET, !, sep )拼接字符串得到Hello ${TARGET}!sep 保证拼接时不插入额外空格。也就是说这一份 R 文件同时完成了「路由声明」与「业务逻辑」两件事这正是 plumber 注解式开发的核心体验。server.R将 R 脚本变成可运行 API新建文件server.R内容如下对应仓库源码 server.Rlibrary(plumber) # https://www.rplumber.io/ # Translate the HelloWorld file into a Plumber API r - plumb(HelloWorld.R) # Get the PORT env var PORT - strtoi(Sys.getenv(PORT, 8080)) # Run the API r$run(portPORT, host0.0.0.0)关键点说明library(plumber)加载 plumber 包。plumb(HelloWorld.R)解析HelloWorld.R中的注解把它翻译成一个 plumber 路由对象r。PORT - strtoi(Sys.getenv(PORT, 8080))读取环境变量PORT并转换为整数默认值8080。r$run(portPORT, host0.0.0.0)以指定端口启动 API并绑定到0.0.0.0确保容器内网任意地址都能访问。Dockerfile把 R 运行时装进容器新建文件Dockerfile内容如下对应仓库源码 Dockerfile# The official R base image # https://hub.docker.com/_/r-base FROM r-base:3.6.0 # Copy local code to the container image. WORKDIR /usr/src/app COPY . . # Install R packages RUN Rscript -e install.packages(plumber, reposhttp://cran.us.r-project.org/) # Run the web service on container startup. CMD [Rscript, server.R]构建逻辑拆解FROM r-base:3.6.0以 R 官方基础镜像为底镜像内自带Rscript解释器。WORKDIR /usr/src/app与COPY . .把当前目录含HelloWorld.R、server.R复制进容器的/usr/src/app。RUN Rscript -e install.packages(plumber, ...)在构建阶段用Rscript从 CRAN 仓库安装 plumber 依赖使镜像开箱即用。CMD [Rscript, server.R]容器启动时执行Rscript server.R拉起 plumber API。service.yamlKnative Service 声明新建文件service.yaml内容如下对应仓库源码 service.yaml记得把{username}替换成你的 Docker Hub 用户名apiVersion: serving.knative.dev/v1 kind: Service metadata: name: helloworld-rserver namespace: default spec: template: spec: containers: - image: docker.io/{username}/helloworld-rserver env: - name: TARGET value: R Server Sample v1这份清单说明了 Knative Serving 的核心声明式模型apiVersion: serving.knative.dev/v1、kind: Service声明一个 KnativeService资源简称ksvc。metadata.name服务名为helloworld-rserver后续查询、删除都要用到这个名字。spec.template.spec.containers定义容器模板。image指向我们即将构建并推送的镜像env中注入TARGETR Server Sample v1让应用启动时通过Sys.getenv(TARGET)读到该值从而在响应中输出Hello R Server Sample v1!。环境变量契约TARGET 与 PORT这个样例演示了 Knative Serving 容器应用的两个通用约定TARGET业务自定义的环境变量由service.yaml的env注入代码中通过Sys.getenv(TARGET, World)消费缺省回退World。PORTKnative 平台注入的端口约定。Serving 会在运行时把监听端口通过PORT环境变量传给容器应用必须监听该端口才能被路由和探活。server.R中的Sys.getenv(PORT, 8080)正是对这一约定的消费。同样的模式在仓库其他样例中反复出现例如 helloworld-nodejs/index.js 的process.env.PORT || 8080以及 autoscale-go/autoscale.go 中的os.Getenv(PORT)兜底8080。构建、推送与部署多架构镜像构建在样例目录下执行以下命令用 Docker Buildx 一次性构建linux/arm64与linux/amd64两种架构的镜像并直接推送到 Docker Hub{username}替换为你的用户名# Build and push the container on your local machine. docker buildx build --platform linux/arm64,linux/amd64 -t {username}/helloworld-rserver --push .使用--platform指定多平台、--push构建后立即推送可以同时覆盖 x86 与 ARM 集群节点避免部署时因镜像架构不匹配而拉取失败。应用 Knative Service构建并推送完成后确认service.yaml中的image与上一步构建的镜像完全一致然后用kubectl应用配置kubectl apply --filename service.yamlKnative 自动完成的编排服务创建成功后Knative 会自动完成以下三件事创建不可变 Revision为当前这一版应用生成一个不可变的 revision版本快照后续任何配置变更都会产生新的 revision便于灰度与回滚。网络编程为应用创建 route、ingress、service 与负载均衡把域名解析与流量入口打通。自动伸缩根据请求量自动扩缩 Pod空闲时可以缩到0 个活跃 Podscale to zero请求到来时再冷启动拉起。验证服务查询服务 URL运行下面的命令获取helloworld-rserver对外暴露的域名 URLkubectl get ksvc helloworld-rserver --outputcustom-columnsNAME:.metadata.name,URL:.status.url说明原 README 中的查询命令写作kubectl get ksvc helloworld-r与service.yaml中声明的服务名helloworld-rserver不一致该命令是从另一样例复制时的遗留。实际部署时请以service.yaml的metadata.name为准查询helloworld-rserver。输出示例NAME URL helloworld-rserver http://helloworld-rserver.default.1.2.3.4.sslip.ioURL 中的default是命名空间1.2.3.4.sslip.io是集群访问入口基于sslip.io的动态 DNS 方案具体域名取决于你的集群配置。用 curl 验证响应把上一步返回的 URL 替换进下面的命令并执行curl http://helloworld-rserver.default.1.2.3.4.sslip.io由于service.yaml中注入了TARGETR Server Sample v1预期输出为[1] Hello R Server Sample v1![1]是 R 控制台输出向量元素序号说明响应内容正是 R 脚本print(message)的结果。若返回的是Hello World!则说明TARGET未被注入例如修改了service.yaml后未重新 apply。排障提示如果curl请求失败可以加上-v参数查看详细的请求/响应过程帮助定位是 DNS 解析、网络路由还是服务未就绪的问题。清理部署验证完毕需要移除样例时删除对应的 Service 记录即可kubectl delete --filename service.yaml删除Service后Knative 会连带回收它管理的 Revision、Route 等派生资源集群恢复原状。横向对比helloworld-r 与 helloworld-rserver仓库中还有一个姊妹样例 helloworld-r两者的业务输出一致但实现路径截然不同维度helloworld-rserverhelloworld-rWeb 层实现纯 Rplumber 注解 r$run()Go 编写的invoke二进制作为 HTTP 服务端点定义HelloWorld.R中的# get /注解invoke.go 中的http.HandleFunc(/, handler)R 的调用方式进程内直接运行 R 函数用exec.CommandContext派生子进程执行Rscript HelloWorld.R构建方式单阶段r-base 镜像直接装 plumber多阶段golang 镜像编译 Go 二进制r-base 镜像承载运行时目录内容HelloWorld.Rserver.RHelloWorld.Rinvoke.gogo.mod对比可见helloworld-rserver更聚焦「R 原生开发体验」适合希望整个服务栈都用 R 实现的场景而helloworld-r把 HTTP 服务交给 Go、把计算留给 R 脚本适合已有 Go 基础设施、只想复用 R 逻辑的场景。两者共用同一套 Knative Service 声明模式与TARGET/PORT环境变量契约。小结helloworld-rserver用最少的代码量完整展示了「R 应用上 Knative」的路径plumber 注解声明端点、server.R消费PORT启动监听、Dockerfile 固化 R 运行时、service.yaml注入TARGET并交给 Knative 做路由与伸缩。按本指南完成构建、部署与验证后你就掌握了将任意 R/plumber 服务 Serverless 化的通用方法后续可以在此基础上扩展更多端点、接入参数校验与 JSON 响应构建更复杂的 R 数据分析 API。赞分享文档教程云原生【免费下载链接】docsUser documentation for Knative components.项目地址https://gitcode.com/gh_mirrors/docs1/docs点击查看免费下载相关推荐Knative Serving 实战用 Go 调用 R 脚本构建 helloworld-r 无服务器服务Knative Serving 实战用 Go 调用 R 脚本构建 helloworld r 无服务器服务 在 Knative Serving 中部署一个非文档教程云原生使用 Deno 构建并部署 Knative Serving 无服务器应用helloworld-deno 完整实践指南使用 Deno 构建并部署 Knative Serving 无服务器应用helloworld deno 完整实践指南 本指南以 Knative 官方社区示例文档教程云原生Knative Serving 实战用 Elixir Phoenix 构建并部署 Hello World 服务Knative Serving 实战用 Elixir Phoenix 构建并部署 Hello World 服务 本篇技术指南以 Knative 官方代码示文档教程云原生上一篇彻底解决Grive2同步难题从安装到高级配置的全方位指南下一篇北欧风格壁纸集项目教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考