使用Docker構(gòu)建你的Serverless樹(shù)莓派集群
這篇博文將向你展示如何使用 Docker 和 OpenFaaS 框架構(gòu)建你自己的 Serverless 樹(shù)莓派集群。大家常常問(wèn)我能用他們的集群來(lái)做些什么?而這個(gè)應(yīng)用完美匹配卡片尺寸的設(shè)備——只需添加更多的樹(shù)莓派就能獲取更強(qiáng)的計(jì)算能力。
“Serverless” (無(wú)服務(wù)器)是事件驅(qū)動(dòng)架構(gòu)的一種設(shè)計(jì)模式,與“橋接模式”、“外觀模式”、“工廠模式”和“云”這些名詞一樣,都是一種抽象概念。
圖片:3 個(gè) Raspberry Pi Zero
這是我在本文中描述的集群,用黃銅支架分隔每個(gè)設(shè)備。
Serverless 是什么?它為何重要?
行業(yè)對(duì)于 “serverless” 這個(gè)術(shù)語(yǔ)的含義有幾種解釋。在這篇博文中,我們就把它理解為一種事件驅(qū)動(dòng)的架構(gòu)模式,它能讓你用自己喜歡的任何語(yǔ)言編寫(xiě)輕量可復(fù)用的功能。更多關(guān)于 Serverless 的資料。
Serverless 架構(gòu)也引出了“功能即服務(wù)服務(wù)”模式,簡(jiǎn)稱(chēng) FaaS
Serverless 的“功能”可以做任何事,但通常用于處理給定的輸入——例如來(lái)自 GitHub、Twitter、PayPal、Slack、Jenkins CI pipeline 的事件;或者以樹(shù)莓派為例,處理像紅外運(yùn)動(dòng)傳感器、激光絆網(wǎng)、溫度計(jì)等真實(shí)世界的傳感器的輸入。
Serverless 功能能夠更好地結(jié)合第三方的后端服務(wù),使系統(tǒng)整體的能力大于各部分之和。
了解更多背景信息,可以閱讀我最近一偏博文:功能即服務(wù)(FaaS)簡(jiǎn)介。
概述
我們將使用 OpenFaaS,它能夠讓主機(jī)或者集群作為支撐 Serverless 功能運(yùn)行的后端。任何能夠使用 Docker 部署的可執(zhí)行二進(jìn)制文件、腳本或者編程語(yǔ)言都能在 OpenFaaS 上運(yùn)作,你可以根據(jù)速度和伸縮性選擇部署的規(guī)模。另一個(gè)優(yōu)點(diǎn)是,它還內(nèi)建了用戶(hù)界面和監(jiān)控系統(tǒng)。
這是我們要執(zhí)行的步驟:
- 在一個(gè)或多個(gè)主機(jī)上配置 Docker (樹(shù)莓派 2 或者 3);
 - 利用 Docker Swarm 將它們連接;
 - 部署 OpenFaaS;
 - 使用 Python 編寫(xiě)我們的第一個(gè)功能。
 
Docker Swarm
Docker 是一項(xiàng)打包和部署應(yīng)用的技術(shù),支持集群上運(yùn)行,有著安全的默認(rèn)設(shè)置,而且在搭建集群時(shí)只需要一條命令。OpenFaaS 使用 Docker 和 Swarm 在你的可用樹(shù)莓派上傳遞你的 Serverless 功能。
我推薦你在這個(gè)項(xiàng)目中使用帶樹(shù)莓派 2 或者 3,以太網(wǎng)交換機(jī)和強(qiáng)大的 USB 多端口電源適配器。
準(zhǔn)備 Raspbian
把 Raspbian Jessie Lite 寫(xiě)入 SD 卡(8GB 容量就正常工作了,但還是推薦使用 16GB 的 SD 卡)。
注意:不要下載成 Raspbian Stretch 了
社區(qū)在努力讓 Docker 支持 Raspbian Stretch,但是還未能做到完美運(yùn)行。請(qǐng)從樹(shù)莓派基金會(huì)網(wǎng)站下載 Jessie Lite 鏡像。
我推薦使用 Etcher.io 燒寫(xiě)鏡像。
在引導(dǎo)樹(shù)莓派之前,你需要在引導(dǎo)分區(qū)創(chuàng)建名為 ssh 的空白文件。這樣才能允許遠(yuǎn)程登錄。
接通電源,然后修改主機(jī)名
現(xiàn)在啟動(dòng)樹(shù)莓派的電源并且使用 ssh 連接:
- $ ssh pi@raspberrypi.local
 
