無伺服器 FaaS 架構的核心概念是將應用程式拆解成獨立的函式,並在雲端平台上按需執行。這種架構模式可以有效降低維運成本、提高開發效率,並提升應用程式的可擴充套件性和可靠性。本文詳細介紹了 FaaS 平台的通用架構,包含系統層和 FaaS 層的各個元件,例如閘道器、啟動器、訊息匯流排、執行器和日誌儲存等。同時,文章也探討了 FaaS 的應用場景,例如 Webhook 系統、API 閘道器、串流資料處理等。

從底層的虛擬機器和作業系統,到容器執行環境和容器協調引擎,構成了 FaaS 平台的系統層基礎。而 FaaS 層則包含了閘道器、啟動器、訊息匯流排、執行器、日誌儲存以及應用級容器執行環境等關鍵元件。這些元件協同工作,確保 FaaS 函式能夠被有效地排程、執行和監控。理解這些元件的功能和互動方式,對於構建和維護 FaaS 平台至關重要。此外,文章也提供了一些程式碼範例,演示如何在不同 FaaS 平台上佈署簡單的應用程式,例如 OpenFaaS 的 echoit 函式,OpenWhisk 的 Hello World 動作,以及 Fn Project 的 Go 函式。

無伺服器FaaS的通用架構

在探討其他技術章節之前,本文首先介紹了在撰寫過程中調查和研究的多達六個無伺服器FaaS平台的通用架構。這個架構是現有FaaS平台的精華概述,也為建立新的FaaS平台提供了參考。

系統層架構描述

從下到上的架構描述如下:

  1. 物理或虛擬機器:這些機器可以位於公有雲或私有雲上,部分機器可能是在防火牆或組織內部執行的物理機器,也可以混合使用形成混合基礎設施。

  2. 作業系統和核心:需要具有支援容器隔離的現代內核的作業系統,如Linux,或至少與runC相容的系統。Windows或Windows Server 2016具有根據Hyper-V的隔離,與Docker相容。

  3. 容器執行環境(系統級):這一層負責提供叢集,不是用於直接執行FaaS函式。

  4. 容器協調引擎(可選):這一層可以使用Docker Swarm或Kubernetes。本文使用Docker Swarm,但一些FaaS平台可能不使用任何協調工具,僅使用Docker和容器網路就足以讓FaaS平台有效地執行。

FaaS層架構描述

FaaS層的架構從左到右描述如下:

  1. FaaS閘道器:是整個架構的最前沿元件,有些實作中是可選的,但大多數實作中,這個元件幫助服務HTTPS請求和快取一些靜態內容,如平台的UI部分。閘道器例項有助於提高吞吐量,通常是一個無狀態的根據HTTP的反向代理,因此易於擴充套件。

  2. 啟動器:是FaaS中最重要的元件之一,負責模擬真實的呼叫請求到平台的其他部分。例如,在OpenWhisk中,這個元件被稱為控制器。在Fn中,其Fn伺服器內部的部分充當啟動器。

  3. 訊息匯流排:是FaaS平台的訊息主幹。一些沒有這個元件的架構將難以正確實作非同步呼叫或重試模式,以使平台更強壯。訊息匯流排將啟動器與執行器解耦。

  4. 執行器:是真正執行函式呼叫的元件,它連線到自己的容器執行環境(應用級別)以啟動真正的函式執行序列。所有結果和日誌都將寫入中央日誌儲存。

  5. 日誌儲存:是平台的單一真實來源,應設計為儲存幾乎所有內容,從函式活動到每次呼叫的錯誤日誌。

  6. 容器執行環境(應用級別):負責啟動函式容器,本文簡單地使用Docker及其底層引擎作為執行環境元件。

無伺服器/FaaS的使用案例

無伺服器/FaaS是一種通用的計算模型,因此幾乎可以使用這種程式設計正規化實作任何型別的工作負載。無伺服器/FaaS的使用案例可以從為普通Web應用程式提供API,到為移動應用程式提供RESTful後端,再到用於日誌或影片處理的函式,後端用於根據WebHook的系統,或流資料處理程式等。

  graph LR;
    A[物理或虛擬機器] --> B[作業系統和核心];
    B --> C[容器執行環境];
    C --> D[容器協調引擎];
    D --> E[FaaS閘道器];
    E --> F[啟動器];
    F --> G[訊息匯流排];
    G --> H[執行器];
    H --> I[容器執行環境];
    I --> J[日誌儲存];

