0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Hybrid License System Day 24: Kubernetes対応

Last updated at Posted at 2025-12-23

🎄 科学と神々株式会社 アドベントカレンダー 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.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?