Azure App Service にデプロイした Spring Boot コンテナに SSH 接続する
こんにちは、@studio_meowtoon です。今回は、Azure App Service 環境でコンテナとして起動する Spring Boot Web アプリケーションに SSH 接続する方法を紹介します。
目的
Windows 11 の Linux でクラウド開発します。
こちらから記事の一覧がご覧いただけます。
実現すること
Microsoft Azure App Service にデプロイした Spring Boot WEBアプリのカスタムコンテナに SSH 接続します。
こちらの関連記事の続編になります。
この記事では、Docker Hub に公開するパブリックアクセス可能なカスタムコンテナイメージを使用しています。実際のシステム開発では、どのレジストリからコンテナイメージを取得するかは異なる場合がありますので、適宜ご確認ください。
また、Azure には完全にマネージドされたレジストリサービスである Azure Container Registry が利用できます。Azure CLI を使用しての操作方法もありますので、別の機会にご紹介したいと思います。
技術トピック
SSH とは?
こちらを展開してご覧いただけます。
SSH (Secure Shell)
SSH は、ネットワークを介して安全な通信を行うためのプロトコルの一つです。 SSH は、通信経路を暗号化し、不正アクセスや盗聴などのセキュリティ上のリスクを低減することができます。SSH は、主にリモートアクセスやファイル転送などの目的で使用されます。
開発環境
- Windows 11 Home 22H2 を使用しています。
WSL の Ubuntu を操作していきますので macOS の方も参考にして頂けます。
WSL (Microsoft Store アプリ版) ※ こちらの関連記事からインストール方法をご確認いただけます
> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47
Ubuntu ※ こちらの関連記事からインストール方法をご確認いただけます
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.1 LTS
Release: 22.04
Java JDK ※ こちらの関連記事からインストール方法をご確認いただけます
$ java -version
openjdk version "11.0.18" 2023-01-17
OpenJDK Runtime Environment (build 11.0.18+10-post-Ubuntu-0ubuntu122.04)
OpenJDK 64-Bit Server VM (build 11.0.18+10-post-Ubuntu-0ubuntu122.04, mixed mode, sharing)
Maven ※ こちらの関連記事からインストール方法をご確認いただけます
$ mvn -version
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 11.0.18, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Docker ※ こちらの関連記事からインストール方法をご確認いただけます
$ docker --version
Docker version 23.0.1, build a5ee5b1
この記事では基本的に Ubuntu のターミナルで操作を行います。Vim を使用してコピペする方法を初めて学ぶ人のために、以下の記事で手順を紹介しています。ぜひ挑戦してみてください。
Hello World を表示する手順
Spring Boot Web サービスの作成
こちらの関連記事の続きから手順を説明する記事となります。
Spring Boot アプリのプロジェクトフォルダに移動
プロジェクトフォルダに移動します。
※ ~/tmp/hello-spring-boot をプロジェクトフォルダとします。
$ cd ~/tmp/hello-spring-boot
コンテナイメージの作成
コンテナに SSH 接続する為、この記事では spring-boot:build-image によるコンテナイメージのビルドではなく、独自に Dockerfile でカスタムコンテナイメージをビルドする例を紹介します。
sshd_config ファイルを作成します。
$ vim sshd_config
ファイルの内容
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
説明を開きます。
sshd_config ファイルの内容
このファイルは、OpenSSH デーモンの設定ファイルであり、コンテナ内で実行される SSH サーバーの設定をカスタマイズするために使用されます。このファイルは、Dockerfile 内の COPY コマンドで /etc/ssh/ ディレクトリにコピーされます。
内容 |
---|
SSH サーバーが待ち受けるポート番号を 2222 に設定しています。 |
ログイン時に表示されるメッセージの表示時間を 180 秒に設定しています。 |
X11 転送を有効にしています。 |
暗号アルゴリズムと MAC アルゴリズムを指定しています。 |
StrictModes を yes に設定することで、ユーザーが直接ホームディレクトリにアクセスすることを禁止しています。 |
パスワード認証を許可し、空のパスワードを許可しないように設定しています。 |
PermitRootLogin を yes に設定しています。これにより、ルートユーザーで SSH 接続できます。 |
Subsystem sftp internal-sftp を設定することで、SFTP サブシステムが有効になり、ファイルの転送が可能になります。 |
ssh_setup.sh ファイルを作成します。
$ vim ssh_setup.sh
#!/bin/sh
# generate an ssh host keys.
ssh-keygen -A
# prepare a run dir.
if [ ! -d "/var/run/sshd" ]; then
mkdir -p /var/run/sshd
fi
説明を開きます。
ssh_setup.sh ファイルの内容
内容 |
---|
このスクリプトは、OpenSSH のための鍵ペアを生成するために ssh-keygen -A コマンドを実行し、/var/run/sshd ディレクトリを作成するための mkdir コマンドを実行します。 |
また、/var/run/sshd ディレクトリが存在しない場合は、それを作成します。このスクリプトは、コンテナイメージをビルドするときに実行され、SSH サービスの起動に必要な準備をします。 |
startup.sh ファイルを作成します。
$ vim startup.sh
#!/bin/sh
# startup openssh daemon.
/usr/sbin/sshd
# startup a jvm app.
java -jar app.jar
説明を開きます。
startup.sh ファイルの内容
このスクリプトは、OpenSSH のデーモンを起動して、Java アプリケーションを実行することにより、コンテナの起動処理を行っています。
コマンド | 内容 |
---|---|
#!/bin/sh | シェルスクリプトであることを示す宣言です。 |
/usr/sbin/sshd | OpenSSH のデーモンを起動します。これにより、コンテナ内へ SSH でアクセスできるようになります。 |
java -jar app.jar | Java アプリケーションを起動します。 java コマンドは、Java ランタイムを起動し、-jar オプションは、指定された JAR ファイルを実行することを示します。 app.jar は、起動するアプリケーションの JAR ファイルです。 |
Dockerfile を編集します。
$ vim Dockerfile
ファイルの内容
# from the base image of a jdk 11 container on Ubuntu 20.04.
FROM adoptopenjdk/openjdk11:x86_64-ubuntu-jdk-11.0.18_10-slim
# create a work dir.
WORKDIR /app
# update the package list.
RUN apt-get -y update
# install openssh and set the password for root to "Docker!".
RUN apt-get install -y openssh-server \
&& echo "root:Docker!" | chpasswd
# copy the sshd_config file to the /etc/ssh/ dir.
COPY sshd_config /etc/ssh/
# copy and configure the ssh_setup file.
COPY ssh_setup.sh .
RUN chmod +x ssh_setup.sh \
&& (sleep 1;/app/ssh_setup.sh 2>&1 > /dev/null)
# copy and configures the startup file.
COPY startup.sh .
RUN chmod +x startup.sh
# copy the jvm app.
COPY target/*.jar app.jar
# open port 8080 for jvm app and port 2222 for ssh access.
EXPOSE 8080 2222
# exec the startup script.
ENTRYPOINT ["/app/startup.sh"]
説明を開きます。
Dockerfile の内容
この Dockerfile は、Ubuntu 20.04 をベースとする JRE コンテナイメージを構築しています。 具体的には、AdoptOpenJDK が提供する OpenJDK 11 をベースとしています。
コマンド | 内容 |
---|---|
FROM adoptopenjdk/openjdk11:x86_64-ubuntu-jdk-11.0.18_10-slim | AdoptOpenJDK が提供する OpenJDK 11 をベースとして、x86_64 アーキテクチャの Ubuntu 20.04 上で実行される JRE コンテナを指定しています。 |
WORKDIR /app | /app ディレクトリを作成し、以降の作業ディレクトリを設定しています。 |
RUN apt install openssh && echo "root:Docker!" | chpasswd | OpenSSH をインストールし、root ユーザーのパスワードを Docker! に設定しています。 |
COPY sshd_config /etc/ssh/ | sshd_config ファイルを /etc/ssh/ ディレクトリにコピーしています。このファイルは、SSH デーモンの設定を定義するためのものです。 |
COPY ssh_setup.sh . | ssh_setup.sh ファイルをコンテナ内の作業ディレクトリにコピーしています。このスクリプトは、SSH 接続を設定するためのもので、コンテナ起動時に実行されます。 |
RUN chmod +x ssh_setup.sh && (sleep 1;/app/ssh_setup.sh 2>&1 > /dev/null) | ssh_setup.sh ファイルに実行権限を与え、SSH 接続を設定するために実行します。 |
COPY startup.sh . | startup.sh ファイルをコンテナ内の作業ディレクトリにコピーしています。このスクリプトは、コンテナ起動時に JVM アプリケーションを実行するためのものです。 |
RUN chmod +x startup.sh | startup.sh ファイルに実行権限を与えます。 |
COPY target/*.jar app.jar | ビルドされた JVM アプリケーションの Jar ファイルをコンテナ内の app.jar ファイルにコピーしています。 |
EXPOSE 8080 2222 | コンテナのポート 8080 と 2222 を公開しています。 |
ENTRYPOINT ["/app/startup.sh"] | コンテナ起動時に startup.sh スクリプトを実行し、JVM アプリケーションを実行します。 |
Docker 環境を確認します。
$ docker --version
Docker version 23.0.1, build a5ee5b1
Docker 環境をお持ちでない場合は、以下の関連記事から Docker Engine のインストール手順をご確認いただけます。
コンテナイメージをビルドします。
$ docker build --no-cache -t app-hello-spring-boot-ssh .
コンテナイメージを確認します。
$ docker images | grep app-hello-spring-boot-ssh
app-hello-spring-boot-ssh latest 4a94045f5846 8 seconds ago 545MB
コンテナイメージを起動
ローカルでコンテナイメージを起動して確認します。
$ docker run --name app-local -p 8080:8080 app-hello-spring-boot-ssh
ローカルのコンテナを停止します。
$ docker stop app-local
Docker Hub にコンテナイメージを登録
Docker Hub のアカウントを作成します。
Docker Hub は、コンテナの共有、保存、および管理のためのクラウドベースのレジストリです。Docker Hub には、コミュニティによって作成された公式およびコミュニティによるイメージが格納されています。また、ユーザーがカスタムコンテナイメージをアップロードおよび共有することもできます。
Docker Hub にログインします。
$ docker login
Login Succeeded
コンテナイメージにタグを付けます。
※ $USER の部分はご自身のコンテナリポジトリに読み替えて下さい。
$ docker tag app-hello-spring-boot-ssh $USER/app-hello-spring-boot-ssh:latest
Docker Hub にコンテナイメージをプュシュします。
$ docker push $USER/app-hello-spring-boot-ssh:latest
ここまでで、Docker Hub に $USER/app-hello-spring-boot-ssh:latest としてカスタムコンテナイメージが公開出来ました。
Azure 環境にサインイン
こちらの関連記事の続きから手順を説明する記事となります。
Azure CLI でログインします。
$ az login
Azure 環境
リソースグループ
リソースグループを作成します。
$ az group create \
--name rg-hello \
--location japaneast
App Service プラン
App Service プランを作成します。
$ az appservice plan create \
--resource-group rg-hello \
--name asp-hello \
--sku Free \
--is-linux
App Service Web アプリ
Web アプリの作成とデプロイを行います。
※ $USER の部分はご自身のコンテナリポジトリに読み替えて下さい。
$ az webapp create \
--resource-group rg-hello \
--plan asp-hello \
--name app-hello-spring-boot-ssh \
--deployment-container-image-name $USER/app-hello-spring-boot-ssh:latest
Web アプリの設定を構成します。
※ App Service Web アプリはデフォルトで 80 番ポートをリッスンする仕様です。
$ az webapp config appsettings set \
--resource-group rg-hello \
--name app-hello-spring-boot-ssh \
--settings WEBSITES_PORT=8080
Web アプリ動作の確認
以下のコマンドを実行すると、WEBブラウザーが立ち上がります。
$ az webapp browse \
--resource-group rg-hello \
--name app-hello-spring-boot-ssh
立ち上がりに少し時間が掛かりますがページが表示されます。 しかし表示されたページ "/" にはコンテンツを設定していません。
WEBブラウザには以下のように表示されます。
改めてWEBブラウザで確認します。
※ URLは環境で読み替えて下さい。
https://app-hello-spring-boot-ssh.awesomewebsites.net/api/data
WEBブラウザに {"message":"Hello World!"} と表示され、JSON データを取得することが出来ました。
※ 別ターミナルから curl コマンドで確認してみます。
$ curl -v https://app-hello-spring-boot-ssh.awesomewebsites.net/api/data
ターミナルに {"message":"Hello World!"} と表示され、JSON データを取得することが出来ました。
Azure App Service 自体が SSL/TLS 対応および HTTP/2 プロトコルをサポートしています。
コンテナに接続
コンテナに SSH で接続します。
$ az webapp ssh \
--resource-group rg-hello \
--name app-hello-spring-boot-ssh
説明を開きます。
このコマンドは、Azure App Service Web アプリに対して SSH 接続を確立します。
コマンド | 内容 |
---|---|
az webapp ssh | App Service Web アプリに SSH 接続を確立するためのコマンドです。 |
オプション | 値 | 内容 |
---|---|---|
--resource-group | rg-hello | App Service Web アプリを含むリソースグループの名前を指定します。 |
--name | app-hello-spring-boot-ssh | App Service Web アプリの名前を指定します。 |
コンテナに接続後にディレクトリを確認します。
※ コンテナから出るときは ctrl + D を押します。
# pwd
/root
# cd /app
# ls -la
total 17256
drwxr-xr-x 2 root root 4096 Mar 8 11:18 .
drwxr-xr-x 59 root root 4096 Mar 8 11:34 ..
-rw-r--r-- 1 root root 17650443 Mar 8 07:17 app.jar
-rwxr-xr-x 1 root root 107 Mar 8 10:30 ssh_setup.sh
-rwxr-xr-x 1 root root 70 Mar 8 11:16 startup.sh
コンテナの情報を表示してみます。
# cat /etc/*-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.5 LTS"
NAME="Ubuntu"
VERSION="20.04.5 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.5 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
このコンテナは Ubuntu をベースに作成されています。つまり、Ubuntu と同じように扱うことができます。
Azure Portal
Azure Portal の App Service Web アプリ の SSH の項目からも確認できます。
Web ブラウザからコンテナに SSH 接続できました。
注意点
Microsoft は、カスタムコンテナで SSH サポートを使用する方法を公開しています。
ただし、SSH デーモンを実行する設定をコンテナイメージ作成時に特別に付け加えることは、コンテナのポータビリティに懸念があるため、実際のシステム開発で避けることが推奨されます。Azure では、Container Apps というカスタムコンテナイメージのデプロイ手法も提供されています。
こちらの記事では、Azure Container Apps を使用した方法について説明しています。
まとめ
Azure App Service 環境で、Dockerfile からビルドした Spring Boot Web サービスのカスタムコンテナに SSH 接続することができました。
Maven、Docker、Azure CLI を使って、Spring Boot アプリの開発からコンテナイメージの作成、Azure 環境へのデプロイまで、すべてをターミナルから行うことができます。このように、クラウドでのシステム開発に必要なスキルや理解を深めることができます。初めての人でも簡単に手順を追うことができるので、ぜひ挑戦してみてください。
どうでしたか? 検証目的として、WSL Ubuntu で、Spring Boot Web アプリケーションを Azure App Service 環境にデプロイし、コンテナに手軽に SSH 接続することができます。ぜひお試しください。今後も Azure の開発環境などを紹介していきますので、ぜひお楽しみにしてください。
推奨コンテンツ