Docker ネットワークの基本概念
コンテナ間の効率的かつ安全な通信を実現するには、Dockerネットワークの仕組みを理解することが重要です。ネットワーク構成は、情報が適切に流れるための基盤となります。
主要な基礎知識
Dockerネットワークは、コンテナの接続と相互作用の方法を定義する重要な要素です。
- ネットワーク名前空間: 各コンテナは独立したネットワーク環境(IPアドレス、ルーティングテーブル、ポート番号)を持ちます。
- 内部・外部通信: コンテナ間の内部通信と、ポートマッピングによる外部通信が可能です。Dockerはサービス名による自動発見のためのDNSサービスを提供します。
- ネットワークドライバ:
- ブリッジ: 同一ホスト上のコンテナ通信に適したデフォルトドライバ
- ホスト: コンテナがホストのネットワークを直接利用するモード
- オーバーレイ: Docker Swarm環境での複数ホスト間通信を可能にするドライバ
- ネットワーク設定: コマンドラインまたはComposeファイルによる設定、IPアドレス管理(IPAM)の構成が可能です。
- セキュリティと分離: ネットワーク分離によるセキュリティ向上と、ファイアウォールルールによる追加保護が実現できます。
実践ケース:Flaskマイクロサービスの構築
FlaskアプリケーションとRedisサービス間の通信を実現するネットワーク構成の例を示します。
アプリケーションの作成
# web_app.py
from flask import Flask
import redis
import os
application = Flask(__name__)
cache_host = os.getenv('CACHE_HOST', 'localhost')
cache_client = redis.Redis(host=cache_host, port=6379)
@application.route('/')
def index():
visits = cache_client.incr('visitor_count')
return f'ようこそ!訪問回数: {visits}回'
if __name__ == '__main__':
application.run(debug=True, host='0.0.0.0', port=8000)
# 依存パッケージ定義ファイル
flask
redis
Dockerイメージのビルド
FROM python:3.9-alpine
WORKDIR /service
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY web_app.py .
EXPOSE 8000
CMD ["python", "web_app.py"]
ネットワークの構築と実行
# カスタムネットワークの作成
docker network create app-network
# Redisサービスの起動
docker run -d --name cache-service --network app-network redis:alpine
# Flaskアプリケーションのビルドと実行
docker build -t web-service .
docker run -d --name web-service --network app-network -p 8000:8000 web-service
ネットワーク構成の詳細設定
高度なネットワーク設定
プロダクション環境でのネットワーク構成には、より詳細な設定が必要です。
データベース連携の例
# database_app.py
from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://db_user:db_pass@database/app_db'
db = SQLAlchemy(app)
class Customer(db.Model):
customer_id = db.Column(db.Integer, primary_key=True)
customer_name = db.Column(db.String(100), unique=True, nullable=False)
@app.route('/customers')
def get_customers():
return jsonify({'status': 'Database connected'})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
# MySQLコンテナの設定
docker run -d --name database \
--network app-backend \
-e MYSQL_ROOT_PASSWORD=admin_pass \
-e MYSQL_DATABASE=app_db \
-e MYSQL_USER=db_user \
-e MYSQL_PASSWORD=db_pass \
mysql:8.0
セキュリティ対策の実装
安全なコンテナ実行
プロダクション環境では、以下のセキュリティ対策が推奨されます。
非特権ユーザーでの実行
FROM python:3.9-slim
# 専用ユーザーの作成
RUN groupadd -r appgroup && useradd -r -g appgroup appuser
# 作業ディレクトリの設定と権限変更
WORKDIR /application
RUN chown -R appuser:appgroup /application
USER appuser
COPY --chown=appuser:appgroup requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
COPY --chown=appuser:appgroup . .
CMD ["python", "secure_app.py"]
機密情報の管理
# Swarm環境でのSecret利用
echo "production-api-key-12345" | docker secret create api_secret_key -
# Composeファイルでの定義
version: '3.8'
services:
api_service:
image: secure-api:v1
secrets:
- api_secret_key
environment:
- API_KEY_FILE=/run/secrets/api_secret_key
secrets:
api_secret_key:
external: true
ネットワーク分離の実践
サービス間通信の制御
# 公開APIサービス
# public_api.py
from flask import Flask, jsonify
import requests
api = Flask(__name__)
@api.route('/status')
def service_status():
return jsonify({"service": "operational"})
@api.route('/fetch-data')
def retrieve_data():
try:
response = requests.get('http://internal-data-service:9001/data')
return response.json()
except Exception as e:
return jsonify({"error": str(e)}), 503
if __name__ == '__main__':
api.run(host='0.0.0.0', port=8080)
# ネットワークの分離設定
docker network create public-access
docker network create private-internal
# サービスの分離実行
docker run -d --name public-api \
--network public-access \
-p 8080:8080 \
public-api-service
docker run -d --name internal-service \
--network private-internal \
internal-data-service
マルチホスト環境の構成
オーバーレイネットワークの利用
# Swarmクラスタでのネットワーク作成
docker network create \
--driver overlay \
--subnet 10.10.0.0/16 \
--attachable \
cluster-network
# 分散サービスのデプロイ
docker service create \
--name distributed-api \
--network cluster-network \
--replicas 3 \
--publish published=80,target=8080 \
web-application:latest
セキュリティスキャンと監視
コンテナの脆弱性検査
# セキュリティスキャンツールの使用例
# イメージの脆弱性検査
docker scan web-application:latest
# 実行時セキュリティチェック
docker run --security-opt no-new-privileges \
--read-only \
--tmpfs /tmp \
secured-container:latest
監視システムの構築
# 監視用Compose設定例
version: '3.7'
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana:latest
environment:
- GF_SECURITY_ADMIN_PASSWORD=secure_pass
ports:
- "3000:3000"
depends_on:
- prometheus
ログ管理の設定
# ログドライバーの指定
docker run -d \
--log-driver=json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
--name monitored-app \
application-service:latest
# ログの確認と分析
docker logs --tail 50 --follow monitored-app
これらの実践を通じて、Docker環境におけるネットワーク構成とセキュリティ対策の重要性を理解できます。適切なネットワーク設計とセキュリティ対策は、本番環境でのアプリケーション運用に不可欠です。