コンテナー シェル (SSH) を開き、Azure App Service でコマンドを実行する

App Serviceはトラブルシューティングや管理作業のために、実行中のアプリコンテナへの認証済みアクセスを提供します。 コンテナアクセスを特権操作として扱い、必要なユーザーにのみアクセスを付与します。

App Serviceは、Windowsカスタムコンテナでホストされているアプリに対してブラウザベースのSSHアクセスを提供します。 ブラウザセッションに特別な画像設定は必要ありません。

Azure CLI az webapp execコマンドはLinuxのウェブアプリでのみサポートされています。 この記事のLinuxのCLI例はWindows アプリサービスプランに使わないでください。

搭載およカスタム Linux コンテナーの場合、新しいブラウザ ターミナルと az webapp exec は、Kudu を認証済みプロキシとして使用し、実行中のコンテナーに接続します。 これらのオプションでは、カスタム イメージにSSH サーバーをインストールしたり、SSH パスワードを埋め込んだり、SSH ポートを公開したり、SSH デーモンを起動したりする必要はありません。 レガシー Kudu の WebSSH や az webapp ssh SSH アクセスは、カスタム イメージ内の SSH サーバーが必要になるかもしれません。

ブラウザセッションにはAzureポータルを使い、ローカルターミナルセッションやデタッチされたコマンド実行にはプレビューaz webapp execコマンドを使います。 ブラウザ端末は画像に /bin/bash が必要で、現在は他のシェルを選択することもサポートしていません。 画像のシェルが異なる場合は、代わりに az webapp exec --shell /bin/sh を使いましょう。 シェルのない画像、ディストロレス画像も含めて、インタラクティブセッションを開くことはできません。

Prerequisites

  • アプリとそのコンテナは動作しています。
  • あなたにはアプリのSCM/Kuduサイトへのアクセス権限があります。 権限については、 Kuduにアクセスするために必要なRBAC権限を参照してください。
  • クライアントはSCMエンドポイントへのネットワークアクセスを持っています。 接続できない場合はアプリの アクセス制限 やプライベートネットワーク設定を確認してください。
  • CLIの例としては、Azure CLI 2.90.0以降をインストールしてサインインしてください。 az version を使用して、お使いのバージョンを確認します。 また、CLIがこの要件を満たしていれば、Azure Cloud Shellも利用できます。
  • CLIのインタラクティブセッションでは、インタラクティブターミナルと、イメージに存在するシェルを使いましょう。 デフォルトは /bin/bash です。bash が含まれていないイメージの場合、そのシェルが利用可能な場合は --shell /bin/sh を指定してください。

ブラウザーで SSH セッションを開く

ブラウザセッションを開く前に、アプリとそのコンテナが稼働している必要があります。

AzureポータルでApp Serviceアプリを開きます。 [開発ツール] で [SSH] を選択し、次に [Go] を選択します。 求められたらAzureアカウントでサインインしてください。

セッションはブラウザで開き、そこでアプリコンテナ内でコマンドを実行できます。

SSH 接続

Azure CLI を使用して SSH セッションを開く

プレビュー az webapp exec コマンドはアプリのメインコンテナ内にインタラクティブシェルを開きます。 セッションはWindows、macOS、Linuxのローカルターミナルを使い、ブラウザは開きません。

az webapp exec --resource-group <resource-group-name> --name <app-name>

/bin/sh の代わりに bash を使うイメージの場合:

az webapp exec --resource-group <resource-group-name> --name <app-name> --shell /bin/sh

このセッションではコマンドを実行し、出力を検査できます。 例えば、イメージにインストールされている場合は top を使いましょう。 アプリのコンテナではなくSCM/Kuduコンテナを検査するには:

az webapp exec --resource-group <resource-group-name> --name <app-name> --target kudu

アプリとKuduコンテナは異なる環境です。 アプリのランタイム、依存関係、ネットワーク接続に依存するコマンドをアプリコンテナ内で実行してください。

インスタンスまたはデプロイスロットを選択してください

デフォルトでは、CLIは1つのアプリインスタンスに接続します。 インスタンスIDを見つけるには:

