- Updated Mermaid diagrams in the deployment and development guides for better visual representation and consistency. - Improved formatting and clarity in the Kubernetes local deployment and IAM migration guides, including detailed workflows and troubleshooting sections. - Enhanced the Vietnamese documentation to align with the English version, ensuring consistency across guides. - Added quick tips and common issues sections to facilitate user navigation and understanding.
357 lines
13 KiB
Markdown
357 lines
13 KiB
Markdown
# Hướng Dẫn Deploy Kubernetes Local
|
|
|
|
> Hướng dẫn triển khai Kubernetes cục bộ với Docker Desktop trên macOS
|
|
|
|
## Quy Trình Deploy
|
|
|
|
```mermaid
|
|
graph TD
|
|
Start([ Bắt đầu]) --> EnvPrep[1. Chuẩn bị Môi trường]
|
|
EnvPrep --> BuildImg[2. Build Docker Image]
|
|
BuildImg --> LoadImg[3. Load Image vào Cluster]
|
|
LoadImg --> Secrets[4. Cấu hình Secrets & Environment]
|
|
Secrets --> Deploy[5. Deploy Service]
|
|
Deploy --> Verify[6. Kiểm tra & Verify]
|
|
Verify --> Test[7. Test Service]
|
|
Test --> End([ Hoàn tất])
|
|
|
|
subgraph "Chi tiết Deploy"
|
|
Deploy --> |Apply| ConfigMap[ConfigMap]
|
|
Deploy --> |Apply| Deployment[Deployment]
|
|
Deploy --> |Apply| Service[Service]
|
|
end
|
|
|
|
style Start fill:#1a1a2e,color:#fff
|
|
style End fill:#0f3460,color:#fff
|
|
style EnvPrep fill:#16213e,color:#fff
|
|
style BuildImg fill:#1a1a40,color:#fff
|
|
style LoadImg fill:#1a1a40,color:#fff
|
|
style Secrets fill:#0f4c75,color:#fff
|
|
style Deploy fill:#3282b8,color:#fff
|
|
style Verify fill:#3282b8,color:#fff
|
|
style Test fill:#3282b8,color:#fff
|
|
style ConfigMap fill:#16213e,color:#fff
|
|
style Deployment fill:#16213e,color:#fff
|
|
style Service fill:#16213e,color:#fff
|
|
```
|
|
|
|
## Tổng Quan
|
|
|
|
Hướng dẫn này mô tả chi tiết cách deploy IAM Service (hoặc bất kỳ microservice nào trong hệ sinh thái GoodGo) lên local Kubernetes cluster sử dụng Docker Desktop trên macOS.
|
|
|
|
> **Lưu ý**: Hướng dẫn này giả định bạn đang sử dụng **Docker Desktop** với **Kubernetes enabled**. Nếu bạn sử dụng Minikube hoặc Kind thuần, các bước có thể hơi khác một chút (đặc biệt là phần load image).
|
|
|
|
## 1. Yêu Cầu
|
|
|
|
### Phần Mềm
|
|
- **Docker Desktop 4.0+**: [Download Link](https://www.docker.com/products/docker-desktop/)
|
|
- Kubernetes phải được enable trong settings.
|
|
- **kubectl CLI**: Công cụ dòng lệnh để tương tác với K8s.
|
|
```bash
|
|
brew install kubectl
|
|
```
|
|
- **kind CLI**: Cần thiết để load images vào cluster nếu dùng Kind backend (mặc định cho dev).
|
|
```bash
|
|
brew install kind
|
|
```
|
|
- **pnpm 8+**: Package manager của dự án.
|
|
```bash
|
|
npm install -g pnpm
|
|
```
|
|
|
|
### Kiến Thức
|
|
- Hiểu cơ bản về các khái niệm Kubernetes: **Pod**, **Deployment**, **Service**, **Secret**, **ConfigMap**.
|
|
- Quen thuộc với các lệnh Docker cơ bản (`docker build`, `docker images`).
|
|
- Biết cách điều hướng và chạy lệnh trong Terminal.
|
|
|
|
## 2. Chuẩn Bị Môi Trường
|
|
|
|
### 2.1 Enable Kubernetes trong Docker Desktop
|
|
|
|
1. Mở **Docker Desktop**.
|
|
2. Nhấn vào biểu tượng **Settings ()**.
|
|
3. Chọn tab **Kubernetes**.
|
|
4. Check vào ô **Enable Kubernetes**.
|
|
5. Chọn **Show system containers (advanced)** để dễ debug (tùy chọn).
|
|
6. Nhấn **Apply & Restart**.
|
|
7. Đợi 2-3 phút cho đến khi icon Kubernetes ở góc dưới chuyển sang màu xanh lá.
|
|
|
|
### 2.2 Verify Kubernetes Connection
|
|
|
|
Kiểm tra xem `kubectl` đã kết nối đúng context chưa:
|
|
|
|
```bash
|
|
# Kiểm tra context hiện tại
|
|
kubectl config current-context
|
|
# Output mong đợi: docker-desktop
|
|
|
|
# Liệt kê các node trong cluster
|
|
kubectl get nodes
|
|
# Output mong đợi:
|
|
# NAME STATUS ROLES AGE VERSION
|
|
# docker-desktop Ready control-plane 10m v1.29.1
|
|
```
|
|
|
|
## 3. Build Docker Image
|
|
|
|
Chúng ta cần build image của service trước khi deploy. Ở đây lấy ví dụ là `iam-service`.
|
|
|
|
```bash
|
|
# Di chuyển đến thư mục deployments/local/kubernetes
|
|
cd deployments/local/kubernetes
|
|
|
|
# Build Docker image từ root context
|
|
# Lưu ý: -f trỏ đến Dockerfile của service, context là root (../../..)
|
|
docker build -t iam-service:local -f ../../../services/iam-service/Dockerfile ../../..
|
|
|
|
# Kiểm tra image đã build thành công chưa
|
|
docker images | grep iam-service
|
|
# Output mong đợi:
|
|
# iam-service local [IMAGE_ID] [SIZE] [CREATED]
|
|
```
|
|
|
|
## 4. Load Image vào Cluster
|
|
|
|
** QUAN TRỌNG**: Docker Desktop có thể sử dụng các backend khác nhau. Nếu bạn đang chạy Kubernetes trong Docker Desktop, đôi khi nó không nhìn thấy image local ngay lập tức nếu sử dụng `kind` node dưới nền.
|
|
|
|
Nếu bạn dùng **Kind** (Kubernetes in Docker) riêng biệt hoặc cấu hình Docker Desktop đặc biệt, bạn cần load image:
|
|
|
|
```bash
|
|
# Load image vào kind cluster (nếu dùng kind rõ ràng)
|
|
kind load docker-image iam-service:local --name desktop
|
|
|
|
# Kiểm tra sự tồn tại của image (tùy chọn)
|
|
```
|
|
|
|
> **Mẹo**: Với Docker Desktop mặc định, việc build image local (`docker build ...`) thường tự động khả dụng cho K8s cluster của Docker Desktop. Bước load này chủ yếu dành cho ai dùng `kind` CLI để tạo cluster riêng.
|
|
|
|
## 5. Cấu Hình Secrets & ConfigMap
|
|
|
|
Môi trường Kubernetes cần các biến môi trường nhạy cảm (Secrets) và cấu hình chung (ConfigMap).
|
|
|
|
### 5.1 Tạo Secrets (Thủ công)
|
|
|
|
Bạn có thể chạy script hoặc lệnh sau để tạo secrets an toàn.
|
|
|
|
```bash
|
|
# Tạo namespace riêng cho local testing
|
|
kubectl create namespace iam-local
|
|
|
|
# Tạo secrets ngẫu nhiên và lưu vào Kubernetes
|
|
kubectl create secret generic iam-service-secrets \
|
|
--from-literal=DATABASE_URL="postgresql://user:password@host.docker.internal:5432/iam_db?schema=public" \
|
|
--from-literal=JWT_SECRET="$(openssl rand -base64 32)" \
|
|
--from-literal=JWT_REFRESH_SECRET="$(openssl rand -base64 32)" \
|
|
--from-literal=ENCRYPTION_KEY="$(openssl rand -base64 32)" \
|
|
-n iam-local
|
|
|
|
# Kiểm tra secrets đã tạo
|
|
kubectl get secrets -n iam-local
|
|
```
|
|
|
|
> **Lưu ý về `host.docker.internal`**: Trên macOS, để pod trong K8s kết nối được với PostgreSQL chạy trên máy host (hoặc container khác qua port mapping), ta dùng `host.docker.internal`.
|
|
|
|
### 5.2 ConfigMap
|
|
|
|
File `iam-service-configmap.yaml` thường chứa các biến không nhạy cảm như `NODE_ENV`, `LOG_LEVEL`.
|
|
|
|
```bash
|
|
# Apply ConfigMap
|
|
kubectl apply -f iam-service-configmap.yaml -n iam-local
|
|
```
|
|
|
|
## 6. Deploy Service
|
|
|
|
Bây giờ chúng ta sẽ deploy các resource chính.
|
|
|
|
```bash
|
|
# Apply file Deployment manifest
|
|
kubectl apply -f iam-service-deployment.yaml -n iam-local
|
|
|
|
# Apply file Service manifest
|
|
kubectl apply -f iam-service-service.yaml -n iam-local
|
|
```
|
|
|
|
## 7. Verify & Debug
|
|
|
|
Sau khi deploy, cần đảm bảo Pod đang chạy ổn định (Running).
|
|
|
|
### 7.1 Kiểm tra Pods
|
|
|
|
```bash
|
|
# Lấy danh sách pod trong namespace
|
|
kubectl get pods -n iam-local
|
|
|
|
# Output mong đợi:
|
|
# NAME READY STATUS RESTARTS AGE
|
|
# iam-service-68994fdc79-gh2mj 1/1 Running 0 30s
|
|
```
|
|
|
|
### 7.2 Xem Logs Chi Tiết
|
|
|
|
Nếu Status không phải `Running` (ví dụ `CrashLoopBackOff` hoặc `ImagePullBackOff`), hãy xem logs:
|
|
|
|
```bash
|
|
# Xem logs thời gian thực từ pod
|
|
kubectl logs -f -n iam-local -l app=iam-service
|
|
|
|
# Xem chi tiết pod để check events (lỗi pull, mount, scheduling)
|
|
kubectl describe pod -n iam-local -l app=iam-service
|
|
```
|
|
|
|
### 7.3 Lỗi Thường Gặp
|
|
|
|
1. **ImagePullBackOff**:
|
|
- **Lý do**: K8s không tìm thấy image `iam-service:local`.
|
|
- **Fix**: Đảm bảo `imagePullPolicy: IfNotPresent` hoặc `Never` trong file yaml deployment local. Nếu dùng Kind, nhớ chạy lệnh `kind load`.
|
|
|
|
2. **CrashLoopBackOff**:
|
|
- **Lý do**: Lỗi runtime, thường là không kết nối được Database.
|
|
- **Fix**: Check biến `DATABASE_URL` trong Secret. Đảm bảo Postgres đang chạy và accessible từ K8s (dùng `host.docker.internal`).
|
|
|
|
3. **Pending Service**:
|
|
- **Lý do**: Type `LoadBalancer` trên local đôi khi mãi pending IP.
|
|
- **Fix**: Không sao cả, chúng ta có thể dùng `port-forward` hoặc truy cập qua `localhost`.
|
|
|
|
## 8. Test Service Access
|
|
|
|
Để truy cập service từ máy local, cách an toàn nhất là dùng `port-forward`.
|
|
|
|
```bash
|
|
# Port forward từ cổng local 5002 tới cổng 80 của service
|
|
kubectl port-forward svc/iam-service 5002:80 -n iam-local
|
|
|
|
# Terminal sẽ treo và hiện: Forwarding from 127.0.0.1:5002 -> 8000
|
|
```
|
|
|
|
Mở terminal khác và test:
|
|
|
|
```bash
|
|
# Test Health Check
|
|
curl http://localhost:5002/health/live
|
|
# Response: {"status":"ok", ...}
|
|
|
|
# Xem tài liệu Swagger/OpenAPI (nếu bật)
|
|
open http://localhost:5002/api-docs
|
|
```
|
|
|
|
## 9. Cleanup
|
|
|
|
Khi hoàn tất, hãy xóa resources để giải phóng tài nguyên.
|
|
|
|
```bash
|
|
# Xóa namespace (xóa tất cả resource bên trong)
|
|
kubectl delete namespace iam-local
|
|
```
|
|
|
|
---
|
|
|
|
## Quick Tips
|
|
|
|
|
|
### Các Vấn Đề Thường Gặp & Giải Pháp
|
|
|
|
| Vấn đề | Triệu chứng | Giải pháp |
|
|
|--------|-------------|-----------|
|
|
| **ImagePullBackOff** | Pod bị kẹt ở trạng thái `ImagePullBackOff` | Đặt `imagePullPolicy: Never` trong deployment YAML<br/>Chạy `kind load docker-image` nếu dùng Kind |
|
|
| **CrashLoopBackOff** | Pod liên tục restart | Kiểm tra logs với `kubectl logs`<br/>Verify `DATABASE_URL` trong secrets<br/>Đảm bảo DB accessible qua `host.docker.internal` |
|
|
| **Pending LoadBalancer** | Service External-IP hiển thị `<pending>` | Bình thường trên local—dùng `kubectl port-forward` thay thế |
|
|
| **Connection Refused** | Không kết nối được sau port-forward | Kiểm tra pod đang `Running` (không phải `CrashLoopBackOff`)<br/>Verify port mapping chính xác |
|
|
|
|
### Tham Chiếu Lệnh Thiết Yếu
|
|
|
|
```bash
|
|
# Debugging
|
|
kubectl get pods -n iam-local -w # Theo dõi pods real-time
|
|
kubectl describe pod <POD_NAME> -n iam-local # Thông tin chi tiết pod + events
|
|
kubectl logs -f <POD_NAME> -n iam-local # Stream logs
|
|
kubectl exec -it <POD_NAME> -n iam-local -- /bin/sh # Shell vào container
|
|
|
|
# Quản Lý Image
|
|
docker build -t service:local -f Dockerfile . # Build image
|
|
kind load docker-image service:local --name desktop # Load vào Kind cluster
|
|
docker images | grep service # Liệt kê local images
|
|
|
|
# Deploy Nhanh
|
|
kubectl apply -f deployment.yaml -n iam-local # Deploy single manifest
|
|
kubectl apply -f . -n iam-local # Deploy tất cả files trong thư mục
|
|
kubectl rollout restart deployment/iam-service -n iam-local # Force restart pods
|
|
|
|
# Cleanup
|
|
kubectl delete pod <POD_NAME> -n iam-local --force # Force delete pod bị kẹt
|
|
kubectl delete namespace iam-local --force --grace-period=0 # Force delete namespace
|
|
```
|
|
|
|
### Deployment Checklist
|
|
|
|
- [ ] Docker Desktop Kubernetes enabled
|
|
- [ ] kubectl context = `docker-desktop`
|
|
- [ ] Image built locally: `docker images | grep iam-service`
|
|
- [ ] Namespace created: `kubectl get ns iam-local`
|
|
- [ ] Secrets created: `kubectl get secrets -n iam-local`
|
|
- [ ] ConfigMap applied: `kubectl get cm -n iam-local`
|
|
- [ ] Deployment applied: `kubectl get deploy -n iam-local`
|
|
- [ ] Service created: `kubectl get svc -n iam-local`
|
|
- [ ] Pods running: `kubectl get pods -n iam-local`
|
|
- [ ] Port-forward works: `kubectl port-forward ...`
|
|
- [ ] Health check passes: `curl http://localhost:5002/health/live`
|
|
|
|
### Resource Management
|
|
|
|
**Recommended Resources per Pod:**
|
|
```yaml
|
|
resources:
|
|
requests:
|
|
memory: "256Mi"
|
|
cpu: "250m"
|
|
limits:
|
|
memory: "512Mi"
|
|
cpu: "500m"
|
|
```
|
|
|
|
**Check Resource Usage:**
|
|
```bash
|
|
# Overall cluster resources
|
|
kubectl top nodes
|
|
|
|
# Pod resource usage
|
|
kubectl top pods -n iam-local
|
|
|
|
# Detailed pod metrics
|
|
kubectl describe node docker-desktop
|
|
```
|
|
|
|
### Best Practices
|
|
|
|
1. **Sử dụng namespaces** để tách biệt môi trường
|
|
2. **Set resource limits** cho mọi pod
|
|
3. **Use health checks** (liveness & readiness probes)
|
|
4. **Tag images** với version cụ thể, không dùng `:latest`
|
|
5. **Store secrets** trong Kubernetes Secrets, không hardcode
|
|
6. **Use ConfigMaps** cho configuration
|
|
7. **Enable logging** để dễ debug
|
|
8. **Regular cleanup** các resources không dùng
|
|
|
|
### Trạng Thái Visual
|
|
|
|
- **Running** - Service hoạt động bình thường
|
|
- **Pending** - Đang chờ resources
|
|
- **CrashLoopBackOff** - Service liên tục fail (kiểm tra logs!)
|
|
- **ContainerCreating** - Pod đang khởi động
|
|
- **Terminating** - Pod đang tắt
|
|
|
|
### Pro Tips
|
|
|
|
1. ** Fast Rebuild**: Để iterate nhanh, dùng `kubectl rollout restart deployment/iam-service -n iam-local` sau khi rebuild image
|
|
2. ** Watch Mode**: Dùng flag `-w` để theo dõi resources update real-time
|
|
3. ** YAML Validation**: Chạy `kubectl apply --dry-run=client -f file.yaml` để validate trước khi apply
|
|
4. ** Label Filtering**: Dùng `-l app=iam-service` để filter resources theo label thay vì gõ pod names
|
|
|
|
### Tài Liệu Tham Khảo
|
|
|
|
- [Kubernetes Documentation](https://kubernetes.io/docs/)
|
|
- [Docker Desktop for Mac](https://docs.docker.com/desktop/mac/networking/)
|
|
- [Prisma Deployment Guide](https://www.prisma.io/docs/guides/deployment/deployment-guides/deploying-to-kubernetes)
|
|
- [kubectl Cheat Sheet](https://kubernetes.io/docs/reference/kubectl/cheatsheet/)
|
|
- [Kubernetes Best Practices](https://kubernetes.io/docs/concepts/configuration/overview/)
|