天天看點

開發函數計算的正确姿勢——使用互動模式安裝依賴

原文作者:倚賢 原文連結 更多雲原生技術資訊可關注 阿裡巴巴雲原生技術圈

前言

首先介紹下在本文出現的幾個比較重要的概念:

函數計算(Function Compute): 函數計算是一個事件驅動的服務,通過函數計算,使用者無需管理伺服器等運作情況,隻需編寫代碼并上傳。函數計算準備計算資源,并以彈性伸縮的方式運作使用者代碼,而使用者隻需根據實際代碼運作所消耗的資源進行付費。函數計算更多資訊 參考

Fun: Fun 是一個用于支援 Serverless 應用部署的工具,能幫助您便捷地管理函數計算、API 網關、日志服務等資源。它通過一個資源配置檔案(template.yml),協助您進行開發、建構、部署操作。Fun 的更多文檔

備注: 本文介紹的技巧需要 Fun 版本大于等于 3.0.0-beta.1 。

依賴工具

本項目是在 MacOS 下開發的,涉及到的工具是平台無關的,對于 Linux 和 Windows 桌面系統應該也同樣适用。在開始本例之前請確定如下工具已經正确的安裝,更新到最新版本,并進行正确的配置。

Fun 和 Fcli 工具依賴于 docker 來模拟本地環境。

對于 MacOS 使用者可以使用

homebrew

進行安裝:

brew cask install docker
brew tap vangie/formula
brew install fun           

Windows 和 Linux 使用者安裝請參考:

  1. https://github.com/aliyun/fun/blob/master/docs/usage/installation.md

安裝好後,記得先執行

fun config

初始化一下配置。

注意, 如果你已經安裝過了 fun,確定 fun 的版本在 3.0.0-beta.1 以上。

$ fun --version
3.0.0-beta.1           

背景

函數計算以 Zip 壓縮檔案格式作為約定的傳遞物,傳遞物通常包含代碼和依賴庫檔案。這些依賴庫檔案通常分為系統依賴(使用 apt-get 包管理安裝的庫)和語言運作時依賴(使用語言相關的包管理器如 npm、pip 安裝的庫)。

系統依賴通常不可移植

通常情況下系統依賴和環境相關,比如我們希望在函數裡調用 brotli 指令解壓檔案,如果我們在開發機 mac 上,使用

brew install brotli

安裝了 brotil 指令,然後打包釋出到函數計算平台是無法運作的。有時候即使開發機是 linux 也不一定可以。這是因為通過系統提供的包管理工具安裝的可執行程式和動态連結庫與系統的類型和版本強相關。不同系統上安裝的這些程式和檔案不具備可移植性。

語言依賴也存在不可移植的情況

通常情況下語言依賴是平台無關的,比如說使用

npm install jszip

安裝一個 nodejs 依賴,該依賴可以運作在不同的作業系統和不同的 nodejs 版本下。語言平台上的依賴通常是可移植的,單也有例外的情況。如:

npm install node-pty

就是一個存在原生綁定(native binding)的例子。node-pty 子產品安裝過程中,依賴一些 c/c++ 代碼,這些代碼會在安裝的過程中進行編譯,我們知道 c/c++ 代碼雖然也具備平台移植性,但是其編譯産物是不可移植的。

DSL 腳本的不足

Fun 2.0 版本支援依賴安裝 DSL 檔案 fun.yml,fun.yml 為依賴安裝提供了批量模式。日常開發提供了一種指令模式,如:

fun install --package-type pip tensorflow

。在 Fun 3.0 中我們提供了一種全新的 DSL 檔案 Funfile。Funfile 可以了解為 Dockerfile 的文法子集,讓熟悉 docker 的開發者可以快速上手。

但是無論是 fun.yml 或 Funfile,以及指令模式,對于開發者都有一個痛點。那就是不知道環境裡目前的狀态:

  1. 已經安裝的軟體有哪些
  2. 某個目錄下有些什麼檔案
  3. 檔案的内容以及屬性是什麼

開發者需要可以互動的沙箱環境。該功能在 Fun 2.0 中沒有,使用者常常使用

fcli sbox

指令作為替代,或者直接使用

fc-docker

項目提供的鏡像啟動一個 container。

docker run --rm -it -v $(pwd):/code aliyunfc/runtime-python2.7:build bash

但是這些複雜的指令和參數需要使用者具備足夠的 docker 背景知識以及對函數計算工作原理的了解。

為了更好的解決上述問題,提升使用者的開發體驗,我們在 Fun 3.0 中提供了

fun install sbox

子指令。

開發函數計算的正确姿勢——使用互動模式安裝依賴

指令行參數

