Kubernetesマニフェスト¶
すべてのKubernetesリソースはk8s/ディレクトリに定義され、番号順に適用されます。
マニフェスト概要¶
| ファイル | リソース | 用途 |
|---|---|---|
00-namespace.yaml |
Namespace | jlpt-kanji namespaceを作成 |
01-secrets.yaml |
Secret | データベースURL、JWTシークレット、OpenAIキー |
02-postgres-pvc.yaml |
PersistentVolumeClaim | PostgreSQL用10Giストレージ |
03-postgres-deployment.yaml |
Deployment + Service | PostgreSQL 15データベース |
04-libretranslate-deployment.yaml |
Deployment + Service | セルフホスト翻訳(オプション) |
05-deployment.yaml |
Deployment | メインアプリ(frontend + backendコンテナ) |
06-service.yaml |
Service (x2) | Frontend (:80)およびBackend (:8080)サービス |
07-ingress.yaml |
Ingress | jlpt.iqquest.appのTraefikルーティング |
08-security-middlewares.yaml |
Middleware (CRD) | レート制限とセキュリティヘッダー |
ingress-kanjiiq.yaml |
Ingress | kanjiiq.comドメインのルーティング |
ingress-docs.yaml |
Ingress | docs.kanjiiq.appのルーティング |
docs-deployment.yaml |
Deployment | ドキュメントサイト |
docs-service.yaml |
Service | ドキュメントサービス |
初回デプロイメント¶
マニフェストを順番に適用します:
# Create namespace and secrets
kubectl apply -f k8s/00-namespace.yaml
kubectl apply -f k8s/01-secrets.yaml
# Database
kubectl apply -f k8s/02-postgres-pvc.yaml
kubectl apply -f k8s/03-postgres-deployment.yaml
# Application
kubectl apply -f k8s/05-deployment.yaml
kubectl apply -f k8s/06-service.yaml
# Networking
kubectl apply -f k8s/07-ingress.yaml
kubectl apply -f k8s/08-security-middlewares.yaml
kubectl apply -f k8s/ingress-kanjiiq.yaml
Namespace:jlpt-kanji¶
すべてのリソースは単一のnamespaceに存在します:
これにより以下が提供されます:
- 他のワークロードからのリソース分離
- スコープ付きRBAC(必要に応じて)
- 簡単なクリーンアップ(
kubectl delete namespace jlpt-kanji) - リソースクォータの適用(必要に応じて)
シークレット管理¶
機密値はKubernetes Secret(Gitにコミットされない)に保存されます:
apiVersion: v1
kind: Secret
metadata:
name: jlpt-kanji-secrets
namespace: jlpt-kanji
type: Opaque
stringData:
database-url: "postgresql://user:pass@jlpt-postgres:5432/jlpt_flashcard"
jwt-secret: "random-secret-string"
openai-api-key: "sk-..."
リポジトリ内の01-secrets.yamlはテンプレートです — 実際の値はサーバー上で手動適用されます。
Pod設計¶
メインアプリケーションPodは2つのコンテナを並行して実行します:
spec:
replicas: 2
template:
spec:
imagePullSecrets:
- name: forgejo-registry
containers:
- name: backend
image: <registry>/jlpt-kanji-backend:latest
ports:
- containerPort: 8080
resources:
requests: { memory: "256Mi", cpu: "250m" }
limits: { memory: "512Mi", cpu: "500m" }
- name: frontend
image: <registry>/jlpt-kanji-frontend:latest
ports:
- containerPort: 80
resources:
requests: { memory: "128Mi", cpu: "100m" }
limits: { memory: "256Mi", cpu: "200m" }
ヘルスチェック¶
両コンテナにはlivenessプローブとreadinessプローブがあります:
- Liveness:コンテナが応答しなくなった場合に再起動(10秒ごと、3回の失敗)
- Readiness:準備完了までServiceエンドポイントからPodを除外(5秒ごと、2回の失敗)
セキュリティコンテキスト¶
すべてのコンテナは非root(UID 1000)で実行されます:
サービス¶
2つのClusterIPサービスがPodのコンテナをクラスターに公開します:
# Frontend service (port 80 → 80)
name: jlpt-kanji-frontend
ports:
- port: 80
targetPort: 80
# Backend service (port 80 → 8080)
name: jlpt-kanji-backend
ports:
- port: 80
targetPort: 8080
バックエンドサービスは外部ポート80を内部ポート8080にマッピングするため、Traefikはすべてのサービスに同じポートでルーティングします。
Ingress¶
Traefik経由のホストベースルーティング:
spec:
ingressClassName: traefik
tls:
- hosts:
- kanjiiq.com
- api.kanjiiq.com
- admin.kanjiiq.com
secretName: kanjiiq-tls
rules:
- host: kanjiiq.com → jlpt-kanji-frontend:80
- host: api.kanjiiq.com → jlpt-kanji-backend:80
- host: admin.kanjiiq.com → jlpt-kanji-backend:80
Ingressが作成されると、TLS証明書はcert-managerによって自動的にプロビジョニングされます。