默認(rèn)密碼是 raspberry
使用 raspi-config 工具把主機(jī)名改為 swarm-1 或者類(lèi)似的名字,然后重啟。
當(dāng)你到了這一步,你還可以把劃分給 GPU (顯卡)的內(nèi)存設(shè)置為 16MB。
現(xiàn)在安裝 Docker
我們可以使用通用腳本來(lái)安裝:
- $ curl -sSL https://get.docker.com | sh
 
這個(gè)安裝方式在將來(lái)可能會(huì)發(fā)生變化。如上文所說(shuō),你的系統(tǒng)需要是 Jessie,這樣才能得到一個(gè)確定的配置。
你可能會(huì)看到類(lèi)似下面的警告,不過(guò)你可以安全地忽略它并且成功安裝上 Docker CE 17.05:
- WARNING: raspbian is no longer updated @ https://get.docker.com/
 - Installing the legacy docker-engine package...
 
之后,用下面這個(gè)命令確保你的用戶(hù)帳號(hào)可以訪問(wèn) Docker 客戶(hù)端:
- $ usermod pi -aG docker
 
如果你的用戶(hù)名不是 pi,那就把它替換成你的用戶(hù)名。
修改默認(rèn)密碼
輸入 $sudo passwd pi,然后設(shè)置一個(gè)新密碼,請(qǐng)不要跳過(guò)這一步!
重復(fù)以上步驟
現(xiàn)在為其它的樹(shù)莓派重復(fù)上述步驟。
創(chuàng)建你的 Swarm 集群
登錄你的第一個(gè)樹(shù)莓派,然后輸入下面的命令:
- $ docker swarm init
 - Swarm initialized: current node (3ra7i5ldijsffjnmubmsfh767) is now a manager.
 - To add a worker to this swarm, run the following command:
 - docker swarm join \
 - --token SWMTKN-1-496mv9itb7584pzcddzj4zvzzfltgud8k75rvujopw15n3ehzu-af445b08359golnzhncbdj9o3 \
 - 192.168.0.79:2377
 
你會(huì)看到它顯示了一個(gè)口令,以及其它節(jié)點(diǎn)加入集群的命令。接下來(lái)使用 ssh 登錄每個(gè)樹(shù)莓派,運(yùn)行這個(gè)加入集群的命令。
等待連接完成后,在第一個(gè)樹(shù)莓派上查看集群的節(jié)點(diǎn):
- $ docker node ls
 - ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
 - 3ra7i5ldijsffjnmubmsfh767 * swarm1 Ready Active Leader
 - k9mom28s2kqxocfq1fo6ywu63 swarm3 Ready Active
 - y2p089bs174vmrlx30gc77h4o swarm4 Ready Active
 
恭喜你!你現(xiàn)在擁有一個(gè)樹(shù)莓派集群了!
更多關(guān)于集群的內(nèi)容
你可以看到三個(gè)節(jié)點(diǎn)啟動(dòng)運(yùn)行。這時(shí)只有一個(gè)節(jié)點(diǎn)是集群管理者。如果我們的管理節(jié)點(diǎn)死機(jī)了,集群就進(jìn)入了不可修復(fù)的狀態(tài)。我們可以通過(guò)添加冗余的管理節(jié)點(diǎn)解決這個(gè)問(wèn)題。而且它們依然會(huì)運(yùn)行工作負(fù)載,除非你明確設(shè)置了讓你的服務(wù)只運(yùn)作在工作節(jié)點(diǎn)上。
要把一個(gè)工作節(jié)點(diǎn)升級(jí)為管理節(jié)點(diǎn),只需要在其中一個(gè)管理節(jié)點(diǎn)上運(yùn)行 docker node promote <node_name> 命令。
注意: Swarm 命令,例如 docker service ls 或者 docker node ls 只能在管理節(jié)點(diǎn)上運(yùn)行。
想深入了解管理節(jié)點(diǎn)與工作節(jié)點(diǎn)如何保持一致性,可以查閱 Docker Swarm 管理指南。
OpenFaaS
現(xiàn)在我們繼續(xù)部署程序,讓我們的集群能夠運(yùn)行 Serverless 功能。OpenFaaS 是一個(gè)利用 Docker 在任何硬件或者云上讓任何進(jìn)程或者容器成為一個(gè) Serverless 功能的框架。因?yàn)?Docker 和 Golang 的可移植性,它也能很好地運(yùn)行在樹(shù)莓派上。
如果你支持 OpenFaaS,希望你能 星標(biāo) OpenFaaS 的 GitHub 倉(cāng)庫(kù)。
登錄你的第一個(gè)樹(shù)莓派(你運(yùn)行 docker swarm init 的節(jié)點(diǎn)),然后部署這個(gè)項(xiàng)目:
- $ git clone https://github.com/alexellis/faas/
 - $ cd faas
 - $ ./deploy_stack.armhf.sh
 - Creating network func_functions
 - Creating service func_gateway
 - Creating service func_prometheus
 - Creating service func_alertmanager
 - Creating service func_nodeinfo
 - Creating service func_markdown
 - Creating service func_wordcount
 - Creating service func_echoit
 
