9.2 KiB
Local Kubernetes Deployment Guide
EN: Local Kubernetes Deployment Guide
VI: Hướng dẫn triển khai Kubernetes cục bộ
Last Updated: 2026-01-05 Difficulty: Intermediate Duration: 30-45 minutes
Workflow
graph TD
Start([Start]) --> EnvPrep[1. Environment Prep]
EnvPrep --> BuildImg[2. Build Docker Image]
BuildImg --> LoadImg[3. Load Image to Cluster<br/>(Kind/Docker Desktop)]
LoadImg --> Secrets[4. Configure Secrets<br/>& Environment]
Secrets --> Deploy[5. Deploy Service<br/>(K8s Manifests)]
Deploy --> Verify[6. Verify Deployment]
Verify --> Test[7. Test Service<br/>(Port Forward & Curl)]
Test --> End([Complete])
subgraph "Deployment Details"
Deploy --> |Apply| ConfigMap
Deploy --> |Apply| Deployment
Deploy --> |Apply| Service
end
style Start fill:#d4edda,stroke:#28a745,stroke-width:2px
style End fill:#d4edda,stroke:#28a745,stroke-width:2px
style EnvPrep fill:#e2e3e5,stroke:#6c757d
style BuildImg fill:#fff3cd,stroke:#ffc107
style LoadImg fill:#fff3cd,stroke:#ffc107
style Secrets fill:#f8d7da,stroke:#dc3545
style Deploy fill:#cce5ff,stroke:#007bff
style Verify fill:#cce5ff,stroke:#007bff
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 Note: 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
- Kubernetes must be enabled in settings.
- kubectl CLI: Command-line tool for interacting with K8s.
brew install kubectl - kind CLI: Required to load images into the cluster if using Kind backend explicitely.
brew install kind - pnpm 8+: Project package manager.
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
- Open Docker Desktop.
- Click the Settings (⚙️) icon.
- Select the Kubernetes tab.
- Check Enable Kubernetes.
- Select Show system containers (advanced) for easier debugging (optional).
- Click Apply & Restart.
- 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:
# EN: Check current context
# VI: Kiểm tra context hiện tại
kubectl config current-context
# Expected Output: docker-desktop
# EN: List all nodes in the cluster
# VI: Liệt kê các node trong 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.
# EN: Navigate to the kubernetes deployment directory
# VI: Di chuyển đến thư mục deployments/local/kubernetes
cd deployments/local/kubernetes
# EN: Build the Docker image from the root context
# VI: Build Docker image từ root context
# Note: -f points to service Dockerfile, context is root (../../..)
docker build -t iam-service:local -f ../../../services/iam-service/Dockerfile ../../..
# EN: Verify the image was built successfully
# VI: Kiểm tra image đã build thành công chưa
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:
# EN: Load image into kind cluster (if using kind explicitly)
# VI: Load image vào kind cluster (nếu dùng kind rõ ràng)
kind load docker-image iam-service:local --name desktop
# EN: Validating image presence (optional, hard with Docker Desktop K8s directly)
# VI: Kiểm tra sự tồn tại của image (tùy chọn)
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 usingkindCLI 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.
# EN: Create a dedicated namespace for local testing
# VI: Tạo namespace riêng cho local testing
kubectl create namespace iam-local
# EN: Generate random secrets and store in Kubernetes
# VI: 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
# EN: Verify secrets creation
# VI: Kiểm tra secrets đã tạo
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 usehost.docker.internal.
5.2 ConfigMap
The iam-service-configmap.yaml file typically contains non-sensitive variables like NODE_ENV, LOG_LEVEL.
# EN: Apply ConfigMap
# VI: Apply ConfigMap
kubectl apply -f iam-service-configmap.yaml -n iam-local
6. Deploy Service
Now we will deploy the main resources.
# EN: Apply Deployment manifest
# VI: Apply file Deployment manifest
kubectl apply -f iam-service-deployment.yaml -n iam-local
# EN: Apply Service manifest (LoadBalancer/NodePort)
# VI: Apply file Service manifest
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
# EN: Get all pods in the namespace
# VI: Lấy danh sách pod trong 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:
# EN: Stream logs from the pod
# VI: Xem logs thời gian thực từ pod
kubectl logs -f -n iam-local -l app=iam-service
# EN: Describe pod to see events (pull error, mounts, scheduling)
# VI: Xem chi tiết pod để check events (lỗi pull, mount, scheduling)
kubectl describe pod -n iam-local -l app=iam-service
7.3 Common Errors
-
ImagePullBackOff:
- Reason: K8s cannot find
iam-service:localimage. - Fix: Ensure
imagePullPolicy: IfNotPresentorNeverin local deployment yaml. If using Kind, remember to runkind load.
- Reason: K8s cannot find
-
CrashLoopBackOff:
- Reason: Runtime error, usually unable to connect to Database.
- Fix: Check
DATABASE_URLin Secret. Ensure Postgres is running and accessible from K8s (usehost.docker.internal).
-
Pending Service:
- Reason:
LoadBalancertype on local sometimes hangs pending IP. - Fix: Not a problem, we can use
port-forwardor access vialocalhost.
- Reason:
8. Test Service Access
To access the service from your local machine, the safest way is port-forward.
# EN: Port forward from local port 5002 to service port 80
# VI: 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 will hang and show: Forwarding from 127.0.0.1:5002 -> 8000
Open another terminal and test:
# EN: Test Health Check
# VI: Test Health Check
curl http://localhost:5002/health/live
# Response: {"status":"ok", ...}
# EN: View Swagger/OpenAPI docs (if enabled)
# VI: Xem tài liệu Swagger/OpenAPI (nếu bật)
open http://localhost:5002/api-docs
9. Cleanup
When done, delete resources to free up capacity.
# EN: Delete the namespace (removes all resources within)
# VI: Xóa namespace (xóa tất cả resource bên trong)
kubectl delete namespace iam-local