圖表翻譯: 此圖表展示了無伺服器FaaS平台的通用架構,從底層的物理或虛擬機器到FaaS層的各個元件,包括FaaS閘道器、啟動器、訊息匯流排、執行器和日誌儲存等,完整描述了無伺服器FaaS平台的系統架構和FaaS層架構。

內容解密:

此圖表清晰地展示了無伺服器FaaS平台的各個層次和元件之間的關係,從基礎設施到應用層,每一層都發揮著至關重要的作用。瞭解這些元件和層次有助於更好地設計和實作無伺服器FaaS平台。

程式碼示例:
def hello_world():
    print("Hello, World!")

# 呼叫函式
hello_world()

內容解密:

此程式碼示例展示了一個簡單的Python函式hello_world,該函式列印預出“Hello, World!”。這個例子說明瞭如何在無伺服器FaaS環境中定義和呼叫一個簡單的函式。無伺服器FaaS允許開發者專注於編寫函式程式碼,而無需擔心底層的基礎設施。

隨著無伺服器FaaS技術的不斷發展和完善,預計將會有更多的企業和開發者採用這一技術來構建和佈署應用程式。未來,無伺服器FaaS可能會與其他技術如容器化、自動化和人工智慧進一步融合,創造出更強大和靈活的應用程式開發和佈署模式。

第8章:系統整合應使用案例項

在第8章「彙整所有元素」中,我們將探討一個如前圖所示的系統,該系統具備以下使用案例:

WebHook系統的API介面

在前面的系統架構圖中,我們注意到有一個名為「Backend for UI」的元件。該系統允許我們定義一個WebHook,並且這個WebHook將被實作為一個FaaS(Function as a Service)函式,使用後續章節中討論的其中一個框架來實作。

包裝舊有系統的API

在系統架構圖的右上角,我們看到有一組函式連線到一個名為Chrome Headless的元件(一個完整功能的Google Chrome例項)。這些函式包裝了一系列指令,用於控制Google Chrome自動操作舊有系統。

作為其他服務抽象層的API

在系統架構圖的右下角,有兩個簡單的區塊。第一個區塊是一個執行在FaaS平台上的函式,它連線到第二個區塊,即「Mock Core Bank System」,這是一個更複雜的REST API。此部分的系統展示瞭如何使用FaaS函式作為抽象層來簡化複雜系統的介面。

串流資料處理

我們還將實作一個資料處理代理(data processing agent),它是一個事件監聽器,用於監聽來自事件源的資料流(在系統架構圖中,可以看到以太坊的標誌)。這個代理將監聽來自資料來源的資料流,然後呼叫執行在FaaS平台上的函式進行處理。

FaaS與Docker的Hello World範例

本文涵蓋了所有三個主要的FaaS框架在Docker上的應用。因此,在本章的第一個「Hello World」範例中,我們將讓讀者自行選擇偏好的FaaS框架。

在Linux上的通用設定

對於Mac或Windows使用者,請跳過此步驟,直接下載Docker for Mac或Docker for Windows:

$ curl -sSL https://get.docker.com | sudo sh

