另一個常見特徵是傾向於最小化和集中程式碼,這就是為什麼無伺服器運算有時被稱為功能即服務 (FaaS) 的原因。
從歷史上看,第一家使用 AWS Lambda 提供 FaaS 的雲端供應商是 Amazon,因此得名。 其他雲端服務供應商也提供類似的服務:
- 來自 Google 的雲端功能
- Microsoft 的 Azure 函數
所有這些公司都提供無伺服器運算、自動擴展,並且只為您實際使用的內容付費,但他們將客戶鎖定在他們的專有產品中。 然而,無伺服器計算有免費和開源的替代方案。 值得注意的是:
- 平台
Apache OpenWhisk ,在 IBM 的孵化器中開發, Spring 雲函數 ,作為相當豐富的 Spring Framework 生態系統的一部分,也可以用作 AWS Lambda、Azure Functions 和 OpenWhisk 的外觀,項目 Fn ,由 Oracle 支援。
所有這些都完全獨立於雲,也就是說,它們可以安裝在任何雲中,包括您自己的雲、公有雲或私有雲,當然還有 Exoscale。
Fn 計畫如何運作
Fn 完全基於 Docker,由兩個主要元件組成:
- CLI程式旨在管理Fn基礎設施的各個方面,並與Fn伺服器交互,
- Fn 伺服器本身是打包在 Docker 容器中的常規應用程式。
Fn 中部署的函數也在單獨的容器中執行,這使您可以支援許多程式語言,例如... Clojure!
函數參數傳遞到標準輸入 (STDIN),結果寫入標準輸出 (STDOUT)。 如果參數或傳回值不是簡單值(例如 JSON 物件),則可以使用 Fn 本身以函數開發工具包(FDK)形式提供的抽象層進行轉換。
為了方便起見,提供了內建的模板集,以方便在廣泛的不同語言及其版本(Go、不同版本的 Java、Python 等)中部署 FaaS。
按照下圖建立 FaaS 很容易:
- 使用Fn CLI部署功能:根據所選模板建立Fn的應用程式設定檔。
- 我們再次使用 CLI Fn 推出自己的功能:將容器映像放置在某個儲存庫中,然後通知伺服器該映像的存在和放置。
向Fn傳遞功能的原理
Serverless功能的本機安裝和測試
讓我們開始在本機上安裝 Fn。 首先,請按照 Fn 的要求安裝 Docker。 假設我們使用 Debian/Ubuntu:
$ sudo apt-get update
$ sudo apt-get install docker.io
或根據您的系統使用套件管理器/Docker 建置。 然後您可以直接安裝 Fn CLI。 例如,使用捲曲:
$ curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh
如果您使用的是安裝了 Homebrew 的 OSX,則可以採用其他方法:
$ brew install fn
==> Downloading https://homebrew.bintray.com/bottles/fn-0.5.8.high_sierra.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/b1/b1767fb00e2e69fd9da73427d0926b1d1d0003622f7ddc0dd3a899b2894781ff?__gda__=exp=1538038849~hmac=c702c9335e7785fcbacad1f29afa61244d02f2eebb
######################################################################## 100.0%
==> Pouring fn-0.5.8.high_sierra.bottle.tar.gz
/usr/local/Cellar/fn/0.5.8: 5 files, 16.7MB
現在我們已準備好使用 CLI 來初步部署我們的函數。 為簡單起見,我們將使用內建的啟動環境,例如 Node:
$ fn init --runtime node --trigger http hellonode
Creating function at: /hellonode
Function boilerplate generated.
func.yaml created.
將會建立一個新目錄 hellonode
使用一些基本設定檔進一步開發我們的 Fn 功能。 在新建立的目錄中,您可以按照所選語言或運行時的標準建立應用程式:
# Каталог с node выглядит так:
hellonode
├── func.js
├── func.yaml
└── package.json
# Свежеустановленное окружение Java11 такое:
hellojava11
├── func.yaml
├── pom.xml
└── src
├── main
│ └── java
│ └── com
│ └── example
│ └── fn
│ └── HelloFunction.java
└── test
└── java
└── com
└── example
└── fn
└── HelloFunctionTest.java
Fn 建立初始專案結構,建立文件 func.yaml
,包含 Fn 的必要設置,並以您選擇的語言設定程式碼範本。
對於 Node 運行時,這意味著:
$ cat hellonode/func.js
const fdk=require('@fnproject/fdk');
fdk.handle(function(input){
let name = 'World';
if (input.name) {
name = input.name;
}
return {'message': 'Hello ' + name}
})
現在我們將在本地快速測試我們的函數,看看一切是如何運作的。
首先,我們將啟動 Fn 伺服器。 前面已經提到,Fn 伺服器是一個 Docker 容器,因此啟動後,它會從 Docker 註冊表中取得映像。
$ fn start -d # запускаем локальный сервер в фоне
Unable to find image 'fnproject/fnserver:latest' locally
latest: Pulling from fnproject/fnserver
ff3a5c916c92: Pull complete
1a649ea86bca: Pull complete
ce35f4d5f86a: Pull complete
...
Status: Downloaded newer image for fnproject/fnserver:latest
668ce9ac0ed8d7cd59da49228bda62464e01bff2c0c60079542d24ac6070f8e5
要運行我們的功能,必須「推出」它。 這需要 имя приложения
:在Fn中,所有應用程式都必須指定為相關函數的命名空間。
Fn CLI 將搜尋該文件 func.yaml
在將用於配置該功能的目前目錄中。 所以首先你需要進入我們的目錄 hellonode
.
$ cd hellonode
$ fn deploy --app fnexo --local # выкатываем функцию локально, имя приложения - fnexo.
# параметр local не заливает образ в удаленный реестр,
# запуская его напрямую
Deploying hellonode to app: fnexo
Bumped to version 0.0.2
Building image nfrankel/hellonode:0.0.3 .
Updating function hellonode using image nfrankel/hellonode:0.0.3...
Successfully created app: fnexo
Successfully created function: hellonode with nfrankel/hellonode:0.0.3
Successfully created trigger: hellonode-trigger
從命令輸出可以看到,建立了一個新的 Docker 容器映像,其中包含我們的函數。 該函數已準備好被調用,我們有兩種方法可以調用:
- 使用 Fn 指令
invoke
- 直接透過調用
http
通話 invoke
透過 Fn 它只是模擬透過 HTTP 進行測試的工作,這方便快速測試:
$ fn invoke fnexo hellonode # вызываем функцию hellonode приложения fnexo
{"message":"Hello World"}
為了直接呼叫函數,您需要知道完整的 URL:
$ curl http://localhost:8080/t/fnexo/hellonode-trigger
{"message":"Hello World"}
Fn 伺服器在連接埠 8080 上公開其函數,且函數 URL 似乎與模式相符 t/app/function
,但不完全。 透過 HTTP,函數不是直接調用的,而是透過所謂的觸發器來調用,根據其名稱,觸發器「啟動」函數調用。 觸發器定義在 `func.yml
專案:
schema_version: 20180708
name: hellonode
version: 0.0.3
runtime: node
entrypoint: node func.js
format: json
triggers:
- name: hellonode-trigger
type: http
source: /hellonode-trigger # URL триггера
我們可以更改觸發器名稱以匹配函數名稱,這將簡化一切:
triggers:
- name: hellonode-trigger
type: http
source: /hellonode # совпадает с именем функции
然後我們再次運行函數傳遞並從新的觸發器中調用它:
$ fn deploy --app fnexo hellonode --local
$ curl http://localhost:8080/t/fnexo/hellonode
{"message":"Hello World"}
一切正常! 是時候進行全面實驗並在伺服器上發布我們的 FaaS 了!
在您自己的基礎架構上安裝無伺服器功能服務
讓我們使用 Exoscale CLI 快速安裝虛擬機器。 如果您還沒有設置,您可以使用
$ exo firewall create fn-securitygroup
$ exo firewall add fn-securitygroup ssh --my-ip
$ exo firewall add fn-securitygroup -p tcp -P 8080-8080 -c 0.0.0.0/0
$ exo vm create fn-server -s fn-securitygroup
然後你可以 ssh 進入虛擬機器並安裝遠端 Fn 伺服器:
$ exo ssh fn-server
The authenticity of host '185.19.30.175 (185.19.30.175)' can't be established.
ECDSA key fingerprint is SHA256:uaCKRYeX4cvim+Gr8StdPvIQ7eQgPuOKdnj5WI3gI9Q.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '185.19.30.175' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 18.04 LTS (GNU/Linux 4.15.0-20-generic x86_64)
然後按照與本機電腦上相同的方式安裝 Docker 和 Fn 伺服器,啟動伺服器:
$ sudo apt-get update
$ sudo apt-get install docker.io
$ sudo systemctl start docker
$ curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh
$ sudo fn start
...
______
/ ____/___
/ /_ / __
/ __/ / / / /
/_/ /_/ /_/
v0.3.643
Fn 已準備好接收函數! 為了有針對性地將功能傳輸到遠端伺服器,我們將使用以下命令 deploy
透過省略標誌從本機計算機 --local
.
此外,Fn 要求您指定 Fn 伺服器和 Docker 註冊表的位置。 這些選項可以透過環境變數設定 FN_API_URL
и FN_REGISTRY
分別,而且還提供了一種更方便的方法來輕鬆管理部署配置的建立和管理。
用 Fn 術語來說,部署的配置稱為 context
。 以下命令將建立上下文:
$ fn create context exoscale --provider default --api-url http://185.19.30.175:8080 --registry nfrankel
您可以像這樣查看可用的上下文:
$ fn list contexts
CURRENT NAME PROVIDER API URL REGISTRY
default default http://localhost:8080/
exoscale default http://185.19.30.175:8080 nfrankel
並切換到剛剛建立的上下文,如下所示:
$ fn use context exoscale
Now using context: exoscale
從這裡開始,Fn 功能交付將使用選定的 DockerHub 帳戶下載 Docker 映像(在我的例子中 - nfrankel
),然後通知遠端伺服器(在本例中 - http://185.19.30.175:8080
)有關包含您的函數的最新映像的位置和版本。
$ fn deploy --app fnexo . # выполняется на локальной машине из каталога hellonode
Deploying function at: /.
Deploying hellonode to app: fnexo
Bumped to version 0.0.5
Building image nfrankel/hellonode:0.0.5 .
最後:
$ curl http://185.19.30.175:8080/t/fnexo/hellonode
{"message":"Hello World"}
基於 Fn 的無伺服器運算中的函數生命週期
根據自己的能力進行無伺服器運算的優勢
無伺服器運算是一種方便的解決方案,可快速實現與更複雜的應用程式或微服務互動的應用程式的獨立部分。
這通常是由於鎖定所選供應商的隱性成本造成的,根據特定的用例和數量,這可能會導致未來更高的成本和更低的靈活性。
在這種情況下,多雲和混合雲架構也會受到影響,因為您很容易發現自己想要使用無伺服器運算,但由於公司政策的原因,這可能是不可能的。
Fn 非常易於使用,可以提供幾乎相同的 FaaS 接口,開銷很小。 它消除了任何供應商鎖定,可以在本地安裝或在您選擇的任何方便的雲端解決方案提供者中安裝。 選擇程式語言也有自由。
本文僅介紹 Fn 的基礎知識,但創建自己的運行時非常簡單,並且可以使用 Fn 負載平衡器或透過將 Fn 放置在代理程式後面進行保護來更廣泛地部署整體架構。
來源: www.habr.com