az webapp list-instances --resource-group <resource-group-name> --name <app-name> --output table

特定のインスタンスに接続するには:

az webapp exec --resource-group <resource-group-name> --name <app-name> --instance <instance-id>

デプロイメントスロットにアクセスするために --slot <slot-name> を追加してください。 スロットのインスタンスを選択する際は、--slotにaz webapp list-instancesも追加してください。

インタラクティブシェルモードは一度に1つのインスタンスのみをサポートします。

インタラクティブなセッションなしでコマンドを実行する

ターミナルセッションを開かずに、 --mode execute を使ってメインのアプリコンテナにコマンドを送信できます。 コマンドはデタッチされた状態で動作します。 このモードは、バックグラウンドでの診断や即時出力を必要としない作業に適しています。

Important

実行モードは fire-and-forgetです。 状態が accepted の結果は、要求が受理されたことのみを確認するものであり、コマンドが実行されたこと、完了したこと、または成功したことを示すものではありません。 CLIはリモートコマンドの標準出力、標準誤り、または終了コードを返しません。 失敗した送信はCLIエラーを引き起こしますが、CLI呼び出しが成功したからといってリモート実行の成功の証明にはなりません。 結果をすぐに確認したいときはインタラクティブシェルを使いましょう。

プログラムを直接実行する

--commandを使ってプログラムとその引数を指定します。 コマンド全体を引用してください:

az webapp exec --resource-group <resource-group-name> --name <app-name> --mode execute --command "python3 /home/site/wwwroot/scripts/diagnostics.py" --working-directory /home/site/wwwroot --instance <instance-id>

スクリプトパスをアプリにデプロイしたスクリプトに置き換えてください。 実行ファイルとその依存関係はコンテナ内に存在しなければなりません。

--command は >、|、&& などのシェル演算子を解釈しません。 シェルが必要なときは --shell-command を使いましょう。 この二つの選択肢は相反するものです。

出力をキャプチャして完了を確認する

以下の例では、Cloud Shell などの Bash クライアントでのクォートを使用しています。 読み取り専用の診断コマンドを1つのインスタンスに送信し、その出力と終了ステータスを別々に記録します。 <run-id>を各呼び出しの新しい識別子に置き換え、az webapp list-instancesを<instance-id>のIDに置き換えてください。

az webapp exec --resource-group <resource-group-name> --name <app-name> \
  --mode execute --instance <instance-id> --shell /bin/sh \
  --shell-command 'uname -a > /home/LogFiles/diagnostics-<run-id>.log 2>&1; result=$?; printf "%s\n" "$result" > /home/LogFiles/diagnostics-<run-id>.exit'

/bin/shと診断コマンドが存在し、/home/LogFilesが存在し書き込み可能であることを確認しましょう。 カスタムコンテナ内で /home の永続性は、アプリの ストレージ構成に依存します。 シングルクォートは、リクエストがコンテナに届く前にクライアントシェルが $? と $result を展開するのを防ぎます。

送信後、同じインスタンス上で インタラクティブなアプリシェル を開き、ファイルを確認してください:

cat /home/LogFiles/diagnostics-<run-id>.log
cat /home/LogFiles/diagnostics-<run-id>.exit

記録された終了ステータスが0である場合、診断コマンドが成功したことを示します。 ゼロ以外のステータスは失敗を示します。ログを確認してください。 状態ファイルが存在しない場合、完了状態は確定していません。コマンドがまだ実行中であるか、まだ開始されていないか、あるいは中断された可能性があります。 受容や部分的なログの存在から成功を推測しないでください。 古いステータスファイルが現在の結果と間違われないように、新しい実行識別子を使いましょう。

CLIは完了ポーリングAPIを提供していません。 出力をファイルにリダイレクトしても、App Serviceのログストリーミングで自動的に利用可能になるわけではありません。

データベースの移行やその他の共有状態を変える操作については、 1つの インスタンスを選択し、完了を別途チェックし、送信時に出力が返っていないからといって操作をやり直さないでください。 成功を確認する必要がある場合はインタラクティブなワークフローを維持してください。

複数のインスタンスで独立したコマンドを実行する

