[Cloud] Fn Hot Docker Functions

原文はこちら。
https://medium.com/fnproject/fn-hot-docker-functions-e02d15033392

理想的には、Fn functionは「ホット」(Cold Startが不要ですぐに動き出せる状態)であるべきです。
Fn Project
http://fnproject.io/
hot functionであれば、関数コンテナの始動後生存し続けて、一連の関数呼び出しを処理しようとします。hot functionがすばらしいのは、コンテナ始動のコストが大きいからです。Fnサーバーは、イメージがローカルにキャッシュされていない場合はリポジトリからイメージをプルし、コンテナを起動し、通常はコンテナ内で言語ランタイムをブートしてから関数呼び出しの処理を開始します。hot functionを使用すると、これらの「コールドスタート」(プル/スタート/ブート)のコストは最初の起動時に支払うだけですみます。後続の呼び出しでのレイテンシは劇的に少なくなります。だから、自然とhot functionを常にデプロイすべきと考えますよね。残念ながら、functionとしてDockerコンテナをデプロイする場合はそれほど簡単ではありませんが、手はあります。

Fn Function Development Kits(FDKs)を使用している場合、hot functionは簡単です。 実際には、おそらくFDKを使用していて、あなたのfunctionがhotかどうかに考えが及んでいなかったかと思います。アプリケーションにFDKライブラリを含め、ハンドラfunction(またはメソッド)を書き、ハンドラをFDKに渡しました。 コンテナが生きている状態で、FDKが関数の呼び出しをリッスンするリクエスト・ループを提供しているという事実はですが、実のところそうなっています。

FDKを使っていない場合、functionをデフォルト(つまりhotではない)コンテナ・コントラクトで実行しています。デフォルトの場合、コンテナは各functionの呼び出しで開始され、入力を標準入力(stdin)でコンテナに渡し、レスポンスを標準出力(stdout)から読み取り、その後シャットダウンされます。動作しますが、hot functionの低レイテンシでのレスポンスは提供しません。


Hot Docker

FDKによる人気のある言語のサポートに加え、FnはfunctionとしてDockerコンテナのデプロイをサポートします。これは他の多くのFunction-as-a-Serviceプラットフォームと比較した場合の大きな差別化要因です。Fnでは、コンテナがサポートされているコンテナ・コントラクトのいずれかを実装している限り、functionとして任意のものをデプロイできます。幸いにも、デフォルトのstdin/stdoutコンテナ・コントラクトをカスタムのコンテナ化されたfunctionに簡単に組み入れることができます。たとえば、コンテナイメージとしてNode.jsプログラムをパッケージ化するDockerfileがあるとします。これをfunctionとしてFnにデプロイできます。

(注意)この例は説明目的にすぎません。実際には、最適なNode.jsのパフォーマンスのためにはFn Node FDKを使うべきです(訳注:2018/10/10現在Experimentalのようです)。
Experimental FDK for Node.js
https://github.com/fnproject/fdk-node
func.js
name = "World";
fs = require('fs');
try {
  input = fs.readFileSync('/dev/stdin').toString();
  if (input) {
    name = input;
  }
} catch(e) {}
console.log("Hello", name, "from Node!");
Node.js default container contract Dockerfile
FROM node:8-alpine

WORKDIR /function

ADD func.js /function/func.js

ENTRYPOINT ["node", "./func.js"]
func.yaml ファイルとfn buildで、このfunctionをビルドできますが、(コンテナ・コントラクト)formatdefaultruntimejavanodeといったFnでサポートされている言語ではなく、dockerを設定することに注意してください。
default docker func.yaml
schema_version: 20180708
name: hello
version: 0.0.1
runtime: docker
format: default
これらの3ファイルを使い、デフォルトのコンテナ・コントラクトのfunctionをデプロイできるのですが、このfunctionはhot functionの場合に比べてレイテンシが小さくなりません。というのも、各呼び出しで、コンテナとNode.jsランタイムの起動コストが必要だからです。ローカルのFnサーバーにデプロイしてこのfunctionをtimeコマンドを付けて起動すると、約1.3秒のレスポンス時間があることがわかります。かなり悪い結果ですが、MacBook上でDockerコンテナを起動しているので、これぐらいの時間がかかるのも無理はありません。

“Hotwrap” Prototype

このコードをhot functionとして実行できれば、ずっといいですね。幸運なことに、FDKを使わないfunctionをhot functionとして簡単にデプロイするために、 コードネーム "hotwrap" というプロトタイプユーティリティを現在開発しています。
hotwrap - Command wrapper that lets you run unix commands as functions
https://github.com/fnproject/hotwrap
Hotwrapはhot functionのコンテナ・コントラクトを実装し、functionが呼び出されるたびに標準入出力ベースのfunctionを実行します。Hotwrapを使用すればfunctionコンテナは生存し続けるので、コンテナの起動コストを回避できます。ただし、各呼び出しで実行可能なfunctionを起動するためのコストはかかります。

hotwrapを使うには、コンテナのENTRYPOINTとしてhotwrapを実行可能にして、実行可能なfunctionを起動するためにCMDを設定するだけです。以下のDockerfileは、先述のNode.jsのサンプルコードに対してhotwrapを追加するために必要な変更を加えたものです。

(注意)この例はマルチステージDocker buildを使ってDockerイメージから実行可能なhotwrapを取得していますが、このイメージはまだDocker Hubには公開されていません。このイメージをGitHubに上がっているソースからビルドできます。
Dockerfile with hotwrap
# Pull the hotwrap container  as a build dependency
FROM fnproject/hotwrap:latest as hotwrap

# Start of your normal docker file
FROM node:8-alpine

WORKDIR /function

# Add function implementation
ADD func.js /function/func.js
CMD node ./func.js

# Install hotwrap binary in your container
COPY --from=hotwrap /hotwrap /hotwrap
ENTRYPOINT ["/hotwrap"]
アップデートしたDockerファイルを使って、Node.jsのfunctionを再デプロイして、再度timeコマンドを使って計測します。最初の呼び出しでは、functionの実行に0.775秒要しました。この時間には、コンテナとNode.jsの開始コストが含まれています。その後の呼び出しでは、約0.2秒と約0.5秒速くなりました。hotwrapのおかげで、Node.jsランタイムを起動しコードを実行するだけのコストで済みます。

The future of Hotwrap

Hotwrapはプロトタイプなので、本番環境では使用しないでください!とはいえ、元々はfunctionとして作成されていなかったプログラムをパッケージ化し、そのランタイム・パフォーマンスを向上する、Fnで提供するしくみの実現可能性およびその価値をHotwrapは示しています。FnではfunctionとしてDockerコンテナのデプロイをサポートしてきましたが、これらのfunctionではデフォルトのコンテナ・コントラクトを使う関係上、レイテンシが大きくなりました。Hotwrapはこの差異をある程度解決するものです。近い将来の公式なhotwrapユーティリティ(たぶん名前は変わると思います)の登場をお待ちください。
hotwrapを開発してくれたOwen Cliffeに感謝いたします。

0 件のコメント:

コメントを投稿