Serving入门

news2025/4/20 19:30:45

ServingHelloWorld

Serverless 一个核心思想就是按需分配,那么 Knative 是如何实现按需分配的呢?另外在前面已经了解到 Knative Serving 在没有流量的时候是可以把Pod 缩容到零的。接下来就通过一些例子体验一下 Knative 缩容到零和按需自动扩缩容的能力。

部署 helloworld-go

Knative 官方给出了好几种语言的 Helloworld 示例,这些不同的语言其实只是编译镜像的 Dockerfile 有所不同,做好镜像之后的使用方式没什么差异。本例以 go 的 Hello World 为例进行演示。为了验证方便,阿里云官方已经提前编译好了一份镜像 registry.cn-hangzhou.aliyuncs.com/knative-sample/simple-app:07 , 可以直接使用。

我的学习路径遵照阿里云云原生《Knative 云原生应用开发指南》进行学习,所有资源均由阿里云提供。

首先编写一个 Knative Service 的 yaml 文件 helloworld-go.yaml , 内容如下:

[root@master Knative]# vi helloword-go.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: helloworld-go
spec:
  template:
    metadata:
      labels:
        app: helloworld-go
      annotations:
        autoscaling.knative.dev/target: "10"
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/helloworld-go:160e4dc8
        ports:
        - name: http1
          containerPort: 8080
        env:
        - name: TARGET
          value: "World"

字段讲解:

apiVersion: serving.knative.dev/v1
指定使用的 Knative Serving API 版本,v1 是稳定版本。
kind: Service
定义资源类型为 Knative Service,Knative 会自动管理此服务的路由、修订版本(Revisions)和自动扩缩。
name: helloworld-go
定义 Knative Service 的名称,在 Kubernetes 集群中唯一标识该服务。通过 kubectl get ksvc 可查看此服务。
template
定义服务的修订版本模板(Revision Template)。每次更新配置时,Knative 会生成新的 Revision(版本),用于灰度发布或回滚。
spec.template.metadata 修订版本元数据
labels
标签(如 app: helloworld-go)用于标识此 Revision,常用于路由或监控筛选。
annotations
注解用于配置 Knative 的扩展行为:
autoscaling.knative.dev/target: "10"
设置自动扩缩的目标并发数。每个 Pod 最多处理10个并发请求,超过时触发扩容。这是 Knative 的核心特性之一。

spec.template.spec 容器规格
containers
定义服务运行的容器:
image
容器镜像地址,这里是阿里云镜像仓库中的示例镜像 registry.cn-hangzhou.aliyuncs.com/knative-sample/helloworld-go:160e4dc8。
ports
容器暴露的端口:
name: http1和containerPort: 8080
Knative 默认通过端口 8080 接收 HTTP 流量,必须与此处配置一致。
env
容器环境变量:
name: TARGET和value: "World"
应用程序通过 TARGET 环境变量获取值,返回 Hello {TARGET},这里会返回 Hello World。

注意其中 autoscaling.knative.dev/target:“10”这个 Annotation 是设置每一个 Pod 的可处理并发请求数 10 ,Knative KPA 自动伸缩的时候会根据当前总请求的并发数和 autoscaling.knative.dev/target 自动调整 Pod 的数量,从而达到自动扩缩的目的。

部署Pod:

[root@master Knative]# kubectl apply -f helloword-go.yaml 
service.serving.knative.dev/helloworld-go created
[root@master Knative]# kubectl get pods 
NAME                                             READY   STATUS    RESTARTS   AGE
helloworld-go-00001-deployment-5479b447b-5vzrl   2/2     Running   0          74s

helloworld已经正常启动,下面进行访问。

访问helloworld

在访问 helloworld-go 之前先来介绍一下在 Knative 模型中流量是怎么进来的。Knative Service 和 Kubernetes 原生的 Deployment 不一样,Knative 不会创建 Loadbalance 的 Service,也不能创建 NodePort 类型的 Service,所以不能通过 SLB 或者 NodePort 访问。只能通过 ClusterIP 访问。而 ClusterIP 是不能直接对外暴露的,所以必须经过 Gateway 才能把用户的流量接入进来。

本例就是使用 Istio 的 Gateway 承接 Knative 的南北流量 ( 进和出 )。如下图所示是 Knative模型中流量的转发路径。用户发起的请求首先会打到 Gateway 上面,然后 Istio 通过 VirtualService 再把请求转发到具体的 Revision 上面。

在这里插入图片描述

所以想要访问 Knative 的服务首先要获取 Gateway 的 IP 地址,可以通过如下方式获取 Gateway 的 IP:

