[Advent Calendar 2017 Day3] Web Apps - Linux への対応

 

こちらの記事は、Qiita に掲載した Microsoft Azure Tech Advent Calendar 2017 の企画に基づき、執筆した内容となります。
カレンダーに掲載された記事の一覧は、こちらよりご確認ください。

 

こんにちは。Azure CIE サポート 今村 です。
今回は、2017 年より強化された Web Apps のコンテナ対応、および Linux 対応について、アドベント カレンダー 3 日目の記事としてまとめてみました。

 

1. 従来の App Service


これまでの App Service は、その基盤にて Windows Server と IIS を利用し、「サンドボックス」と呼ばれる環境の中にアプリケーションを配置していました。

App Service におけるアーキテクチャに関しては、弊社開発部門の Yochay および Stefan が書いた MSDN マガジンの以下の記事に、詳細が記載されています。
"Azure - Inside the Azure App Service Architecture" : https://msdn.microsoft.com/en-us/magazine/mt793270.aspx

 

なかでも、Linux をベースとした Web Apps においては、Web Worker と呼ばれるインスタンス群が、従来の Web Apps とは大きく異なっています。
Web Worker は、ユーザーがデプロイしたアプリケーションを動作させるためのインスタンスで、App Service プランよりスケール アウト/スケール インを行う際には、この Web Worker と呼ばれるインスタンスが増減しています。
Web Apps のコンテナ対応、ならびに Linux プラットフォームへの対応にあたっては、Web Worker と呼ばれるインスタンス群を Linux OS にて動作させ、さらにそのうえで Docker エンジンを動かすことで、サービスを実現しています。

 

また、既定の Docker イメージを利用して様々な言語のアプリケーションが配置可能な App Service on Linux というサービスと、ユーザーが独自にビルドした Docker イメージをデプロイ出来る Web App for Containers というサービスに分かれています。
次項よりそれぞれのサービスを見ていきたいと思います。

 

2. App Service on Linux


Linux プラットフォームに対応したことで、Web App の作成の際に、Azure ポータルでは新たに OS の種類を選択するオプションが追加されました。
ここで Linux OS を選択すると、App Service on Linux としてデプロイが行われます。

 

2017 年 12 月 3 日現在では、Node.js、PHP、.NET Core、Ruby の 4 種類の言語が、バージョンごとに選択可能となっています。
これらのランタイム スタックは、いずれも Docker イメージとなっており、Azure ポータルで言語を選択すると、docker run コマンドによりイメージからコンテナが起動される仕組みとなっています。
また、これらの Docker イメージは Dockerfile とともに、下記の通り Docker Hub 上に公開されています。

"Azure App Service" :
https://hub.docker.com/u/appsvc/

後述する Web App for Containers を利用して、独自にビルドした Docker イメージをデプロイする場合、これらのリポジトリをフォークしたうえで Dockerfile の作成に取り掛かると、より分かりやすいかもしれません。

 

次に、高度なツール (Kudu) はどのように Windows OS の場合と異なっているか見てみます。
Debug console を見てみると、Bash と SSH という 2 通りの選択肢があることが分かります。

 

ここで注意すべきなのが、Bash を選択した場合、Kudu 自体のファイル システムにアクセスする動作となる点です。
実は、上述した Docker Hub でも Kudu というリポジトリがあったとおり、Kudu も Docker エンジン上で機能するコンテナとして配置されており、Bash はこの Kudu コンテナに対するアクセスになります。

この Bash コンソールへのアクセスは、内部で実行されている docker コマンドの動作をトラブルシュートする際に有用です。
例えば docker pull や docker run といったコマンドの実行ログは、下記のように /home/LogFiles ディレクトリの配下に配置されます。

そのため、実際に Node.js や PHP アプリケーションが動作しているコンテナにアクセスするには、SSH コンソールの方を利用します。

 

ランタイム スタックを切り替えて、言語ごとに動作しているミドルウェアを SSH コンソールから確認してみると、それぞれが異なる仕組みで動作していることが分かります。

例えば、PHP のランタイム スタックで ps コマンドを実行してプロセスの一覧を確認すると、Web サーバーおよびアプリケーション サーバーとして Apache2 が動作しています。

一方で  Node.js では、node が直に HTTP の要求をリッスンしているため、下記のようなプロセスが動いている形になります。

