目前最火的 ChatGpt,据说微软在 2019 年向 OpenAI 投资了约10亿美元的现金和云代金券,让团队购买微软云进行训练。在 Cloud Native 的时代背景下,Serverless 这种云原生开发模型,让开发者不需要关注服务器底层的部署,只需要编写功能函数。下面我们介绍如何使用 Knative 部署一个属于自己的 Serverless 服务集群。
Knative 服务安装
Knative 本质上是在K8s 上的一个容器管理服务。在K8s集群中能轻松运行无服务器容器,Knative 负责网络的自动扩缩容,而且可以通过 knative/func
插件支持构建多种编程语言容器。目前支持的编程语言或框架如下,当然用户能自己扩展函数模板。
根据官网的介绍, 使用 Knative 需要先安装一些软件,而且至少需要3核内存3GB的机器。
- 安装 Kind , Kind 可以很方便的一键式创建一个 k8s 集群。
1 2 3
| curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.17.0/kind-linux-amd64 chmod +x ./kind sudo mv ./kind /usr/local/bin/kind
|
- 安装 kubectl, 顾名思义这个工具是 k8s 客户端管理工具。
1 2 3
| curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256" chmod +x kubectl sudo mv ./kubectl /usr/local/bin/kind
|
- 安装 knative client 插件, knative 命令式客户端;
1 2 3 4
| wget https://github.com/knative/client/releases/download/knative-v1.9.0/kn-linux-amd64 mv kn-linux-amd64 kn chmod +x ./kn sudo mv ./kn /usr/local/bin/
|
- 安装 knative quickstart 插件, 一键创建k8s集群并部署 knative 服务的工具, 注意我写文档时候 最新版
version 1.9.0
是有问题的因此只能先下载 v1.8.1

1 2 3 4 5
| wget https://github.com/knative-sandbox/kn-plugin-quickstart/releases/download/knative-v1.8.1/kn-quickstart-linux-amd64
mv kn-quickstart-linux-amd64 kn-quickstart chmod +x ./kn-quickstart sudo mv ./kn-quickstart /usr/local/bin/
|
安装完这些我们已经可以部署一个 knative 的集群了,启动后通过 kind get clusters
能看到对应集knative群说明服务正常。
1 2
| kn quickstart kind kind get clusters
|

- 下面我们来安装构建 serverless 函数的插件 kn-func, 用户新建函数,构建函数镜像和镜像部署到对应的仓库,knative 服务可以从镜像仓库拉取对应的镜像启动服务。
1 2 3 4
| wget get https://github.com/knative/func/releases/download/knative-v1.9.0/func_linux_amd64 mv func_linux_amd64 kn-func sudo mv ./kn-func /usr/local/bin/ kn func version
|

创建 Serverless 函数
至此我们安装软件的准备工作已经完成,下面我们开始创建函数。例如我们在 cloud-funs
文件夹下创建一个 go 的函数
1 2
| mkdir cloud-funs && cd cloud-funs kn func create -l go hello-go
|
go 函数主要内容见链接 https://github.com/knative/func/blob/main/templates/go/http/handle.go

构建 Serveless 镜像
- 建过程中需要依赖 Google 镜像 https://gcr.io/paketo-buildpacks/builder:base 因为众所周知的网络隔离,我们无法使用 Google 的镜像,网络上说的改本地镜像名的方法也不靠谱。最终我折腾了好久解决了这个问题…
Registry for function images:
填docker仓库地址(用于镜像部署),如果没有仓库可以暂时随便填个字符串,不影响以下流程。
1 2
| cloud-funs cd hello-go kn func build
|

- 本地校验函数, 可以看到服务运行在 8080 端口

另一个终端执行
curl "http://127.0.0.1:8080?hello=1"
能收到返回值如下,符合刚刚我们创建的函数的返回值,说明 serverless 函数运行成功。
1 2 3
| GET /?hello=1 HTTP/1.1 127.0.0.1:8080 User-Agent: curl/7.68.0 Accept: */*
|

- 镜像部署, 部署成功后能在镜像仓库中看到对应的镜像。


使用 Knative 服务
上一步我们将镜像部署到仓库的同时,也部署在了本地 knative 集群中,访问地址是 http://hello-go.default.127.0.0.1.sslip.io
1 2
| kn service list curl "http://hello-go.default.127.0.0.1.sslip.io?hello=1"
|

kn service --help
可以查看完成的命令使用说明:

- 部署 knative service
这次我们使用远程镜像 gcr.io/knative-samples/helloworld-go
进行部署。
1 2 3 4
| kn service create hello1 \ --image gcr.io/knative-samples/helloworld-go \ --port 8080 \ --env TARGET=World
|

- 自动扩缩容
1 2 3 4
| kn service list kubectl get pod -l serving.knative.dev/service=hello1 -w
curl "http://hello1.default.127.0.0.1.sslip.io"
|

- 流量治理
每次更新服务都会产生一个服务快照,可以通过流量配置指定新旧版本之间的流量。@latest
表示最新版,
1 2 3 4 5
| kn service update hello1 --env TARGET=Knative
curl "http://hello1.default.127.0.0.1.sslip.io"
kn revisions list
|

可以看到流量现在 100% 都在 函数 hello1-00002
, 接下来我们设置两个函数各占 50% 流量。
1 2 3 4 5
| kn service update hello1 \ --traffic hello1-00001=50 \ --traffic @latest=50
kn revisions list
|
