news 2026/10/13 9:20:00

用 Deno 编写 Hello World 应用并部署到 Knative Serving:社区示例完整实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用 Deno 编写 Hello World 应用并部署到 Knative Serving:社区示例完整实战
  • 文档
  • 教程
  • 云原生

【免费下载链接】docs

User documentation for Knative components.

项目地址:https://gitcode.com/gh_mirrors/docs1/docs
点击查看免费下载

本文基于 Knative 官方文档仓库中的社区示例 helloworld-deno,完整演示如何用 Deno 编写一个极简 HTTP 服务,通过 Dockerfile 容器化并构建多架构镜像,最终以 Knative Service 形式部署到 Kubernetes 集群,验证域名访问与自动扩缩容行为。读完本文,你将掌握 Deno 应用的容器化打包、Knative Serving 资源的声明式部署,以及使用kubectl完成从构建到验证、清理的完整闭环。

示例概览:这个示例教会你什么

helloworld-deno是 Knative 社区维护的 Serving 示例之一,定位与仓库中的 Go、Node.js、Python 等 Hello World 示例一致:用最小的代码量演示"一个服务从源码到上线"的完整链路。该示例的关键点在于:

  • 服务逻辑极简:监听PORT环境变量指定的端口(默认8080),对每个 HTTP 请求返回固定文本Hello Deno\n;
  • 容器镜像自建:不像官方示例那样使用预构建镜像,而是从本地 Dockerfile 构建并推送到镜像仓库,更贴近真实项目流程;
  • 多架构镜像:使用docker buildx同时构建linux/amd64与linux/arm64镜像,适配异构 Kubernetes 节点。

示例目录在仓库中的完整结构如下:

文件作用
deps.ts集中声明 Deno 远程依赖(HTTP 服务模块)
main.ts应用入口,实现 HTTP 服务
Dockerfile容器镜像构建定义
service.yamlKnative Service 声明(仓库中为空占位文件,需按下文创建)
index.md本示例的官方操作指南
README.md示例说明(与 index.md 内容一致)
.dockerignore构建上下文排除文件

前置条件

开始之前,请确认以下环境就绪:

  1. 一个已安装 Knative 的 Kubernetes 集群。如果还没有,请参照仓库中的 Knative 安装文档(含 Operator 安装 与 YAML 安装 两条路径)完成部署;
  2. 本机安装并运行 Docker,且已配置 Docker Hub 账号——本示例使用 Docker Hub 作为容器镜像仓库,后续所有{username}占位符都替换为你的 Docker Hub 用户名。

获取示例代码

你可以按照指南逐步重建四个文件,也可以直接获取一份可运行的副本。若使用 git clone 方式:

git clone https://gitcode.com/gh_mirrors/docs1/docs knative-docs cd knative-docs/code-samples/community/serving/helloworld-deno

逐步创建示例代码

1.deps.ts:集中管理 Deno 远程依赖

Deno 没有 npm 之类的集中式包管理器,而是直接以 URL 形式导入远程模块。创建一个名为deps.ts的文件,将依赖统一收口:

export { serve } from "https://deno.land/std@0.50.0/http/server.ts";

serve是 Deno 标准库提供的 HTTP 服务函数。需要说明的是,指南原文此处写作std@std@0.50.0,属于笔误,仓库中实际生效的 deps.ts 使用的是正确的std@0.50.0版本号。集中依赖管理的好处是:后续升级标准库版本时,只需修改这一个文件。

2.main.ts:HTTP 服务主体

创建main.ts,粘贴如下脚本(与仓库中的 main.ts 完全一致):

import { serve } from "./deps.ts"; import "https://deno.land/x/dotenv/mod.ts"; const PORT = Deno.env.get('PORT') || 8080; const s = serve(`0.0.0.0:${PORT}`); const body = new TextEncoder().encode("Hello Deno\n"); console.log(`Server started on port ${PORT}`); for await (const req of s) { req.respond({ body }); }