[root@master Knative]# kubectl get svc istio-ingressgateway -n istio-system
NAME                   TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                                      AGE
istio-ingressgateway   NodePort   10.106.147.32   <none>        15021:30249/TCP,80:32727/TCP,443:30590/TCP,31400:30239/TCP,15443:31723/TCP   72m

前面也介绍了 Gateway 是通过 VirtualService 来进行流量转发的,这就要求访问者要知道目标服务的名字才行 ( 域名 ),所以要先获取 helloworld-go 的域名 , 注意下面这条命令中的 ${SVC_NAME} 需要替换成 helloworld-go ,这个名字必须要和 Knative Service 的名字一致,因为每一个 Service 都有一个唯一的名字。

[root@master Knative]# kubectl get route helloworld-go -o jsonpath='{.status.url}'
http://helloworld-go.default.example.com
[root@master Knative]# kubectl get route helloworld-go -o jsonpath='{.status.url}' | awk -F/ '{print $3}'
helloworld-go.default.example.com
#两个命令的区别在于是否是纯URL方式显示

至此已经拿到 IP 地址和 Hostname,可以通过 curl 直接发起请求:

[root@master Knative]# curl  -H "Host:helloworld-go.default.example.com" "http://10.106.147.32"
Hello World!

访问成功。

缩容到零

刚刚部署完 Service 的时候 Knative 默认会创建出一个 Pod 提供服务,如果你超过 90 秒没有访问 helloworld-go 这个服务那么这个 Pod 就会自动删除,此时就是缩容到零了。现在看一下 Pod 情况 , 你可能会发现没有 Pod。

[root@master Knative]# kubectl get pods 
No resources found in default namespace.

当我们再次访问:

[root@master Knative]# time curl  -H "Host:helloworld-go.default.example.com" "http://10.108.241.97"
Hello World!

real    0m2.728s
user    0m0.004s
sys     0m0.006s

“real 0m2.728s”意思意思是 curl 请求执行一共消耗了 2.728s,也就是说Knative 从零到 1 扩容 + 启动容器再到服务响应请求总共消耗了 2.728s。可以看出来这个速度还是很快的。再看一下 pod 数量,你会发现此时 Pod 自动扩容出来了。并且 Pod 数量为零时发起的请求并没有拒绝链接。

[root@master Knative]# kubectl get pods -o wide 
NAME                                              READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
helloworld-go-00001-deployment-67857f6664-wf6hm   2/2     Running   0          4s    10.244.166.152   node1   <none>           <none>

按需分配,自动扩缩

接下来再测试一下 Knative 按需扩容的功能。使用社区提供的 hey 进行测试。hey 有 Windows、Linux 和 Mac 的二进制可以在这里下载。安装hey:

[root@master ~]# wget https://hey-release.s3.us-east-2.amazonaws.com/hey_linux_amd64
[root@master ~]# chmod +x hey_linux_amd64 
[root@master ~]# mv hey_linux_amd64 /usr/local/bin/
[root@master ~]# mv /usr/local/bin/hey_linux_amd64 /usr/local/bin/hey

使用这个命令测试之前需要在本机进行 Host 绑定,对于 helloworld-go 来说要把 helloworld-go 的域名绑定到 Istio Gateway 的 IP 上,/etc/hosts 添加如下配置:

[root@master ~]# vi /etc/hosts 
10.108.241.97 helloworld-go.default.example.com

进行测试:

hey -z 30s -c :

● -z 30s 持续测试 30s

● -c 50 保持每秒 50 个请求

[root@master ~]# hey -z 30s -c 50 "http://helloworld-go.default.example.com/" && kubectl get pods 

Summary:
  Total:        30.0115 secs
  Slowest:      2.1634 secs
  Fastest:      0.0025 secs
  Average:      0.0197 secs
  Requests/sec: 2539.9240
  
  Total data:   990951 bytes
  Size/request: 13 bytes

Response time histogram:
  0.003 [1]     |
  0.219 [76176] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
  0.435 [0]     |
  0.651 [0]     |
  0.867 [0]     |
  1.083 [0]     |
  1.299 [0]     |
  1.515 [0]     |
  1.731 [0]     |
  1.947 [0]     |
  2.163 [50]    |


Latency distribution:
  10% in 0.0089 secs
  25% in 0.0114 secs
  50% in 0.0154 secs
  75% in 0.0212 secs
  90% in 0.0324 secs
  95% in 0.0421 secs
  99% in 0.0582 secs

Details (average, fastest, slowest):
  DNS+dialup:   0.0000 secs, 0.0025 secs, 2.1634 secs
  DNS-lookup:   0.0000 secs, 0.0000 secs, 0.0033 secs
  req write:    0.0000 secs, 0.0000 secs, 0.0225 secs
  resp wait:    0.0195 secs, 0.0023 secs, 2.1546 secs
  resp read:    0.0001 secs, 0.0000 secs, 0.0153 secs

