目前对kubernetes上无服务器架构(Faas/Serverless)都是热门话题,各大公司也都相继进行投入。本文主要是想通过实际例子,了解无服务器架构。
自己的认识: care code, don`t care server 。开发人员将通用的功能以函数的形式提交注册到kubernetes作为其中的CRD,使用这根据输入规范使用CRD。当然函数提供方和基础设施(kubernetes)提供方会按照相应的规则计量计费。
Serverless的开发框架由很多,比如:
环境准备
# 下载kubeless [root@node4 kubeless]# ll total 9792 -rw-r--r-- 1 root root 10004863 Oct 14 14:47 kubeless_linux-amd64.zip -rw-r--r-- 1 root root 17544 Oct 14 14:47 kubeless-v1.0.4.yaml #解压将kubeless拷贝到/usr/local/bin #如果不能俩连外网,预先加载以下镜像 #这里只下载go-init和go的镜像,因为这里的函数式基于golang写的,不同的开发语言可以下载对应的镜像 [root@node4 soft]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE kubeless/function-controller v1.0.4 b65aa9b834b7 3 months ago 85.3MB kubeless/go-init latest e07ff96bf0a5 3 months ago 954MB kubeless/go latest 493ee8f547df 3 months ago 58.4MB kubeless/http-trigger-controller v1.0.1 d6f09f3299d9 3 months ago 83.4MB kubeless/cronjob-trigger-controller v1.0.1 aec1dd30bb57 3 months ago 77.1MB kubeless/unzip latest abb7a6ac3e05 3 months ago 75.4MB bitnami/kubeless-ui latest 43d3109c8a74 9 months ago 231MB lachlanevenson/k8s-kubectl v1.13.1 d2525e8609a3 10 months ago 44.2MB k8s.gcr.io/pause 3.1 da86e6ba6ca1 22 months ago 742kB
注册kubeless到kubernetes集群中
[root@node4 kubeless]# kubectl create ns kubeless namespace/kubeless created #下载地址:https://github.com/kubeless/kubeless/releases [root@node4 kubeless]# kubectl apply -f kubeless-v1.0.4.yaml clusterrole.rbac.authorization.k8s.io/kubeless-controller-deployer created clusterrolebinding.rbac.authorization.k8s.io/kubeless-controller-deployer created customresourcedefinition.apiextensions.k8s.io/functions.kubeless.io created customresourcedefinition.apiextensions.k8s.io/httptriggers.kubeless.io created customresourcedefinition.apiextensions.k8s.io/cronjobtriggers.kubeless.io created configmap/kubeless-config created deployment.apps/kubeless-controller-manager created serviceaccount/controller-acct created #查看部署情况 [root@node4 kubeless]# kubectl get all -n kubeless NAME READY STATUS RESTARTS AGE pod/kubeless-controller-manager-5bcb6757d9-wb6hr 3/3 Running 0 28s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/kubeless-controller-manager 1/1 1 1 29s NAME DESIRED CURRENT READY AGE replicaset.apps/kubeless-controller-manager-5bcb6757d9 1 1 1 29s #查看CRD [root@node4 kubeless]# kubectl get crd |grep kubeless cronjobtriggers.kubeless.io 2019-10-14T08:18:28Z functions.kubeless.io 2019-10-14T08:18:28Z httptriggers.kubeless.io 2019-10-14T08:18:28Z
开发函数,主要通过golang实现数组求和
package main import ( "github.com/kubeless/kubeless/pkg/functions" "strconv" "strings" ) func Sum(event functions.Event, context functions.Context) (string, error) { strs := strings.Split(event.Data,",") var result = 0; for _,str := range strs { value,_ := strconv.Atoi(str) result += value } return strconv.Itoa(result), nil }
发布function
### flink: 表示function名称 ### runtime: 表示运行时,实际对应镜像,支持的类型可通过kubeless get-server-config查看 ###image-pull-policy:镜像拉去策略,默认Always,这里无法连接外网设置为IfNotPresent ### from-file: 表示function源文件 ### handler: 表示function具体函数名称,模块.函数名称 如果需要有依赖包通过dependencies指定, --dependencies Gopkg.toml [root@node4 kubeless]# kubeless function deploy flink \ > --runtime go1.12 \ > --image-pull-policy IfNotPresent \ > --from-file flink.go \ > --handler flink.Sum INFO[0000] Deploying function... INFO[0000] Function flink submitted for deployment INFO[0000] Check the deployment status executing 'kubeless function ls flink' #查看发布的functions和对应的pod [root@node4 kubeless]# kubeless function ls flink NAME NAMESPACE HANDLER RUNTIME DEPENDENCIES STATUS flink default flink.Sum go1.12 1/1 READY [root@node4 kubeless]# kubectl get pod NAME READY STATUS RESTARTS AGE flink-69c84f8fd7-hrf2w 1/1 Running 0 16s #错误排查 [root@node4 kubeless]# kubectl get pod -l function=flink -o yaml
apiVersion: kubeless.io/v1beta1 kind: Function metadata: name: testfunc spec: deployment: ### Definition as per v1beta2.Deployment metadata: annotations: "annotation-to-deploy": "final-value-in-deployment" spec: replicas: 2 ### Final deployment gets Replicas as 2 template: metadata: annotations: "annotation-to-pod": "value" deps: "" function: | module.exports = { foo: function (req, res) { res.end('hello world updated!!!') } } function-content-type: text handler: hello.foo runtime: nodejs8 service: ports: - name: http-function-port port: 8080 protocol: TCP targetPort: 8080 type: ClusterIP
函数调用 <除了主动请求,还支持事件和数据流的输入方式>
#kubeless客户端方式 [root@node4 kubeless]# kubeless function call flink --data '1,3,5' 9 #API接口方式,通常是Ingress->Service,为外部提供接口 [root@node4 kubeless]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE flink ClusterIP 172.20.49.159 <none> 8080/TCP 6m18s kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 5d [root@node4 kubeless]# curl -L --data '1,3,5,7,8' \ > --header "Content-Type:application/json" \ > 172.20.49.159:8080/api/v1/namespaces/default/services/flink:http-function-port/proxy/ 24
调用参数模板
event: data: # Event data foo: "bar" # The data is parsed as JSON when required event-id: "2ebb072eb24264f55b3fff" # Event ID event-type: "application/json" # Event content type event-time: "2009-11-10 23:00:00 +0000 UTC" # Timestamp of the event source event-namespace: "kafkatriggers.kubeless.io" # Event emitter extensions: # Optional parameters request: ... # Reference to the request received response: ... # Reference to the response to send # (specific properties will depend on the function language) context: function-name: "pubsub-nodejs" timeout: "180" runtime: "nodejs6" memory-limit: "128M"
#下载地址:https://github.com/kubeless/kubeless-ui/releases #修改内部的imagePullPolicy策略 [root@node4 kubeless]# kubectl apply -f kubeless-ui.yaml [root@node4 kubeless]# kubectl get svc -n kubeless NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ui NodePort 172.20.207.2 <none> 3000:30498/TCP 3h23m
访问测试
image.png
我来评几句
登录后评论已发表评论数()