From 67fef542bd6a44ea8e526331377079d9544b4081 Mon Sep 17 00:00:00 2001 From: Ho Ngoc Hai Date: Sun, 4 Jan 2026 13:08:40 +0700 Subject: [PATCH] =?UTF-8?q?feat:=20Th=C3=AAm=20h=C6=B0=E1=BB=9Bng=20d?= =?UTF-8?q?=E1=BA=ABn=20tri=E1=BB=83n=20khai=20d=E1=BB=8Bch=20v=E1=BB=A5?= =?UTF-8?q?=20l=C3=AAn=20Kubernetes=20c=E1=BB=A5c=20b=E1=BB=99=20b?= =?UTF-8?q?=E1=BA=B1ng=20ti=E1=BA=BFng=20Vi=E1=BB=87t=20v=C3=A0=20ti?= =?UTF-8?q?=E1=BA=BFng=20Anh,=20=C4=91=E1=BB=93ng=20th=E1=BB=9Di=20c?= =?UTF-8?q?=E1=BA=ADp=20nh=E1=BA=ADt=20t=C3=A0i=20li=E1=BB=87u=20ph=C3=A1t?= =?UTF-8?q?=20tri=E1=BB=83n=20hi=E1=BB=87n=20c=C3=B3.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/guides/development.md | 23 ++ docs/en/guides/kubernetes-local.md | 396 +++++++++++++++++++++++++++++ docs/vi/guides/development.md | 23 ++ docs/vi/guides/kubernetes-local.md | 396 +++++++++++++++++++++++++++++ 4 files changed, 838 insertions(+) create mode 100644 docs/en/guides/kubernetes-local.md create mode 100644 docs/vi/guides/kubernetes-local.md diff --git a/docs/en/guides/development.md b/docs/en/guides/development.md index 06103b7b..01c29cfc 100644 --- a/docs/en/guides/development.md +++ b/docs/en/guides/development.md @@ -81,6 +81,29 @@ pnpm format ./scripts/db/migrate.sh iam-service deploy ``` +## Kubernetes Deployment + +### Local Kubernetes (Docker Desktop) + +```bash +# Enable Kubernetes in Docker Desktop +# Settings → Kubernetes → Enable Kubernetes + +# Deploy service +cd deployments/local/kubernetes +./deploy.sh + +# Verify deployment +kubectl get pods -n iam-local +kubectl logs -f -n iam-local -l app=iam-service + +# Port forward for testing +kubectl port-forward svc/iam-service 5002:80 -n iam-local +curl http://localhost:5002/health/live +``` + +**See detailed guide**: [Kubernetes Local Deployment Guide](./kubernetes-local.md) + ## Debugging - Use logger from `@goodgo/logger` diff --git a/docs/en/guides/kubernetes-local.md b/docs/en/guides/kubernetes-local.md new file mode 100644 index 00000000..a4f20e02 --- /dev/null +++ b/docs/en/guides/kubernetes-local.md @@ -0,0 +1,396 @@ +# Local Kubernetes Deployment Guide + +**Last Updated**: 2026-01-04 +**Difficulty**: Intermediate +**Duration**: 30-45 minutes + +## Overview + +This guide describes how to deploy the IAM Service to a local Kubernetes cluster using Docker Desktop on macOS. + +## Prerequisites + +### Software +- Docker Desktop 4.0+ with Kubernetes enabled +- kubectl CLI +- kind CLI (for loading images into cluster) +- pnpm 8+ + +### Knowledge +- Basic understanding of Kubernetes (Pods, Deployments, Services) +- Familiarity with Docker and containerization +- Command line proficiency + +## Step 1: Environment Preparation + +### 1.1 Enable Kubernetes in Docker Desktop + +1. Open **Docker Desktop** +2. Go to **Settings → Kubernetes** +3. Check **Enable Kubernetes** +4. Select cluster provisioning: + - **kind** (recommended for development) + - or **kubeadm** +5. Click **Apply & Restart** +6. Wait 2-3 minutes for Kubernetes to start + +### 1.2 Verify Kubernetes + +```bash +# Check kubectl context +kubectl config current-context +# Output: docker-desktop + +# Check nodes +kubectl get nodes +# Output: docker-desktop Ready control-plane ... + +# Check kind cluster name (if using kind) +kind get clusters +# Output: desktop +``` + +### 1.3 Install kind CLI + +```bash +# Install kind +brew install kind + +# Verify installation +kind version +``` + +## Step 2: Build Docker Image + +```bash +# Navigate to deployments directory +cd deployments/local/kubernetes + +# Build image (script auto-builds) +docker build -t iam-service:local -f ../../../services/iam-service/Dockerfile ../../.. + +# Verify image +docker images | grep iam-service +# Output: iam-service:local ... 1.67GB +``` + +## Step 3: Load Image into Kubernetes Cluster + +**⚠️ Important**: Docker Desktop Kubernetes with kind backend **does not automatically share images** with Docker Desktop. You must load the image into the cluster: + +```bash +# Load image into kind cluster +kind load docker-image iam-service:local --name desktop + +# Wait for completion (may take 1-2 minutes) +``` + +**Note**: If using kubeadm instead of kind, you can skip this step as kubeadm shares images better. + +## Step 4: Configure Secrets + +### 4.1 Prepare Environment Variables + +Create `.env.k8s` file with the following variables: + +```bash +# Database +DATABASE_URL=postgresql://user:password@host:5432/database?sslmode=require + +# JWT Secrets (MUST change in production!) +JWT_SECRET=your-strong-jwt-secret-min-32-chars +JWT_REFRESH_SECRET=your-strong-refresh-secret-min-32-chars +JWT_ID_SECRET=your-strong-id-secret-min-32-chars + +# Encryption (optional) +ENCRYPTION_KEY=your-32-char-encryption-key-here +``` + +### 4.2 Create Kubernetes Secrets + +The `deploy.sh` script will automatically create secrets, or you can create them manually: + +```bash +# Create namespace +kubectl create namespace iam-local + +# Create secrets +kubectl create secret generic iam-service-secrets \ + --from-literal=DATABASE_URL="postgresql://..." \ + --from-literal=JWT_SECRET="$(openssl rand -base64 32)" \ + --from-literal=JWT_REFRESH_SECRET="$(openssl rand -base64 32)" \ + --from-literal=JWT_ID_SECRET="$(openssl rand -base64 32)" \ + --from-literal=ENCRYPTION_KEY="$(openssl rand -base64 32)" \ + -n iam-local + +# Verify secrets +kubectl get secrets -n iam-local +``` + +## Step 5: Deploy Service + +### 5.1 Using Automated Script + +```bash +cd deployments/local/kubernetes + +# Run deployment script +./deploy.sh + +# Script will: +# 1. Create namespace +# 2. Create secrets +# 3. Apply ConfigMap +# 4. Build Docker image +# 5. Deploy service +``` + +### 5.2 Manual Deployment + +```bash +# Apply ConfigMap +kubectl apply -f iam-service-configmap.yaml + +# Apply Deployment +kubectl apply -f iam-service-deployment.yaml + +# Apply Service +kubectl apply -f iam-service-service.yaml +``` + +## Step 6: Verify Deployment + +### 6.1 Check Pod Status + +```bash +# View pods +kubectl get pods -n iam-local + +# Expected output: +# NAME READY STATUS RESTARTS AGE +# iam-service-68994fdc79-gh2mj 1/1 Running 0 2m +``` + +### 6.2 Check Logs + +```bash +# View logs +kubectl logs -f -n iam-local -l app=iam-service + +# Successful logs: +# [iam-service] Database connected successfully +# [iam-service] Service started on port 5001 +``` + +### 6.3 Check Service + +```bash +# View services +kubectl get svc -n iam-local + +# Output: +# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) +# iam-service LoadBalancer 10.96.187.160 80:30577/TCP +``` + +**Note**: `EXTERNAL-IP` will be `` because local cluster doesn't have a cloud load balancer. + +## Step 7: Test Service + +### 7.1 Port Forward + +```bash +# Forward port to access service +kubectl port-forward svc/iam-service 5002:80 -n iam-local + +# Service will be available at http://localhost:5002 +``` + +### 7.2 Test Health Endpoints + +```bash +# Test liveness probe +curl http://localhost:5002/health/live + +# Response: +# { +# "success": true, +# "data": {"status": "live"}, +# "timestamp": "2026-01-04T06:04:03.425Z" +# } + +# Test readiness probe +curl http://localhost:5002/health/ready + +# Test API docs +open http://localhost:5002/api-docs +``` + +## Troubleshooting + +### Issue 1: ImagePullBackOff + +**Symptoms**: +```bash +kubectl get pods -n iam-local +# NAME READY STATUS RESTARTS AGE +# iam-service-6b8fbb574d-hn27z 0/1 ImagePullBackOff 0 2m +``` + +**Cause**: kind cluster cannot find image `iam-service:local` + +**Solution**: +```bash +# Load image into kind cluster +kind load docker-image iam-service:local --name desktop + +# Restart deployment +kubectl rollout restart deployment/iam-service -n iam-local +``` + +### Issue 2: CrashLoopBackOff + +**Symptoms**: +```bash +kubectl get pods -n iam-local +# NAME READY STATUS RESTARTS AGE +# iam-service-xxx 0/1 CrashLoopBackOff 5 5m +``` + +**Cause**: Service crashes on startup + +**Debug**: +```bash +# View logs +kubectl logs -n iam-local -l app=iam-service --tail=50 + +# Describe pod +kubectl describe pod -n iam-local -l app=iam-service +``` + +**Common solutions**: +- Check DATABASE_URL in secrets +- Verify Prisma migrations have run +- Check environment variables in ConfigMap + +### Issue 3: Database Connection Failed + +**Symptoms**: Logs show `Database connection error` + +**Solution**: +```bash +# Verify DATABASE_URL +kubectl get secret iam-service-secrets -n iam-local -o jsonpath='{.data.DATABASE_URL}' | base64 -d + +# Test connection from pod +kubectl exec -it -n iam-local deployment/iam-service -- sh +# Inside pod: +# npx prisma db push +``` + +### Issue 4: Redis Connection Errors + +**Symptoms**: Logs show `Redis connection error` + +**Cause**: Redis not deployed in cluster + +**Solution** (optional - only if Redis needed): +```bash +# Deploy Redis +kubectl apply -f - < 80:30577/TCP +``` + +**Lưu ý**: `EXTERNAL-IP` sẽ là `` vì local cluster không có cloud load balancer. + +## Bước 7: Test Service + +### 7.1 Port Forward + +```bash +# Forward port để access service +kubectl port-forward svc/iam-service 5002:80 -n iam-local + +# Service sẽ available tại http://localhost:5002 +``` + +### 7.2 Test Health Endpoints + +```bash +# Test liveness probe +curl http://localhost:5002/health/live + +# Response: +# { +# "success": true, +# "data": {"status": "live"}, +# "timestamp": "2026-01-04T06:04:03.425Z" +# } + +# Test readiness probe +curl http://localhost:5002/health/ready + +# Test API docs +open http://localhost:5002/api-docs +``` + +## Troubleshooting + +### Issue 1: ImagePullBackOff + +**Triệu chứng**: +```bash +kubectl get pods -n iam-local +# NAME READY STATUS RESTARTS AGE +# iam-service-6b8fbb574d-hn27z 0/1 ImagePullBackOff 0 2m +``` + +**Nguyên nhân**: kind cluster không thể tìm thấy image `iam-service:local` + +**Giải pháp**: +```bash +# Load image vào kind cluster +kind load docker-image iam-service:local --name desktop + +# Restart deployment +kubectl rollout restart deployment/iam-service -n iam-local +``` + +### Issue 2: CrashLoopBackOff + +**Triệu chứng**: +```bash +kubectl get pods -n iam-local +# NAME READY STATUS RESTARTS AGE +# iam-service-xxx 0/1 CrashLoopBackOff 5 5m +``` + +**Nguyên nhân**: Service crash khi start + +**Debug**: +```bash +# Xem logs +kubectl logs -n iam-local -l app=iam-service --tail=50 + +# Describe pod +kubectl describe pod -n iam-local -l app=iam-service +``` + +**Giải pháp phổ biến**: +- Check DATABASE_URL trong secrets +- Verify Prisma migrations đã chạy +- Check environment variables trong ConfigMap + +### Issue 3: Database Connection Failed + +**Triệu chứng**: Logs hiển thị `Database connection error` + +**Giải pháp**: +```bash +# Verify DATABASE_URL +kubectl get secret iam-service-secrets -n iam-local -o jsonpath='{.data.DATABASE_URL}' | base64 -d + +# Test connection từ pod +kubectl exec -it -n iam-local deployment/iam-service -- sh +# Inside pod: +# npx prisma db push +``` + +### Issue 4: Redis Connection Errors + +**Triệu chứng**: Logs hiển thị `Redis connection error` + +**Nguyên nhân**: Redis chưa được deploy trong cluster + +**Giải pháp** (optional - chỉ nếu cần Redis): +```bash +# Deploy Redis +kubectl apply -f - <