$ fun install sbox --help
Usage: fun install sbox [-f|--function <[service/]function>] [-r|--runtime <runtime>] [-i|--interactive] [-e|--env key=val ...] [-e|--cmd <cmd>]
Start a local sandbox for installation dependencies or configuration
Options:
  -f, --function <[service/]function>  Specify which function to execute installation task.
  -r, --runtime <runtime>              function runtime, avaliable choice is: nodejs6, nodejs8, nodejs10, python2.7, python3, java8, php7.2, custom
  -i, --interactive                    run as interactive mode. Keep STDIN open and allocate a pseudo-TTY when in a interactive shell. (default: false)
  -e, --env <env>                      environment variable, ex. -e PATH=/code/bin (default: [])
  -c, --cmd <cmd>                      command with arguments to execute inside the installation sandbox.
  -h, --help                           output usage information           

快速開始

下面以項目

pyzbar_example 為例, pyzbar_example 項目包含如下檔案

$  tree .             
.
├── fun.yml
├── index.py
├── qrcode.png
└── template.yml
0 directories, 4 files           

其中 template.yml 檔案内容如下

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
 pyzbar-srv:
   Type: 'Aliyun::Serverless::Service'
   pyzbar-fun:
     Type: 'Aliyun::Serverless::Function'
     Properties:
       Handler: index.handler
       Runtime: python3
       Timeout: 60
       MemorySize: 128
       CodeUri: .           

啟動互動模式 sbox

$ fun install sbox -f pyzbar-fun -i
using template: template.yml
root@fc-python3:/code# ls
fun.yml  index.py  qrcode.png  template.yml
root@fc-python3:/code# exit
exit
$           

在 template.yml 所在的項目目錄執行 fun install sbox,其中參數

  • -f/--function 參數指定啟動 sbox 的函數,本例中函數所設定的 runtime 為 python3,是以 python3 環境的沙箱環境會被啟動起來,函數 pyzbar-fun 所對應的 CodeUri 目錄會被挂載到沙箱環境内部的 /code 目錄,上面例子中在沙箱環境内 ls 指令傳回的檔案清單證明了這一點。
  • -i/--interactive 參數表示啟動互動模式,對應非互動模式的用途可以看後面的示例。

如果 template.yml 檔案并不存在,或者 template.yml 配置檔案内的函數尚未配置可以 使用 --runtime 參數啟動互動模式,此時目前目錄會被挂載到沙箱環境的 /code 目錄。

$ fun install sbox -r nodejs10 -i                                               
root@fc-nodejs10:/code# ls
fun.yml  index.py  qrcode.png  template.yml
root@fc-nodejs10:/code# exit
exit
$           

上面的方法适用于臨時啟動一個 sbox 做些動手實驗的場景。

使用 fun-install 安裝 apt 和 pip 依賴

$ fun install sbox -f pyzbar-fun -i          
using template: template.yml
root@fc-python3:/code# fun-install apt-get install libblas3
Task => [UNNAMED]
     => apt-get update (if need)
     => apt-get install -y -d -o=dir::cache=/code/.fun/tmp libblas3
     => bash -c 
        for f in $(ls /code/.fun/tmp/archives/*.deb); do
          dpkg -x $f /code/.fun/root; 
          mkdir -p /code/.fun/tmp/deb-control/${f%.*}; 
          dpkg -e $f /code/.fun/tmp/deb-control/${f%.*}; 
          if [ -f "/code/.fun/tmp/deb-control/${f%.*}/postinst" ]; then 
            FUN_INSTALL_LOCAL=true /code/.fun/tmp/deb-control/${f%.*}/postinst configure;
          fi; 
        done;
     => bash -c 'rm -rf /code/.fun/tmp/archives'
root@fc-python3:/code# fun-install --help
Usage: fun local [options] [command]
build function codes or install related depedencies for Function Compute
Options:
  -h, --help  output usage information
Commands:
  apt-get     install apt depencies
  pip         install pip depencies
  build       build function codes for Function Compute
  help [cmd]  display help for [cmd]           

非互動模式下使用 sbox

使用如下一行指令列印出 pyzbar-fun 函數的 sbox 内預裝的 deb 包。

$ fun install sbox -f pyzbar-fun -c 'dpkg -l'
using template: template.yml
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                               Version                          Architecture Description
+++-==================================-================================-============-===============================================================================
ii  acl                                2.2.52-2                         amd64        Access control list utilities
ii  adduser                            3.113+nmu3                       all          add and remove users and groups
ii  apt                                1.0.9.8.4                        amd64        commandline package manager
ii  apt-utils                          1.0.9.8.5                        amd64        package management related utility programs
ii  autoconf                           2.69-8                           all          automatic configure script builder
ii  automake                           1:1.14.1-4+deb8u1                all          Tool for generating GNU Standards-compliant Makefiles
...(此處省略了許多行)           

也可以通過管道将外部指令的内容傳遞到内部

$  echo hello | fun install sbox -r nodejs10  -i -c 'cat -'
hello           

注意這裡

-i

參數不能省略,該參數表示接受标準輸入。

小結

fun install sbox 是 fcli sbox 的替代工具,除了支援互動模式,沿用了指定 runtime 啟動 sbox,也實作了 fun 風格的指定函數啟動 sbox,更加便利。同時也支援内聯指令和管道等非互動模式的用法,為編寫腳本提供了更好的支援。

阿裡巴巴雲原生 關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的技術圈。”