阿里云K8s+Istio+Knative搭建Serverless平台

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
函数计算FC,每月15万CU 3个月
简介: 本文以一个Nodejs前端开发者角度出发,从零基于阿里云平台能力搭建一个弹性的Serverless平台的记录。希望对也想了解这个产品整体的小伙伴们有一定帮助 以上我们利用阿里云K8s+Istio+Knative 搭建Serverless平台 - 部署了k8s集群 - 部署了Istio - .

前言

本文以一个Nodejs前端开发者角度出发,从零基于阿里云平台能力搭建一个弹性的Serverless平台的记录。希望对也想了解这个产品整体的小伙伴们有一定帮助。

官方文档:https://help.aliyun.com/document_detail/121509.html
控制台:https://cs.console.aliyun.com/

为什么是Knative

项目主页:https://knative.dev/
项目仓库:https://github.com/knative

总结为下面两张之前我分享的PPT

  • knative 定位:

enter image description here

  • knative 三大组件:

enter image description here

前置依赖

  • 创建一个k8s集群,且集群中Worker节点的数量大于等于3个。
  • 部署 Istio。

下图可知它们之间的关系:
enter image description here

部署k8s集群

文档:https://help.aliyun.com/document_detail/86488.html
Kubernetes 是流行的开源容器编排技术,按照以下步骤快速创建一个k8s集群

  1. 选择标准托管k8s
  2. 创建专有网络和虚拟交换机, 否则无法选择购买实例规格
  3. 选择worker实例规格,因为是体验平台,故我选择了3台最小规格支持Pod的实例, 这是最低要求。因为是托管k8s集群,故不需要选择master

enter image description here

  1. 创建和选择 密钥对,后面在本机电脑操作远端服务的认证
  2. 公网访问:使用 EIP 暴露 API Server 记得选择上集群创建好不能修改, 不然无法在本机电脑上通过http url 访问服务
  3. 选择上日志服务
  4. 保障账户余额不低于100
  5. 其他默认配置

点击创建k8s集群,所有检查项通过后,约10 分钟创建成功所有资源
enter image description here

部署Istio

Istio为解决微服务的分布式应用架构在运维、调试、和安全管理等维度存在的问题,可通过部署Istio创建微服务网络,并提供负载均衡、服务间认证以及监控等能力,同时Istio不需要修改服务即可实现以上功能
通过下面步骤快速在上面的k8s中部署istio

  1. 选择对应集群部署istio

enter image description here

  1. 如果要实现 Tracing 分布式追踪服务,勾选开启
  2. 在链路追踪服务,打开Region对应信息查看token, 复制与集群region一直的内网接入http url 到istio配置中
  3. 其他默认配置,点击部署,很快相应服务部署成功再k8s集群上

enter image description here

部署Knative

文档:https://help.aliyun.com/document_detail/121509.html
在控制台左侧,找到Knative(公测),选择组件管理,点击右上方一键部署,部署我们前面讲到的Knative 三大组件

  • Tekton 组件 (原build 组件不在推荐) - v0.9.2
  • Serving 组件 - v0.11.0
  • Eventing 组件 - v0.11.0

enter image description here

检查未通过,需要开启 istio-ingressgateway,解决:
在控制台> 服务网格 > istio管理, 点右侧更新
将如下,光标高亮 gateways enabled 默认false 修改为 true, 点击更新后,
enter image description here

再次部署kantive组件,很快即可部署成功
enter image description here

部署服务

下载Knative 官方服务demo 工程

git clone https://github.com/knative/docs

# nodejs demo 服务
cd docs/serving/samples/hello-world/helloworld-nodejs
AI 代码解读

查看修复成,你想要的服务


const express = require('express');
const app = express();

app.get('/', (req, res) => {
  console.log('Hello world received a request.');

  const target = process.env.TARGET || 'World';

 // 我添加了输出,可以查看流量访问的不同服务版本
  const kRevision = process.env.K_REVISION || '';  
  res.send(`Hello ${target} (revision: ${kRevision}) \n`);
});

const port = process.env.PORT || 8080;
app.listen(port, () => {
  console.log('Hello world listening on port', port);
});
AI 代码解读

镜像构建与发布

# 目前 Docker 官方维护了一个公共仓库Docker Hub 我们将自己构建的镜像发布上去
# https://hub.docker.com/
# 进行镜像构建, 其中859652049替换成你的账号名
docker build -t 859652049/helloworld-nodejs .
# 推送镜像到公共仓库Docker Hub
docker push 859652049/helloworld-nodejs
AI 代码解读

