🦭

コンテナ技術入門 (Podman編)  Javaアプリハンズオン ビルドからLambdaでの公開まで

に公開

注釈

本記事は2025/05段階のGemini 2.5 Proによる出力を基盤とし、著者が修正を加える形で作成しています。
友人へのハンズオン資料を改編しています。そのため、見出し1つ1つが短く、AWS環境設定は省略しております。ご了承ください。

この記事のゴール

  • コンテナ技術の基本的な概念を理解する。
  • Podman を使ってコンテナを操作する基本を学ぶ。
  • 簡単なJavaアプリケーションをビルドし、イメージを作成、AWS ECR にPushし、コンテナとして動作させる手順を体験する。

対象読者

  • コンテナ技術について初めて学ぶ方
  • アプリケーション開発の効率化、モダンなデプロイ手法に興味がある方
  • Docker以外のコンテナツール(特にPodman)に関心がある方

座学

従来の開発・デプロイの課題

  • 「自分の環境では動くのに...」
    • 開発環境と本番環境の違い(OS、ライブラリ、ミドルウェアのバージョンなど)による問題が頻発。
  • 環境構築に時間がかかる
    • 新しいメンバーが加わるたび、新しいサーバーを準備するたびに環境構築が必要。
  • リソースの無駄
    • 物理サーバーや仮想マシンは、OSごと起動するため、起動が遅く、リソース消費が大きい。

そこで登場!コンテナ技術

  • アプリケーションとその実行に必要な依存関係(ライブラリ、設定ファイルなど)をひとまとめにして、隔離された環境で動かす技術。
  • 「コンテナ」という軽量な箱に入れて、どこでも同じように動かせるようにします。
    このことを「可搬性(Portability)」と言います。

仮想マシンとの違い

特徴 コンテナ 仮想マシン (例: VMware, VirtualBox)
隔離レベル プロセスレベル OSレベル
起動速度 速い (秒単位) 遅い (分単位)
リソース 軽量 (ホストOSのカーネルを共有) 重量 (ゲストOSが必要)
用途 アプリケーションの実行環境 OS全体の仮想化

コンテナのメリット

  • 可搬性:
    • 開発環境、テスト環境、本番環境で同じコンテナを動かせる。環境差異の問題を解消。
  • 軽量・高速:
    • 適切な設計の元では起動が速くリソース消費が少ない。1台のサーバーでより多くのアプリを分離し実行可能。
  • スケーラビリティ:
    • コンテナはVMと比較して軽量であるため、サーバー上でコンテナ化させた複数のアプリケーションを並列に動作させることが容易。

コンテナ技術: Podmanを使ってみよう

  • Dockerと互換性のあるコマンドラインインターフェースを持つ、デーモンレスなコンテナエンジン。
  • Red Hat社が開発を主導しており、エンタープライズ環境での利用も増えています。

なぜPodmanか?

  1. デーモンレスアーキテクチャ:
    • Dockerのように常駐する管理デーモンが不要。
    • コンテナはユーザープロセスとして直接起動されるため、システムへの影響が少なく、管理がシンプル。
    • デーモンを介さないため、ユーザーごとの操作やリソース管理が独立し、責任範囲が明確になりやすい。
  2. セキュリティ (Rootless):
    • 一般ユーザー権限でのコンテナ実行(Rootlessモード)が容易かつ標準的。セキュリティリスクを低減。
  3. Kubernetes (k8s) との親和性:
    • Pod(複数のコンテナのグループ)の概念をサポート。
    • k8sのマニフェストファイルを生成する機能など、連携がスムーズ。
  4. 開発元の信頼性:
    • Red Hat社による開発とサポートは、特にエンタープライズ利用において安心感があります。
    • エンタープライズ環境でRHELを用いている場合、その提供元からPodmanのサポートを得られる可能性があります。

Dockerとの主な違い:

  • デーモンの有無: Podmanはデーモンレス、Dockerはデーモン(dockerd)が必要。
  • コマンド: ほとんどの基本コマンド(run, build, push, pullなど)は互換性がありますが、一部異なるオプションやコマンドも存在します (dockerpodman に置き換えて使えることが多い)。

