📦

Azure App ServiceのカスタムコンテナでSSHを有効にする

に公開

Azure App ServiceのカスタムコンテナでSSHを有効にする

Azure App Service は手軽に Web アプリケーションをホストできる便利なサービスです。
Azure Container Registry (ACR) を活用すれば、独自にビルドしたコンテナをデプロイできるため、組織の要件に応じた柔軟なアプリケーション運用が可能になります。

ただし、ACRで単純にコンテナをデプロイすると、SSH 接続でコンテナ内部を確認できない という制約があります。
一時的に確認したいファイルを Azure Files に保存する方法もありますが、実際にはコンテナの中に直接入り、ログや設定を確認したい場面が多々あると思います。
そのため、カスタムコンテナに SSH を組み込み、App Service 上から安全に利用できるようにしておくと便利です。

本記事では、Python Flask アプリを例に、SSH を有効にするための具体的な手順を解説したいと思います。

1. 前提条件

  • アプリケーションは Docker イメージで動作
  • 今回は Flask アプリを想定
  • ACR にイメージを push し、App Service にデプロイする流れ

2. sshd_configの作成

リポジトリ直下に SSH サーバー用の設定ファイル sshd_config を用意します。
ポート番号は 2222 を利用します。

Port 			2222
ListenAddress 		0.0.0.0
LoginGraceTime 		180
X11Forwarding 		yes
Ciphers aes128-cbc,3des-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr
MACs hmac-sha1,hmac-sha1-96
StrictModes 		yes
SyslogFacility 		DAEMON
PasswordAuthentication 	yes
PermitEmptyPasswords 	no
PermitRootLogin 	yes
Subsystem sftp internal-sftp

3. entrypoint.shスクリプトの作成

entrypoint.sh を作成し、アプリ起動と同時に SSH サービスも立ち上げます。
以下は Flask + Gunicorn の例です。exec以降の部分は、各々の環境に応じて、適宜置き換えてください。

#!/bin/sh
set -e
echo "SSH is now starting..."
service ssh start
exec gunicorn --bind 0.0.0.0:5000 wsgi:app --workers=4 --threads=4 --timeout=120

4. Dockerfile の構成

以下のように Dockerfile を構成します。

  • OpenSSH サーバーをインストール
  • sshd_config をコピー
  • ルートパスワードを設定(App Service 内部のみに利用される)
  • SSH 用ポート 2222 を公開
# Dockerfile (抜粋)
FROM python:3.11-slim

WORKDIR flask_pj

# ...(省略)...
# (必要なライブラリのインストールやリポジトリファイルのコピー)

COPY entrypoint.sh ./

# SSH
RUN apt-get update \
    && apt-get install -y --no-install-recommends dialog \
    && apt-get install -y --no-install-recommends openssh-server \
    && echo "root:Docker!" | chpasswd \
    && chmod u+x ./entrypoint.sh
COPY sshd_config /etc/ssh/

EXPOSE 8000 2222

ENTRYPOINT [ "./entrypoint.sh" ] 

5. ACRリソースの作成

ACR(Azure Container Registry)は、App Service にコンテナをデプロイする際の必須リソースです。
以下のように Azure CLI から作成できます。

az acr create \
  --resource-group your-resource-group \
  --name acrname \
  --sku Basic

6. Docker Imageのビルド&push

逐一コマンドを打っても良いのですが、面倒なので、以下のようにACR へのビルド & push をスクリプト化しておくと便利です。
スクリプトの実行前にはaz loginを実行し、AzureCLIで認証を済ませておいてください。

#!/usr/bin/env bash
set -euo pipefail

# ユーザーに質問をする関数
ask_question() {
  read -r -p "$1 " user_response
  echo "$user_response"
}

echo "デプロイを実行します。"

TAG=$(ask_question "イメージタグを入力")
echo "タグ ${TAG} でデプロイを実行します。"

# パラメータ
RESOURCE_GROUP="your-resource-group"
REGISTRY_NAME="acrname"   # ACR名
REPO="acrname"            # リポジトリ名

# ACR情報取得
LOGIN_SERVER=$(az acr show --resource-group "$RESOURCE_GROUP" --name "$REGISTRY_NAME" --query loginServer -o tsv)
CRED=$(az acr credential show --resource-group "$RESOURCE_GROUP" --name "$REGISTRY_NAME")
USER=$(echo "$CRED" | jq -r '.username')
PASS=$(echo "$CRED" | jq -r '.passwords[0].value')

# Docker login
echo "$PASS" | docker login "$LOGIN_SERVER" --username "$USER" --password-stdin

# ビルド・タグ付け・プッシュ
docker build --platform linux/amd64 -t "$REPO:$TAG" .
docker tag "$REPO:$TAG" "$LOGIN_SERVER/$REPO:$TAG"
docker push "$LOGIN_SERVER/$REPO:$TAG"

7. App Service 上での SSH 接続確認

Docker イメージを ACR に push し、App Service にデプロイしたら、SSH 接続が正しく動作しているかを確認します。
App Service では、外部から直接ポート 2222 にアクセスできないため、App Service SSH コンソール を利用します。

  1. Azure Portal で対象の App Service を開く

  2. 左メニューから 「開発ツール」>「SSH」 → 「移動」を選択
    screenshot

  3. ブラウザベースのコンソールが起動します
    以下のように、コンソール画面の下側で、緑の背景色で「SSH CONNECTION ESTABLISHED」と表示されていたら成功です。
    screenshot

なお、App Service の SSH 接続は 診断やデバッグ用途 が前提になっています。
本番環境の稼働中に恒常的に利用するべきではありませんので、常時運用するなら、ログの外部転送や Azure Monitor の活用を検討してください。

参考

https://learn.microsoft.com/ja-jp/azure/app-service/configure-custom-container?pivots=container-linux&tabs=debian#enable-ssh

Discussion