the-power-of-interfaces-openfaas


翻譯自: https://blog.alexellis.io/the-power-of-interfaces-openfaas/ 2019年5月28日
首發於:hiknowledge.top

在這篇文章中,我將探索如何將接口的思想引入OpenFaaS,以使項目適應不斷變化的容器環境。您將瞭解如何通過提供程序模型和faas-provider SDK擴展OpenFaaS。然後,我將向您介紹爲什麼我們要構建faas-cli generate命令,它的作用,以及如何使用它來爲Kubernetes生成CRD。

OpenFaaS架構介紹

一開始有OpenFaaS, OpenFaaS只在Docker Swarm上運行。

四個月後,一個名爲Kubernetes的容器編配平臺的需求也出現了,該平臺的吸引力和業界的接受度都在增長。回顧歷史,很難想象 Kubernetes 並不總是容器戰爭的贏家。

當時,OpenFaaS網關和API接口的集羣實現是緊密耦合的。

Provider模型

因此,我將OpenFaaS網關現有的REST API分爲三個組件——網關、提供者接口和faas-swarm。 其思想是,提供者可以接入任何容器編制器,並瞭解如何在不更改接口或工具的情況下執行CRUD、伸縮和調用

這意味着網關組件不需要像Kubernetes的client-go包那樣有大量的依賴關係而膨脹起來,這意味着我們可以更緊密地遵循單一責任原則(SRP)。

從現在開始,OpenFaaS網關只作爲配置選項(如驗證、跟蹤和度量)的中間件

faas-provider

今天,有一個Golang SDK允許任何人引導OpenFaaS提供者——你只需填寫“http.Handler”函數即可,簡化了整個體驗。

OpenDNS的Alex Boten領導的團隊在不到24小時內創建了他們自己的OpenFaaS provider

faas-memory

這是一個 in-memory provider實現的例子。

import (
	bootstrap "github.com/openfaas/faas-provider"
	bootTypes "github.com/openfaas/faas-provider/types"
)

func main() {

	bootstrapHandlers := bootTypes.FaaSHandlers{
		FunctionProxy:  handlers.MakeProxy(),
		DeleteHandler:  handlers.MakeDeleteHandler(),
		DeployHandler:  handlers.MakeDeployHandler(),
		FunctionReader: handlers.MakeFunctionReader(),
		ReplicaReader:  handlers.MakeReplicaReader(),
		ReplicaUpdater: handlers.MakeReplicaUpdater(),
		UpdateHandler:  handlers.MakeUpdateHandler(),
		HealthHandler:  handlers.MakeHealthHandler(),
		InfoHandler:    handlers.MakeInfoHandler(version.BuildVersion(), version.GitCommitSHA),
	}

	readConfig := types.ReadConfig{}
	osEnv := types.OsEnv{}
	cfg := readConfig.Read(osEnv)

	bootstrapConfig := bootTypes.FaaSConfig{
		ReadTimeout:     cfg.ReadTimeout,
		WriteTimeout:    cfg.WriteTimeout,
		TCPPort:         &cfg.Port,
		EnableHealth:    true,
		EnableBasicAuth: false,
	}

	log.Infof("listening on port %d ...", cfg.Port)
	bootstrap.Serve(&bootstrapHandlers, &bootstrapConfig)
}

您可以看到,我們在 bootTypes.FaaSHandlers 中有效地設置了各Handler結構,然後運行 bootstrap.Serve 用於啓動provider。

通過遵循provider模型,任何容器編配器或其他系統(如內存存儲)都可以作爲接入對象,整個OpenFaaS生態系統仍然可用且兼容。

保持兼容

爲了保持提供者的兼容性,我們引入了在構建時爲Swarm和Kubernetes提供者運行的certifier項目,以確保它們支持API接口。

當Hashicorp的Nic Jackson啓動faas-nomad提供程序時,他使用這個工具進行了一種測試驅動的開發。