Windows OS をベースとした Web Apps では、HTTP の要求はすべて IIS を介在させる形となっていましたが、App Service on Linux では、言語ごとにミドルウェアが全く異なった内容で、アプリケーションを動作させている点が大きな違いであると言えます。

 

また、Web ブラウザを経由した SSH コンソールを利用して、アプリケーションが動作するコンテナにアクセスはできますが、SSH コンソールから何らかの設定変更や、コンポーネントのインストールを行うことは推奨されません。
これは、/home ディレクトリ以外のファイルは、App Service on Linux が再起動されるたびに初期化されるためです。
App Service on Linux を再起動すると、docker run コマンドが実行され、Docker イメージからコンテナが再構成されるため、マウントされている /home ディレクトリ以外に保存した内容は、既定の内容に置き換えられます。

そのため、例えば PHP のランタイム スタックで Apache2 の設定を変更するために、apache2.conf を書き換えて保存したとしても、その設定内容を恒久的に反映させることはできません。
.htaccess など、/home ディレクトリに配置できるような方法で、設定変更を行う必要がありますので、注意が必要です。

 

 

3. Web App for Containers


Web App for Containers は、App Service on Linux とは異なり、独自に作成した Docker イメージをデプロイできる点が大きな特徴です。
新たな Web App リソースを追加する際に、"Web App for Containers" と入力して検索を行うと、サービスが表示されます。
(2017 年 12 月 3 日現在、日本語環境の Azure ポータルにて "Web App on Linux" と表示される場合がありますが、"Web App on Linux" をそのままご選択ください。)

 

作成画面を見ると、App Service on Linux のときとは異なり、Docker Hub や Azure Container Registry 等に存在する、Docker イメージを指定する方式に変わっていることが分かります。
例えば、Docker Hub の Public リポジトリより WordPress をデプロイする場合は、wordpress と入力して作成を行います。

ここで選択した Docker イメージは、Azure ポータルの Docker コンテナのメニューより、あとから切り替えることも可能です。

 

WordPress の作成後、アクセスしてみると分かりますが、App Service on Linux の場合と比較して、Web App for Containers にアクセスしてもすぐには WordPress が立ち上がっていないことが確認できます。
この理由は、Kudu の Bash コンソールより、docker ログを確認すると分かります。

Web App for Containers の場合、App Service on Linux の場合と比較して、docker pull コマンドが実行され、イメージをダウンロードする動作となっていることが確認できます。
ここでは 13:12:22 から 13:12:58 までのおよそ 30 秒間、docker pull コマンドに時間を要していたことになります。
そのため、重い Docker イメージを利用する場合は注意が必要です。

 

また、App Service on Linux の場合と異なり、SSH コンソールへ繋がらないことも分かります。

カスタムの Docker イメージにて SSH 接続を行う場合、Dockerfile の中でいくつかの設定を含める必要があります。
例えば、root アカウントのパスワードを "Docker!" にするといった変更が必要となり、そのため多くの Docker Hub 上のイメージは、Kudu から SSH 接続ができません。
SSH をセットアップする手順の詳細は、下記よりご確認ください。

"カスタム Docker イメージでの SSH サポート" :
/ja-jp/azure/app-service/containers/app-service-linux-ssh-support#ssh-support-with-custom-docker-images

一方で App Service on Linux では、SSH コンソールを提供するために、ランタイム スタックの中で SSH のセットアップが含まれています。

 

また、Web App for Containers の場合、再起動が行われた際には /home 以下のディレクトリも、docker run コマンドの実行直後の状態に戻る設定が、デフォルトとなっています。
この状態は、Web Worker として利用されているインスタンスが個別に /home 以下のディレクトリを保持しており、インスタンス間で、マウントしたディレクトリを共有していない状態であることを意味します。
この場合、ネットワーク経由でマウントした領域を利用しないため、I/O が高速に行えるというメリットはありますが、インスタンス間で共有したいファイルがある場合、この既定の設定では要望を満たせないことになります。

ディレクトリのマウントは、Web Apps の「アプリケーション設定」のメニューより有効・無効が切り替えられるようになっているため、マウントが必要な場合は "WEBSITES_ENABLE_APP_SERVICE_STORAGE" の値を "true" に設定してください。
既定では下記のように false が入力されています。

 

 

このように、App Service では、今後も Linux への対応を拡充していきます。
もちろん、これまで提供してきた Windows 版も同様にご利用いただけますので、配置するアプリケーションの要件や用途に応じて、プラットフォームをご検討ください。