ほどよく、Azure Functions と Docker の組み合わせがうまくいくことが分かったので、実運用でのパターンを考えてみる。Docker は内部のポートを外部のポートへ -p オプションを使ってフォワードして、外部から http://servername.com:8000/ のようにアクセスできる。だが、こうすると Docker を動かして機能を増やすたびにポートを開放しないといけなくて、結構リスキーだったりする。
ならば、host://func.servername.com/ のようにサブドメイン名をしておいて、これを http://servername.com:8000/ にフォワードしてくれるように設定すれば、開放するポートは 80 番だけで済む。これを実現するのが「リバースプロキシ」なんだけど、Apache や Nginx でその機能がある。
Apacheでリバースプロキシ – Qiita https://qiita.com/tac0x2a/items/1ad05f204ac5ab679fb2
ひとまず、Apache を使って動作を確認してみよう。
目的
リバースプロキシを使って、サブドメインを指定すると、内部で起動している Docker コンテナに接続できるようにする。
実現方法
- ローカルで動作している Linux サーバー「luna.local」を使う。
- Docker コンテナを -p 8000:80 で起動しておく
- Windows 10 から azfunc.luna.local にアクセスすると、luna.local:8000 とアクセスしたと同じように設定する
設定手順
リバースプロキシの設定
Linux サーバーの luna.local に apache2 をインストールして、
1 | /etc/apache2/sites-available/azfunc.luna.local.conf |
を設定する。
1 2 3 4 5 6 7 8 9 10 | <VirtualHost *:80> ServerAdmin webmaster@azfunc.luna.local ErrorLog /var/log/apache2/error.log CustomLog /var/log/apache2/access.log combined LogLevel warn ProxyPreserveHost On ServerName azfunc.luna.local ProxyPass / http://localhost:8000/ ProxyPassReverse / http://localhost:8000/ </VirtualHost> |
これでリバースプロキシを使って、azfunc.luna.local のアクセスが http://localhost:8000/ にフォワードされる。
proxy 用のコマンドを動かして、apache2 をリブートする。
1 2 3 4 | $ sudo a2enmod proxy $ sudo a2enmod proxy_http $ sudo a2ensite azfunc.luna.local.conf $ sudo service apache2 restart |
Docker の起動
1 | sudo docker run -it --rm -p 8000:80 moonmile/sample-azure-docker |
あらかじめ、hub.docker.com にアップロード済みの moonmile/sample-azure-docker をダウンロードして実行する。
sample-azure-docker は、func init と func new して作った .NET 環境の Azure Function である。
Windows 10 の hosts 設定
実は、luna.local は、DNS を使っているのではなくて、ubuntu 上で avahi-daemon を起動している。なので、Windows 10 から luna.local は見れるけど、azfunc.luna.local は見れない。
これを見れるようにするため、Windows 10 の hosts に以下の行を追加する。IP は Docker が動いている Linux サーバーの IP になる。この場合は、luna.local と同じ値になる。
1 | 192.168.1.11 azfunc.luna.local |
ping azfunc.luna.local として通知できているか確認しておく。
ブラウザからアクセス
ブラウザから http://azfunc.luna.local/ へアクセスすると、無事 Function App の最初のページが表示される。これでうまく通達ができていることがわかる。
再びブラウザで、URLアドレス http://azfunc.luna.local/api/HttpTrigger1?name=masuda にアクセスすると、「Hello, masuda」と表示されることがわかる。
これでうまくローカルのFunction Appが動いていることが確認できた。
まとめ
構造的にはこんな形になっている。
- ブラウザからサブドメイン付きで呼び出す
- Apache2 は 80 番で受ける
- リバースプロキシで、指定サブドメインは 8000 番へ送る
- Dockerは 8000 番で受けたものを、コンテナの 80 番へ送る
- .NET Core + Function App が動作する
いわゆる、本番の Azure 上で sample-azure-docker.azurewebsites.net のようにアクセスしている部分を、Azure 無し&ローカル環境で構築できるというわけだ。当然のことながら、Azure の機能は使えないけど、Azure Functions だけの機能を使って試したいというのは結構簡単に実現できることが分かる。特に、本番の Azure Functions で Linux 環境+Docker の組み合わせにしようとすると、Linux の VM が必要になってしまい、月額5,000円位かかることになる。これはちょっと高い。
なので、一般的な VPS を借りてきて、そこの中でサブドメイン付きで作れれば、.NET Core + Azure Functions な環境を Docker で動かすのも悪くないかなと思うのだがどうだろうか。たぶん、Docker の運用系の使い方としては、こういうサブドメインを経由させるほうが一般的だと思う。
実際は認証やSSLなどは、HTTPヘッダの部分をリバースプロキシのところで設定しないといけないのだが。まあ、ひとまずローカルな Linux サーバーで確認がとれたといことで。
あとで、nginx のリバースプロキシも確認してみる。