逐行理解这段代码:

  • 端口读取:Deno.env.get('PORT') || 8080从环境变量读取监听端口,缺省回退到8080。Knative Serving 约定用户容器监听$PORT环境变量,平台注入的默认端口也是8080,两者在此对齐;
  • 监听地址:绑定0.0.0.0,确保 Kubernetes Pod 网络内的请求(来自 queue-proxy 的转发)可以到达;
  • 响应体预编码:new TextEncoder().encode("Hello Deno\n")在启动阶段就把字符串编码为Uint8Array,请求到来时直接复用,避免每次响应重复编码;
  • 异步请求循环:for await (const req of s)逐个取出请求并调用req.respond({ body }),这是 Deno std 0.50 时代serve的标准用法;
  • dotenv 导入:import "https://deno.land/x/dotenv/mod.ts"为本地开发加载.env文件提供便利;由于是副作用导入(未显式使用导出符号),仅影响本地开发体验,部署到 Knative 时环境变量由平台注入。

3.Dockerfile:容器化 Deno 应用

创建Dockerfile(与仓库中的 Dockerfile 一致):

FROM hayd/alpine-deno:1.0.0-rc2 WORKDIR /app # These steps will be re-run upon each file change in your working directory: COPY . ./ # Added to ENTRYPOINT of base image. CMD ["run", "--allow-env", "--allow-net", "main.ts"]

关键点解读:

  • 基础镜像hayd/alpine-deno:1.0.0-rc2基于 Alpine Linux,内置 Deno 1.0.0-rc2 运行时,镜像本身定义了 Deno 入口点,因此这里的CMD不需要写deno前缀;
  • COPY . ./把当前目录(deps.ts、main.ts等)复制进/app工作目录。由于.dockerignore的存在,Dockerfile、.git等文件不会进入镜像,避免构建上下文膨胀;
  • CMD ["run", "--allow-env", "--allow-net", "main.ts"]中,--allow-env授予环境变量读取权限(代码里Deno.env.get('PORT')依赖它),--allow-net授予网络监听权限(HTTP 服务器必需)。这两个权限缺一不可,否则 Deno 会在运行时抛出权限错误。

4.service.yaml:Knative Service 声明

创建service.yaml,将下面的服务定义粘贴进去,并把{username}替换为你的 Docker Hub 用户名:

apiVersion: serving.knative.dev/v1 kind: Service metadata: name: helloworld-deno namespace: default spec: template: spec: containers: - image: docker.io/{username}/helloworld-deno

注意:仓库中现存的 service.yaml 是 0 字节的空占位文件,使用时必须按上面的内容自行创建,这与仓库其他语言示例(如 helloworld-nodejs 的 service.yaml)保持一致的结构。

该清单是标准 Knative Service 资源:spec.template描述 Revision 的 Pod 模板,containers.image指向我们即将构建的镜像。相比普通 Kubernetes Deployment,这里不写replicas、strategy、service等字段——副本数与网络均由 Knative Serving 托管,这正是后续自动扩缩容的基础。如需为服务注入自定义环境变量,可以参考 creating-services.md 中的env写法。

构建并推送容器镜像

四个文件就绪后,先构建镜像。为保证镜像能在arm64与amd64两种架构的 Kubernetes 节点上运行,使用docker buildx进行多架构构建并直接推送:

# Build and push the container on your local machine. docker buildx build --platform linux/arm64,linux/amd64 -t "{username}/helloworld-deno" --push .

参数含义:

  • --platform linux/arm64,linux/amd64:一次性产出两种 CPU 架构的镜像清单(manifest list),集群中的节点按自身架构自动拉取对应镜像;
  • --push:构建完成后直接推送到 Docker Hub,省去docker push单独一步;
  • 镜像名{username}/helloworld-deno与service.yaml中的image字段必须一致。

如果你的 Docker 环境不支持 buildx 多架构构建,也可以退化为docker build -t "{username}/helloworld-deno" . && docker push "{username}/helloworld-deno"的常规流程(此时镜像仅适用于构建机所在架构)。

部署到集群

推送完成后,应用 Knative Service 清单:

kubectl apply --filename service.yaml

服务创建成功后,Knative Serving 会在后台自动执行以下三件事(与 creating-services.md 中的描述一致):

  1. 创建不可变的 Revision:为当前版本的镜像生成一个不可变的 Revision,后续每次更新template都会生成新的 Revision,旧的 Revision 保留以便流量回滚;
  2. 网络编程:自动创建 Route、Ingress、Service 与负载均衡器,将域名解析并转发到对应 Revision;
  3. 自动扩缩容:根据流量自动伸缩 Pod 副本,包括在无流量时将副本缩到0 个——这就是 Knative 标志性的 Scale to Zero 能力。