你的其它樹(shù)莓派會(huì)收到 Docer Swarm 的指令,開(kāi)始從網(wǎng)上拉取這個(gè) Docker 鏡像,并且解壓到 SD 卡上。這些工作會(huì)分布到各個(gè)節(jié)點(diǎn)上,所以沒(méi)有哪個(gè)節(jié)點(diǎn)產(chǎn)生過(guò)高的負(fù)載。
這個(gè)過(guò)程會(huì)持續(xù)幾分鐘,你可以用下面指令查看它的完成狀況:
- $ watch 'docker service ls'
 - ID NAME MODE REPLICAS IMAGE PORTS
 - 57ine9c10xhp func_wordcount replicated 1/1 functions/alpine:latest-armhf
 - d979zipx1gld func_prometheus replicated 1/1 alexellis2/prometheus-armhf:1.5.2 *:9090->9090/tcp
 - f9yvm0dddn47 func_echoit replicated 1/1 functions/alpine:latest-armhf
 - lhbk1fc2lobq func_markdown replicated 1/1 functions/markdownrender:latest-armhf
 - pj814yluzyyo func_alertmanager replicated 1/1 alexellis2/alertmanager-armhf:0.5.1 *:9093->9093/tcp
 - q4bet4xs10pk func_gateway replicated 1/1 functions/gateway-armhf:0.6.0 *:8080->8080/tcp
 - v9vsvx73pszz func_nodeinfo replicated 1/1 functions/nodeinfo:latest-armhf
 
我們希望看到每個(gè)服務(wù)都顯示 “1/1”。
你可以根據(jù)服務(wù)名查看該服務(wù)被調(diào)度到哪個(gè)樹(shù)莓派上:
- $ docker service ps func_markdown
 - ID IMAGE NODE STATE
 - func_markdown.1 functions/markdownrender:latest-armhf swarm4 Running
 
狀態(tài)一項(xiàng)應(yīng)該顯示 Running,如果它是 Pending,那么鏡像可能還在下載中。
在這時(shí),查看樹(shù)莓派的 IP 地址,然后在瀏覽器中訪問(wèn)它的 8080 端口:
- $ ifconfig
 
例如,如果你的 IP 地址是 192.168.0.100,那就訪問(wèn) http://192.168.0.100:8080 。
這是你會(huì)看到 FaaS UI(也叫 API 網(wǎng)關(guān))。這是你定義、測(cè)試、調(diào)用功能的地方。
點(diǎn)擊名稱(chēng)為 “func_markdown” 的 Markdown 轉(zhuǎn)換功能,輸入一些 Markdown(這是 Wikipedia 用來(lái)組織內(nèi)容的語(yǔ)言)文本。
然后點(diǎn)擊 “invoke”。你會(huì)看到調(diào)用計(jì)數(shù)增加,屏幕下方顯示功能調(diào)用的結(jié)果。
部署你的第一個(gè) Serverless 功能:
這一節(jié)的內(nèi)容已經(jīng)有相關(guān)的教程,但是我們需要幾個(gè)步驟來(lái)配置樹(shù)莓派。
獲取 FaaS-CLI
- $ curl -sSL cli.openfaas.com | sudo sh
 - armv7l
 - Getting package https://github.com/alexellis/faas-cli/releases/download/0.4.5-b/faas-cli-armhf
 
下載樣例
- $ git clone https://github.com/alexellis/faas-cli
 - $ cd faas-cli
 
為樹(shù)莓派修補(bǔ)樣例模版
我們臨時(shí)修改我們的模版,讓它們能在樹(shù)莓派上工作:
- $ cp template/node-armhf/Dockerfile template/node/
 - $ cp template/python-armhf/Dockerfile template/python/
 