実行モードは、--instance all またはインスタンス ID のカンマ区切りリストも受け入れます。 複数インスタンスの作成リクエストは並行して送信されます。 例えば、すべてのインスタンスでデプロイされたインスタンスごとの診断スクリプトを実行します:

az webapp exec --resource-group <resource-group-name> --name <app-name> --mode execute --command "python3 /home/site/wwwroot/scripts/diagnostics.py" --instance all

スクリプトは、自身の処理結果を記録する必要があります。 ストレージが共有されている場合は、インスタンスごと、および実行ごとに異なる出力パスを使用します。 共有データベースの移行や、一度だけ実行しなければならない他の操作には all を使わないでください。 一部の送信が失敗すると、他のインスタンスがそのコマンドを受け入れている可能性にもかかわらず、CLIはエラーを報告します。

デプロイ スロットに対して実行するには、--slot <slot-name> を追加します。

Limitations

  • 実行モードはメインのアプリコンテナのみをターゲットにします。 --target kuduはインタラクティブシェルモードでのみ使用できます。
  • --working-directoryまたは--cwdは実行モードでのみ使用し、絶対パスを指定してください。
  • --shellに絶対パスを指定してください。 実行モードでは、それは--shell-commandでのみ使用できます。
  • このプレビューにはファイル転送、ポートフォワーディング、任意のサイドカーコンテナ選択のオプションはありません。 サポートされている デプロイ方法 を使ってファイルをアップロードしてください。
  • デタッチ実行は、永続的なジョブ スケジューラーではありません。 コンテナの再起動や交換は作業を中断させることがあります。 自動再試行や「正確に 1 回」の実行を前提にしないでください。

SSHアクセスの制御

SSHアクセスを必要としないアプリでは、アプリのsshEnabled設定プロパティをfalseに設定してSSHアクセスを無効にしてください。 以下の例はBash JSONの引用を使用しています。

az webapp config set --resource-group <resource-group-name> --name <app-name> \
  --generic-configurations '{"sshEnabled": false}'

SSHアクセスを再度有効にするには:

az webapp config set --resource-group <resource-group-name> --name <app-name> \
  --generic-configurations '{"sshEnabled": true}'

構成を確認するために:

az webapp config show --resource-group <resource-group-name> --name <app-name> --query sshEnabled

展開スロットを設定または確認するには、--slot <slot-name> を追加してください。

アプリとスロット全体のガバナンスには、App Service アプリは SSH を無効にする必要がある および App Service アプリ スロットは SSH を無効にする必要がある 組み込みポリシーを使用します。 割り当てリンクについては App Service ポリシー リファレンス を参照してください。

両ポリシーとも Audit をデフォルトで提供し、 Deny と Disabledもサポートしています。 ここでは、欠落値または偽ではない sshEnabled の値を、準拠していないものと評価します。 監査レポートでは不適合が指摘されていますが、SSH は無効化されません。 Denyは非準拠のリソース変更を防ぎます。既存のアプリを自動的に再構成するわけではありません。 サブスクリプションや管理グループの範囲でポリシーを割り当てることができ、テナント全体のガバナンスのためのテナントルート管理グループも含まれます。

SSHの設定やポリシー準拠は、SCM/Kuduへのアクセスの保護の代わりにはなりません。 適切な RBAC権限 と ネットワークアクセス制限を活用してください。

コンテナアクセスのトラブルシューティング

  • アプリが正常に起動しているか確認してください。 起動失敗の 診断ログ を確認してください。
  • CLIアクセスについては、CLIバージョン、選択したアプリ、スロット、インスタンス、そして要求された実行ファイルやシェルが存在するかどうかを確認してください。
  • SCMエンドポイントへの認可とネットワーク接続を確認してください。 基本的な公開認証を有効にする必要はありません。CLIはSCMの基本認証が無効化されている場合、Microsoft Entra認証をサポートしています。 基本認証を無効にするを参照してください。
  • コンテナ内で行った変更は、アプリやイメージの更新や再デプロイの代わりにはなりません。 コンテナの再起動により、永続保存ストレージの外にあるファイルは失われる可能性があります。