控制台可视化部署

  1. 回到控制面板 > Knative > 服务管理 > 选择k8s集群命名空间default, 创建服务
  2. 支持根据模板快速创建 和 可视化编辑创建。
  3. 我们选择可视化创建
  4. 镜像名称输入:docker.io/859652049/helloworld-nodejs (也可以用你上面自己创建的镜像)
  5. 配置环境变量 TARGET: NodeX 1 (服务代码里用到这个环境变量)
  6. 其他默认配置,可以自由配置

    • 最大并发不控制
    • 弹性实例最小0, 最大100
    • CPU 0.25Core, 内存 125M
    • 不挂载额外存储数据卷

enter image description here

服务部署成功
enter image description here

访问服务,其中下面的ip 和 host 对应,上图中默认域名和访问网关ip

curl -H "HOST: nodejs.default.example.com" http://47.111.223.97 
AI 代码解读

或者通过绑定公网ip 到默认域名上

# 推荐工具SwitchHosts https://github.com/oldj/SwitchHosts/blob/master/README_cn.md
47.111.223.97 nodejs.default.example.com
AI 代码解读

两种方式,接口数据返回成功
enter image description here
enter image description here

Kubectl命令行部署

文档:https://help.aliyun.com/document_detail/86494.html

  1. 安装 kubectl 客户端,根据文档, 我这边mac 通过docker 客户端 Preferences 设置中 enable kubernetes 后安装了。
  2. 配置登录凭据
  3. 集群列表,点击集群名,选择KubeConfig(公网访问)页签,并单击复制,将内容复制到本地计算机的 $HOME/.kube/config

enter image description here

  1. 执行 kubectl get revisions 查看部署服务的版本,如下可以看到我们上面通过控制台可视化部署的服务nodejs, 一个版本nodejs-dn5vh
    enter image description here

5.通过kubectl 部署新的一个版本

还是我们之前使用的 helloworld-nodejs 工程, 将配置文件service.yaml

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: nodejs # 服务名
  namespace: default  # 服务部署的命名空间
spec:
  template:
    metadata:
      name: nodejs-dn5vh-v2
    spec:
      containers:
      - image: docker.io/859652049/helloworld-nodejs
        env:
        - name: TARGET
          value: "NodeX 2" # 环境变量更新为2
  traffic:  # 设置流量分配到不同服务版本, 也可通过如下图可视化修改配置
    - tag: current
      revisionName: nodejs-dn5vh # 修改为自动可视化自动生成的版本号
      percent: 50 # 50% 流量版本1
    - tag: candidate
      revisionName: nodejs-dn5vh-v2  # 与当前版本号一致
      percent: 50  # 50% 流量版本2
    - tag: latest
      latestRevision: true
      percent: 0
AI 代码解读
  1. 部署服务
kubectl --namespace default apply -f ./service.yaml 
AI 代码解读
  1. 多次访问服务,流量按比例导入到2个版本

enter image description here
enter image description here
enter image description here

自定义域名

在Knative Serving route 路由中默认使用 example.com 作为默认域名,route 完全定义的域名格式默认为:
{service}.{namespace}.{default-domain} ,如:nodejs.default.example.com

域名A记录到网关

  1. 首先你要有个阿里云备案过的域名,否则最后访问会显示需要接入备案
  2. 将域名 A记录 指向自己的公网网关地址,如上:47.111.223.97

这个有个注意点,因为服务部署的命名空间和服务名 都会不断变化,或者有多个。故A记录时候使用泛域名绑定
比如 dev.lianxuify.com 这个子域名是我用来开发测试的
dev.lianxuify.com
nodejs.default.dev.lianxuify.com
nodejs-1.default.dev.lianxuify.com

  1. 修改默认域名example.com 为 dev.lianxuify.com

通过控制台配置

菜单 Knative > 组件管理 > 点击核心组件Serving 详情 > 自定义域名模板 > 点击查看yaml

apiVersion: v1
data:
  _example: |
    ################################
    #                              #
    #    EXAMPLE CONFIGURATION     #
    #                              #
    ################################

    # This block is not actually functional configuration
    # ....
    example.org: |
      selector:
        app: nonprofit

    # Routes having domain suffix of 'svc.cluster.local' will not be exposed
    # through Ingress. You can define your own label selector to assign that
    # ...
    svc.cluster.local: |
      selector:
        app: secret
  # 以上都是注释
  dev.lianxuify.com: '' # 自定义域名,仅需要添加该行,前面添加两个空格,与顶部_example对齐
