Day 5: ボリュームとネットワーク:コンテナ間でデータを共有し、通信する方法 🌐
皆さん、こんにちは!30日集中講座、Day 5へようこそ。
昨日までの講座で、単一のコンテナを動かす方法から、Docker Composeで複数コンテナのアプリケーションを構築する方法まで学びました。しかし、まだ解決すべき重要な課題が2つあります。
- データの永続化: コンテナを削除すると、その中に保存されていたデータも消えてしまう。
- コンテナ間の通信: 複数のコンテナがどのようにして安全に、そして安定して通信するのか。
今日の講座では、これらの課題を解決するDockerの2つの重要な概念、「ボリューム」と「ネットワーク」について詳しく見ていきます。これらの概念は、ローカル開発とAWS上での本番運用で考え方が大きく変わるため、その点にも焦点を当てて解説します。
1. ボリューム:コンテナの「揮発性」を乗り越える
コンテナは、デフォルトでは「一時的な存在」です。コンテナからアクセスするデータを永続化(コンテナが消えてもデータが残ること)するための仕組みがボリュームです。
ローカル開発におけるボリューム
ローカル環境では、主に以下の2つのボリュームタイプが利用されます。
- バインドマウント(Bind Mounts): ホストPCのディレクトリを、コンテナに直接マッピングします。ローカル開発に最も適しており、コードのリアルタイム同期が可能です。
- ボリューム(Volumes): Dockerが管理する領域にボリュームを作成し、コンテナにマウントします。データベースなど、ホストから直接編集する必要のないデータの永続化によく使われます。
セキュリティと永続化を意識したボリューム設定
services:
web:
build: .
ports:
- "5000:5000"
volumes:
# 開発時:ソースコードの同期(読み取り専用推奨)
- ./src:/app/src:ro
# ログファイルの永続化
- app_logs:/app/logs
# アップロードファイルの永続化
- user_uploads:/app/uploads
user: "1000:1000" # セキュリティのため非root実行
depends_on:
- db
volumes:
app_logs:
user_uploads:
postgres_data:
user
の指定により、コンテナ内で実行されるプロセスに不要な権限を与えないようにできます。ただし、UID/GIDがホスト環境と一致しない場合、Permission denied
エラーが発生する可能性があるため注意が必要です。
AWS上でのボリューム:本番環境のベストプラクティスとコスト
本番環境でデータを永続化する場合、専用のマネージドストレージサービスを利用するのがベストプラクティスです。それぞれのサービスには、パフォーマンスやコスト面で特徴があります。
サービス | 特徴 | コスト(東京リージョン) |
---|---|---|
Amazon EBS | 単一インスタンスに紐づく高性能なブロックストレージ。Multi-Attach機能を持つ一部のボリュームタイプでは、限定的に複数インスタンスからアクセス可能。 | EBS gp3: $0.096/GB/月 + IOPS/スループット料金 |
Amazon EFS | 複数コンテナから同時にアクセスできる共有ファイルシステム。アクセス量に応じてIOPSとスループットがスケール。 | EFS Standard: $0.30/GB/月 |
Amazon S3 | 静的ファイルやオブジェクトデータ用。直接的なファイルシステムアクセスには不向き。 | S3 Standard: $0.025/GB/月 |
本番環境では、これらのマネージドストレージの権限設定にIAMポリシーを適用し、コンテナがアクセスできるリソースを厳密に管理することが不可欠です。
2. ネットワーク:コンテナ間の通信を司る
コンテナは、デフォルトでは互いに隔離されています。Dockerは、コンテナ同士が通信できる仮想的な「ネットワーク」を自動で作成してくれます。
Docker Composeにおけるネットワーク
Docker Composeは、デフォルトで一つのプライベートネットワークにすべてのサービスを接続します。
より高度な制御が必要な場合は、カスタムネットワークを定義できます。internal: true
を設定すると、コンテナ同士は通信できますが、ホストやDocker Compose外のネットワークからは隔離されます。
# カスタムネットワークの例
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # 外部ネットワークとホストから隔離
AWS上でのネットワークとセキュリティ
AWSのクラウド環境では、ネットワークの考え方が大きく変わります。
- VPC(Virtual Private Cloud): AWSリソースを配置する仮想的なネットワークです。VPC内はさらにサブネットに分割し、セキュリティグループや**NACL(ネットワークACL)**を使って、きめ細やかなアクセス制御を行います。
- サービスディスカバリ: ECSではAWS Cloud Map、EKSではKubernetes DNSを利用して、サービス名とIPアドレスを結びつけます。
3. データベースの永続化とパフォーマンス
- 学習用: ローカル開発では、Docker Composeでデータベースをコンテナとして起動します。
- 本番環境: 本番環境では、可用性の高いRDSやAuroraなどのマネージドサービスを使います。これらは、自動バックアップやパッチ適用などをAWSが管理してくれるため、運用負荷が大幅に軽減されます。
コスト最適化の観点から、開発・検証環境では低コストのRDSを、本番環境では冗長構成と監視を備えたAurora Serverless v2(使用量に応じた自動スケーリング: $0.12/ACU/時間
)を利用するなど、目的に応じた選択が重要です。
4. 監視、ロギング、そしてトラブルシューティング
本番環境を意識した設定
ローカル開発から本番運用へ移行する際には、ログの管理とヘルスチェックが不可欠です。
# 本番環境を意識したログ設定
services:
web:
# ログドライバーの設定
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ヘルスチェックの追加
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
interval: 30s
timeout: 10s
retries: 3
logging
ドライバーをawslogs
に設定すれば、AWS CloudWatch Logsと連携し、ログを一元管理できます。
よくある問題と解決法
-
ボリューム未作成エラー:
docker compose up
で自動作成されますが、削除した後は注意が必要です。docker system df -v
でボリュームの使用状況を確認できます。 -
ボリューム権限エラー:
Permission denied
エラーが出る場合、権限がありません。docker compose exec web chown -R $(id -u):$(id -g) /app/uploads
で所有者を変更します。 -
ネットワーク接続エラー: サービス名で接続できない場合、
docker compose exec web nslookup db
で名前解決できるか確認しましょう。
5. まとめ:実践的なDocker運用へ
今日は、コンテナの永続化と通信を司る「ボリューム」と「ネットワーク」について深く掘り下げました。
- ボリューム: 開発ではバインドマウント、本番では名前付きボリュームやAWSのマネージドサービスを利用します。
- ネットワーク: サービスの分離やセキュリティを意識して、カスタムネットワークを活用します。
これらの知識は、単なるローカル開発にとどまらず、AWSでスケーラブルなシステムを構築するための土台となります。
次回の予告
Day 6: 第1週のまとめ:Dockerスキルチェックリスト
それでは、また明日お会いしましょう!