如果您在本章選擇使用OpenFaaS,可以透過「Play with Docker」(https://labs.play-with-docker.com/)簡化設定過程,它會在單節點的Docker Swarm上自動安裝OpenFaaS。

初始化Docker Swarm

安裝好Docker後,只需初始化Swarm來使我們的單節點叢集準備好執行:

$ docker swarm init --advertise-addr=eth0

如果上述命令失敗,請嘗試更改網路介面名稱以符合您的系統組態。如果仍然失敗,可以直接使用其中一台機器的IP地址。

Hello OpenFaaS

我們將使用OpenFaaS的echoit函式來進行「Hello World」的示範。首先,從https://github.com/openfaas/faas 複製專案,只複製最近的一層提交以加快複製速度:

$ git clone --depth=1 https://github.com/openfaas/faas

然後,切換到faas目錄,並使用以下命令佈署OpenFaaS的預設堆積疊:

$ cd faas
$ docker stack deploy -c docker-compose.yml func

等待堆積疊啟動完成。然後,我們可以使用curl命令進行「Hello World」的測試:

$ curl -d "hello world." -v http://localhost:8080/function/func_echoit

輸出結果將顯示伺服器的回應:

* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> POST /function/func_echoit HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Length: 12
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 12 out of 12 bytes
< HTTP/1.1 200 OK
< Content-Length: 12
< Content-Type: application/x-www-form-urlencoded
< Date: Fri, 23 Mar 2018 16:37:30 GMT
< X-Call-Id: 866c9294-e243-417c-827c-fe0683c652cd
< X-Duration-Seconds: 0.000886
< X-Start-Time: 1521823050543598099
<
* Connection #0 to host localhost left intact
hello world.

完成後,可以使用docker stack rm命令移除所有正在執行的服務:

$ docker stack rm func

內容解密:

上述步驟展示瞭如何在OpenFaaS上佈署一個簡單的「Hello World」函式。首先,我們從GitHub上複製了OpenFaaS的faas倉函式庫,並使用docker stack deploy命令佈署了預設的OpenFaaS堆積疊。然後,我們使用curl命令向echoit函式發送了一個POST請求,請求中包含了字串「hello world.」。伺服器成功回應了我們的請求,並傳回了相同的字串。

Hello OpenWhisk

接下來,我們將轉到OpenWhisk。同樣地,我們需要一個docker-compose二進位制檔案。請存取https://github.com/docker/compose/releases 並按照指示安裝它。

與OpenFaaS相比,OpenWhisk的整體設定稍為複雜,但「Hello World」的示範則更為簡單,因為它已經內建在系統中。

首先,從GitHub倉函式庫複製OpenWhisk開發工具:

$ git clone --depth=1 https://github.com/apache/incubator-openwhisk-devtools devtools

然後,切換到devtools/docker-compose目錄,並手動提取映象:

$ cd devtools/docker-compose
$ docker-compose pull
$ docker pull openwhisk/nodejs6action

之後,使用make quick-start命令進行設定:

$ make quick-start

等待OpenWhisk叢集啟動完成,這可能需要長達10分鐘。

完成後,執行以下命令註冊並呼叫「Hello World」動作:

$ make hello-world

輸出結果將顯示動作的呼叫結果:

creating the hello.js function ...
invoking the hello-world function ...
adding the function to whisk ...
ok: created action hello
invoking the function ...
invokation result: { "payload": "Hello, World!" }
{ "payload": "Hello, World!" }
deleting the function ...
ok: deleted action hello

內容解密:

上述步驟展示瞭如何在OpenWhisk上佈署一個「Hello World」函式。首先,我們從GitHub上複製了OpenWhisk的開發工具,並使用docker-compose提取了必要的映象。然後,我們使用make quick-start命令啟動了OpenWhisk叢集,並使用make hello-world命令註冊並呼叫了預先定義好的「Hello World」動作。動作成功執行並傳回了「Hello, World!」的結果。

Fn Project的Hello World

最後,我們將介紹另一個FaaS專案——Fn Project。我們將透過安裝Fn CLI來快速完成「Hello World」的示範。然後,使用它來啟動一個本地的Fn伺服器,建立一個應用,並建立一個路由連結到預先構建好的Go函式。之後,我們將使用curl命令測試佈署好的「Hello World」函式。

以下是安裝Fn客戶端的標準命令:

$ curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sudo sh

安裝完成後,我們可以使用fn命令。讓我們啟動一個Fn伺服器,並使用--detach選項使其在後台執行:

$ fn start --detach

如果看到容器ID,表示啟動成功。接下來,快速建立一個Fn應用並命名為goapp

$ fn apps create goapp

然後,我們已經在Docker Hub上有一個預先構建好的映象chanwit/fn_ch1:0.0.2。只需使用fn routes create命令將新的路由連結到該映象:

$ fn routes create --image chanwit/fn_ch1:0.0.2 goapp /fn_ch1

路由建立完成後,我們可以使用curl命令測試佈署好的函式。

內容解密:

上述步驟展示瞭如何在Fn Project上佈署一個「Hello World」函式。首先,我們安裝了Fn CLI並啟動了一個本地的Fn伺服器。然後,我們建立了一個名為goapp的應用,並建立了一個路由將請求連結到預先構建好的Go函式。最後,我們可以使用curl命令測試佈署好的函式。

隨著無伺服器架構(Serverless Architecture)的持續發展,FaaS技術將在未來的軟體開發和佈署中扮演越來越重要的角色。未來的FaaS框架預計將進一步簡化開發流程、提高執行效率並增強安全性。

開發者需要持續關注最新的FaaS技術發展,並根據實際需求選擇合適的框架和工具。同時,透過不斷的實踐和學習,開發者將能夠更好地利用FaaS技術來構建高效、靈活且可擴充套件的應用系統。

參考資料

  • OpenFaaS官方檔案:https://docs.openfaas.com/
  • OpenWhisk官方檔案:https://openwhisk.apache.org/documentation.html
  • Fn Project官方檔案:https://fnproject.io/docs/
  graph LR
    A[開始] --> B[選擇FaaS框架]
    B --> C[安裝Docker]
    C --> D[初始化Swarm]
    D --> E[佈署OpenFaaS]
    E --> F[測試Hello World]
    F --> G[清理環境]
    G --> H[結束]

Docker與Swarm叢集:容器技術的基礎

在上一章中,我們成功地在Fn平台上執行了一個簡單的「Hello World」程式。本章將探討容器技術,並介紹Docker及其協調引擎Docker Swarm。我們將討論為什麼需要Docker基礎設施來佈署和執行無伺服器(Serverless)和函式即服務(FaaS)應用程式。

容器技術簡介

在討論Docker之前,我們需要了解容器技術的基礎。虛擬機器(VM)是一種常見的虛擬化技術,已經被雲端供應商和企業公司廣泛採用。軟體容器(簡稱容器)也是一種虛擬化技術,但它們之間存在一些關鍵差異。容器的主要特點是,每個容器分享主機上的相同核心,而每個虛擬機器都有自己的核心。容器使用作業系統層級的虛擬化技術,而不是Hypervisor。

容器與虛擬機器的比較

下圖展示了容器和虛擬機器堆積疊之間的比較:

此圖示
容器堆積疊:
  - 應用程式
  - 函式庫
  - 容器引擎
  - 作業系統
虛擬機器堆積疊:
  - 應用程式
  - 函式庫
  - 作業系統
  - Hypervisor
  - 硬體

圖表翻譯: 上圖顯示了容器和虛擬機器堆積疊之間的比較。容器堆積疊直接在作業系統上執行,而虛擬機器堆積疊則需要Hypervisor來管理虛擬機器。

Linux的容器技術嚴重依賴兩個重要的核心功能:Namespace和Cgroups。Namespace將程式隔離,使其擁有自己的全域性資源集,例如PID和網路。Cgroups(控制群組)提供了一種機制,用於測量和限制資源,例如CPU使用率、記憶體、區塊I/O和網路頻寬。

Docker簡介

Docker基本上是一組技術的集合,用於幫助我們準備、管理、執行容器。在虛擬機器的世界中,我們需要Hypervisor來管理所有VM例項。同樣,在容器的世界中,我們使用Docker作為容器引擎來管理與容器相關的一切。

Docker是目前最流行的容器引擎。使用Docker時,我們遵循Docker本身推薦的三個概念:建置(Build)、運送(Ship)和執行(Run)。

建置-運送-執行流程

Docker的建置-運送-執行流程最佳化了開發和佈署的效率。在建置步驟中,我們可以快速建置和銷毀容器映像檔。作為開發人員,我們可以將容器建置步驟納入開發週期的一部分。

在運送步驟中,我們將容器映像檔運送到各個地方,從開發人員的筆記型電腦到QA伺服器和預備伺服器。我們將容器映像檔儲存在公共Hub或公司內的私有註冊中心。最終,我們將容器映像檔佈署到生產環境中。

在執行步驟中,Docker幫助我們使用Swarm叢集準備生產環境。我們從容器映像檔啟動容器,並根據特定的約束條件將容器排程到叢集的特定部分執行。

安裝Docker

在遵循建置-運送-執行步驟之前,我們需要在機器上安裝Docker。在Linux上,我們使用經典的安裝方法,Docker社群版(CE或Docker-CE):

$ curl -sSL https://get.docker.com | sudo bash

在本文中,我們將使用Debian或Ubuntu機器來示範Docker。在Debian/Ubuntu機器上,我們將透過apt-get獲得最穩定的Docker版本(截至撰寫時):

$ sudo apt-get install docker-ce=17.06.2~ce-0~ubuntu

對於macOS和Windows系統,我們可以從Docker官網下載Docker:

  • Docker for Mac:https://www.docker.com/docker-mac
  • Docker for Windows:https://www.docker.com/docker-windows

要檢查已安裝的Docker版本,我們可以使用docker version命令:

$ docker version
Client:
 Version:      17.06.2-ce
 API version:  1.30

Docker版本檢查程式碼解析

$ docker version

#### 內容解密: 此命令用於檢查已安裝的Docker版本。輸出結果顯示了客戶端和伺服器的版本資訊,包括版本號和API版本。

練習題
  1. 什麼是容器的定義?
  2. Docker的主要功能是什麼?
  3. 如何安裝Docker?
  4. Docker的建置-運送-執行流程是什麼?
  5. 如何檢查已安裝的Docker版本?

在下一章中,我們將探討Docker Swarm叢集的設定和管理。我們將學習如何建立和管理Swarm叢集,以及如何在Swarm叢集上佈署應用程式。