プライベートな AWS Lambda が欲しくて OpenFaaS を (swarm で) 試した

近々、自前 FaaS で、システムを構築するという構想のため、OpenFaaS を試した。

## OpenFaaS 起動

ほぼ、[ココ](https://kuroeveryday.blogspot.com/2018/05/build-faas-environment-and-experience-serverless.html) のまま。

```shell
docker swarm init

git clone https://github.com/openfaas/faas
cd faas

./deploy_stack.sh
```
- サーバが立ち上がって、Basic認証の user と password が表示されるのでチェック。
- `deploy_stack.sh` の中を見ると、 `docker stack deploy func --compose-file docker-compose.yml` を最後で呼んでる。
- Basic 認証が有効らしい `export BASIC_AUTH="true"` 
- Basic 認証の情報が出力される `echo "[Credentials]\n username: admin \n password: $secret\n echo -n "$secret" | faas-cli login --username=admin --password-stdin"`

Basic 認証の情報はこんな感じに出力される。メモっとく。ブラウザで管理画面へアクセスする時や、デプロイ時に必要。

```
[Credentials]
 username: admin
 password: 9c6208072a2389f1a9451c7fefbd2545e39bdf0a1d6cad5fd83d84f045fae173
 echo -n 9c6208072a2389f1a9451c7fefbd2545e39bdf0a1d6cad5fd83d84f045fae173 | faas-cli login --username=admin --password-stdin
```

`docker ps` 叩くとこんな感じ。

```
CONTAINER ID        IMAGE                         COMMAND                  CREATED              STATUS              PORTS                NAMES
98d484de2d2a        openfaas/faas-swarm:0.4.4     "./faas-swarm"           50 seconds ago       Up 49 seconds       8080/tcp             func_faas-swarm.1.un383dnfpqk1h5cd2c7bdn7co
62a944864920        openfaas/gateway:0.9.10       "./gateway"              54 seconds ago       Up 53 seconds       8080/tcp             func_gateway.1.iqgnmze692cleburpvw5jh9pc
fcfbcd09c3bd        prom/alertmanager:v0.15.0     "/bin/alertmanager -…"   58 seconds ago       Up 57 seconds       9093/tcp             func_alertmanager.1.04pes9jdabhxm9w8aapdxf2z4
eea4efca8daa        prom/prometheus:v2.3.1        "/bin/prometheus --c…"   About a minute ago   Up About a minute   9090/tcp             func_prometheus.1.bwl1j63bjmxv7ixl25j99ez3n
dc8c546038ef        openfaas/queue-worker:0.5.4   "./app"                  About a minute ago   Up About a minute   8080/tcp             func_queue-worker.1.nnlvo3ixpc5rf5f65hzhdb2qh
893e162a290f        nats-streaming:0.11.2         "/nats-streaming-ser…"   About a minute ago   Up About a minute   4222/tcp, 8222/tcp   func_nats.1.g33o99phxe0gx3ubt4625ih57
``` 

ブラウザで http://localhost:8080 にアクセスすると。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201797/3bcd991d-68b6-5382-06b3-bd7fddb12f36.png)

## OpenFaaS の CLI インストール

```
curl -sSL https://cli.openfaas.com | sh
```

上記のコマンドインストールを行うと、以下のように言われた。（Mac の一般ユーザで実行時）
ので、言われるがままに2つのコマンドを実行。

```
=========================================================
==    As the script was run as a non-root user the     ==
==    following commands may need to be run manually   ==
=========================================================

  sudo cp faas-cli-darwin /usr/local/bin/faas-cli
  sudo ln -sf /usr/local/bin/faas-cli /usr/local/bin/faas
```

`faas-cli version` でバージョン確認。

```
  ___                   _____           ____
 / _ \ _ __   ___ _ __ |  ___|_ _  __ _/ ___|
| | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \
| |_| | |_) |  __/ | | |  _| (_| | (_| |___) |
 \___/| .__/ \___|_| |_|_|  \__,_|\__,_|____/
      |_|

CLI:
 commit:  b24c5763d9b61e0c04018a722f8f2f765498f18a
 version: 0.7.8
```

faas-cli の help

```
Manage your OpenFaaS functions from the command line

Usage:
  faas-cli [flags]
  faas-cli [command]

Available Commands:
  build          Builds OpenFaaS function containers
  cloud          OpenFaaS Cloud commands
  deploy         Deploy OpenFaaS functions
  describe       Describe an OpenFaaS function
  generate       Generate Kubernetes CRD YAML file
  help           Help about any command
  invoke         Invoke an OpenFaaS function
  list           List OpenFaaS functions
  login          Log in to OpenFaaS gateway
  logout         Log out from OpenFaaS gateway
  new            Create a new template in the current folder with the name given as name
  push           Push OpenFaaS functions to remote registry (Docker Hub)
  remove         Remove deployed OpenFaaS functions
  store          OpenFaaS store commands
  template       Downloads templates from the specified github repo
  up             Builds, pushes and deploys OpenFaaS function containers
  version        Display the clients version information

Flags:
      --filter string   Wildcard to match with function names in YAML file
  -h, --help            help for faas-cli
      --regex string    Regex to match with function names in YAML file
  -f, --yaml string     Path to YAML file describing function(s)

Use "faas-cli [command] --help" for more information about a command.
```

## Function 作成

Function 管理用のディレクトリを作る。

```
mkdir functions
cd functions
```

### 新規 Function

- - -
💡 _追記_
_ただ試すだけなら、_

- _`faas-cli new` の `--prefix localhost:5000` はいらない_
- _Docker Registry もいらない_
- _`faas-cli push` もいらない_
- _`faas-cli build` の `--tag latest` はいらない_
- _`new` して `build` して、 OpenFaaS へのログインと `deploy` すればいい_

それだけだった。他にもいろいろ勘違いしていそう。
- - -

node の Function を作成。今回は、Private Docker Registry を利用するので `--prefix` の指定が重要。

```
faas-cli new hello-openfaas --lang node --prefix localhost:5000
```

`tree` コマンドで構成を見てみる。

```
.
├── hello-openfaas
│   ├── handler.js
│   └── package.json
├── hello-openfaas.yml
└── template
```

`cat hello-openfaas.yml` は。

```yaml
provider:
  name: faas
  gateway: http://127.0.0.1:8080
functions:
  hello-openfaas:
    lang: node
    handler: ./hello-openfaas
    image: hello-openfaas:latest
```

`cat hello-openfaas/handler.js` は。

```js
"use strict"

module.exports = (context, callback) => {
    callback(undefined, {status: "done"});
}
```

`cat hello-openfaas/package.json` は。

```json
{
  "name": "function",
  "version": "1.0.0",
  "description": "",
  "main": "handler.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```


`faas-cli new` で指定できる `node` 以外のテンプレートを確認してみる。

```
faas-cli template pull
faas-cli new --list
```

その結果は。（2018-11-12 時点）

```
Languages available as templates:
- csharp
- dockerfile
- go
- go-armhf
- java8
- node
- node-arm64
- node-armhf
- php7
- python
- python-armhf
- python3
- python3-armhf
- ruby
```

### Docker Registry 用意

下記コマンドは、永続性とか考えてない。お試し用。

```
docker run -d -p 5000:5000 --name registry registry:latest
```

### Docker Image 作成

```
faas-cli build -f hello-openfaas.yml --tag latest
```

`docker image ls` で確認。

```
REPOSITORY                      TAG                    IMAGE ID            CREATED              SIZE
localhost:5000/hello-openfaas   latest                 bd1a24eefc35        About a minute ago   72.2MB
```

### Docker Image を Registry に Push

```
faas-cli push -f hello-openfaas.yml --tag latest
```

### OpenFaaS へデプロイ

`./deploy_stack.sh` 実行時に表示された `echo` から始まるコマンドを実行し、OpenFaaS へログインする。

```
echo -n 9c6208072a2389f1a9451c7fefbd2545e39bdf0a1d6cad5fd83d84f045fae173 | faas-cli login --username=admin --password-stdin
```

デプロイ〜

```
faas-cli deploy -f hello-openfaas.yml
```

ブラウザで http://localhost:8080 へアクセスすると、画面左側に `hello-openfaas` が増えてるので、それを選択すると、画面右側に情報が表示される。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201797/247bca8c-1352-e93f-08df-24c1f9e1ab2e.png)

`INVOKE` ボタンを押せば、Function が実行され、Response body に結果が表示される。
URL にブラウザでアクセスしても良い。

### Function の削除

```
faas-cli remove -f hello-openfaas.yml
```

画面上のゴミ箱でも削除できる。

## 掃除

掃除の仕方は、もっと良い方法があるかも。

```shell
# サーバをダウンする
docker stack rm func
docker rm -f registry

# docker secret の削除
docker secret rm basic-auth-user
docker secret rm basic-auth-password

# docker image の削除
docker rmi localhost:5000/hello-openfaas
```

## 所感

いい感じだ。
システム作るなら kubernetes の cluster で構築かな。
kubernetes を構築したことないけど。
Fargate で OpenFaaS ？ これは気になる。 https://github.com/ewilde/faas-fargate
AWS 公式で EKS にデプロイする方法？ 気になる。 https://aws.amazon.com/jp/blogs/opensource/deploy-openfaas-aws-eks/