規則的一個例外:Operator和CRD

2017年,我和Stefan Prodan在KubeCon討論了將我們的faas-netes改造成一使用自己的Function CRD的Operator。

在Stefan使用來自faas-netes控制器的代碼將一個工作操作符組合在一起後不久,它就工作了,這意味着用戶可以進行選擇。他們可以使用REST API或CRD,實際上他們可以兩者都使用。REST API創建了CRD條目。

我們已經有了一個OpenFaaS provider的生態系統和用於不同的容器編制器的 後端,如:Docker Swarm、Kubernetes、AWS Fargate和Hashicorp Nomad。這意味着我們現在有兩種正交的方式來在OpenFaaS中部署函數。

所有現有的提供程序都使用stack.yml文件和REST API,但是OpenFaaS Operator現在有了一個CRD。

進入faas-cli generate

我提出了以下建議:特性:通過CLI生成Kubernetes CRD YAML文件

假設我們有一個名爲webhook-responder的函數,它接收HTTP消息,然後在Slack中向傳入的webhook URL發送消息。

它看起來是下面這樣的,由於我們的faas-provider接口,我們可以將它部署到任何兼容的OpenFaaS Provider。

#stack.yml
provider:
  name: openfaas
  gateway: http://127.0.0.1:8080

functions:
  webhook-responder:
    lang: go
    handler: ./webhook-responder
    image: alexellisuk/webhook-responder:latest
    environment:
      write_debug: true
    secrets:
     - webhook-token
     - slack-incoming-url

我們可以使用faas-cli deployfaas-cli up來部署這個函數。

對於Kubernetes的操作人員和開發人員來說,使用REST API提供了一些價值,但是在本質上,我們更喜歡我們最喜歡的工具kubectlkubectl工具允許本地Kubernetes策略和與RBAC和其他工具的深度集成。

我提出的解決方案是創建一個生成命令,它將用一個stack.yml文件作爲輸入,然後生成一個CRD。下面是它實際的樣子:

$ faas-cli generate
# or
$ faas-cli generate --api=openfaas.com/v1alpha2

注意:您可以運行faas-cli generate --help來獲得更多的選項。

#webhook-responder.yaml
---
apiVersion: openfaas.com/v1alpha2
kind: Function
metadata:
  name: webhook-responder
  namespace: openfaas-fn
spec:
  name: webhook-responder
  image: alexellisuk/webhook-responder:latest
  environment:
    write_debug: "true"
  secrets:
  - webhook-token
  - slack-incoming-url

這個函數可以用: kubectl apply -f webhook-responder.yaml 來部署。

如果您想了解faas-cli如何生成,那麼請查看這裏的命令文件:generate.go。最初的版本是由社區的Vivek Syngh編寫的。

爲Knative擴展faas-cli generate

在2018年夏天,谷歌宣佈了一個新的無服務器項目,名爲Knative。我立即着手評估這個已經飽和的市場的新進入者,發現用OpenFaaS構建的任何功能都可以部署,而不需要 到他們的平臺上修改。

Portability with Knative (gist)

OpenFaaS函數商店允許社區和最終用戶共享、發現和協作函數。

在我的Gist,我展示了來自函數存儲的函數可以部署到Knative。這啓發了Michael Hausenblas, RedHat的開發者倡導者,在他的第一篇Knative博客文章中展示了着色功能 colorise

在這裏插入圖片描述

就在今年KubeCon Barcelona的無服務器從業者峯會(SPS)之前,我開始更新faas-cli以生成Knative服務定義。

Pull request: Add knative serving v1alpha1 to generate CRD command.

$ faas-cli generate --api=serving.knative.dev/v1alpha1

---
apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: webhook-responder
  namespace: openfaas-fn
