Ubuntu16.04でDockerSwarmを使用してOpenFaaSをインストールして保護する方法
著者は、 Write for DOnations プログラムの一環として、 Diversity in TechFundを選択して寄付を受け取りました。
序章
サーバーレスアーキテクチャは、サーバーインスタンスを開発者から隠し、通常、開発者がクラウドでアプリケーションを実行できるようにするAPIを公開します。 このアプローチは、インスタンスのプロビジョニングと保守を適切なDevOpsチームに任せることができるため、開発者がアプリケーションを迅速にデプロイするのに役立ちます。 また、適切なツールを使用すると、需要ごとにインスタンスをスケーリングできるため、インフラストラクチャのコストも削減されます。
サーバーレスプラットフォームで実行されるアプリケーションは、サーバーレス関数と呼ばれます。 関数は、特定の操作を実行するために使用される、コンテナー化された実行可能コードです。 アプリケーションをコンテナ化することで、多くのマシンで一貫した環境を再現できるようになり、更新とスケーリングが可能になります。
OpenFaaS は、サーバーレス機能を構築およびホストするための無料のオープンソースフレームワークです。 DockerSwarmとKubernetesの両方が公式にサポートされているため、強力なAPI、コマンドラインインターフェイス、またはWebUIを使用してアプリケーションをデプロイできます。 Prometheus が提供する組み込みの指標が付属しており、ゼロからのスケーリングだけでなく、オンデマンドの自動スケーリングもサポートしています。
このチュートリアルでは、Ubuntu16.04で実行されているDockerSwarmでOpenFaaSをセットアップして使用し、 Let’sEncyptでTraefikをセットアップしてWebUIとAPIを保護します。 これにより、クラスター内のノード間、およびOpenFaaSとそのオペレーター間の安全な通信が保証されます。
前提条件
このチュートリアルに従うには、次のものが必要です。
- ローカルマシンで実行されているUbuntu16.04。 他のディストリビューションやオペレーティングシステムを使用することもできますが、オペレーティングシステムに適切なOpenFaaSスクリプトを使用し、これらの前提条件にリストされているすべての依存関係をインストールするようにしてください。
git
、curl
、およびjq
がローカルマシンにインストールされています。git
を使用してOpenFaaSリポジトリのクローンを作成し、curl
を使用してAPIをテストし、jq
を使用して生のJSON応答をAPIから人間に変換します-読み取り可能なJSON。 このセットアップに必要な依存関係をインストールするには、次のコマンドを使用します:sudo apt-get update && sudo apt-get install git curl jq
- Ubuntu16.04にDockerをインストールして使用する方法のステップ1と2に従ってDockerをインストールしました。
- DockerHubアカウント。 関数をOpenFaaSにデプロイするには、それらをパブリックコンテナレジストリに公開する必要があります。 このチュートリアルではDockerHubを使用します。これは、無料で広く使用されているためです。
docker login
コマンドを使用して、ローカルマシンでDockerを使用して認証してください。 - Docker Machine がインストールされ、 Ubuntu16.04でDockerMachineを使用してリモートDockerホストをプロビジョニングおよび管理する方法に従います。
- DigitalOceanパーソナルアクセストークン。 トークンを作成するには、これらの手順に従ってください。
- Ubuntu16.04でDockerSwarmとDigitalOceanを使用してDockerコンテナのクラスターを作成する方法に従ってプロビジョニングされた3ノードのDockerSwarmクラスター。
- DockerSwarmのインスタンスの1つを指すAレコードを持つ完全に登録されたドメイン名。 チュートリアル全体を通して、ドメインの例としてexample.comが表示されます。 これを独自のドメインに置き換える必要があります。このドメインは、 Namecheap で購入するか、Freenomで無料で入手できます。 選択した別のドメインレジストラを使用することもできます。
ステップ1—OpenFaaSのダウンロードとOpenFaaSCLIのインストール
OpenFaaSをDockerSwarmにデプロイするには、デプロイメントマニフェストとスクリプトをダウンロードする必要があります。 それらを取得する最も簡単な方法は、公式のOpenFaasリポジトリのクローンを作成し、OpenFaaSリリースを表す適切なタグを確認することです。
リポジトリのクローンを作成するだけでなく、ターミナルから新しい機能を管理および展開するために使用できる強力なコマンドラインユーティリティであるFaaSCLIもインストールします。 これは、ほとんどの主要なプログラミング言語で独自の関数を作成するためのテンプレートを提供します。 ステップ7では、これを使用して Python 関数を作成し、OpenFaaSにデプロイします。
このチュートリアルでは、OpenFaaS v 0.8.9をデプロイします。 他のバージョンをデプロイする手順も同様である必要がありますが、プロジェクト変更ログをチェックして、重大な変更がないことを確認してください。
まず、ホームディレクトリに移動し、次のコマンドを実行して、リポジトリを~/faas
ディレクトリに複製します。
- cd ~
- git clone https://github.com/openfaas/faas.git
新しく作成された~/faas
ディレクトリに移動します。
- cd ~/faas
リポジトリのクローンを作成すると、マスターブランチから最新の変更を含むファイルを取得します。 重大な変更はマスターブランチに入る可能性があるため、本番環境での使用はお勧めしません。 代わりに、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 <new-branch-name>
HEAD is now at 8f0d2d1 Expose scale-function endpoint
エラーが表示された場合は、続行する前に、画面の指示に従ってエラーを解決してください。
OpenFaaSリポジトリをダウンロードし、必要なマニフェストファイルを完成させたら、FaaSCLIのインストールに進みましょう。
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
エラーが表示された場合は、チュートリアルを続行する前に、画面の指示に従ってエラーを解決してください。
この時点で、FaaSCLIがインストールされています。 使用できるコマンドの詳細については、引数なしで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にデプロイできることを意味します。 その前に、展開マニフェストファイルを変更してTraefikを含めましょう。これにより、Let’sEncryptを設定してOpenFaaSのセットアップを保護できます。
ステップ2—Traefikを構成する
Traefikは、Let’sEncryptによって提供されるSSLサポートが付属するDocker対応のリバースプロキシです。 SSLプロトコルは、ノード間で送受信するデータを暗号化することにより、Swarmクラスターと安全に通信することを保証します。
TraefikをOpenFaaSで使用するには、OpenFaaSデプロイメントマニフェストを変更してTraefikを含め、OpenFaaSにサービスをインターネットに直接公開する代わりにTraefikを使用するように指示する必要があります。
~/faas
ディレクトリに戻り、テキストエディタでOpenFaaS展開マニフェストを開きます。
- cd ~/faas
- nano ~/faas/docker-compose.yml
注: DockerComposeマニフェストファイルはYAMLフォーマットを使用します。これはタブを厳密に禁止し、インデントに2つのスペースを必要とします。 ファイルの形式が正しくない場合、マニフェストはデプロイに失敗します。
OpenFaaSデプロイメントは、services
ディレクティブで定義されたいくつかのサービスで構成され、OpenFaaS、OpenFaaSAPIとWebUI、およびPrometheusとAlertManager(メトリックを処理するため)の実行に必要な依存関係を提供します。
services
セクションの先頭に、traefik
という新しいサービスを追加します。このサービスは、展開にtraefik:v1.6
イメージを使用します。
version: "3.3"
services:
traefik:
image: traefik:v1.6
gateway:
...
Traefikイメージは、 Traefik Docker Hubリポジトリから取得されます。ここには、使用可能なすべてのイメージのリストがあります。
次に、command
ディレクティブを使用してTraefikを実行するようにDockerに指示しましょう。 これにより、Traefikが実行され、Docker Swarmで動作するように構成され、Let’sEncryptを使用してSSLが提供されます。 次のフラグはTraefikを構成します。
--docker.*
:これらのフラグは、TraefikにDockerを使用し、DockerSwarmクラスターで実行されていることを指定するように指示します。--web=true
:このフラグは、TraefikのWebUIを有効にします。--defaultEntryPoints
および--entryPoints
:これらのフラグは、使用するエントリポイントとプロトコルを定義します。 この場合、これにはポート80
のHTTPとポート443
のHTTPSが含まれます。--acme.*
:これらのフラグは、Traefikに ACMEを使用してLet’sEncrypt証明書を生成し、SSLでOpenFaaSクラスターを保護するように指示します。
--acme.domains
および--acme.email
フラグのexample.com
ドメインプレースホルダーを、OpenFaaSへのアクセスに使用するドメインに置き換えてください。 複数のドメインをコンマとスペースで区切ることで指定できます。 電子メールアドレスは、証明書の有効期限アラートを含むSSL通知およびアラート用です。 この場合、Traefikは証明書の更新を自動的に処理するため、有効期限アラートを無視できます。
image
ディレクティブの下、およびgateway
の上に次のコードブロックを追加します。
...
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
を使用します。
command
ディレクティブの下に次のports
ディレクティブを追加します。 port-internet:port-docker
表記は、左側のポートがTraefikによってインターネットに公開され、右側のコンテナーのポートにマップされることを保証します。
...
command:
...
ports:
- 80:80
- 8080:8080
- 443:443
...
次に、volumes
ディレクティブを使用して、Dockerを実行しているホストからTraefikにDockerソケットファイルをマウントします。 DockerソケットファイルはDockerAPIと通信して、コンテナーを管理し、コンテナーの数やIPアドレスなどの詳細を取得します。 また、acme
というボリュームをマウントします。これは、このステップの後半で定義します。
networks
ディレクティブは、OpenFaaSとともに展開されるfunctions
ネットワークを使用するようにTraefikに指示します。 このネットワークにより、関数はAPIを含むシステムの他の部分と通信できるようになります。
deploy
ディレクティブは、DockerSwarmマネージャーノードでのみTraefikを実行するようにDockerに指示します。
ports
ディレクティブの下に次のディレクティブを追加します。
...
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "acme:/etc/traefik/acme"
networks:
- functions
deploy:
placement:
constraints: [node.role == manager]
この時点で、traefik
サービスブロックは次のようになります。
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
サービスは、Traefikと重複するポート8080
で実行するように構成されています。
gateway
サービスは、関数のデプロイ、実行、および管理に使用できるAPIゲートウェイを提供します。 メトリック(Prometheus経由)と自動スケーリングを処理し、WebUIをホストします。
私たちの目標は、gateway
サービスをインターネットに直接公開するのではなく、Traefikを使用して公開することです。
gateway
サービスを見つけます。これは次のようになります。
...
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
...
ports
ディレクティブをサービスから削除して、gateway
サービスが直接公開されないようにします。
次に、次のlables
ディレクティブをgateway
サービスのdeploy
セクションに追加します。 このディレクティブは、Traefikを介してポート8080
の/ui
、/system
、および/function
エンドポイントを公開します。
...
deploy:
labels:
- traefik.port=8080
- traefik.frontend.rule=PathPrefix:/ui,/system,/function
resources:
...
/ui
エンドポイントは、このチュートリアルのステップ6で説明されているOpenFaaSWebUIを公開します。 /system
エンドポイントはOpenFaaSの管理に使用されるAPIエンドポイントであり、/function
エンドポイントは関数を管理および実行するためのAPIエンドポイントを公開します。 このチュートリアルのステップ5では、OpenFaaSAPIについて詳しく説明しています。
変更後、gateway
サービスは次のようになります。
...
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’sEncrypt証明書の保存に使用されるacme
ボリュームを定義しましょう。 空のボリュームを定義できます。つまり、コンテナを破棄してもデータは保持されません。 コンテナを破棄すると、次にTraefikを起動したときに証明書が再生成されます。
ファイルの最後の行に次のvolumes
ディレクティブを追加します。
...
volumes:
acme:
完了したら、ファイルを保存してテキストエディタを閉じます。 この時点で、OpenFaaSデプロイメントとDockerSwarmを保護するようにTraefikを構成しました。 これで、SwarmクラスターにOpenFaaSと一緒にデプロイする準備が整いました。
ステップ3—OpenFaaSの導入
OpenFaaSデプロイメントマニフェストを準備したので、それをデプロイしてOpenFaaSの使用を開始する準備が整いました。 展開するには、deploy_stack.sh
スクリプトを使用します。 このスクリプトは、LinuxおよびmacOSオペレーティングシステムで使用することを目的としていますが、OpenFaaSディレクトリには、WindowsおよびARMシステムに適したスクリプトもあります。
OpenFaaSをデプロイする前に、Swarm内のマシンの1つでスクリプトからDockerコマンドを実行するようにdocker-machine
に指示する必要があります。 このチュートリアルでは、スウォームマネージャーを使用してみましょう。
docker-machine use
コマンドを構成している場合は、次のコマンドを使用できます。
- docker-machine use node-1
そうでない場合は、次のコマンドを使用します。
- eval $(docker-machine env node-1)
deploy_stack.sh
スクリプトは、構成ファイル、ネットワーク設定、サービス、OpenFaaSサーバーでの認証用のクレデンシャルなど、OpenFaaSが期待どおりに機能するために必要なすべてのリソースを展開します。
スクリプトを実行してみましょう。デプロイが完了するまでに数分かかります。
- ~/faas/deploy_stack.sh
出力には、展開プロセスで作成されるリソースのリストと、OpenFaaSサーバーおよびFaaSCLIコマンドへのアクセスに使用する資格情報が表示されます。
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サーバーでFaaSCLIを認証しましょう。
スクリプトはコマンドに提供する必要のあるフラグを出力しましたが、FaaS CLIはゲートウェイサーバーが[で実行されていると想定しているため、OpenFaaSサーバーのアドレスにフラグ--gateway
を追加する必要があります。 X222X]