作成日: 2025-01-24 ステータス: Draft コンセプト: Simple Queue-Based Autoscaling
Kubernetes標準のHPAを使い、Redisキュー深度に基づいてWorker数を自動調整する。
設計原則:
- Kubernetes標準のHPA(Horizontal Pod Autoscaler)を使用
- サードパーティツール(KEDA等)は使わない
- シンプルな実装(Prometheus Adapter + HPA)
スケーリングロジック:
desired_workers = ceil(queue_depth / tasks_per_worker)
例: キューに100タスク、1 Workerあたり10タスク → 10 Workers
Producer → Redis Queue ← Worker Pods
↓
Queue Metrics → Prometheus → Prometheus Adapter
↓
HPA → Scale Workers
コンポーネント:
- Redis: タスクキュー(既存)
- Metrics Exporter: キュー深度をPrometheusメトリクスとして公開
- Prometheus: メトリクス収集(既存を想定)
- Prometheus Adapter: PrometheusメトリクスをKubernetes Custom Metricsに変換
- HPA: キュー深度で自動スケール
- Worker Deployment: Kubernetes Deploymentで管理
# graflow/metrics/queue_exporter.py
from prometheus_client import Gauge, generate_latest
from flask import Flask, Response
import redis, os
app = Flask(__name__)
gauge = Gauge('graflow_queue_depth', 'Queue depth', ['key_prefix'])
r = redis.Redis(host=os.getenv('REDIS_HOST', 'localhost'), port=6379)
@app.route('/metrics')
def metrics():
prefix = os.getenv('KEY_PREFIX', 'graflow')
depth = r.llen(f"{prefix}:queue")
gauge.labels(key_prefix=prefix).set(depth)
return Response(generate_latest(), mimetype='text/plain')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)Worker Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: graflow-worker
spec:
replicas: 2 # 手動スケーリング: この値を変更
selector:
matchLabels:
app: graflow-worker
template:
metadata:
labels:
app: graflow-worker
spec:
containers:
- name: worker
image: graflow-worker:latest
args:
- --worker-id=$(POD_NAME)
- --redis-host=redis-service
- --redis-key-prefix=graflow
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2000m"
memory: "2Gi"HPA設定:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: graflow-worker-hpa
spec:
scaleTargetRef:
kind: Deployment
name: graflow-worker
minReplicas: 1
maxReplicas: 20
metrics:
- type: External
external:
metric:
name: graflow_queue_depth
target:
type: AverageValue
averageValue: "10" # 1 Workerあたり10タスクNote: Prometheus Adapterの設定が必要(後述)
- Kubernetes クラスタ(v1.23+)
- Prometheus(既存を想定、なければHelm等で導入)
- kubectl CLI
1. Prometheus Adapter インストール(Helm):
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus-adapter prometheus-community/prometheus-adapter \
--set prometheus.url=http://prometheus-server.monitoring.svc \
--set prometheus.port=802. Metrics Exporter デプロイ:
kubectl apply -f metrics-exporter.yaml3. Worker Deployment デプロイ:
kubectl apply -f worker-deployment.yaml4. HPA 作成:
kubectl apply -f hpa.yaml5. 動作確認:
# HPA状態確認
kubectl get hpa graflow-worker-hpa
# メトリクスが取得できているか確認
kubectl get --raw /apis/external.metrics.k8s.io/v1beta1/namespaces/default/graflow_queue_depth
# Worker Pods確認
kubectl get pods -l app=graflow-worker --watchHPAの状態確認:
# HPA状態
kubectl get hpa graflow-worker-hpa
# 詳細表示(スケーリングイベント含む)
kubectl describe hpa graflow-worker-hpa
# リアルタイム監視
watch kubectl get hpa graflow-worker-hpaキュー深度確認:
# Redis CLI経由
kubectl exec -it deployment/redis -- redis-cli LLEN "graflow:queue"
# Metrics Exporter経由
kubectl port-forward svc/metrics-exporter 8000:8000
curl http://localhost:8000/metrics | grep graflow_queue_depthWorker状態確認:
kubectl get pods -l app=graflow-worker
kubectl top pods -l app=graflow-worker # CPU/メモリ使用率HPAが自動でスケールしますが、緊急時やテスト時には手動でも調整可能:
# 一時的にHPAを無効化
kubectl delete hpa graflow-worker-hpa
# 手動でスケール
kubectl scale deployment graflow-worker --replicas=10
# HPAを再度有効化
kubectl apply -f hpa.yaml注意: HPAが有効な状態で手動スケールしても、すぐにHPAが上書きします。
HPAが動作しない:
# HPA状態確認
kubectl describe hpa graflow-worker-hpa
# メトリクスが取得できているか確認
kubectl get --raw /apis/external.metrics.k8s.io/v1beta1/namespaces/default/graflow_queue_depth
# Prometheus Adapterログ確認
kubectl logs -n monitoring deployment/prometheus-adapter
# Metrics Exporterログ確認
kubectl logs deployment/metrics-exporterWorkerが起動しない:
kubectl logs deployment/graflow-worker
kubectl describe pod <pod-name>スケールが遅い:
HPAのデフォルト設定では安全のためゆっくりスケールします。必要に応じてbehavior設定を調整:
spec:
behavior:
scaleUp:
stabilizationWindowSeconds: 0 # すぐにスケールアップ
policies:
- type: Percent
value: 100 # 一度に2倍まで
periodSeconds: 15
scaleDown:
stabilizationWindowSeconds: 300 # 5分待ってからスケールダウン採用する技術:
- ✅ Kubernetes標準のHPA(Horizontal Pod Autoscaler)
- ✅ Prometheus + Prometheus Adapter(標準的なメトリクスパイプライン)
- ✅ シンプルなMetrics Exporter(~15行)
実装しないもの(YAGNI):
- ❌ KEDA(標準HPAで十分)
- ❌ 複雑なbehavior設定(必要になったら追加)
- ❌ マルチテナント専用設定(key_prefixで分離可能)
- ❌ 優先度ベーススケーリング(必要になったら追加)
設計原則:
- Kubernetes標準機能を優先: サードパーティツールは避ける
- シンプル: 必要最小限の構成
- 保守性: 標準的な構成なので引き継ぎやすい
本設計の特徴:
- Kubernetes標準のHPAを使用した自動スケーリング
- Prometheus Adapterでキュー深度をKubernetesメトリクスに変換
- シンプルな構成で保守しやすい
導入のメリット:
- ワークロード変動に自動対応
- 手動スケーリング不要
- コスト最適化(アイドル時はminReplicas、ピーク時は自動増強)
推奨セットアップ:
本番環境:
minReplicas: 2 (冗長性確保)
maxReplicas: 20-50 (ワークロードに応じて)
averageValue: 10 (1 Workerあたり10タスク)
開発環境:
minReplicas: 1
maxReplicas: 10
averageValue: 20 (コスト削減)