spec:
  runLatest:
    configuration:
      revisionTemplate:
        spec:
          container:
            image: alexellisuk/webhook-responder:latest
            env:
            - name: write_debug
              value: "true"
            volumeMounts:
            - name: webhook-token
              mountPath: /var/openfaas/secrets/webhook-token
              readOnly: true
            - name: slack-incoming-url
              mountPath: /var/openfaas/secrets/slack-incoming-url
              readOnly: true
          volumes:
          - name: webhook-token
            secret:
              secretName: webhook-token
          - name: slack-incoming-url
            secret:
              secretName: slack-incoming-url

您甚至可以將這個命令傳遞到kubectl apply,甚至在stack.yml中也可以使用它包含多個函數。

faas-cli generate --api=serving.knative.dev/v1alpha1 | kubectl apply -f -

你可以這樣搜索商店:

$ faas-cli store list --verbose
FUNCTION                    DESCRIPTION
Colorization                Turn black and white photos to color ...
Inception                   This is a forked version of the work ...
Have I Been Pwned           The Have I Been Pwned function lets y...
SSL/TLS cert info           Returns SSL/TLS certificate informati...
Face blur by Endre Simo     Blur out faces detected in JPEGs. Inv...
Figlet                      OpenFaaS Figlet image. This repositor...
...

然後將一個函數從商店部署到Knative,例如figlet(生成ASCII標誌):

$ faas-cli generate --api=serving.knative.dev/v1alpha1 --from-store="figlet"

包裝

OpenFaaS提供者模型及其REST API意味着該項目可以針對各種容器編制器,甚至是AWS Lambda這樣的專有SaaS產品,而無需對接口進行任何額外的更改。

faas-cli生成命令還爲我們提供了一種方法,可以在不拋棄原始設計的情況下深入集成Kubernetes當前和未來的生態系統。

您可能想知道OpenFaaS REST API和Kubernetes或Knative上OpenFaaS的CRD是否互相正交?這可能是事實,但是OpenFaaS Operator表明我們可以兩全其美。

本設計之所以成功,是因爲OpenFaaS的目標是Docker或OCI鏡像格式和端口8080上的簡單HTTP接口。我稱之爲“Serverless 2.0運行時契約”或“一個Serverless工作負載”。

Serverless 2.0 Landscape

在Serverless 2.0世界中,您可以在任何列出的模板系統中構建函數,然後在選擇的任何服務平臺和列出的可安裝或託管的基礎設施產品上運行它們。

我的 其他相關工作:

未來的工作

OpenFaaS的使命是:簡化無服務器函數。因此,在我看來,未來的工作是擴展OpenFaaS提供商和CRD生態系統,以便將開發人員的體驗帶到所有平臺。

在2019年,我們的社區將對Kubernetes生態系統的目標進行雙重調整:性能、安全性和企業特性。我們也超越了Kubernetes和faas-lambda。Edward Wilde在SPS活動中談到了他如何創建一個直接部署到AWS Lambda的faas-provider,而不需要對爲OpenFaaS構建的圖像進行額外的修改。訂閱博客獲取更多信息。

在我看來,這是社區未來的一些工作:

  • 一個以Knative Serving CRD爲接入目標的OpenFaaS provider,它將被(想象地)稱爲faas-knative,並將OpenFaaS REST API、CLI、函數存儲和UI帶給Knative用戶,以及在無服務器環境下的最佳開發體驗之一。
  • Rancher的首席架構師Darren Shepherd表示有興趣構建一個OpenFaaS Provider,爲名爲Rio的新Rancher microPaaS平臺帶來開發者體驗。
  • 一個 faas-cli generate --api=services.rio.cattle.io 命令爲Rio生成自己的Service定義,以支持實驗和快速反饋。看issue

Get involved

我們擁有強大的核心團隊和200多名貢獻者,現在是參與項目的最佳時機。歡迎貢獻和反饋,以及任何其他問題或意見。

不知道如何貢獻?加入Slack,然後跟上我們最新的社區視頻簡報:如何貢獻,2019年

Follow @alexellisuk and @openfaas on Twitter.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章