注釈: 開発現場ではいまだDockerが標準ですが、今後の潮流として十分Podmanが主軸となる可能性を期待しています。今回はPodmanを採用しましたが、今回の記載範囲では同様の動作となるため、Dockerを利用いただいても問題ありません。

Podmanの基本要素

  1. コンテナイメージ (Image):
    • コンテナの「設計図」。Dockerイメージと互換性があります。
  2. Containerfile:
    • コンテナイメージの作成手順を記述したファイル。Dockerfile という名前でも認識されますが、Podmanでは Containerfile が推奨されます。構文はDockerfileとほぼ同じです。
  3. コンテナ (Container):
    • イメージを実行した「実体」。隔離されたプロセスとして動作。
  4. コンテナレジストリ (Registry):
    • コンテナイメージを保存・共有する場所。
    • Docker Hub、Quay.io、そして今回利用する AWS Elastic Container Registry (ECR) など、様々なレジストリを利用できます。

デモ: JavaアプリケーションをPodmanとAWS ECRで扱う

これから、簡単なWebサーバー機能を持つJavaアプリケーションをビルドし、Podmanでイメージを作成、AWS ECRにPushし、コンテナとして実行するデモを行います。

デモのステップ

  1. 準備:(ご自分でご用意ください)
    • Podman のインストール
    • AWSアカウントAWS CLI のインストールおよび設定 (認証情報、デフォルトリージョン)
    • IAM権限: 使用するAWSユーザーまたはロールにECRへのPush権限,Lambda操作権限
  2. Containerfileの作成: Javaアプリをビルド・実行する手順を記述。
  3. Podmanイメージのビルド: podman build コマンドでイメージ作成。
  4. ローカルでのコンテナ起動確認: podman run コマンドで動作確認。
  5. AWS ECRへのログイン: aws ecr get-login-password コマンドと podman login を組み合わせて認証。
  6. イメージへのタグ付け: ECRの命名規則 (<AWSアカウントID>.dkr.ecr.<リージョン>.amazonaws.com/<リポジトリ名>:<タグ>) に合わせて podman tag でタグ付け。
  7. AWS ECRへのイメージPush: podman push コマンドでアップロード。
  8. AWS Lambdaでの公開: ECR上のイメージをLambdaで公開します。

Containerfileの作成

プロジェクトのルートディレクトリに Containerfile という名前でファイルを作成します。
ビルド用のアプリケーションをご用意ください。

デモ用のファイル、アプリケーションをご用意しています。
アプリケーションリポジトリを確認してください。
git cloneの上podman_trainingディレクトリへ移動し次のコマンドを実行ください。

demoディレクトリにはSpring Frameworkのクイックスタートで生成されるファイル群が格納されており、エンドポイントとして /hello,/container-info,/actuator/healthが有効化されています。

Podmanイメージのビルド

ターミナルを開き、Containerfile があるディレクトリで以下のコマンドを実行します。

# podman build -t <イメージ名>:<タグ> .
# 例: イメージ名を 'my-java-app-podman', タグを 'latest' とする
podman build -t my-java-app-podman:latest .
  • -t: イメージ名とタグを指定します。
  • .: Containerfileがある現在のディレクトリを指定します。

ローカルでのコンテナ起動確認

ビルドしたイメージをローカルで実行してみます。

# podman run -d --rm -p <ホストのポート>:<コンテナのポート> <イメージ名>:<タグ>
# 例: ホストの8080をコンテナの8080にマッピング、コンテナ終了時に自動削除(--rm)
podman run -d --rm -p 8080:8080 my-java-app-podman:latest
  • -d: バックグラウンド実行
  • --rm: コンテナ停止時に自動で削除
  • -p 8080:8080: ポートマッピング

Webブラウザで http://localhost:8080 にアクセスし、"Hello from Podman Container!" と表示されるか確認します。

確認後、podman ps でコンテナIDを確認し、podman stop <コンテナID> で停止します (--rm をつけていれば停止と同時に削除されます)。

AWS ECRへのログイン

AWS ECRにイメージをPushするために、Podmanでログインします。AWS CLIを使って一時的な認証トークンを取得し、それをPodmanに渡します。

