一番楽な方法でOpenFaaSチュートリアルしてみる

# きっかけ
Rancher Meetup Tokyo #11( https://rancherjp.connpass.com/event/68806/ ) に参加した際、OpenFaaSというオープンソースなFaaS基盤が紹介されていた。
導入は簡単らしいので、試してみる。

参考資料
https://speakerdeck.com/player/a594805a003d40eeb50e7b37b9e80021#
https://www.slideshare.net/ukitiyan/openfaas-on-rancher-java

# OpenFaaSって何？
分かりやすくいってしまえば、Amazon Lambda＋API Gatewayと同じ機能を提供するオープンソースソフトウェア
※機能を模倣しているわけではないので、正確ではない
Docker SwarmおよびK8sをベースに動作する

各クラウド事業者が提供するマネージドサービスにロックインする事が無いため、マルチクラウド時代を見据えたFaaS基盤、という位置づけ（だと思う）

## コンポーネント
関数事にDockerコンテナを作成、Docker SwarmないしK8sで管理できる。

API Gateway: 動作を受け付けるゲートウェイ
Function Watchdog: 各関数のコンテナの入出力を制御するデーモン
Prometheus: 各関数コンテナのメトリックを取得、可視化

# TestDriveする
https://github.com/openfaas/faas/blob/master/TestDrive.md

まずは一番楽な方法がいい、、ということでdocker playgroudで試す。

# OpenFaaSスタックのインストール
下記を実行。楽ちん

```
# docker swarm init --advertise-addr eth0 && \
  git clone https://github.com/openfaas/faas && \
  cd faas && \
  git checkout 0.6.7 && \
  ./deploy_stack.sh && \
  docker service ls
```

CLIインストール
$ curl -sL cli.openfaas.com | sh

CLIのヘルプ
$ faas-cli --help

CLIでサンプル関数（マークダウンtoHTML）を実行:
$ echo "# Test *Drive*"| faas-cli invoke func_markdown

登録されている関数をリスト
$ faas-cli list

# Pythonの関数をデプロイする
https://blog.alexellis.io/first-faas-python-function/

## CLIでセットアップ
$ faas-cli new --lang python <関数名>

## ソースコード作成
<関数名>/handler.py に実行する処理を記述
def handle(req):  
    print("Hello! You said: " + req)

<関数名>.ymlに実行環境を記述
provider:  
  name: faas
  gateway: http://localhost:8080 # ゲートウェイのURL。必要であれば、リモートを指定すること。

functions:  # この中に指定する実行環境を記述
  hello-python:
    lang: python # どの言語を使うか？
    handler: ./hello-python # ハンドラ関数や他のコードのパスを指定
    image: hello-python # Dockerイメージ名。もしDockerHubを利用する場合は、DockerHubアカウントを前につけること。

## 関数をビルド
faas-cli build -f ./hello-python.yml

イメージ一覧を表示
docker images | grep hello-python

マルチノードクラスタの場合、
イメージをリモートのレジストリへpushする
Docker Hubを使う場合は、image: でDocker Hubアカウント名をつけておき、下記を実行
$ faas-cli push -f ./hello-python.yml
※ --parallelを指定すると、複数関数をプッシュする時、早くなる（らしい）

## デプロイ
faas-cli deploy -f ./hello-python.yml

関数一覧を確認
faas-cli list

curlで試す
curl localhost:8080/function/hello-python -d "it's Alex here"

CLIで試す
echo "Hello!" | faas-cli invoke hello-python

## 標準以外のライブラリを読み込みたい場合
<関数名>/requirements.txt に記述
handler.pyでimport
ビルド、デプロイ

## ロギング、トラブルシューティング
デプロイされているかどうか？
$ docker service ls

関数のコンテナについて確認
docker service ps <function_name_here>  

関数のコンテナのログを確認
docker service logs <function_name_here>  
※ ログが多い場合、--tail <N> オプションをつけて確認。-fをつければ、標準出力へ流しっぱなしにできる

メトリック
Prometheusのコンテナが組み込まれているので、そこで確認可能。

トラブルシューティング
「Can't reach service」のようなエラーが出る場合、下記を確認
- マルチノードクラスタであれば、デプロイ前に、Docker Hubなどのレジストリへpushすること
- docker service logs --no-trunc=true でより詳細なログを見てみる
- 再デプロイしてみる。

# 気になる
## 現状、どの言語が使える？
$ fass-cli new --list
で確認可能

- Node.js
- Python(Python 2)
- Python 3
- Ruby
- C#
- Go
- Dockerfile

Goでのデプロイ例
https://blog.alexellis.io/serverless-golang-with-openfaas/

## OpenFaaSはWindows系OSでも動く？
明確な記述は見つけられなかったが、インストール方法などが公表されていないため、恐らく現時点（2017/11/19）では不可。

# Docker Swarmとk8sの違い
https://blog.alexellis.io/you-need-to-know-kubernetes-and-swarm/

## 対象システム
Docker Swarm:
小規模向け(IoTデバイス上でも動く)

K8s:
大規模向け

## クラスタリング
Docker Swarm:
構成は独自形式で記述
Serviceという単位でクラスタリング、一つ一つのコンテナはtask

K8s:
構成はYAML形式で記述
deploymentという単位でクラスタリング
Podという単位で複数コンテナをグルーピング（同じディスクボリュームを共有する）

## CLI
Docker Swarm:
DockerのCLIに組み込まれてる
docker swarm COMMAND
docker service COMMAND
直接マスターのコンテナを操作する形

K8s:
kubectlを使用（DebianベースのOSで利用可能
kubectlはクラスタ、Deployment管理のみ行う。
クラスタ作成はサードパーティ製ツールを使う。kops,GKE,kubeadmなど

## ホスト間ネットワーク
Docker Swarm:
オーバーレイネットワークがデフォルトで使用される。
更に、macvlanによる設定や、他のベンダが出しているドライバも利用可
https://docs.docker.com/engine/swarm/networking/#create-an-overlay-network

K8s:
デフォルトでは組み込まれていないため、サードパーティ製のものを使う。
CoreOS Flannelなど

## API/Integration
Docker Swarm:
mobyプロジェクトの中で作成されている

K8s:
プロジェクト公式のGo製クライアントがGithu上にある。

## スケール
Docker Swarm:
明確な上限は公表されていない。
2000～以上のノードで動いた実例あり。
現在、3000～以上のノードで動かすプロジェクトが動いており、すでに目標数は突破済み
https://github.com/swarmzilla/swarm3k

K8s:
公式な値で5000クラスタノードまで(v1.8の場合)とされる。
https://kubernetes.io/docs/admin/cluster-large/