這么做是因?yàn)闃?shù)莓派和我們平時(shí)關(guān)注的大多數(shù)計(jì)算機(jī)使用不一樣的處理器架構(gòu)。
了解 Docker 在樹(shù)莓派上的最新?tīng)顩r,請(qǐng)查閱: 你需要了解的五件事。
現(xiàn)在你可以跟著下面為 PC、筆記本和云端所寫(xiě)的教程操作,但我們?cè)跇?shù)莓派上要先運(yùn)行一些命令。
注意第 3 步:
- 把你的功能放到先前從 GitHub 下載的 faas-cli 文件夾中,而不是 ~/functinos/hello-python 里。
 - 同時(shí),在 stack.yml 文件中把 localhost 替換成第一個(gè)樹(shù)莓派的 IP 地址。
 
集群可能會(huì)花費(fèi)幾分鐘把 Serverless 功能下載到相關(guān)的樹(shù)莓派上。你可以用下面的命令查看你的服務(wù),確保副本一項(xiàng)顯示 “1/1”:
- $ watch 'docker service ls'
 - pv27thj5lftz hello-python replicated 1/1 alexellis2/faas-hello-python-armhf:latest
 
繼續(xù)閱讀教程: 使用 OpenFaaS 運(yùn)行你的第一個(gè) Serverless Python 功能
關(guān)于 Node.js 或者其它語(yǔ)言的更多信息,可以進(jìn)一步訪問(wèn) FaaS 倉(cāng)庫(kù)。
檢查功能的指標(biāo)
既然使用 Serverless,你也不想花時(shí)間監(jiān)控你的功能。幸運(yùn)的是,OpenFaaS 內(nèi)建了 Prometheus 指標(biāo)檢測(cè),這意味著你可以追蹤每個(gè)功能的運(yùn)行時(shí)長(zhǎng)和調(diào)用頻率。
指標(biāo)驅(qū)動(dòng)自動(dòng)伸縮
如果你給一個(gè)功能生成足夠的負(fù)載,OpenFaaS 將自動(dòng)擴(kuò)展你的功能;當(dāng)需求消失時(shí),你又會(huì)回到單一副本的狀態(tài)。
這個(gè)請(qǐng)求樣例你可以復(fù)制到瀏覽器中:
只要把 IP 地址改成你的即可。
- http://192.168.0.25:9090/graph?g0.range_input=15m&g0.stacked=1&g0.expr=rate(gateway_function_invocation_total%5B20s%5D)&g0.tab=0&g1.range_input=1h&g1.expr=gateway_service_count&g1.tab=0
 
這些請(qǐng)求使用 PromQL(Prometheus 請(qǐng)求語(yǔ)言)編寫(xiě)。第一個(gè)請(qǐng)求返回功能調(diào)用的頻率:
- rate(gateway_function_invocation_total[20s])
 
第二個(gè)請(qǐng)求顯示每個(gè)功能的副本數(shù)量,最開(kāi)始應(yīng)該是每個(gè)功能只有一個(gè)副本。
- gateway_service_count
 
如果你想觸發(fā)自動(dòng)擴(kuò)展,你可以在樹(shù)莓派上嘗試下面指令:
- $ while [ true ]; do curl -4 localhost:8080/function/func_echoit --data "hello world" ;
 - done
 
查看 Prometheus 的 “alerts” 頁(yè)面,可以知道你是否產(chǎn)生足夠的負(fù)載來(lái)觸發(fā)自動(dòng)擴(kuò)展。如果沒(méi)有,你可以嘗試在多個(gè)終端同時(shí)運(yùn)行上面的指令。
當(dāng)你降低負(fù)載,副本數(shù)量顯示在你的第二個(gè)圖表中,并且 gateway_service_count 指標(biāo)再次降回 1。
結(jié)束
我們現(xiàn)在配置好了 Docker、Swarm, 并且讓 OpenFaaS 運(yùn)行代碼,把樹(shù)莓派像大型計(jì)算機(jī)一樣使用。
你是如何搭建好了自己的 Docker Swarm 集群并且運(yùn)行 OpenFaaS 的呢?在 Twitter @alexellisuk 上分享你的照片或推文吧。
觀看我在 Dockercon 上關(guān)于 OpenFaaS 的視頻
我在 Austin 的 Dockercon 上展示了 OpenFaaS。——觀看介紹和互動(dòng)例子的視頻: https://www.youtube.com/embed/-h2VTE9WnZs
有問(wèn)題?在下面的評(píng)論中提出,或者給我發(fā)郵件,邀請(qǐng)我進(jìn)入你和志同道合者討論樹(shù)莓派、Docker、Serverless 的 Slack channel。
想要學(xué)習(xí)更多關(guān)于樹(shù)莓派上運(yùn)行 Docker 的內(nèi)容?
我建議從 你需要了解的五件事 開(kāi)始,它包含了安全性、樹(shù)莓派和普通 PC 間微妙差別等話(huà)題。






















 
 
 




 
 
 
 