# aws ecr get-login-password --region <リージョン> | podman login --username AWS --password-stdin <AWSアカウントID>.dkr.ecr.<リージョン>.amazonaws.com
# 例: リージョンが ap-northeast-1, AWSアカウントIDが 457227455307 の場合
aws ecr get-login-password --region ap-northeast-1 | podman login --username AWS --password-stdin 457227455307.dkr.ecr.ap-northeast-1.amazonaws.com
  • AWS CLIが認証情報を取得し、そのパスワードを標準入力経由 (--password-stdin) で podman login に渡します。ユーザー名は常に AWS です。
  • このコマンドを実行する前に、AWS CLIが正しく設定され、ECRへのアクセス権限があることを確認してください。

イメージへのタグ付け (AWS ECR用)

前提作業としてリポジトリ作成 (まだ作成していない場合)があります。

aws ecr create-repository --repository-name my-java-app-repo --region ap-northeast-1

AWS ECRへPushするイメージには、Push先のリポジトリを示すために以下の形式でタグを付けます。

<AWSアカウントID>.dkr.ecr.<リージョン>.amazonaws.com/<リポジトリ名>:<タグ>

# podman tag <ローカルイメージ名>:<タグ> <ECR用イメージ名>:<タグ>
# 例: アカウントID 457227455307, リージョン ap-northeast-1, リポジトリ名 my-java-app-repo の場合
podman tag my-java-app-podman:latest 457227455307.dkr.ecr.ap-northeast-1.amazonaws.com/my-java-app-repo:latest

AWS ECRへのイメージPush

タグ付けしたイメージをAWS ECRにPushします。

イメージのPush:

# podman push <ECR用イメージ名>:<タグ>
podman push 457227455307.dkr.ecr.ap-northeast-1.amazonaws.com/my-java-app-repo:latest
  • <AWSアカウントID>, <リージョン>, <リポジトリ名> はご自身の環境に合わせて置き換えてください。
  • Pushが完了すると、AWSマネジメントコンソールのECRリポジトリ内で確認できます。

Lambdaで公開する

Lambdaから、関数の作成を選択します。

以下のパラーメーターで作成を行います。

  • 関数名: my-java-app
  • コンテナイメージURI: GUI上から先ほどアップロードしたイメージを指定
  • アーキテクチャ: x86_64

画面遷移後、設定 > 関数URL から認証タイプ NONE で保存をしてください。
その後表示される関数URLでコンテナが公開されています。
URLにエンドポイント (/hello 等)を追加してアクセスしてみてください。

ただし、このままだとLambda側のリソースが不足しています。
そのため、設定 > 一般設定 からメモリを 512 MB、タイムアウトを 10秒 に変更します。(アプリケーションの要件に応じて調整してください)

まとめ

  • Podman はデーモンレスでセキュア、k8sとの親和性も高いコンテナエンジン。
  • Containerfile (または Dockerfile) でコンテナイメージの構築手順を定義できる。
  • 基本的なコマンドはDockerと互換性があり、移行も比較的容易。
  • AWS ECR はスケーラブルで高可用性なコンテナイメージレジストリ。AWS CLI経由で認証し podman push 可能。
  • Docker Hubの代替として、開発ワークフローに適したレジストリを選択することが重要。

参考資料


補足

IAM権限: 使用するAWSユーザーまたはロールにECRへのPush権限

今回はIAM Identity Centerにて研修用のログインアカウントを作成している想定です。
許可セットについては信頼可能なユーザーのため広めに設定しており、次の権限を割り当てています。

aws configure コマンドでアクセスキー、シークレットキー、デフォルトリージョンの設定は省略していますが、IAM Identity Centerであればログイン後にアクセスキーを容易に確認できます。

  • AmazonEC2ContainerRegistryFullAccess
  • AmazonEC2ReadOnlyAccess
  • AmazonS3FullAccess
  • AWSLambda_FullAccess

自己研鑽として簡単にお手元で試す場合、非商用の管理アカウントでのログインでも問題は無いかと思います。

実行環境

WSL2環境のUbuntu (24.04) で動作確認済みです。

AWS CLIおよびPodmanが動作すれば良いため、Podman Desktopは利用していません。任意の環境で実行可能です。
友人にやらせた際にはEC2上のUbuntuを利用しました。

Podmanの主要コマンドについて

Scrapにて基礎的なコマンドをまとめています。

Discussion