Create Express.js virtual machine using Azure CLI
このチュートリアルでは、Express.js アプリ用の Linux 仮想マシン (VM) を作成します。 この VM は、cloud-init 構成ファイルで構成され、NGINX と Express.js アプリの GitHub リポジトリが含まれています。 SSH を使用して VM に接続し、トレースのログ記録を含めるように Web アプリを変更して、公開された Express.js サーバー アプリを Web ブラウザーで表示します。
このチュートリアルに含まれるタスクは次のとおりです。
- Azure CLI を使用して Azure にサインインする
- Azure CLI を使用して Azure Linux VM リソースを作成する
- パブリック ポート 80 を開く
- GitHub リポジトリから Express.js Web アプリのデモをインストールする
- Web アプリの依存関係をインストールする
- Web アプリの起動
- Azure CLI を使用して Azure 監視リソースを作成する
- SSH を使用して VM に接続する
- npm を使用して Azure SDK クライアント ライブラリをインストールする
- Application Insights クライアント ライブラリ コードを追加して、カスタム トレースを作成する
- ブラウザーから Web アプリを表示する
/trace
ルートを要求して、Application Insights ログにカスタム トレースを生成する- Azure CLI を使用して、ログに収集されたトレースの数を表示する
- Azure portal でトレースの一覧を表示する
- Azure CLI を使用してリソースを削除する
前提条件
- Azure ユーザー アカウントとサブスクリプション: 無料のサブスクリプションを作成します。
- VM に接続するための SSH: Azure Cloud Shell、または SSH を含む bash シェルなどの最新ターミナルを使用します。
Azure Cloud Shell で Bash 環境を使用します。 詳細については、「Azure Cloud Shell の Bash のクイックスタート」を参照してください。
CLI リファレンス コマンドをローカルで実行する場合、Azure CLI をインストールします。 Windows または macOS で実行している場合は、Docker コンテナーで Azure CLI を実行することを検討してください。 詳細については、「Docker コンテナーで Azure CLI を実行する方法」を参照してください。
ローカル インストールを使用する場合は、az login コマンドを使用して Azure CLI にサインインします。 認証プロセスを完了するには、ターミナルに表示される手順に従います。 その他のサインイン オプションについては、Azure CLI でのサインインに関するページを参照してください。
初回使用時にインストールを求められたら、Azure CLI 拡張機能をインストールします。 拡張機能の詳細については、Azure CLI で拡張機能を使用する方法に関するページを参照してください。
az version を実行し、インストールされているバージョンおよび依存ライブラリを検索します。 最新バージョンにアップグレードするには、az upgrade を実行します。
1. Web ページ用の Application Insights リソースを作成する
すべての Azure リソース用の Azure リソース グループと、Web アプリのログ ファイルを Azure クラウドに収集するための Monitor リソースを作成します。 リソース グループを作成することにより、リソースを見つけやすくなり、完了時に削除しやすくなります。 Azure Monitor は Azure サービスの名前ですが、Application Insights はこのチュートリアルで使用するクライアント ライブラリの名前です。
(省略可能) サブスクリプションが複数ある場合は、az account set を使用して既定のサブスクリプションを設定してから、残りのコマンドを完了します。
az account set \ --subscription "ACCOUNT NAME OR ID"
az group create を使用して Azure リソース グループを作成します。
rg-demo-vm-eastus
という名前を使用します。az group create \ --location eastus \ --name rg-demo-vm-eastus
Azure CLI を使用して Azure Monitor リソースを作成する
Azure CLI に Application Insights 拡張機能をインストールします。
az extension add -n application-insights
az monitor app-insights component create を使用して監視リソースを作成するには、次のコマンドを使用します。
az monitor app-insights component create \ --app demoWebAppMonitor \ --location eastus \ --resource-group rg-demo-vm-eastus \ --query instrumentationKey --output table
出力から結果をコピーします。後でその値が
instrumentationKey
として必要になります。このターミナルは開いたままにしてください。次のステップで使用します。
2. Azure CLI を使用して Linux 仮想マシンを作成する
cloud-init 構成ファイルを使用して、NGINX リバース プロキシ サーバーと Express.js サーバーの両方を作成します。 NGINX は、Express.js ポート (3000) をパブリック ポート (80) に転送するために使用されます。
cloud-init-github.txt
という名前のローカル ファイルを作成して次の内容をファイルに保存するか、ローカル コンピューターにリポジトリのファイルを保存することができます。 cloud init 形式のファイルは、Azure CLI コマンドのターミナル パスと同じフォルダーに存在している必要があります。#cloud-config package_upgrade: true packages: - nginx write_files: - owner: www-data:www-data path: /etc/nginx/sites-available/default content: | server { listen 80 default_server; server_name _; location / { # First, try if the file exists locally, otherwise request it from the app try_files $uri @app; } location @app { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } runcmd: # install Node.js - 'curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -' - 'sudo apt-get install -y nodejs' # clone GitHub Repo into myapp directory - 'cd /home/azureuser' - git clone "https://github.com/Azure-Samples/js-e2e-vm" myapp # Start app - 'cd myapp && npm install && npm start' # restart NGINX - systemctl restart nginx
ファイルの
runcmd
セクションを確認して、その内容を理解します。runcmd
には、いくつかのタスクがあります。- Node.js をダウンロードしてインストールします
- GitHub から
myapp
ディレクトリにサンプル Express.js リポジトリを複製します - アプリケーションの依存関係をインストールします
- PM2 を使用して Express.js アプリを開始します
仮想マシンのリソースを作成する
ターミナルで Azure CLI コマンド az vm create を入力して、Linux 仮想マシンの Azure リソースを作成します。 このコマンドでは、cloud-init ファイルから VM が作成され、SSH キーが生成されます。 コマンドを実行すると、キーが格納されている場所が表示されます。
az vm create \ --resource-group rg-demo-vm-eastus \ --name demo-vm \ --location eastus \ --public-ip-sku Standard \ --image UbuntuLTS \ --admin-username azureuser \ --generate-ssh-keys \ --custom-data cloud-init-github.txt
この処理には数分かかることがあるため、待機します。
publicIpAddress の値を控えておきます。これは、ブラウザーで Web アプリを表示するため、および VM に接続するために必要です。 この IP が失われた場合は、Azure CLI コマンドの az vm list-ip-addresses を使用して、もう一度取得します。
このプロセスで SSH キーが作成され、応答に記載されている場所に保存されました。
その場所に移動し、
authorized_keys
ファイルを作成します。cd <SSH-KEY-LOCATION> && cat id_rsa >> authorized_keys
仮想マシンのポートを開く
仮想マシンを最初に作成したときに、開いているポートは "ありません"。 続いて、Azure CLI コマンド az vm open-port を使用してポート 80 を開き、Web アプリが一般公開されるようにします。
az vm open-port \
--port 80 \
--resource-group rg-demo-vm-eastus \
--name demo-vm
Web サイトの参照
Web ブラウザーでパブリック IP アドレスを使用して、仮想マシンが使用可能で実行されていることを確認します。
publicIpAddress
の値を使用するように URL を変更します。http://YOUR-VM-PUBLIC-IP-ADDRESS
ゲートウェイ エラーが発生してリソースにアクセスできなかった場合は、しばらくしてからもう一度やり直してください。Web アプリが開始されるまでに 1 分ほどかかることがあります。
仮想マシンの Web アプリから次の情報が返されます。
- VM 名
- クライアント IP
- 現在の日時
Web アプリの最初のコード ファイルには、NGINX プロキシを経由したルートが 1 つあります。
const os = require('os'); const express = require('express') const app = express() app.use('/public', express.static('public')) app.get('/', function (req, res) { const clientIP = req.headers['x-forwarded-for']; const msg = `HostName: ${os.hostname()}<br>ClientIP: ${clientIP}<br>DateTime: ${new Date()}<br><img width='200' height='200' src='/public/leaves.jpg' alt='flowers'>` console.log(msg) res.send(msg) }) app.listen(3000, function () { console.log(`Hello world app listening on port 3000! ${Date.now()}`) })
3. SSH を使用して Linux 仮想マシンに接続する
チュートリアルのこのセクションでは、ターミナルで SSH を使用して仮想マシンに接続します。 SSH は、Azure Cloud Shell を含む多くの最新シェルに用意されている一般的なツールです。
SSH を使用して接続して Web アプリを変更する
以下のコマンドを使用して、リモート仮想マシンに接続します。
YOUR-VM-PUBLIC-IP
を、お使いの仮想マシンのパブリック IP に置き換えます。ssh azureuser@YOUR-VM-PUBLIC-IP
このプロセスでは、お使いの SSH クライアントが SSH キーを検出でき、VM 作成の一環として作成され、ローカル コンピューター上に配置されていることを前提としています。
接続を確認するメッセージが表示されたら、
y
またはyes
と回答して続行します。次のコマンドを使用して、仮想マシン上の自分の場所を把握します。 azureuser のルート
/home/azureuser
にいるはずです。pwd
接続が完了すると、ターミナル プロンプトはリモート仮想マシンのユーザー名とリソースを示すように変更されます。
azureuser@demo-vm:
Web アプリはサブ ディレクトリ
myapp
にあります。myapp
ディレクトリに移動し、内容を一覧表示します。cd myapp && ls -l
仮想マシンに複製された GitHub リポジトリと npm パッケージ ファイルを表す内容が表示されます。
-rw-r--r-- 1 root root 891 Nov 11 20:23 cloud-init-github.txt -rw-r--r-- 1 root root 1347 Nov 11 20:23 index-logging.js -rw-r--r-- 1 root root 282 Nov 11 20:23 index.js drwxr-xr-x 190 root root 4096 Nov 11 20:23 node_modules -rw-r--r-- 1 root root 84115 Nov 11 20:23 package-lock.json -rw-r--r-- 1 root root 329 Nov 11 20:23 package.json -rw-r--r-- 1 root root 697 Nov 11 20:23 readme.md
Monitoring SDK のインストール
仮想マシンに接続されている SSH ターミナルで、Application Insights 用の Azure SDK クライアント ライブラリをインストールします。
sudo npm install --save applicationinsights
コマンドが完了するまで待ってから続行します。
監視インストルメンテーション キーの追加
仮想マシンに接続されている SSH ターミナルで、Nano エディターを使用して
package.json
ファイルを開きます。sudo nano package.json
APPINSIGHTS_INSTRUMENTATIONKEY
環境変数を Start スクリプトの先頭に追加します。 次の例では、REPLACE-WITH-YOUR-KEY
をインストルメンテーション キーの値に置き換えてください。"start": "APPINSIGHTS_INSTRUMENTATIONKEY=REPLACE-WITH-YOUR-KEY pm2 start index.js --watch --log /var/log/pm2.log"
引き続き SSH ターミナルで、Ctrl + X を使用して Nano エディターでファイルを保存します。
Nano エディターでダイアログが表示されたら、「Y」と入力して保存します。
Nano エディターでダイアログが表示されたら、表示されたときにファイル名を受け入れます。
VM を停止してアプリケーションを変更する
これで Azure クライアント ライブラリは node_modules に配置され、キーは環境変数としてアプリに渡されました。 次の手順では、プログラムで Application Insights を使用します。
次のコマンドを使用して、PM2 を停止します。これは、Node.js アプリケーション用の実稼働プロセス マネージャーです。
sudo npm run-script stop
Application Insights を使用して元の
index.js
をファイルに置き換えます。sudo npm run-script appinsights
クライアント ライブラリとログ コードが指定されます。
const express = require('express') const app = express() const os = require('os'); console.log(JSON.stringify(process.env)); const AppInsights = require('applicationinsights'); if (process.env.APPINSIGHTS_INSTRUMENTATIONKEY) { console.log(`AppInsights configured with key ${process.env.APPINSIGHTS_INSTRUMENTATIONKEY}`); } else{ console.log(`AppInsights not configured`); } AppInsights.setup(process.env.APPINSIGHTS_INSTRUMENTATIONKEY) .setAutoDependencyCorrelation(true) .setAutoCollectRequests(true) .setAutoCollectPerformance(true, true) .setAutoCollectExceptions(true) .setAutoCollectDependencies(true) .setAutoCollectConsole(true) .setUseDiskRetryCaching(true) .setSendLiveMetrics(false) .setDistributedTracingMode(AppInsights.DistributedTracingModes.AI) .start(); const AppInsightsClient = AppInsights.defaultClient; app.get('/trace', (req, res) => { const clientIP = req.headers['x-forwarded-for']; const msg = `trace route ${os.hostname()} ${clientIP} ${new Date()}`; console.log(msg) if (process.env.APPINSIGHTS_INSTRUMENTATIONKEY) { AppInsightsClient.trackPageView(); AppInsightsClient.trackTrace({ message: msg }) AppInsightsClient.flush(); } else { msg += ' AppInsights not configured'; } res.send(`${msg}`) }) app.get('/', function (req, res) { const clientIP = req.headers['x-forwarded-for']; const msg = `root route ${os.hostname()} ${clientIP} ${new Date()}` console.log(msg) res.send(msg) }) app.listen(3000, function () { console.log(`Hello world app listening on port 3000! ${os.hostname()}`) })
PM2 を使用してアプリを再起動し、次の環境変数を取得します。
sudo npm start
アプリを使用してログ記録を確認する
Web ブラウザーで、新しい
trace
ルートを使用してアプリをテストします。http://YOUR-VM-PUBLIC-IP-ADDRESS/trace
ブラウザーに応答が表示されます。
trace route demo-vm YOUR-CLIENT-IP VM-DATE-TIME
とお使いの IP アドレスです。
NGINX のログの表示
仮想マシン (VM) で収集される NGINX のログを表示できます。
サービス | ログの場所 |
---|---|
NGINX | /var/log/nginx/access.log |
- 引き続き SSH ターミナルで、次のコマンドを使用して NGINX プロキシ サービスの VM ログを表示します。
cat /var/log/nginx/access.log
- ログには、お使いのローカル コンピューターからの呼び出しが含まれています。
"GET /trace HTTP/1.1" 200 10 "-"
PM2 のログの表示
仮想マシン (VM) で収集される PM2 のログを表示できます。
サービス | ログの場所 |
---|---|
PM2 | /var/log/pm2.log |
Express.js Node Web アプリである PM2 サービスの VM ログを表示します。 同じ bash シェルで、次のコマンドを使用してログを表示します。
cat /var/log/pm2.log
ログには、お使いのローカル コンピューターからの呼び出しが含まれています。
grep "Hello world app listening on port 3000!" /var/log/pm2.log
ログには、npm start スクリプトで渡された、ApplicationInsights キーを含む環境変数も含まれています。 次の grep コマンドを使用して、お使いのキーが環境変数に含まれていることを確認します。
grep APPINSIGHTS_INSTRUMENTATIONKEY /var/log/pm2.log
これにより、
APPINSIGHTS_INSTRUMENTATIONKEY
が別の色で強調表示された PM2 ログが表示されます。
VM ログとクラウド ログ
このアプリケーションでは、console.log
を使用して、VM でのみ検出される PM2 ログにメッセージを書き込んでいます。 ログまたは VM を削除すると、その情報は失われます。
仮想マシンの使用期間を超えてログを保持する場合は、Application Insights を使用します。
5.リソースをクリーンアップする
このチュートリアルを完了したら、リソース グループを削除する必要があります。リソース グループにはすべてのリソースが含まれているため、削除することで、それ以上の使用に対して課金されないようにします。
同じターミナルで、Azure CLI コマンドの az group delete を使用してリソース グループを削除します。
az group delete --name rg-demo-vm-eastus -y
このコマンドには数分かかります。
トラブルシューティング
問題がある場合は、次の表を使用して問題を解決する方法を確認してください。
問題 | 解決方法 |
---|---|
502 ゲートウェイ エラー | これは、index.js または package.js にエラーがあることを示している可能性があります。 詳細については、/var/log/pm2.log の PM2 ログを参照してください。 最新のエラーは、ファイルの下部にあります。 これらのファイルが正しい場合は、package.json の npm スクリプトを使用して PM2 を停止して起動します。 |