kind: ConfigMap
metadata:
  creationTimestamp: '2020-02-05T15:21:13Z'
  labels:
    serving.knative.dev/release: v0.11.0
  name: config-domain
  namespace: knative-serving
  resourceVersion: '83466654'
  selfLink: /api/v1/namespaces/knative-serving/configmaps/config-domain
  uid: 257133b2-482b-11ea-9d30-8e59b18ed506
AI 代码解读

yaml语法 基本语法 http://www.ruanyifeng.com/blog/2016/07/yaml.html

  • 大小写敏感
  • 使用缩进表示层级关系,几个空格不重要
  • 缩进时不允许使用Tab键,只允许使用空格 已验证
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
  • \#表示注释
  • | 保留换行符 字符串

通过 kubectl 配置

kubectl edit cm config-domain --namespace knative-serving
# 同上添加一行,保存即生效

# 验证生效
kubectl get route
# NAME     URL                                       READY   REASON
# nodejs   http://nodejs.default.dev.lianxuify.com   True
AI 代码解读

enter image description here

路由转发

当我们有多个服务使用相同的域名,通过请求的Path不同,将流量转发到不同服务中

坑:knative 官方demo 工程,不支持路径访问,只处理根路径访问。 因为这个一直接口返回失败,以为配置搭建问题。

const express = require('express');
const app = express();
// 修改/ 为 *
// app.get('/', (req, res) => {
app.get('*', (req, res) => {
  // ...
});

// 
AI 代码解读
  1. 修改代码路由为*,重新构建镜像,发布镜像 (docker.io/859652049/helloworld-nodejs:latest 已经修改过)
  2. 重新部署服务, 按照上面可视化、或者 kubectl 方式重新部署两个服务 nodejs、nodejs2

enter image description here

  1. 选择 Knative > 服务管理 > 点击服务名 > 选择路由转发 > 点击配置

enter image description here

  1. 配置保存后立即生效,访问符合预期

    • dev.lianxuify.com/nodejs 到服务1 nodejs
    • dev.lianxuify.com/nodejs 到服务2 nodejs2

enter image description here
enter image description here

弹性验证与配置

 kubectl get pods -w  // 查看运行的容器组,sidecar+业务服务
AI 代码解读

如下所示,当没有流量后 pod 自动会删除,流量进来会弹性扩展
enter image description here

流量根据如下配置进行扩缩容,可根据业务场景要求配置
Knative > 组件管理 > 点击Serving组件详情> 点击扩缩容配置
enter image description here
这些参数是服务弹性算法的关键配置,需要结合业务配置出最佳实践,鼠标hover小绿点有详细说明。

日志监控

在Knative 上对分布式的日志,监控接入这里没有进行深度探索。文档整体看下来,流程与常规服务接入没区别,开通对应产品进行接入即可。
以下是创建集群默认创建的部分日志和监控
enter image description here
enter image description here

回滚

在Knative 上对发布进行回滚,没有进行深度探索。大致理解如下

  • 回滚历史版本,通过流量配置修改,将流量切到老版本
  • 对应同版本回滚,找到如下回滚面板

enter image description here

CICD

持续集成持续交付这块,还在探索中。看到 GitHub 事件源add-on 组件,通过github 仓库的钩子事件能触发到
Knative平台去构建镜像、部署服务。另一种方式自己监听gitlab 钩子事件,构建推送镜像,调用平台OpenAPI接口 (如上图有个触发重新部署的接口)或者 自己的部署平台调用kubectl 命令行工具部署

总结

以上我们利用阿里云K8s+Istio+Knative 搭建Serverless平台

  • 部署了k8s集群
  • 部署了Istio
  • 部署了Knative 三大组件
  • 部署了业务服务,验证了弹性扩缩容
  • 自定义了域名 + 路由转发 到不同服务
  • 不停服蓝绿部署、按流量灰度发布, 同个服务多个版本

该平台提供可视化配置 + 以及其yaml配置文件,对一个新手认识、使用这个生态能力有很好的帮助。
整套方案对应传统服务迁移到Serverless平台上灵活性、友好性较高,未来大有可为。但目前开发者工具相关还不是这么丰富,平台在公测中,整体使用成本和门槛相对阿里云函数计算更高些。因为最低集群3台worker要求,一直占用, 我目前是体验,选择了低配置,大概是4元多一个小时 (不知道能不能更低)

