- 文档
- 教程
- 云原生
【免费下载链接】docs
User documentation for Knative components.
本文基于 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.yaml | Knative Service 声明(仓库中为空占位文件,需按下文创建) |
| index.md | 本示例的官方操作指南 |
| README.md | 示例说明(与 index.md 内容一致) |
.dockerignore | 构建上下文排除文件 |
前置条件
开始之前,请确认以下环境就绪:
- 一个已安装 Knative 的 Kubernetes 集群。如果还没有,请参照仓库中的 Knative 安装文档(含 Operator 安装 与 YAML 安装 两条路径)完成部署;
- 本机安装并运行 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 中的描述一致):
- 创建不可变的 Revision:为当前版本的镜像生成一个不可变的 Revision,后续每次更新
template都会生成新的 Revision,旧的 Revision 保留以便流量回滚; - 网络编程:自动创建 Route、Ingress、Service 与负载均衡器,将域名解析并转发到对应 Revision;
- 自动扩缩容:根据流量自动伸缩 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.yamlKnative 会随之回收该 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.
相关推荐
用 Clojure 编写并部署 Knative Serving Hello World 服务
用 Clojure 编写并部署 Knative Serving Hello World 服务 导读 本文基于 Knative 文档仓库中的社区示例 hellow
文档教程云原生使用 Deno 构建并部署 Knative Serving 无服务器应用:helloworld-deno 完整实践指南
使用 Deno 构建并部署 Knative Serving 无服务器应用:helloworld deno 完整实践指南 本指南以 Knative 官方社区示例
文档教程云原生Neutone SDK 性能调优:benchmark 速度、延迟与 Profiling 三大 CLI 工具完整指南
Neutone SDK 性能调优:benchmark 速度、延迟与 Profiling 三大 CLI 工具完整指南 Neutone SDK 是一个开源的神经音频
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考