Ubuntu 16.04でDocker Swarmを使用してOpenFaaSをインストールして保護する方法

著者は、Write for DOnationsプログラムの一部として寄付を受け取るためにDiversity in Tech Fundを選択しました。

前書き

サーバーレスアーキテクチャは、サーバーインスタンスを開発者から隠し、通常、開発者がクラウドでアプリケーションを実行できるようにするAPIを公開します。 このアプローチにより、開発者は適切なDevOpsチームにインスタンスのプロビジョニングとメンテナンスを任せることができるため、アプリケーションを迅速に展開できます。 また、適切なツールを使用して、要求ごとにインスタンスをスケーリングできるため、インフラストラクチャコストも削減されます。

サーバーレスプラットフォームで実行されるアプリケーションは、serverless functionsと呼ばれます。 関数は、特定の操作を実行するために使用されるコンテナー化された実行可能コードです。 アプリケーションをコンテナ化することで、多くのマシンで一貫した環境を再現でき、更新とスケーリングが可能になります。

OpenFaaSは、サーバーレス機能を構築およびホストするための無料のオープンソースフレームワークです。 Docker SwarmKubernetesの両方が公式にサポートされているため、強力なAPI、コマンドラインインターフェイス、またはWebUIを使用してアプリケーションをデプロイできます。 Prometheusによって提供される組み込みのメトリックが付属しており、ゼロからのスケーリングだけでなく、オンデマンドの自動スケーリングもサポートしています。

このチュートリアルでは、Ubuntu16.04で実行されているDockerSwarmでOpenFaaSを設定して使用し、Let’s EncyptTraefikを設定してWebUIとAPIを保護します。 これにより、クラスター内のノード間、およびOpenFaaSとそのオペレーター間の安全な通信が保証されます。

前提条件

このチュートリアルに従うには、次のものが必要です。

  • ローカルマシンで実行されているUbuntu 16.04。 他のディストリビューションおよびオペレーティングシステムを使用できますが、オペレーティングシステムに適切なOpenFaaSスクリプトを使用し、これらの前提条件にリストされているすべての依存関係をインストールしてください。

  • ローカルマシンにインストールされているgitcurl、およびjqgitを使用してOpenFaaSリポジトリのクローンを作成し、curlを使用してAPIをテストし、jqを使用して生のJSON応答をAPIから人間が読めるJSONに変換します。 このセットアップに必要な依存関係をインストールするには、次のコマンドを使用します:sudo apt-get update && sudo apt-get install git curl jq

  • How To Install and Use Docker on Ubuntu 16.04のステップ1と2に従って、Dockerがインストールされました。

  • Docker Hubアカウント。 OpenFaaSに機能を展開するには、パブリックコンテナーレジストリに公開する必要があります。 このチュートリアルでは、無料で広く使用されているDocker Hubを使用します。 必ずdocker loginコマンドを使用して、ローカルマシン上のDockerで認証してください。

  • How To Provision and Manage Remote Docker Hosts with Docker Machine on Ubuntu 16.04に続いて、Docker Machineがインストールされました。

  • DigitalOceanの個人アクセストークン。 トークンを作成するには、these instructionsに従います。

  • 次のHow to Create a Cluster of Docker Containers with Docker Swarm and DigitalOcean on Ubuntu 16.04によってプロビジョニングされた3ノードのDockerSwarmクラスター。

  • Docker Swarmのインスタンスの1つを指すAレコードを持つ完全に登録されたドメイン名。 チュートリアル全体を通して、ドメインの例としてexample.comが表示されます。 これを独自のドメインに置き換える必要があります。このドメインは、Namecheapで購入するか、Freenomで無料で入手できます。 選択した別のドメインレジストラーを使用することもできます。

[[step-1 -—- downloading-openfaas-and-installing-the-openfaas-cli]] ==ステップ1—OpenFaaSのダウンロードとOpenFaaSCLIのインストール

OpenFaaSをDocker Swarmにデプロイするには、デプロイマニフェストとスクリプトをダウンロードする必要があります。 それらを取得する最も簡単な方法は、公式のOpenFaasリポジトリのクローンを作成し、OpenFaaSリリースを表す適切なタグをチェックアウトすることです。

リポジトリのクローンに加えて、FaaS CLIもインストールします。これは、ターミナルから新しい機能を管理および展開するために使用できる強力なコマンドラインユーティリティです。 ほとんどの主要なプログラミング言語で独自の関数を作成するためのテンプレートを提供します。 Step 7では、これを使用してPython関数を作成し、OpenFaaSにデプロイします。

このチュートリアルでは、OpenFaaS v0.8.9をデプロイします。 他のバージョンをデプロイする手順も同様である必要がありますが、project changelogをチェックして、重大な変更がないことを確認してください。

まず、ホームディレクトリに移動し、次のコマンドを実行して、リポジトリを~/faasディレクトリに複製します。

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

新しく作成された~/faasディレクトリに移動します。

cd ~/faas

リポジトリを複製すると、最新の変更を含むファイルがmasterブランチから取得されます。 重大な変更はmasterブランチに入る可能性があるため、実稼働環境での使用は推奨されません。 代わりに、0.8.9タグを確認してみましょう。

git checkout 0.8.9

出力には、正常なチェックアウトに関するメッセージと、このブランチへの変更のコミットに関する警告が含まれています。

OutputNote: checking out '0.8.9'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b 

HEAD is now at 8f0d2d1 Expose scale-function endpoint

エラーが表示された場合は、続行する前に画面の指示に従ってエラーを解決してください。

OpenFaaSリポジトリがダウンロードされ、必要なマニフェストファイルが完成したら、FaaS CLIのインストールに進みます。

