🎄 科学と神々株式会社 アドベントカレンダー 2025
Hybrid License System Day 24: Kubernetes対応
統合・デプロイ編 (4/5)
📖 はじめに
Day 24では、Kubernetes対応を学びます。Kubernetesマニフェスト作成、Service/Deployment設定、ConfigMap/Secret管理、Ingress設定を実装しましょう。
🎯 Kubernetesアーキテクチャ
クラスター構成
┌─────────────────────────────────────┐
│ Ingress Controller │
│ (NGINX/Traefik) │
└──────────┬──────────────────────────┘
│
┌─────┴─────┐
│ Ingress │ (ルーティング)
└─────┬─────┘
│
┌───────┴────────┐
│ │
┌──▼───────┐ ┌──────▼──────┐ ┌────────▼─────┐
│API GW │ │Auth Service │ │Admin Service │
│Service │ │Service │ │Service │
│ │ │ │ │ │
│ Pod×3 │ │ Pod×3 │ │ Pod×2 │
└──────────┘ └─────────────┘ └──────────────┘
│ │ │
└────────────┴──────────────────┘
│
┌──────▼──────┐
│ SQLite DB │
│ (PV/PVC) │
└─────────────┘
📦 Namespace設定
namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: license-system
labels:
app: license-system
environment: production
🔐 ConfigMapとSecret
ConfigMap
# k8s/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: license-system-config
namespace: license-system
data:
NODE_ENV: "production"
LOG_LEVEL: "info"
API_GATEWAY_PORT: "3000"
AUTH_SERVICE_PORT: "3001"
ADMIN_SERVICE_PORT: "3002"
AUTH_SERVICE_URL: "http://auth-service:3001"
ADMIN_SERVICE_URL: "http://admin-service:3002"
DB_PATH: "/data/licenses.db"
Secret
# k8s/secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: license-system-secrets
namespace: license-system
type: Opaque
stringData:
JWT_SECRET: "your-super-secret-jwt-key-change-this-in-production"
SERVICE_SECRET: "your-service-secret-key-change-this"
ADMIN_PASSWORD: "secure-admin-password"
🚀 Deployment設定
API Gateway Deployment
# k8s/api-gateway-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-gateway
namespace: license-system
labels:
app: api-gateway
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
app: api-gateway
template:
metadata:
labels:
app: api-gateway
tier: frontend
spec:
containers:
- name: api-gateway
image: ghcr.io/yourorg/license-system-api-gateway:v1.0.0
ports:
- containerPort: 3000
name: http
env:
- name: NODE_ENV
valueFrom:
configMapKeyRef:
name: license-system-config
key: NODE_ENV
- name: AUTH_SERVICE_URL
valueFrom:
configMapKeyRef:
name: license-system-config
key: AUTH_SERVICE_URL
- name: ADMIN_SERVICE_URL
valueFrom:
configMapKeyRef:
name: license-system-config
key: ADMIN_SERVICE_URL
- name: SERVICE_SECRET
valueFrom:
secretKeyRef:
name: license-system-secrets
key: SERVICE_SECRET
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 2
---
apiVersion: v1
kind: Service
metadata:
name: api-gateway
namespace: license-system
labels:
app: api-gateway
spec:
type: ClusterIP
selector:
app: api-gateway
ports:
- port: 3000
targetPort: 3000
protocol: TCP
name: http
Auth Service Deployment
# k8s/auth-service-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: auth-service
namespace: license-system
labels:
app: auth-service
tier: backend
spec:
replicas: 3
selector:
matchLabels:
app: auth-service
template:
metadata:
labels:
app: auth-service
tier: backend
spec:
containers:
- name: auth-service
image: ghcr.io/yourorg/license-system-auth-service:v1.0.0
ports:
- containerPort: 3001
name: http
env:
- name: NODE_ENV
valueFrom:
configMapKeyRef:
name: license-system-config
key: NODE_ENV
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: license-system-secrets
key: JWT_SECRET
- name: SERVICE_SECRET
valueFrom:
secretKeyRef:
name: license-system-secrets
key: SERVICE_SECRET
- name: DB_PATH
valueFrom:
configMapKeyRef:
name: license-system-config
key: DB_PATH
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 1000m
memory: 1Gi
livenessProbe:
httpGet:
path: /health
port: 3001
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 3001
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: data
persistentVolumeClaim:
claimName: license-db-pvc
---
apiVersion: v1
kind: Service
metadata:
name: auth-service
namespace: license-system
spec:
type: ClusterIP
selector:
app: auth-service
ports:
- port: 3001
targetPort: 3001
protocol: TCP
💾 永続化ボリューム
PersistentVolumeClaim
# k8s/pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: license-db-pvc
namespace: license-system
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: standard
🌐 Ingress設定
Ingress(NGINX)
# k8s/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: license-system-ingress
namespace: license-system
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/rate-limit: "100"
spec:
ingressClassName: nginx
tls:
- hosts:
- license-system.example.com
secretName: license-system-tls
rules:
- host: license-system.example.com
http:
paths:
- path: /api/v1
pathType: Prefix
backend:
service:
name: api-gateway
port:
number: 3000
- path: /admin
pathType: Prefix
backend:
service:
name: admin-service
port:
number: 3002
📈 HPA(Horizontal Pod Autoscaler)
HPA設定
# k8s/hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-gateway-hpa
namespace: license-system
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-gateway
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 15
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 2
periodSeconds: 15
selectPolicy: Max
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: auth-service-hpa
namespace: license-system
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: auth-service
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 75
🔍 デプロイコマンド
Kubectlコマンド
#!/bin/bash
# deploy-k8s.sh
# Namespace作成
kubectl apply -f k8s/namespace.yaml
# ConfigMapとSecret
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/secret.yaml
# PVC
kubectl apply -f k8s/pvc.yaml
# Deployments
kubectl apply -f k8s/api-gateway-deployment.yaml
kubectl apply -f k8s/auth-service-deployment.yaml
kubectl apply -f k8s/admin-service-deployment.yaml
# HPA
kubectl apply -f k8s/hpa.yaml
# Ingress
kubectl apply -f k8s/ingress.yaml
# デプロイ状態確認
kubectl rollout status deployment/api-gateway -n license-system
kubectl rollout status deployment/auth-service -n license-system
kubectl rollout status deployment/admin-service -n license-system
# Pod確認
kubectl get pods -n license-system
kubectl get services -n license-system
kubectl get ingress -n license-system
📊 監視設定
ServiceMonitor(Prometheus)
# k8s/service-monitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: license-system-monitor
namespace: license-system
labels:
app: license-system
spec:
selector:
matchLabels:
tier: frontend
endpoints:
- port: http
interval: 30s
path: /metrics
🧪 テストコマンド
# ポートフォワードでローカルアクセス
kubectl port-forward -n license-system svc/api-gateway 3000:3000
# ヘルスチェック
curl http://localhost:3000/health
# ログ確認
kubectl logs -n license-system -l app=api-gateway --tail=100
# スケーリングテスト
kubectl scale deployment/api-gateway -n license-system --replicas=5
# HPA確認
kubectl get hpa -n license-system
🎯 次のステップ
Day 25では、最終日として運用とモニタリングを学びます。Prometheus統合、Grafanaダッシュボード、ELKログ集約、アラート設定、運用ベストプラクティスについて詳しく解説します。
🔗 関連リンク
次回予告: Day 25では、Four Golden SignalsとPrometheusメトリクス収集を詳しく解説します!
Copyright © 2025 Gods & Golem, Inc. All rights reserved.