Status code distribution:
  [200] 76227 responses


NAME                                              READY   STATUS    RESTARTS   AGE
helloworld-go-00001-deployment-67857f6664-2trps   2/2     Running   0          37s
helloworld-go-00001-deployment-67857f6664-p4znc   2/2     Running   0          40s
helloworld-go-00001-deployment-67857f6664-s7spf   2/2     Running   0          37s
helloworld-go-00001-deployment-67857f6664-sv8hc   2/2     Running   0          37s
helloworld-go-00001-deployment-67857f6664-zqhgn   2/2     Running   0          37s

回想一下刚才 helloworld-go.yaml 文 件 配 置, 已 经 设 置 了 autoscaling.knative.dev/target:“10”这个 Annotation。这表示每一个 Pod 能够接受并发 10个请求,而刚才并发请求数设置的是 50 所以理论上应该会创建出来 5 个 Pod!!

所以,我们的配置文件是生效且正常运行的哦。
在这里插入图片描述

可以看到此时 Knative 自动扩容出来了 5 个 Pod 处理请求。
置, 已 经 设 置 了 autoscaling.knative.dev/target:“10”这个 Annotation。这表示每一个 Pod 能够接受并发 10个请求,而刚才并发请求数设置的是 50 所以理论上应该会创建出来 5 个 Pod!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2338944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【HDFS入门】HDFS数据冗余与容错机制解析:如何保障大数据高可靠存储?

目录 1 HDFS冗余机制设计哲学 1.1 多副本存储策略的工程权衡 1.2 机架感知的智能拓扑算法 2 容错机制实现原理 2.1 故障检测的三重保障 2.2 数据恢复的智能调度 3 关键场景容错分析 3.1 数据中心级故障应对 3.2 数据损坏的校验机制 4 进阶优化方案 4.1 纠删码技术实…

UE学习记录part19

231 insect: insect enemy type 创建dead动画资源 往insect head上添加socket 创建攻击root motion动画。motion warping需要与root motion合作使用 为buff_blue创建物理资产 设置simulate physic使sinsect死亡后能落到地板上而不是漂浮在空中&#xff0c;要将die函数设置为 -…

运行后allure报告没有自动更新(已解决)

pycharm直接运行run.py文件&#xff0c; allure生成的报告都没有更新&#xff0c;需要手动删除旧报告后再次运行才可以 pytest.ini [pytest]testpaths testcases/ addopts --alluredir ./report/result --clean-alluredir run.py主要代码 if __name__ "__main__&qu…

微信小程序 时间戳与日期格式的转换

1. 微信小程序 时间戳与日期格式的转换 微信小程序中的时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。例如现在北京时间2015-12-31 17:00:00的时间戳是1451552400&#xff0c;就是指从北京时间1970-01-01 08:00:00到…

【深度学习—李宏毅教程笔记】Transformer

目录 一、序列到序列&#xff08;Seq2Seq&#xff09;模型 1、Seq2Seq基本原理 2、Seq2Seq模型的应用 3、Seq2Seq模型还能做什么&#xff1f; 二、Encoder 三、Decoder 1、Decoder 的输入与输出 2、Decoder 的结构 3、Non-autoregressive Decoder 四、Encoder 和 De…

【人工智能学习-01-01】20250419《数字图像处理》复习材料的word合并PDF,添加页码

前情提要 20250419今天是上师大继续教育人工智能专升本第一学期的第一次线下课。 三位老师把视频课的内容提炼重点再面授。&#xff08;我先看了一遍视频&#xff0c;但是算法和图像都看不懂&#xff0c;后来就直接挂分刷满时间&#xff0c;不看了&#xff09; 今天是面对面授…

使用 Docker 安装 Elastic Stack 并重置本地密码

Elastic Stack&#xff08;也被称为 ELK Stack&#xff09;是一个非常强大的工具套件&#xff0c;用于实时搜索、分析和可视化大量数据。Elastic Stack 包括 Elasticsearch、Logstash、Kibana 等组件。本文将展示如何使用 Docker 安装 Elasticsearch 并重置本地用户密码。 ###…

利用 Deepseek 和 Mermaid 画流程图

提示词 你是一个产品经理&#xff0c;请绘制一个报名比赛的流程图&#xff0c;要求生成符合Mermaid语法的代码&#xff0c;具体要求如下&#xff1a; 1.注册账号 2.填写报名信息 3.参加比赛 4.查看比赛结果 生成的结果 flowchart TDA([开始]) --> B[注册账号]B --> C{账…

学习笔记: Mach-O 文件

“结构决定性质,性质决定用途”。如果不了解结构,是很难真正理解的。 通过一个示例的可执行文件了解Mach-O文件的结构 Mach-O基本结构 Header: &#xff1a;文件类型、目标架构类型等Load Commands&#xff1a;描述文件在虚拟内存中的逻辑结构、布局Data: 在Load commands中…