这里还有篇我对阿里云函数计算整体调研的文章: https://yq.aliyun.com/articles/743665
希望两篇文章对大家整体上认识两款产品,以及搭建serverless有帮助。
如有理解有误,欢迎指出,共同成长。
其间感谢阿里云 @元毅 的帮助与解答。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
打赏
0
1
1
1
2
分享
相关文章
AI 短剧遇上函数计算,一键搭建内容创意平台
为了帮助更多内容创作者和企业快速实现 AI 短剧创作,函数计算 FC 联合百炼联合推出“AI 剧本生成与动画创作解决方案”,通过函数计算 FC 构建 Web 服务,结合百炼模型服务和 ComfyUI 生图平台,实现从故事剧本撰写、插图设计、声音合成和字幕添加到视频合成的一站式自动化流程。创作者只需通过简单操作,就能快速生成高质量的剧本,并一键转化为精美的动画。
475 110
阿里云 Serverless 助力海牙湾构建弹性、高效、智能的 AI 数字化平台
海牙湾(G-Town)是一家以“供应链+场景+技术+AI”为核心驱动力的科技公司,致力于为各行业提供数字化转型解决方案。通过采用阿里云Serverless架构,解决了弹性能力不足、资源浪费与运维低效的问题。SAE全托管特性降低了技术复杂度,并计划进一步探索Serverless与AI结合,推动智能数字化发展。海牙湾业务覆盖金融、美妆、能源等领域,与多家知名企业建立战略合作,持续优化用户体验和供应链决策能力,保障信息安全并创造可量化的商业价值。未来,公司将深化云原生技术应用,助力更多行业实现高效数字化转型。
266 20
C5GAME 游戏饰品交易平台借助 RocketMQ Serverless 保障千万级玩家流畅体验
游戏行业蓬勃发展,作为国内领先的 STEAM 游戏饰品交易的服务平台,看 C5GAME 如何利用 RocketMQ Serverless 技术,为千万级玩家提供流畅的游戏体验,同时降低成本并提升运维效率。
456 113
C5GAME 游戏饰品交易平台借助 RocketMQ Serverless 保障千万级玩家流畅体验
AI 短剧遇上函数计算,一键搭建内容创意平台
AI 短剧遇上函数计算,一键搭建内容创意平台
Serverless Argo Workflows大规模计算工作流平台荣获信通院“云原生技术创新标杆案例”
2024年12月24日,阿里云Serverless Argo Workflows大规模计算工作流平台荣获由中国信息通信研究院颁发的「云原生技术创新案例」奖。
拥抱Knative, 合思加速Serverless化演进实践
合思信息基于阿里云容器服务Knative, 实现Serverless化演进的最佳实践。
拥抱Knative, 合思加速Serverless化演进实践
全托管一站式大规模数据处理和分析Serverless平台 | EMR Serverless Spark 评测
【7月更文挑战第6天】全托管一站式大规模数据处理和分析Serverless平台 | EMR Serverless Spark 评测
23844 42
基于函数计算FC一键部署ComfyUI绘画平台体验
【8月更文挑战第11天】基于函数计算FC一键部署ComfyUI绘画平台体验
284 1
一键上天!如何将Spring PetClinic瞬间迁移到云端函数计算平台
【8月更文挑战第8天】在现代云原生开发中,将Spring应用迁移到Serverless环境正成为趋势。本文通过对比传统部署与函数计算,指导如何快速部署Spring PetClinic应用。传统部署需手动配置服务器和中间件,而函数计算则免除了这些步骤,仅需上传代码。首先,准备好Spring PetClinic源码或jar包;接着选择函数计算平台,本文以阿里云为例;随后对应用进行适配,并使用Maven构建部署包;登录阿里云控制台上传jar包并配置HTTP触发器;最后测试应用确保正常运行。
111 3
详解基于百炼平台及函数计算快速上线网页AI助手
通过阿里云百炼平台,企业可在10分钟内为其网站添加智能客服系统,提升用户体验并降低成本。流程包括:创建大模型应用、配置参数(如温度系数以控制回复的随机性)、发布应用获取API密钥;使用函数计算快速搭建示例网站,并通过简单的代码更改启用AI助手功能;还可导入私有知识库增强助手的能力。前端基于NLUX开发,支持定制化需求如样式调整和历史会话管理。服务端代码提供了调用大模型获取答案的接口。借助百炼平台,企业能迅速部署即时且个性化的在线服务,适应数字化转型的需求。

相关产品

  • 函数计算
  • 推荐镜像

    更多
    AI助理

    你好,我是AI助理

    可以解答问题、推荐解决方案等

    登录插画

    登录以查看您的控制台资源

    管理云资源
    状态一览
    快捷访问