1.總得扯點啥
目前對kubernetes上無服務器架構(gòu)(Faas/Serverless)都是熱門話題,各大公司也都相繼進行投入。本文主要是想通過實際例子,了解無服務器架構(gòu)。
2.什么是無服務器架構(gòu)(Faas/Serverless)
自己的認識:care code, don`t care server。開發(fā)人員將通用的功能以函數(shù)的形式提交注冊到kubernetes作為其中的CRD,使用這根據(jù)輸入規(guī)范使用CRD。當然函數(shù)提供方和基礎設施(kubernetes)提供方會按照相應的規(guī)則計量計費。
3.Serverless的開發(fā)框架
Serverless的開發(fā)框架由很多,比如:
- Kubeless:Kubernetes原生的無服務器框架
- Fission:Kubernetes的快速無服務器框架,專注于開發(fā)人員的生產(chǎn)力和高性能。支持ython,NodeJS,Go,C?;騊HP編寫函數(shù)。
- Funktion:專為Kubernetes設計的開源事件驅(qū)動的Lambda風格編程模型。Funktion與fabric8平臺緊密相連。
-
IronFunctions:一個開源的無服務器平臺或FaaS平臺,可以在任何地方運行。IronFunction是用Golang編寫的,實際上支持任何語言的功能。
還有OpenWhisk,OpenFaaS,Nuclio,Virtual Kubelet,F(xiàn)nproject等其他的開源框架。
4.以Kubeless為例,開發(fā)Serverless。
環(huán)境準備
# 下載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
#如果不能倆連外網(wǎng),預先加載以下鏡像
#這里只下載go-init和go的鏡像,因為這里的函數(shù)式基于golang寫的,不同的開發(fā)語言可以下載對應的鏡像
[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
開發(fā)函數(shù),主要通過golang實現(xiàn)數(shù)組求和
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
}
發(fā)布function
- 通過kubeless發(fā)布
### flink: 表示function名稱
### runtime: 表示運行時,實際對應鏡像,支持的類型可通過kubeless get-server-config查看
###image-pull-policy:鏡像拉去策略,默認Always,這里無法連接外網(wǎng)設置為IfNotPresent
### from-file: 表示function源文件
### handler: 表示function具體函數(shù)名稱,模塊.函數(shù)名稱
如果需要有依賴包通過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'
#查看發(fā)布的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
- 通過apiserver發(fā)布
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
函數(shù)調(diào)用 <除了主動請求,還支持事件和數(shù)據(jù)流的輸入方式>
#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
調(diào)用參數(shù)模板
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"
5.kubeless-UI
#下載地址:https://github.com/kubeless/kubeless-ui/releases
#修改內(nèi)部的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