9.0 KiB
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
- Mở Docker Desktop
- Vào Settings → Kubernetes
- Check Enable Kubernetes
- Chọn cluster provisioning:
- kind (recommended cho development)
- hoặc kubeadm
- Click Apply & Restart
- Đợi 2-3 phút để Kubernetes khởi động
1.2 Verify Kubernetes
# 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
# Install kind
brew install kind
# Verify installation
kind version
Bước 2: Build Docker Image
# 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:
# 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:
# 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:
# 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
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
# 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
# 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
# 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
# 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
# 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
# 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:
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:
# 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:
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:
# 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:
# 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):
# 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
# 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
# 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
- Deploy Redis (optional): Để enable caching và rate limiting
- Setup Ingress: Để expose service ra ngoài
- Configure HPA: Horizontal Pod Autoscaler cho auto-scaling
- Add Monitoring: Prometheus + Grafana
- Setup CI/CD: Tự động deploy khi có code changes