个人自用-导入安装Hexo

因为本人原来就有备份好的资料&#xff0c;所以重新安装起来会很方便&#xff0c;这个教程也只适合我自己用 但是所有的命令行都要在Git的命令行里面使用&#xff08;因为我就是这样操作的&#xff09; 1 安装Git Git的官网 Git git --version 这个是查看Git的版本 git --…

《AI大模型应知应会100篇》第26篇:Chain-of-Thought:引导大模型进行步骤推理

第26篇&#xff1a;Chain-of-Thought&#xff1a;引导大模型进行步骤推理 摘要 在自然语言处理&#xff08;NLP&#xff09;和人工智能领域&#xff0c;如何让大模型像人类一样进行逐步推理是一个核心挑战。Chain-of-Thought (思维链) 技术的出现为这一问题提供了强有力的解决…

STM32单片机入门学习——第43节: [12-3] 读写备份寄存器实时时钟

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难&#xff0c;但我还是想去做&#xff01; 本文写于&#xff1a;2025.04.19 STM32开发板学习——第43节: [12-3] 读写备份寄存器&实时时钟 前言开发板说明…

零基础上手Python数据分析 (18):Matplotlib 基础绘图 - 让数据“开口说话”

写在前面 —— 告别枯燥数字,拥抱可视化力量,掌握 Matplotlib 绘图基础 欢迎来到 “高效数据分析实战指南:Python零基础入门” 专栏! 经过前面 Pandas 模块的学习和实战演练,我们已经掌握了使用 Python 和 Pandas 进行数据处理、清洗、整合、分析的核心技能。 我们能够从…

【网络原理】UDP协议

目录 一. UDP 报文格式 &#xff08;1&#xff09;端口号 &#xff08;2&#xff09;UDP长度 &#xff08;3&#xff09;校验和 UDP协议属于传输层协议&#xff0c;由操作系统内核内置 一. UDP 报文格式 UDP数据报&#xff1a;无连接&#xff0c;不可靠传输&#xff0c;面…

HCIP OSPF综合实验

1.网络拓扑图 实验要求&#xff1a; 2.需求分析 IP规划&#xff1a; 对每个路由器配置ospf并用172.16.0.0/16网段进行划分&#xff0c;项目中一共有area0 - area4五个ospf区域加一个rip网段&#xff0c;所以我们在172.16.0.0/16选出6个网段 ISP 对r5只能配ip可以把他看成外…

实现批量图片文字识别(python+flask+EasyOCR)

话不多说,向上效果图 1)先说框架版本 为什么要先说框架版本呢,因为我在各种版本中尝试了两天,总算确定了如下版本适合我,至于其他的版本,各位自己去尝试 python 3.9.7 EasyOCR 1.7.2 flask 3.0.3 2)执行操作效果图 2.1)多选文件 2.2)图片预览 2.3)提取选中文件 2.4)提取所有文…

【java实现+4种变体完整例子】排序算法中【堆排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格

以下是堆排序的详细解析&#xff0c;包含基础实现、常见变体的完整代码示例&#xff0c;以及各变体的对比表格&#xff1a; 一、堆排序基础实现 原理 基于二叉堆结构&#xff08;最大堆&#xff09;&#xff0c;通过以下步骤实现排序&#xff1a; 构建最大堆&#xff1a;将…

WhatTheDuck:一个基于浏览器的CSV查询工具

今天给大家介绍一个不错的小工具&#xff1a;WhatTheDuck。它是一个免费开源的 Web 应用程序&#xff0c;允许用户上传 CSV 文件并针对其内容执行 SQL 查询分析。 WhatTheDuck 支持 SQL 代码自动完成以及语法高亮。 WhatTheDuck 将上传的数据存储为 DuckDB 内存表&#xff0c;继…

工控系统前端设计(pyqt)

题目源自&#xff1a;白月黑羽的项目实战四-[工控系统前端] 代码已上传至gitcode https://gitcode.com/m0_37662818/Industrial_Control_System_Front_End 心得体会&#xff1a;直接用组态软件或者js吧 项目亮点 tablemodel的使用&#xff0c;绑定了表格和数据风机自定义ite…

剑指Offer(数据结构与算法面试题精讲)C++版——day15

剑指Offer&#xff08;数据结构与算法面试题精讲&#xff09;C版——day15 题目一&#xff1a;二叉树最低层最左边的值题目二&#xff1a;二叉树的右侧视图题目三&#xff1a;二叉树剪枝附录&#xff1a;源码gitee仓库 题目一&#xff1a;二叉树最低层最左边的值 题目&#xff…