FaaS CLIをインストールする最も簡単な方法は、公式スクリプトを使用することです。 ターミナルで、ホームディレクトリに移動し、次のコマンドを使用してスクリプトをダウンロードします。

cd ~
curl -sSL -o faas-cli.sh https://cli.openfaas.com

これにより、faas-cli.shスクリプトがホームディレクトリにダウンロードされます。 スクリプトを実行する前に、内容を確認することをお勧めします。

less faas-cli.sh

qを押すと、プレビューを終了できます。 スクリプトの内容を確認したら、スクリプトに実行権限を付与して実行することにより、インストールを続行できます。 スクリプトをrootとして実行すると、スクリプトが自動的にPATHにコピーされます。

chmod +x faas-cli.sh
sudo ./faas-cli.sh

出力には、インストールの進行状況とインストールしたCLIバージョンに関する情報が含まれます。

Outputx86_64
Downloading package https://github.com/openfaas/faas-cli/releases/download/0.6.17/faas-cli as /tmp/faas-cli
Download complete.

Running as root - Attempting to move faas-cli to /usr/local/bin
New version of faas-cli installed to /usr/local/bin
Creating alias 'faas' for 'faas-cli'.
  ___                   _____           ____
 / _ \ _ __   ___ _ __ |  ___|_ _  __ _/ ___|
| | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \
| |_| | |_) |  __/ | | |  _| (_| | (_| |___) |
 \___/| .__/ \___|_| |_|_|  \__,_|\__,_|____/
      |_|

CLI:
 commit:  b5597294da6dd98457434fafe39054c993a5f7e7
 version: 0.6.17

エラーが表示された場合、チュートリアルを続行する前に、画面上の指示に従ってエラーを解決してください。

この時点で、FaaS CLIがインストールされています。 使用できるコマンドの詳細については、引数なしでCLIを実行してください。

faas-cli

出力には、使用可能なコマンドとフラグが表示されます。

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


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
  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
  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.

これで、OpenFaaSマニフェストを正常に取得し、FaaS CLIをインストールしました。これを使用して、ターミナルからOpenFaaSインスタンスを管理できます。

~/faasディレクトリには、0.8.9リリースのファイルが含まれています。これは、OpenFaaSをDockerSwarmにデプロイできることを意味します。 その前に、Let's Encryptを設定してOpenFaaSのセットアップを保護するTraefikを含むように展開マニフェストファイルを変更しましょう。

[[step-2 -—- configuring-traefik]] ==ステップ2—Traefikの構成

Traefikは、Let’s Encryptが提供するSSLサポートを備えたDocker対応リバースプロキシです。 SSLプロトコルは、ノード間で送受信するデータを暗号化することにより、Swarmクラスターと安全に通信できるようにします。

TraefikをOpenFaaSで使用するには、OpenFaaS展開マニフェストを変更してTraefikを含め、OpenFaaSにサービスをインターネットに直接公開する代わりにTraefikを使用するように指示する必要があります。

~/faasディレクトリに戻り、テキストエディタでOpenFaaSデプロイメントマニフェストを開きます。

cd ~/faas
nano ~/faas/docker-compose.yml

[.note]#Note: Docker ComposeマニフェストファイルはYAML formattingを使用します。これはタブを厳密に禁止し、インデントのために2つのスペースを必要とします。 ファイルのフォーマットが正しくないと、マニフェストのデプロイに失敗します。

OpenFaaSデプロイメントは、servicesディレクティブで定義されたいくつかのサービスで構成され、OpenFaaS、OpenFaaSAPIとWebUI、およびPrometheusとAlertManager(メトリックの処理用)の実行に必要な依存関係を提供します。

servicesセクションの先頭に、traefikという新しいサービスを追加します。このサービスは、展開にtraefik:v1.6イメージを使用します。

~/faas/docker-compose.yml

version: "3.3"
services:
    traefik:
        image: traefik:v1.6
    gateway:
         ...

Traefik画像はTraefik Docker Hub repositoryから取得されており、使用可能なすべての画像のリストを見つけることができます。

次に、commandディレクティブを使用してTraefikを実行するようにDockerに指示しましょう。 これによりTraefikが実行され、Docker Swarmと連携するように設定され、Let’s Encryptを使用してSSLが提供されます。 次のフラグはTraefikを構成します。

  • --docker.*:これらのフラグは、TraefikにDockerを使用し、DockerSwarmクラスターで実行されていることを指定するように指示します。

  • --web=true:このフラグは、TraefikのWebUIを有効にします。

  • --defaultEntryPointsおよび--entryPoints:これらのフラグは、使用するエントリポイントとプロトコルを定義します。 この場合、これにはポート80のHTTPとポート443のHTTPSが含まれます。

  • --acme.*:これらのフラグは、ACMEを使用してLet’s Encrypt証明書を生成し、SSLでOpenFaaSクラスターを保護するようにTraefikに指示します。

--acme.domainsフラグと--acme.emailフラグのexample.comドメインプレースホルダーを、OpenFaaSへのアクセスに使用するドメインに置き換えてください。 複数のドメインをコンマとスペースで区切って指定できます。 電子メールアドレスは、証明書の有効期限アラートを含むSSL通知およびアラート用です。 この場合、Traefikは証明書の更新を自動的に処理するため、期限切れアラートを無視できます。

imageディレクティブの下、およびgatewayの上に次のコードブロックを追加します。

~/faas/docker-compose.yml

...
    traefik:
        image: traefik:v1.6
        command: -c --docker=true
            --docker.swarmmode=true
            --docker.domain=traefik
            --docker.watch=true
            --web=true
            --defaultEntryPoints='http,https'
            --entryPoints='Name:https Address::443 TLS'
            --entryPoints='Name:http Address::80'
            --acme=true
            --acme.entrypoint='https'
            --acme.httpchallenge=true
            --acme.httpchallenge.entrypoint='http'
            --acme.domains='example.com, www.example.com'
            --acme.email='[email protected]'
            --acme.ondemand=true
            --acme.onhostrule=true
            --acme.storage=/etc/traefik/acme/acme.json
...

commandディレクティブを配置したら、インターネットに公開するポートをTraefikに指示しましょう。 Traefikは操作にポート8080を使用しますが、OpenFaaSは非セキュア通信にポート80を使用し、セキュア通信にポート443を使用します。

次のportsディレクティブをcommandディレクティブの下に追加します。 port-internet:port-docker表記は、左側のポートがTraefikによってインターネットに公開され、右側のコンテナのポートにマップされることを保証します。

~/faas/docker-compose.yml

        ...
        command:
            ...
        ports:
            - 80:80
            - 8080:8080
            - 443:443
        ...

次に、volumesディレクティブを使用して、Dockerを実行しているホストからTraefikにDockerソケットファイルをマウントします。 Dockerソケットファイルは、Docker APIと通信して、コンテナを管理し、コンテナの数やIPアドレスなどのコンテナに関する詳細を取得します。 また、acmeというボリュームをマウントします。これは、このステップの後半で定義します。

networksディレクティブは、OpenFaaSとともに展開されるfunctionsネットワークを使用するようにTraefikに指示します。 このネットワークにより、機能がAPIを含むシステムの他の部分と通信できるようになります。

deployディレクティブは、DockerSwarmマネージャーノードでのみTraefikを実行するようにDockerに指示します。

portsディレクティブの下に次のディレクティブを追加します。

~/faas/docker-compose.yml

        ...
        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock"
            - "acme:/etc/traefik/acme"
        networks:
            - functions
        deploy:
            placement:
                constraints: [node.role == manager]

この時点で、traefikサービスブロックは次のようになります。

~/faas/docker-compose.yml

version: "3.3"
services:
    traefik:
        image: traefik:v1.6
        command: -c --docker=true
            --docker.swarmmode=true
            --docker.domain=traefik
            --docker.watch=true
            --web=true
            --defaultEntryPoints='http,https'
            --entryPoints='Name:https Address::443 TLS'
            --entryPoints='Name:http Address::80'
            --acme=true
            --acme.entrypoint='https'
            --acme.httpchallenge=true
            --acme.httpchallenge.entrypoint='http'
            --acme.domains='example.com, www.example.com'
            --acme.email='[email protected]'
            --acme.ondemand=true
            --acme.onhostrule=true
            --acme.storage=/etc/traefik/acme/acme.json
        ports:
            - 80:80
            - 8080:8080
            - 443:443
        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock"
            - "acme:/etc/traefik/acme"
        networks:
          - functions
        deploy:
          placement:
            constraints: [node.role == manager]

    gateway:
        ...

この構成により、TraefikがOpenFaaSで展開されることが保証されますが、Traefikと連携するようにOpenFaaSを構成する必要もあります。 デフォルトでは、gatewayサービスはポート8080で実行するように構成されており、これはTraefikと重複しています。

gatewayサービスは、関数のデプロイ、実行、および管理に使用できるAPIゲートウェイを提供します。 (Prometheusを介して)メトリックと自動スケーリングを処理し、Web UIをホストします。

私たちの目標は、gatewayサービスをインターネットに直接公開するのではなく、Traefikを使用して公開することです。

gatewayサービスを見つけます。これは次のようになります。

~/faas/docker-compose.yml

...
    gateway:
        ports:
            - 8080:8080
        image: openfaas/gateway:0.8.7
        networks:
            - functions
        environment:
            functions_provider_url: "http://faas-swarm:8080/"
            read_timeout:  "300s"        # Maximum time to read HTTP request
            write_timeout: "300s"        # Maximum time to write HTTP response
            upstream_timeout: "300s"     # Maximum duration of upstream function call - should be more than read_timeout and write_timeout
            dnsrr: "true"               # Temporarily use dnsrr in place of VIP while issue persists on PWD
            faas_nats_address: "nats"
            faas_nats_port: 4222
            direct_functions: "true"    # Functions are invoked directly over the overlay network
            direct_functions_suffix: ""
            basic_auth: "${BASIC_AUTH:-true}"
            secret_mount_path: "/run/secrets/"
            scale_from_zero: "false"
        deploy:
            resources:
                # limits:   # Enable if you want to limit memory usage
                #     memory: 200M
                reservations:
                    memory: 100M
            restart_policy:
                condition: on-failure
                delay: 5s
                max_attempts: 20
                window: 380s
            placement:
                constraints:
                    - 'node.platform.os == linux'
        secrets:
            - basic-auth-user
            - basic-auth-password
...

gatewayサービスが直接公開されないように、サービスからportsディレクティブを削除します。

次に、次のlablesディレクティブをgatewayサービスのdeployセクションに追加します。 このディレクティブは、Traefikを介してポート8080/ui/system、および/functionエンドポイントを公開します。

~/faas/docker-compose.yml

        ...
        deploy:
            labels:
                - traefik.port=8080
                - traefik.frontend.rule=PathPrefix:/ui,/system,/function
            resources:
            ...

/uiエンドポイントは、このチュートリアルのStep 6で説明されているOpenFaaS WebUIを公開します。 /systemエンドポイントはOpenFaaSの管理に使用されるAPIエンドポイントであり、/functionエンドポイントは関数を管理および実行するためのAPIエンドポイントを公開します。 このチュートリアルのStep 5は、OpenFaaSAPIについて詳しく説明しています。

変更後、gatewayサービスは次のようになります。

~/faas/docker-compose.yml

...
    gateway:
        image: openfaas/gateway:0.8.7
        networks:
            - functions
        environment:
            functions_provider_url: "http://faas-swarm:8080/"
            read_timeout:  "300s"        # Maximum time to read HTTP request
            write_timeout: "300s"        # Maximum time to write HTTP response
            upstream_timeout: "300s"     # Maximum duration of upstream function call - should be more than read_timeout and write_timeout
            dnsrr: "true"               # Temporarily use dnsrr in place of VIP while issue persists on PWD
            faas_nats_address: "nats"
            faas_nats_port: 4222
            direct_functions: "true"    # Functions are invoked directly over the overlay network
            direct_functions_suffix: ""
            basic_auth: "${BASIC_AUTH:-true}"
            secret_mount_path: "/run/secrets/"
            scale_from_zero: "false"
        deploy:
            labels:
                - traefik.port=8080
                - traefik.frontend.rule=PathPrefix:/ui,/system,/function
            resources:
                # limits:   # Enable if you want to limit memory usage
                #     memory: 200M
                reservations:
                    memory: 100M
            restart_policy:
                condition: on-failure
                delay: 5s
                max_attempts: 20
                window: 380s
            placement:
                constraints:
                    - 'node.platform.os == linux'
        secrets:
            - basic-auth-user
            - basic-auth-password
...

最後に、Let's Encrypt証明書の保存に使用されるacmeボリュームを定義しましょう。 空のボリュームを定義できます。つまり、コンテナを破棄するとデータは保持されません。 コンテナを破棄すると、次回Traefikを起動したときに証明書が再生成されます。

ファイルの最後の行に次のvolumesディレクティブを追加します。

~/faas/docker-compose.yml

...
volumes:
    acme:

完了したら、ファイルを保存してテキストエディターを閉じます。 この時点で、OpenFaaS展開とDocker Swarmを保護するためにTraefikを設定しました。 これで、SwarmクラスターにOpenFaaSとともにデプロイする準備が整いました。

[[step-3 -—- deploying-openfaas]] ==ステップ3—OpenFaaSのデプロイ

OpenFaaS展開マニフェストを準備したので、これを展開してOpenFaaSの使用を開始する準備が整いました。 デプロイするには、deploy_stack.shスクリプトを使用します。 このスクリプトは、LinuxおよびmacOSオペレーティングシステムで使用することを目的としていますが、OpenFaaSディレクトリには、WindowsおよびARM systemsに適したスクリプトもあります。

OpenFaaSをデプロイする前に、Swarm内のマシンの1つでスクリプトからDockerコマンドを実行するようにdocker-machineに指示する必要があります。 このチュートリアルでは、Swarm managerを使用しましょう。

docker-machine useコマンドを構成している場合は、次のコマンドを使用できます。

docker-machine use node-1

そうでない場合は、次のコマンドを使用します。

eval $(docker-machine env node-1)

deploy_stack.shスクリプトは、構成ファイル、ネットワーク設定、サービス、OpenFaaSサーバーでの認証用の資格情報など、OpenFaaSが期待どおりに機能するために必要なすべてのリソースを展開します。

スクリプトを実行してみましょう。展開が完了するまでに数分かかります。

~/faas/deploy_stack.sh

出力には、展開プロセスで作成されたリソースのリストと、OpenFaaSサーバーおよびFaaS CLIコマンドへのアクセスに使用する資格情報が表示されます。

これらの資格情報は、チュートリアル全体でWeb UIおよびAPIにアクセスするために必要になるため、書き留めてください。

OutputAttempting to create credentials for gateway..
roozmk0y1jkn17372a8v9y63g
q1odtpij3pbqrmmf8msy3ampl
[Credentials]
 username: admin
 password: your_openfaas_password
 echo -n your_openfaas_password | faas-cli login --username=admin --password-stdin

Enabling basic authentication for gateway..

Deploying OpenFaaS core services
Creating network func_functions
Creating config func_alertmanager_config
Creating config func_prometheus_config
Creating config func_prometheus_rules
Creating service func_alertmanager
Creating service func_traefik
Creating service func_gateway
Creating service func_faas-swarm
Creating service func_nats
Creating service func_queue-worker
Creating service func_prometheus

エラーが表示された場合は、画面に表示される指示に従ってエラーを解決してから、チュートリアルを続けてください。

続行する前に、展開スクリプトで提供されるコマンドを使用して、OpenFaaSサーバーでFaaS CLIを認証しましょう。

スクリプトはコマンドに提供する必要のあるフラグを出力しましたが、FaaS CLIはゲートウェイサーバーが%(で実行されていると想定しているため、OpenFaaSサーバーのアドレスとともにフラグ--gatewayを追加する必要があります。 t1)s:

echo -n your_openfaas_password | faas-cli login --username=admin --password-stdin --gateway https://example.com

出力には、許可の成功に関するメッセージが含まれます。

OutputCalling the OpenFaaS server to validate the credentials...
credentials saved for admin https://example.com

この時点で、Docker Swarmクラスターに完全に機能するOpenFaaSサーバーがデプロイされ、新しくデプロイされたサーバーを使用するようにFaaS CLIが構成されています。 OpenFaaSの使用方法をテストする前に、いくつかのサンプル関数をデプロイして始めましょう。

[[step-4 -—- deploying-openfaas-sample-functions]] ==ステップ4—OpenFaaSサンプル関数のデプロイ

当初、OpenFaaSには機能がデプロイされていません。 テストと使用を開始するには、いくつかの機能が必要です。

OpenFaaSプロジェクトはいくつかのサンプル関数をホストしており、available functions along with their deployment manifests in the OpenFaaS repositoryのリストを見つけることができます。 一部のサンプル関数には、関数が実行されているノードに関する情報を表示するためのnodeinfo、渡された要求の単語数をカウントするためのwordcount、および変換するためのmarkdownが含まれます。マークダウン入力をHTML出力に渡しました。

~/faasディレクトリのstack.ymlマニフェストは、上記の関数とともにいくつかのサンプル関数をデプロイします。 FaaS CLIを使用して展開できます。

次のfaas-cliコマンドを実行します。このコマンドは、スタックマニフェストへのパスとOpenFaaSサーバーのアドレスを取得します。

faas-cli deploy -f ~/faas/stack.yml --gateway https://example.com

出力には、展開が成功したかどうかを示すステータスコードとメッセージが含まれます。

OutputDeploying: wordcount.

Deployed. 200 OK.
URL: https://example.com/function/wordcount

Deploying: base64.

Deployed. 200 OK.
URL: https://example.com/function/base64

Deploying: markdown.

Deployed. 200 OK.
URL: https://example.com/function/markdown

Deploying: hubstats.

Deployed. 200 OK.
URL: https://example.com/function/hubstats

Deploying: nodeinfo.

Deployed. 200 OK.
URL: https://example.com/function/nodeinfo

Deploying: echoit.

Deployed. 200 OK.
URL: https://example.com/function/echoit

エラーが表示された場合は、画面上の指示に従ってエラーを解決してください。

スタックの展開が完了したら、すべての機能をリストし、それらが展開されて使用できる状態であることを確認します。

faas-cli list --gateway https://example.com

出力には、レプリカ番号と呼び出し回数とともに、関数のリストが含まれます。

OutputFunction                        Invocations     Replicas
markdown                        0               1
wordcount                       0               1
base64                          0               1
nodeinfo                        0               1
hubstats                        0               1
echoit                          0               1

ここに関数が表示されない場合は、faas-cli deployコマンドが正常に実行されたことを確認してください。

サンプルOpenFaaS関数を使用して、API、Web UI、およびCLIの使用方法をテストおよび実証できるようになりました。 次のステップでは、OpenFaaS APIを使用して機能を一覧表示して実行することから始めます。

[[step-5 --- using-the-openfaas-api]] ==ステップ5— OpenFaaSAPIの使用

OpenFaaSには、サーバーレス機能の管理と実行に使用できる強力なAPIが付属しています。 APIの設計、テスト、ドキュメント化のためのツールであるSwaggerを使用してAPIドキュメントを参照し、APIを使用して関数を一覧表示して実行しましょう。

Swaggerを使用すると、APIドキュメントを調べて、使用可能なエンドポイントとその使用方法を確認できます。 OpenFaaSリポジトリには、Swagger API specificationがあります。これは、Swaggerエディターで使用して、仕様を人間が読める形式に変換できます。

Webブラウザをhttp://editor.swagger.io/に移動します。 次の画面で歓迎されるはずです。

Swagger Editor Welcome page

ここには、サンプルSwagger仕様のソースコードを含むテキストエディターと、人間が読めるAPIドキュメントが右側にあります。

OpenFaaS Swagger仕様をインポートしましょう。 トップメニューで、Fileボタンをクリックしてから、Import URLをクリックします。

Swagger Editor Import URL

Swagger API仕様のアドレスを入力する必要があるポップアップが表示されます。 ポップアップが表示されない場合は、Webブラウザでポップアップが有効になっていることを確認してください。

フィールドに、Swagger OpenFaaS API仕様へのリンクを入力します:https://raw.githubusercontent.com/openfaas/faas/master/api-docs/swagger.yml

Swagger Editor Input URL

OKボタンをクリックすると、SwaggerエディターにOpenFaaSのAPIリファレンスが表示されます。これは次のようになります。

Swagger Editor OpenFaaS API specification

左側にはAPIリファレンスファイルのソースが表示され、右側には簡単な説明とともにエンドポイントのリストが表示されます。 エンドポイントをクリックすると、そのパラメーターの詳細、使用するメソッド、可能な応答など、エンドポイントに関する詳細が表示されます。

Swagger Editor Endpoint details

使用可能なエンドポイントとそれらが期待するパラメーターがわかったら、それらを使用して機能を管理できます。

次に、curlコマンドを使用してAPIと通信するので、ターミナルに戻ります。 -uフラグを使用すると、手順3で取得したadmin:your_openfaas_passwordペアを渡すことができ、-Xフラグは要求メソッドを定義します。 また、エンドポイントURLhttps://example.com/system/functionsを渡します。

curl -u admin:your_openfaas_password -X GET https://example.com/system/functions

APIドキュメントで各エンドポイントに必要なメソッドを確認できます。

ステップ4で、出力に表示されるはずのいくつかのサンプル関数をデプロイしました。

Output[{"name":"base64","image":"functions/alpine:latest","invocationCount":0,"replicas":1,"envProcess":"base64","availableReplicas":0,"labels":{"com.openfaas.function":"base64","function":"true"}},{"name":"nodeinfo","image":"functions/nodeinfo:latest","invocationCount":0,"replicas":1,"envProcess":"","availableReplicas":0,"labels":{"com.openfaas.function":"nodeinfo","function":"true"}},{"name":"hubstats","image":"functions/hubstats:latest","invocationCount":0,"replicas":1,"envProcess":"","availableReplicas":0,"labels":{"com.openfaas.function":"hubstats","function":"true"}},{"name":"markdown","image":"functions/markdown-render:latest","invocationCount":0,"replicas":1,"envProcess":"","availableReplicas":0,"labels":{"com.openfaas.function":"markdown","function":"true"}},{"name":"echoit","image":"functions/alpine:latest","invocationCount":0,"replicas":1,"envProcess":"cat","availableReplicas":0,"labels":{"com.openfaas.function":"echoit","function":"true"}},{"name":"wordcount","image":"functions/alpine:latest","invocationCount":0,"replicas":1,"envProcess":"wc","availableReplicas":0,"labels":{"com.openfaas.function":"wordcount","function":"true"}}]

このような出力が表示されない場合、またはエラーが表示される場合は、画面の指示に従って問題を解決してからチュートリアルを続行してください。 推奨される方法と適切な認証情報を使用して、正しいエンドポイントにリクエストを送信していることを確認してください。 次のコマンドを使用して、gatewayサービスのログを確認することもできます。

docker service logs func_gateway

デフォルトでは、curl呼び出しに対するAPI応答は、新しい行のない生のJSONを返します。これは、人間が読める形式ではありません。 それを解析するには、curlの応答をjqユーティリティにパイプします。これにより、JSONが人間が読める形式に変換されます。

curl -u admin:your_openfaas_password -X GET https://example.com/system/functions | jq

出力は人間が読める形式になりました。 APIで関数を管理および呼び出すために使用できる関数名、呼び出しの数、Dockerに関連するラベルやレプリカの数などの情報を確認できます。

Output[
  {
    "name": "base64",
    "image": "functions/alpine:latest",
    "invocationCount": 0,
    "replicas": 1,
    "envProcess": "base64",
    "availableReplicas": 0,
    "labels": {
      "com.openfaas.function": "base64",
      "function": "true"
    }
  },
  {
    "name": "nodeinfo",
    "image": "functions/nodeinfo:latest",
    "invocationCount": 0,
    "replicas": 1,
    "envProcess": "",
    "availableReplicas": 0,
    "labels": {
      "com.openfaas.function": "nodeinfo",
      "function": "true"
    }
  },
  {
    "name": "hubstats",
    "image": "functions/hubstats:latest",
    "invocationCount": 0,
    "replicas": 1,
    "envProcess": "",
    "availableReplicas": 0,
    "labels": {
      "com.openfaas.function": "hubstats",
      "function": "true"
    }
  },
  {
    "name": "markdown",
    "image": "functions/markdown-render:latest",
    "invocationCount": 0,
    "replicas": 1,
    "envProcess": "",
    "availableReplicas": 0,
    "labels": {
      "com.openfaas.function": "markdown",
      "function": "true"
    }
  },
  {
    "name": "echoit",
    "image": "functions/alpine:latest",
    "invocationCount": 0,
    "replicas": 1,
    "envProcess": "cat",
    "availableReplicas": 0,
    "labels": {
      "com.openfaas.function": "echoit",
      "function": "true"
    }
  },
  {
    "name": "wordcount",
    "image": "functions/alpine:latest",
    "invocationCount": 0,
    "replicas": 1,
    "envProcess": "wc",
    "availableReplicas": 0,
    "labels": {
      "com.openfaas.function": "wordcount",
      "function": "true"
    }
  }
]

これらの関数の1つを使用して、API/function/function-nameのエンドポイントを使用して実行してみましょう。 このエンドポイントは、-dフラグを使用して関数にデータを送信できるPOSTメソッドを介して使用できます。

たとえば、次のcurlコマンドを実行して、echoit関数を実行します。この関数は、OpenFaaSに付属しており、送信した文字列をリクエストとして出力します。 文字列"Sammy The Shark"を使用して、次のことを示すことができます。

curl -u admin:your_openfaas_password -X POST https://example.com/function/func_echoit -d "Sammy The Shark"

出力にはSammy The Sharkが表示されます。

OutputSammy The Shark

エラーが表示された場合は、画面上のログに従って問題を解決してからチュートリアルを続行してください。 gatewayサービスのログを確認することもできます。

この時点で、OpenFaaS APIを使用して機能を管理および実行しました。 それでは、OpenFaaS Web UIを見てみましょう。

[[step-6 -—- using-the-openfaas-web-ui]] ==ステップ6— OpenFaaS WebUIの使用

OpenFaaSには、新しい機能を追加したり、インストールされた機能を実行したりできるWeb UIが付属しています。 このステップでは、FaaSストアからQRコードを生成する機能をインストールし、サンプルコードを生成します。

まず、Webブラウザでhttps://example.com/ui/を指定します。 「見つかりません」エラーを回避するには、末尾のスラッシュが必要であることに注意してください。

HTTP認証ダイアログボックスで、ステップ3でOpenFaaSを展開するときに取得したユーザー名とパスワードを入力します。

ログインすると、画面の左側に使用可能な機能と、新しい機能のインストールに使用されるDeploy New Functionsボタンが表示されます。

Deploy New Functionsをクリックして、新しい関数をデプロイします。 FaaSストアウィンドウが表示されます。このウィンドウには、ワンクリックでインストールできるコミュニティでテストされた機能があります。

OpenFaaS Functions store

これらの関数に加えて、Dockerイメージから関数を手動でデプロイすることもできます。

このチュートリアルでは、FaaSストアからQR Code Generator関数をデプロイします。 リストでQR Code Generator - Goアイテムを見つけてクリックし、ウィンドウの下部にあるDeployボタンをクリックします。

OpenFaaS QR Code Generator function

Deployをクリックすると、Deploy A New Functionウィンドウが閉じ、関数がデプロイされます。 ウィンドウの左側のリストに、qrcode-go関数のリストが表示されます。 このエントリをクリックして選択します。 メイン関数ウィンドウには、関数を呼び出すオプションとともに、関数名、レプリカの数、呼び出し回数、およびイメージが表示されます。

OpenFaaS QR Code Function

ドメインのURLを含むQRコードを生成しましょう。 Request bodyフィールドに、生成するQRコードのコンテンツを入力します。この場合、これは“example.com”になります。 完了したら、Invokeボタンをクリックします。

TextまたはJSON出力オプションのいずれかを選択すると、関数はファイルのコンテンツを出力しますが、これは使用できないか、人間が読める形式ではありません。

OpenFaaS generated QR code

応答をダウンロードできます。 この場合、QRコードを含むPNGファイルになります。 これを行うには、Downloadオプションを選択してから、もう一度Invokeをクリックします。 その後すぐに、QRコードをダウンロードして、選択した画像ビューアーで開くことができます。

Generated QR code

FaaSストアまたはDockerイメージから機能をデプロイすることに加えて、独自の機能を作成することもできます。 次のステップでは、FaaSコマンドラインインターフェイスを使用してPython関数を作成します。

[[step-7 -—- creating-functions-with-the-faas-cli]] ==ステップ7— FaaSCLIを使用した関数の作成

前の手順で、OpenFaaSサーバーと連携するようにFaaS CLIを構成しました。 FaaS CLIは、APIを介して、またはWeb UIを使用するのと同じように、OpenFaaSの管理と機能のインストールと実行に使用できるコマンドラインインターフェイスです。

Web UIまたはAPIと比較して、FaaS CLIには、独自の機能を作成するために使用できる多くのプログラミング言語のテンプレートがあります。 また、関数コードに基づいてコンテナーイメージを構築し、Docker Hubなどのイメージレジストリにイメージをプッシュすることもできます。

この手順では、関数を作成し、Docker Hubに公開してから、OpenFaaSサーバーで実行します。 この関数は、リクエストとして渡された入力を返すデフォルトのechoit関数に似ています。

Pythonを使用して関数を記述します。 Pythonについて詳しく知りたい場合は、How To Code in Python 3 tutorial seriesHow To Code in Python eBookを確認してください。

新しい関数を作成する前に、FaaS関数を保存するディレクトリを作成してナビゲートしましょう。

mkdir ~/faas-functions
cd ~/faas-functions

次のコマンドを実行して、echo-inputという新しいPython関数を作成します。 関数を後でDockerHubにプッシュするため、必ずyour-docker-hub-usernameをDockerHubユーザー名に置き換えてください。

faas-cli new echo-input --lang python --prefix your-docker-hub-username --gateway https://example.com

出力には、正常な関数作成に関する確認が含まれます。 テンプレートをダウンロードしていない場合、CLIは現在のディレクトリにテンプレートをダウンロードします。

Output2018/05/13 12:13:06 No templates found in current directory.
2018/05/13 12:13:06 Attempting to expand templates from https://github.com/openfaas/templates.git
2018/05/13 12:13:11 Fetched 12 template(s) : [csharp dockerfile go go-armhf node node-arm64 node-armhf python python-armhf python3 python3-armhf ruby] from https://github.com/openfaas/templates.git
Folder: echo-input created.
  ___                   _____           ____
 / _ \ _ __   ___ _ __ |  ___|_ _  __ _/ ___|
| | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \
| |_| | |_) |  __/ | | |  _| (_| | (_| |___) |
 \___/| .__/ \___|_| |_|_|  \__,_|\__,_|____/
      |_|


Function created in folder: echo-input
Stack file written: echo-input.yml

faas-cli newコマンドの結果は、関数のコードとecho-input.ymlファイルを含む新しく作成された~/faas-fucntions/echo-inputディレクトリです。 このファイルには、機能に関する情報(使用言語、名前、デプロイするサーバー)が含まれています。

~/faas-fucntions/echo-inputディレクトリに移動します。

cd ~/faas-fucntions/echo-input

ディレクトリの内容を表示するには、次を実行します。

ls

ディレクトリには2つのファイルが含まれています。関数のコードを含むhandler.pyと、関数に必要なPythonモジュールを含むrequirements.txtです。

現在、デフォルト以外のPythonモジュールは必要ないため、requirements.txtファイルは空です。 catコマンドを使用して確認できます。

cat requirements.txt

次に、リクエストを文字列として返す関数を作成しましょう。

handler.pyファイルには、受信した応答を文字列として返すサンプルハンドラコードがすでに含まれています。 コードを見てみましょう。

nano handler.py

デフォルトの関数はhandleと呼ばれ、呼び出されたときに関数に渡されるリクエストを含む単一のパラメータreqを取ります。 この関数は1つのことだけを行い、渡された要求を応答として返します。

def handle(req):
    """handle a request to the function
    Args:
        req (str): request body
    """

    return req

次のように、returnディレクティブの文字列を置き換えて、追加のテキストを含めるように変更しましょう。

    return "Received message: " + req

完了したら、ファイルを保存してテキストエディターを閉じます。

次に、関数のソースコードからDockerイメージを作成しましょう。 echo-input.ymlファイルが配置されているfaas-functionsディレクトリに移動します。

cd ~/faas-functions

次のコマンドは、関数のDockerイメージを作成します。

faas-cli build -f echo-input.yml

出力には、ビルドの進行状況に関する情報が含まれます。

Output[0] > Building echo-input.
Clearing temporary build folder: ./build/echo-input/
Preparing ./echo-input/ ./build/echo-input/function
Building: sammy/echo-input with python template. Please wait..
Sending build context to Docker daemon  7.168kB
Step 1/16 : FROM python:2.7-alpine
 ---> 5fdd069daf25
Step 2/16 : RUN apk --no-cache add curl     && echo "Pulling watchdog binary from Github."     && curl -sSL https://github.com/openfaas/faas/releases/download/0.8.0/fwatchdog > /usr/bin/fwatchdog     && chmod +x /usr/bin/fwatchdog     && apk del curl --no-cache
 ---> Using cache
 ---> 247d4772623a
Step 3/16 : WORKDIR /root/
 ---> Using cache
 ---> 532cc683d67b
Step 4/16 : COPY index.py           .
 ---> Using cache
 ---> b4b512152257
Step 5/16 : COPY requirements.txt   .
 ---> Using cache
 ---> 3f9cbb311ab4
Step 6/16 : RUN pip install -r requirements.txt
 ---> Using cache
 ---> dd7415c792b1
Step 7/16 : RUN mkdir -p function
 ---> Using cache
 ---> 96c25051cefc
Step 8/16 : RUN touch ./function/__init__.py
 ---> Using cache
 ---> 77a9db274e32
Step 9/16 : WORKDIR /root/function/
 ---> Using cache
 ---> 88a876eca9e3
Step 10/16 : COPY function/requirements.txt .
 ---> Using cache
 ---> f9ba5effdc5a
Step 11/16 : RUN pip install -r requirements.txt
 ---> Using cache
 ---> 394a1dd9e4d7
Step 12/16 : WORKDIR /root/
 ---> Using cache
 ---> 5a5893c25b65
Step 13/16 : COPY function           function
 ---> eeddfa67018d
Step 14/16 : ENV fprocess="python index.py"
 ---> Running in 8e53df4583f2
Removing intermediate container 8e53df4583f2
 ---> fb5086bc7f6c
Step 15/16 : HEALTHCHECK --interval=1s CMD [ -e /tmp/.lock ] || exit 1
 ---> Running in b38681a71378
Removing intermediate container b38681a71378
 ---> b04c045b0994
Step 16/16 : CMD ["fwatchdog"]
 ---> Running in c5a11078df3d
Removing intermediate container c5a11078df3d
 ---> bc5f08157c5a
Successfully built bc5f08157c5a
Successfully tagged sammy/echo-input:latest
Image: your-docker-hub-username/echo-input built.
[0] < Building echo-input done.
[0] worker done.

エラーが発生した場合は、関数を展開する前に画面上の指示に従って解決してください。

OpenFaaS関数をデプロイするには、コンテナ化する必要があります。 アプリケーションをコンテナ化することで、アプリケーションの実行に必要な環境を簡単に再現でき、アプリケーションを簡単にデプロイ、スケーリング、更新できます。

このチュートリアルでは、無料のソリューションであるDocker Hubを使用しますが、独自のプライベートレジストリを含む任意のコンテナレジストリを使用できます。

次のコマンドを実行して、作成したイメージをDocker Hubの指定されたリポジトリにプッシュします。

faas-cli push -f echo-input.yml

インターネット接続速度に応じて、プッシュには数分かかります。 出力には、画像のアップロードの進行状況が含まれます。

Output[0] > Pushing echo-input.
The push refers to repository [docker.io/sammy/echo-input]
320ea573b385: Pushed
9d87e56f5d0c: Pushed
6f79b75e7434: Pushed
23aac2d8ecf2: Pushed
2bec17d09b7e: Pushed
e5a0e5ab3be6: Pushed
e9c8ca932f1b: Pushed
beae1d55b4ce: Pushed
2fcae03ed1f7: Pushed
62103d5daa03: Mounted from library/python
f6ac6def937b: Mounted from library/python
55c108c7613c: Mounted from library/python
e53f74215d12: Mounted from library/python
latest: digest: sha256:794fa942c2f593286370bbab2b6c6b75b9c4dcde84f62f522e59fb0f52ba05c1 size: 3033
[0] < Pushing echo-input done.
[0] worker done.

最後に、イメージをDocker Hubにプッシュしたら、それを使用してOpenFaaSサーバーに機能をデプロイできます。

関数をデプロイするには、deployコマンドを実行します。このコマンドは、関数を説明するマニフェストへのパスと、OpenFaaSサーバーのアドレスを取得します。

faas-cli deploy -f echo-input.yml --gateway https://example.com

出力には、展開のステータスが、展開している機能の名前と展開ステータスコードとともに表示されます。

OutputDeploying: echo-input.

Deployed. 200 OK.
URL: https://example.com/function/echo-input

展開が成功すると、200ステータスコードが表示されます。 エラーが発生した場合は、提供される指示に従って問題を修正してから続行してください。

この時点で、関数がデプロイされ、使用できる状態になります。 呼び出して、期待どおりに機能していることをテストできます。

FaaS CLIを使用して関数を呼び出すには、関数名とOpenFaaSアドレスを渡してinvokeコマンドを使用します。 コマンドを実行すると、関数に送信するリクエストを入力するよう求められます。

次のコマンドを実行して、echo-input関数を呼び出します。

faas-cli invoke echo-input --gateway https://example.com

関数に送信するリクエストを入力するよう求められます。

OutputReading from STDIN - hit (Control + D) to stop.

次のように、関数に送信するテキストを入力します。

Sammy The Shark!

完了したら、ENTERを押してからCTRL + Dを押してリクエストを終了します。 端末のCTRL + Dショートカットは、ファイルの終わり(EOF)を登録するために使用されます。 EOFが受信されると、OpenFaaS CLIは端末からの読み取りを停止します。

数秒後、コマンドは関数の応答を出力します:

OutputReading from STDIN - hit (Control + D) to stop.
Sammy The Shark!
Received message: Sammy The Shark!

出力が表示されない場合、またはエラーが発生する場合は、前述の手順に戻って、説明どおりに機能を展開したことを確認し、画面の指示に従って問題を解決します。

この時点で、Web UI、API、およびCLIの3つのメソッドを使用して関数を操作しました。 これらの方法のいずれかを使用して機能を実行できると、既存のワークフローに機能を統合する方法を柔軟に決定できます。

結論

このチュートリアルでは、サーバーレスアーキテクチャとOpenFaaSを使用して、OpenFaaS API、Web UI、CLIを使用してアプリケーションをデプロイおよび管理しました。 また、Let’s Encryptを使用してTraefikを利用してSSLを提供することにより、インフラストラクチャを保護しました。

OpenFaaSプロジェクトについて詳しく知りたい場合は、それらのwebsiteproject’s official documentationを確認できます。