經過前面 20 天的修煉,我們已經掌握了 Kubernetes 的各種武器。今天,是時候建造我們自己的「微服務王國」了!就像建造一座城市需要先規劃基礎設施一樣,我們要為接下來的可觀測性和混沌工程實驗,建立一個穩固的後端服務架構。
今天來建立一個基本的後端服務架構,分別有order-service
與user-service
以及一台資料庫。
這將作為我們接著幾天的實驗場。
simple-ecommerce/
.
├── database
│ ├── devspace.yaml
│ └── postgres.yaml
├── deployments
│ ├── deploy-namespace.sh
│ ├── order-service.yaml
│ └── user-service.yaml
├── deploy-services.sh
├── devspace.yaml
├── go.mod
├── go.sum
├── kind-config.yaml
├── order-service
│ ├── devspace.yaml
│ ├── Dockerfile
│ └── main.go
├── shared
│ ├── config
│ │ └── config.go
│ └── telemetry
│ └── telemetry.go
└── user-service
├── devspace.yaml
├── Dockerfile
└── main.go
因為整個系統有 2 個 API 服務和依賴一個資料庫,我們能活用之前學到的 DevSpace Dependencies:微服務編排的藝術 🎭來編排這三個服務的依賴關係跟啟動順序。
然後每個服務裡面也都有自己的 devspace.yaml
跟對應的 K8s Deployment
、Service
等資源的宣告。根目錄的devspace.yaml
則是用來定義全局相關的設定。
建立 namespace,這次的 pod 就都在這 ecommerce 下操作。
kubectl create namespace ecommerce --dry-run=client -o yaml | kubectl apply -f -
# day21/kind-config.yaml
# kind-config.yaml - 遊樂場的設計圖
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: ecommerce-cluster
nodes:
- role: control-plane # 🎪 馬戲團團長(管理一切)
- role: worker # 🎭 表演者1(運行應用)
- role: worker # 🎭 表演者2(運行應用)
kind create cluster --config=kind-config.yaml
# day21/devspace.yaml
# devspace.yaml - 總指揮官的配置
version: v2beta1
name: ecommerce-microservices
# 🎼 依賴關係編排 - 就像樂團的演奏順序
dependencies:
database: # 🥁 鼓手先開始(基礎服務)
path: ./database
user-service: # 🎹 鋼琴跟上(核心服務)
path: ./user-service
order-service: # 🎻 小提琴最後(業務服務)
path: ./order-service
# 🎮 開發模式配置 - 讓你像玩遊戲一樣調試
dev:
user-service:
labelSelector:
app: user-service
ports:
- port: "8080:8080" # 🚪 為用戶服務開門
order-service:
labelSelector:
app: order-service
ports:
- port: "8081:8081" # 🚪 為訂單服務開門
postgresql:
labelSelector:
app: postgresql
ports:
- port: "5432:5432" # 🚪 為資料庫開門
# 🛠️ 便民服務指令 - 就像遙控器的快捷鍵
commands:
migrate: # 🔄 一鍵資料庫初始化
command: |-
kubectl exec -it deployment/postgresql -- psql -U postgres -d ecommerce -c "
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- 更多 SQL..."
test: # 🧪 一鍵系統測試
command: |-
echo "🔍 測試用戶服務..."
curl -X POST http://localhost:8080/users \
-H "Content-Type: application/json" \
-d '{"username":"testuser2","email":"test2@example.com"}'
status: # 📊 一鍵健康檢查
command: |-
echo "=== 🏥 系統健康檢查 ==="
kubectl get pods -o wide
curl -s http://localhost:8080/health || echo "❌ User service not ready"
資料庫就像銀行的金庫,需要特別小心地設置:
# day21/database/devspace.yaml
# database/devspace.yaml - 金庫管理員的手冊
version: v2beta1
name: database
deployments:
postgresql:
kubectl:
manifests:
- ./postgres.yaml # 📋 金庫建造藍圖
# 🎣 生命週期鉤子 - 像釣魚一樣等待時機
hooks:
- name: "wait-for-database"
events: ["after:deploy"] # 🎪 部署完成後的表演
command: |
echo "⏳ 等待金庫就緒..."
kubectl wait --for=condition=ready pod -l app=postgresql --timeout=300s
sleep 10 # 😴 讓資料庫喝杯咖啡醒醒腦
echo "✅ 金庫已就緒!"
- name: "run-migrations"
events: ["after:deploy"]
command: |
echo "🔧 開始裝修金庫內部..."
kubectl exec deployment/postgresql -- psql -U postgres -d ecommerce -c "
-- 🏗️ 建造用戶資料的保險箱
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- 🏗️ 建造訂單資料的保險箱
CREATE TABLE IF NOT EXISTS orders (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
product_name VARCHAR(200) NOT NULL,
quantity INTEGER NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) DEFAULT 'pending',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- 🎁 放入一些樣品資料
INSERT INTO users (username, email) VALUES
('admin', 'admin@example.com'),
('testuser', 'test@example.com')
ON CONFLICT (username) DO NOTHING;
"
echo "🎉 金庫裝修完成!"
訂單服務就像餐廳的廚房,負責處理所有的訂單邏輯:
# day21/order-service/devspace.yaml
# order-service/devspace.yaml - 廚房主廚的操作手冊
version: v2beta1
name: order-service
images:
order-service:
image: order-service:latest
dockerfile: ./Dockerfile
context: ..
deployments:
order-service:
kubectl:
manifests:
- ../deployments/order-service.yaml
dev:
order-service:
imageSelector: order-service:latest
workingDir: /app
ports:
- port: "8081:8081" # 🚪 廚房的專用通道
env:
- name: DATABASE_URL # 🗺️ 金庫位置
value: "postgres://postgres:postgres123@postgresql:5432/ecommerce?sslmode=disable"
- name: USER_SERVICE_URL # 🗺️ 前台位置
value: "http://user-service:8080"
- name: PORT
value: "8081"
hooks:
- name: "wait-for-order-service"
events: ["after:deploy"]
command: |
echo "👨🍳 檢查主廚是否準備就緒..."
kubectl wait --for=condition=ready pod -l app=order-service --timeout=300s
echo "✅ 主廚已準備就緒!"
用戶服務就像餐廳的前台接待,負責處理所有與客戶相關的事務:
# user-service/devspace.yaml - 前台接待員的工作手冊
version: v2beta1
name: user-service
# 🏭 映像工廠 - 打造服務的容器
images:
user-service:
image: user-service:latest
dockerfile: ./Dockerfile
context: .. # 📂 工廠的原料倉庫
deployments:
user-service:
kubectl:
manifests:
- ../deployments/user-service.yaml
# 🎮 開發者模式 - 讓你像超級瑪利歐一樣靈活
dev:
user-service:
imageSelector: user-service:latest
workingDir: /app
ports:
- port: "8080:8080" # 🚪 為客戶開啟專屬通道
env:
- name: DATABASE_URL # 🗺️ 告訴服務金庫在哪裡
value: "postgres://postgres:postgres123@postgresql:5432/ecommerce?sslmode=disable"
- name: PORT
value: "8080"
# 🎭 服務就緒檢查 - 像醫生檢查病人一樣仔細
hooks:
- name: "wait-for-user-service"
events: ["after:deploy"]
command: |
echo "🏥 檢查前台接待員是否就位..."
kubectl wait --for=condition=ready pod -l app=user-service --timeout=300s
echo "✅ 前台接待員已就位!"
# 🎮 進入開發模式(熱重載 + 端口轉發)
devspace dev --debug
20:55:50 info Using namespace 'ecommerce'
20:55:50 info Using kube context 'kind-demo'
# 🧪 測試用戶服務
curl -X POST http://localhost:8080/users \
-H "Content-Type: application/json" \
-d '{"username":"testuser2","email":"test2@example.com"}'
# 🧪 測試訂單服務
curl -X POST http://localhost:8081/orders \
-H "Content-Type: application/json" \
-d '{"user_id":1,"product_name":"Test Product","quantity":2,"total_amount":99.99}'
# 📊 檢查系統狀態
devspace run status
也可以透過 devspace ui
來觸發我們自定義的 command 有個 status
能檢查系統。
今天我們建立的這個微服務架構,就像一座精心設計的實驗室。在接下來的日子裡,我們預計將在這個實驗室中:
🎯 關鍵洞察
微服務不是銀彈,而是一把雙刃劍。 它帶來了靈活性和可擴展性,但也增加了複雜度。DevSpace Dependencies 這樣的工具,就是幫我們駕馭這把雙刃劍的利器。
好的架構不是一蹴而就的,而是在實踐中不斷演進的。 今天的基礎架構,將成為我們探索可觀測性和韌性工程的堅實基石。