# Hướng Dẫn Deploy Kubernetes Local

**Cập nhật**: 2026-01-04  
**Độ khó**: Intermediate  
**Thời gian**: 30-45 phút

## Tổng Quan

Hướng dẫn này mô tả cách deploy IAM Service lên local Kubernetes cluster sử dụng Docker Desktop trên macOS.

## Yêu Cầu

### Phần Mềm
- Docker Desktop 4.0+ với Kubernetes enabled
- kubectl CLI
- kind CLI (để load images vào cluster)
- pnpm 8+

### Kiến Thức
- Hiểu cơ bản về Kubernetes (Pods, Deployments, Services)
- Quen thuộc với Docker và containerization
- Biết cách sử dụng terminal/command line

## Bước 1: Chuẩn Bị Môi Trường

### 1.1 Enable Kubernetes trong Docker Desktop

1. Mở **Docker Desktop**
2. Vào **Settings → Kubernetes**
3. Check **Enable Kubernetes**
4. Chọn cluster provisioning:
   - **kind** (recommended cho development)
   - hoặc **kubeadm**
5. Click **Apply & Restart**
6. Đợi 2-3 phút để Kubernetes khởi động

### 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 (nếu dùng kind)
kind get clusters
# Output: desktop
```

### 1.3 Install kind CLI

```bash
# Install kind
brew install kind

# Verify installation
kind version
```

## Bước 2: Build Docker Image

```bash
# Di chuyển đến thư mục deployments
cd deployments/local/kubernetes

# Build image (script tự động build)
docker build -t iam-service:local -f ../../../services/iam-service/Dockerfile ../../..

# Verify image
docker images | grep iam-service
# Output: iam-service:local   ...   1.67GB
```

## Bước 3: Load Image vào Kubernetes Cluster

**⚠️ Quan Trọng**: Docker Desktop Kubernetes với kind backend **không tự động share images** với Docker Desktop. Bạn phải load image vào cluster:

```bash
# Load image vào kind cluster
kind load docker-image iam-service:local --name desktop

# Đợi quá trình hoàn tất (có thể mất 1-2 phút)
```

**Lưu ý**: Nếu dùng kubeadm thay vì kind, bạn có thể skip bước này vì kubeadm share images tốt hơn.

## Bước 4: Cấu Hình Secrets

### 4.1 Chuẩn Bị Environment Variables

Tạo file `.env.k8s` với các biến sau:

```bash
# Database
DATABASE_URL=postgresql://user:password@host:5432/database?sslmode=require

# JWT Secrets (PHẢI thay đổi trong 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 Tạo Kubernetes Secrets

Script `deploy.sh` sẽ tự động tạo secrets, hoặc bạn có thể tạo thủ công:

```bash
# Tạo namespace
kubectl create namespace iam-local

# Tạo 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
```

## Bước 5: Deploy Service

### 5.1 Sử Dụng Script Tự Động

```bash
cd deployments/local/kubernetes

# Run deployment script
./deploy.sh

# Script sẽ:
# 1. Tạo namespace
# 2. Tạo secrets
# 3. Apply ConfigMap
# 4. Build Docker image
# 5. Deploy service
```

### 5.2 Deploy Thủ Công

```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
```

## Bước 6: Verify Deployment

### 6.1 Check Pod Status

```bash
# Xem pods
kubectl get pods -n iam-local

# Output mong đợi:
# NAME                           READY   STATUS    RESTARTS   AGE
# iam-service-68994fdc79-gh2mj   1/1     Running   0          2m
```

### 6.2 Check Logs

```bash
# Xem logs
kubectl logs -f -n iam-local -l app=iam-service

# Logs thành công:
# [iam-service] Database connected successfully
# [iam-service] Service started on port 5001
```

### 6.3 Check Service

```bash
# Xem services
kubectl get svc -n iam-local

# Output:
# NAME          TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)
# iam-service   LoadBalancer   10.96.187.160   <pending>     80:30577/TCP
```

**Lưu ý**: `EXTERNAL-IP` sẽ là `<pending>` 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 - <<EOF
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
  namespace: iam-local
spec:
  serviceName: redis
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:7-alpine
        ports:
        - containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: iam-local
spec:
  selector:
    app: redis
  ports:
  - port: 6379
EOF

# Update ConfigMap với REDIS_HOST=redis
kubectl edit configmap iam-service-config -n iam-local

# Restart deployment
kubectl rollout restart deployment/iam-service -n iam-local
```

## Debugging Commands

```bash
# Xem tất cả resources
kubectl get all -n iam-local

# Describe deployment
kubectl describe deployment iam-service -n iam-local

# Describe pod
kubectl describe pod -n iam-local -l app=iam-service

# Xem events
kubectl get events -n iam-local --sort-by='.lastTimestamp'

# Exec vào pod
kubectl exec -it -n iam-local deployment/iam-service -- sh

# Xem logs realtime
kubectl logs -f -n iam-local -l app=iam-service

# Xem logs từ container trước (nếu pod restart)
kubectl logs -n iam-local -l app=iam-service --previous
```

## Cleanup

```bash
# Xóa deployment
kubectl delete -f iam-service-deployment.yaml
kubectl delete -f iam-service-service.yaml
kubectl delete -f iam-service-configmap.yaml

# Xóa secrets
kubectl delete secret iam-service-secrets -n iam-local

# Xóa namespace (xóa tất cả)
kubectl delete namespace iam-local
```

## Next Steps

1. **Deploy Redis** (optional): Để enable caching và rate limiting
2. **Setup Ingress**: Để expose service ra ngoài
3. **Configure HPA**: Horizontal Pod Autoscaler cho auto-scaling
4. **Add Monitoring**: Prometheus + Grafana
5. **Setup CI/CD**: Tự động deploy khi có code changes

## Resources

- [Kubernetes Documentation](https://kubernetes.io/docs/)
- [Docker Desktop Kubernetes](https://docs.docker.com/desktop/kubernetes/)
- [kind Documentation](https://kind.sigs.k8s.io/)
- [kubectl Cheat Sheet](https://kubernetes.io/docs/reference/kubectl/cheatsheet/)
- [Local Kubernetes README](../../../deployments/local/kubernetes/README.md)