关于第 3 点的底层机制,可以参考 request-flow.md:当 Revision 处于零流量或低流量状态时,HTTP 路由器将请求转发给集群级的 Activator 组件暂存,Activator 随即通知 Autoscaler 扩容,新 Pod 就绪后请求被放行到用户容器,这个冷启动过程称为cold-start。而containerConcurrency(并发上限)与autoscaling.knative.dev/target(软性并发目标)等参数,决定了 Autoscaler 在何种并发水位触发扩容,详见 concurrency.md。

获取服务 URL 并验证

部署完成后,通过如下命令获取 Knative 为服务分配的域名:

kubectl get ksvc helloworld-deno --output=custom-columns=NAME:.metadata.name,URL:.status.url

输出形如:

NAME URL helloworld-deno http://helloworld-deno.default.1.2.3.4.sslip.io

域名规则为服务名.命名空间.<集群默认域名>,示例中的sslip.io是 Knative 默认的占位域名方案。随后用curl发起请求:

curl http://helloworld-deno.default.1.2.3.4.sslip.io

预期返回Hello Deno(注意:指南原文的示例输出误写为Hello R Sample v1!,实际返回内容以 main.ts 中编码的"Hello Deno\n"为准)。

如果curl失败,可以加-v选项查看详细请求与响应头,并结合 troubleshooting.md 排查。另一个值得观察的现象是:由于 Scale to Zero,首次请求通常伴随冷启动延迟(Activator 唤醒 Pod),这是 Knative Serving 的正常行为。

移除示例部署

验证完毕后清理资源,删除服务记录即可:

kubectl delete --filename service.yaml

Knative 会随之回收该 Service 关联的 Revision、Route 与配置等资源。若同时不再需要本机镜像,可另行执行docker image rm清理本地镜像。

延伸阅读

  • 仓库内其他语言的 Hello World 对照实现:见 code-samples/serving/hello-world(Go、Node.js、Python、Ruby、Shell 等)与 code-samples/community/serving(Clojure、Dart、Elixir、Rust、Swift 等社区语言);
  • Knative Service 的完整配置字段:参见 creating-services.md;
  • 请求流转与 Activator 原理:参见 request-flow.md;
  • 并发与扩缩容参数调优:参见 autoscaling 目录。
  • 文档
  • 教程
  • 云原生

【免费下载链接】docs

User documentation for Knative components.

项目地址:https://gitcode.com/gh_mirrors/docs1/docs
点击查看免费下载
上一篇:AI Voice Cloning高级配置:GPU加速、内存优化与性能调优终极指南
下一篇:brat标注工具核心功能解析:文本标注、关系标注与事件标注

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

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

领导力内在塑造的四大核心维度与实践方法

1. 领导力的本质与内在塑造领导力从来不是职位赋予的权威&#xff0c;而是一种由内而外散发的能量场。我在管理岗位上摸爬滚打十几年&#xff0c;见过太多手握重权却无法服众的"名义领导"&#xff0c;也见证过不少没有正式头衔却能一呼百应的"隐形领袖"。这…

作者头像 李华
网站建设 2026/10/13 9:16:02

中国地震动峰值加速度区划图SHP矢量化与ArcGIS应用全解析

简介&#xff1a;这份压缩包提供的是中国地震动峰值加速度区划图的矢量边界成果&#xff0c;面向GIS从业者、地震工程与城市规划人员&#xff0c;将栅格形式的地震动峰值加速度数据转换为标准Shapefile格式&#xff0c;便于在ArcGIS、QGIS等软件中直接进行空间查询、叠加分析和…

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

风电-水电联合优化运行模型复现与工程实践

1. 项目背景与核心价值风电-水电联合优化运行是当前新能源消纳领域的热点研究方向。我国西部地区的风电资源丰富&#xff0c;但风电出力具有显著的随机性和波动性&#xff0c;而水电则具备良好的调节性能。将两者联合运行&#xff0c;既能提高风电消纳率&#xff0c;又能优化水…

作者头像 李华