Files
pos-system/docs/en/guides/kubernetes-local.md
Ho Ngoc Hai 9ba4a478ee feat(docs): Enhance deployment and development guides with improved clarity and structure
- 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.
2026-01-08 17:10:06 +07:00

313 lines
11 KiB
Markdown

# Local Kubernetes Deployment Guide
**Last Updated**: 2026-01-05
**Difficulty**: Intermediate
**Duration**: 30-45 minutes
## Workflow
```mermaid
graph TD
Start([ Start]) --> EnvPrep[1⃣ Environment Prep<br/>Enable K8s in Docker Desktop]
EnvPrep --> BuildImg[2⃣ Build Docker Image<br/>docker build -t service:local]
BuildImg --> LoadImg[3⃣ Load Image to Cluster<br/>kind load docker-image]
LoadImg --> Secrets[4⃣ Configure Secrets<br/>kubectl create secret]
Secrets --> Deploy[5⃣ Deploy Service<br/>kubectl apply -f manifests]
Deploy --> Verify[6⃣ Verify Deployment<br/>kubectl get pods]
Verify --> Test[7⃣ Test Service<br/>Port Forward & Curl]
Test --> End([ Complete])
subgraph Deployment[" Deployment Resources"]
Deploy --> |Apply| ConfigMap[ConfigMap<br/>Environment Config]
Deploy --> |Apply| K8sDeployment[Deployment<br/>Pod Template]
Deploy --> |Apply| Service[Service<br/>LoadBalancer/NodePort]
end
%% Start/End nodes - Success Green
style Start fill:#004d40,stroke:#00bfa5,stroke-width:3px,color:#e0f2f1
style End fill:#1b5e20,stroke:#66bb6a,stroke-width:3px,color:#e8f5e9
%% Workflow steps - Dark theme with distinct colors
style EnvPrep fill:#263238,stroke:#546e7a,stroke-width:2px,color:#eceff1
style BuildImg fill:#3e2723,stroke:#8d6e63,stroke-width:2px,color:#efebe9
style LoadImg fill:#1a237e,stroke:#5c6bc0,stroke-width:2px,color:#e8eaf6
style Secrets fill:#b71c1c,stroke:#ef5350,stroke-width:2px,color:#ffebee
style Deploy fill:#004d40,stroke:#26a69a,stroke-width:2px,color:#e0f2f1
style Verify fill:#1565c0,stroke:#42a5f5,stroke-width:2px,color:#e3f2fd
style Test fill:#4a148c,stroke:#ab47bc,stroke-width:2px,color:#f3e5f5
%% Deployment resources subgraph
style Deployment fill:#1a1a1a,stroke:#424242,stroke-width:2px,color:#e0e0e0
style ConfigMap fill:#263238,stroke:#78909c,stroke-width:1px,color:#cfd8dc
style K8sDeployment fill:#263238,stroke:#78909c,stroke-width:1px,color:#cfd8dc
style Service fill:#263238,stroke:#78909c,stroke-width:1px,color:#cfd8dc
```
## Overview
This guide details how to deploy the IAM Service (or any microservice in the GoodGo ecosystem) to a local Kubernetes cluster using Docker Desktop on macOS.
**Important:** This guide assumes you are using **Docker Desktop** with **Kubernetes enabled**. If you are using Minikube or plain Kind, the steps might differ slightly (especially the image loading part).
## 1. Prerequisites
### Software
- **Docker Desktop 4.0+**: [Download Link](https://www.docker.com/products/docker-desktop/)
- Kubernetes must be enabled in settings.
- **kubectl CLI**: Command-line tool for interacting with K8s.
```bash
brew install kubectl
```
- **kind CLI**: Required to load images into the cluster if using Kind backend explicitely.
```bash
brew install kind
```
- **pnpm 8+**: Project package manager.
```bash
npm install -g pnpm
```
### Knowledge
- Basic understanding of Kubernetes concepts: **Pod**, **Deployment**, **Service**, **Secret**, **ConfigMap**.
- Familiarity with basic Docker commands (`docker build`, `docker images`).
- Ability to navigate and run commands in the Terminal.
## 2. Environment Preparation
### 2.1 Enable Kubernetes in Docker Desktop
1. Open **Docker Desktop**.
2. Click the **Settings ()** icon.
3. Select the **Kubernetes** tab.
4. Check **Enable Kubernetes**.
5. Select **Show system containers (advanced)** for easier debugging (optional).
6. Click **Apply & Restart**.
7. Wait 2-3 minutes until the Kubernetes icon in the bottom corner turns green.
### 2.2 Verify Kubernetes Connection
Check if `kubectl` is connected to the correct context:
```bash
# Check current context
kubectl config current-context
# Expected Output: docker-desktop
# List all nodes in the cluster
kubectl get nodes
# Expected Output:
# NAME STATUS ROLES AGE VERSION
# docker-desktop Ready control-plane 10m v1.29.1
```
## 3. Build Docker Image
We need to build the service image before deploying. Taking `iam-service` as an example.
```bash
# Navigate to the kubernetes deployment directory
cd deployments/local/kubernetes
# Build the Docker image from the root context
# Note: -f points to service Dockerfile, context is root (../../..)
docker build -t iam-service:local -f ../../../services/iam-service/Dockerfile ../../..
# Verify the image was built successfully
docker images | grep iam-service
# Expected Output:
# iam-service local [IMAGE_ID] [SIZE] [CREATED]
```
## 4. Load Image into Cluster
** IMPORTANT**: Docker Desktop can use different backends. If you are running Kubernetes inside Docker Desktop, sometimes it doesn't immediately see local images if using a `kind` node underneath.
If you are using **Kind** (Kubernetes in Docker) separately or a specific Docker Desktop config, you need to load the image:
```bash
# Load image into kind cluster (if using kind explicitly)
kind load docker-image iam-service:local --name desktop
# Validating image presence (optional, hard with Docker Desktop K8s directly)
```
**Tip:** With default Docker Desktop, building the local image (`docker build ...`) is usually automatically available to Docker Desktop's K8s cluster. This loading step is mainly for those using `kind` CLI to create separate clusters.
## 5. Configure Secrets & ConfigMap
Kubernetes environments need sensitive environment variables (Secrets) and general configuration (ConfigMap).
### 5.1 Create Secrets (Manually)
You can run a script or the following commands to create secrets securely.
```bash
# Create a dedicated namespace for local testing
kubectl create namespace iam-local
# Generate random secrets and store in 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
# Verify secrets creation
kubectl get secrets -n iam-local
```
**Note on `host.docker.internal`:** On macOS, for a K8s pod to connect to PostgreSQL running on the host machine (or another container via port mapping), we use `host.docker.internal`.
### 5.2 ConfigMap
The `iam-service-configmap.yaml` file typically contains non-sensitive variables like `NODE_ENV`, `LOG_LEVEL`.
```bash
# Apply ConfigMap
kubectl apply -f iam-service-configmap.yaml -n iam-local
```
## 6. Deploy Service
Now we will deploy the main resources.
```bash
# Apply Deployment manifest
kubectl apply -f iam-service-deployment.yaml -n iam-local
# Apply Service manifest (LoadBalancer/NodePort)
kubectl apply -f iam-service-service.yaml -n iam-local
```
## 7. Verify & Debug
After deployment, ensure the Pod is stable (Running).
### 7.1 Check Pods
```bash
# Get all pods in the namespace
kubectl get pods -n iam-local
# Expected Output:
# NAME READY STATUS RESTARTS AGE
# iam-service-68994fdc79-gh2mj 1/1 Running 0 30s
```
### 7.2 View Detailed Logs
If Status is not `Running` (e.g., `CrashLoopBackOff` or `ImagePullBackOff`), check logs:
```bash
# Stream logs from the pod
kubectl logs -f -n iam-local -l app=iam-service
# Describe pod to see events (pull error, mounts, scheduling)
kubectl describe pod -n iam-local -l app=iam-service
```
### 7.3 Common Errors
1. **ImagePullBackOff**:
- **Reason**: K8s cannot find `iam-service:local` image.
- **Fix**: Ensure `imagePullPolicy: IfNotPresent` or `Never` in local deployment yaml. If using Kind, remember to run `kind load`.
2. **CrashLoopBackOff**:
- **Reason**: Runtime error, usually unable to connect to Database.
- **Fix**: Check `DATABASE_URL` in Secret. Ensure Postgres is running and accessible from K8s (use `host.docker.internal`).
3. **Pending Service**:
- **Reason**: `LoadBalancer` type on local sometimes hangs pending IP.
- **Fix**: Not a problem, we can use `port-forward` or access via `localhost`.
## 8. Test Service Access
To access the service from your local machine, the safest way is `port-forward`.
```bash
# Port forward from local port 5002 to service port 80
kubectl port-forward svc/iam-service 5002:80 -n iam-local
# Terminal will hang and show: Forwarding from 127.0.0.1:5002 -> 8000
```
Open another terminal and test:
```bash
# Test Health Check
curl http://localhost:5002/health/live
# Response: {"status":"ok", ...}
# View Swagger/OpenAPI docs (if enabled)
open http://localhost:5002/api-docs
```
## 9. Cleanup
When done, delete resources to free up capacity.
```bash
# Delete the namespace (removes all resources within)
kubectl delete namespace iam-local
```
## Quick Tips
### Common Issues & Solutions
| Issue | Symptoms | Solution |
|-------|----------|----------|
| **ImagePullBackOff** | Pod stuck in `ImagePullBackOff` | Set `imagePullPolicy: Never` in deployment YAML<br/>Run `kind load docker-image` if using Kind |
| **CrashLoopBackOff** | Pod keeps restarting | Check logs with `kubectl logs`<br/>Verify `DATABASE_URL` in secrets<br/>Ensure DB is accessible via `host.docker.internal` |
| **Pending LoadBalancer** | Service External-IP shows `<pending>` | Normal on local—use `kubectl port-forward` instead |
| **Connection Refused** | Can't connect after port-forward | Check pod is `Running` (not `CrashLoopBackOff`)<br/>Verify correct port mapping |
### Essential Commands Reference
```bash
# Debugging
kubectl get pods -n iam-local -w # Watch pods in real-time
kubectl describe pod <POD_NAME> -n iam-local # Detailed pod info + events
kubectl logs -f <POD_NAME> -n iam-local # Stream logs
kubectl exec -it <POD_NAME> -n iam-local -- /bin/sh # Shell into container
# Image Management
docker build -t service:local -f Dockerfile . # Build image
kind load docker-image service:local --name desktop # Load to Kind cluster
docker images | grep service # List local images
# Quick Deployment
kubectl apply -f deployment.yaml -n iam-local # Deploy single manifest
kubectl apply -f . -n iam-local # Deploy all files in directory
kubectl rollout restart deployment/iam-service -n iam-local # Force pod restart
# Cleanup
kubectl delete pod <POD_NAME> -n iam-local --force # Force delete stuck pod
kubectl delete namespace iam-local --force --grace-period=0 # Force delete namespace
```
### Visual Status Indicators
- **Running** - Service is healthy
- **Pending** - Waiting for resources
- **CrashLoopBackOff** - Service keeps failing (check logs!)
- **ContainerCreating** - Pod starting up
- **Terminating** - Pod shutting down
### Pro Tips
1. ** Fast Rebuild**: For quick iteration, use `kubectl rollout restart deployment/iam-service -n iam-local` after rebuilding image
2. ** Watch Mode**: Use `-w` flag to watch resources update in real-time
3. ** YAML Validation**: Run `kubectl apply --dry-run=client -f file.yaml` to validate before applying
4. ** Label Filtering**: Use `-l app=iam-service` to filter resources by label instead of typing pod names
## References
- [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)