一個 Domain,多個 API Service:從地基蓋到屋頂
Clawd 內心戲:
AI 時代的學習哲學:你不需要背 YAML 怎麼縮排、nginx.conf 的每一行怎麼寫。那些東西 AI 30 秒就能生出來,你背它幹嘛?
人類真正該掌握的是兩件事:概念(每一層是什麼、為什麼存在)和 trade-off(什麼時候該用什麼、用錯了會怎樣)。
所以這篇文章不會教你一行行設定 Ingress YAML 或 Istio VirtualService。我只教你「每層是什麼」和「什麼時候該用」。Implementation details?丟給 AI 就好。你是 Tech Lead,不是 YAML 工程師。
歡迎來到 Level-Up 系列第三篇。
情境:你剛進一間新公司,第一天 Tech Lead 就丟給你一個任務:
「我們有三個 FastAPI service ——
user-service、order-service、notification-service。現在它們各自跑在不同 port,我需要你把它們全部放到api.mycompany.com這個 domain 底下。」
你心想:三個 service、一個 domain?聽起來簡單吧?
然後你開始 Google,發現牽涉到 DNS、Ingress、Istio、URL prefix、Swagger… 每個關鍵字都是一個兔子洞。
別慌。這篇文章就是那棟大樓的藍圖。我們從地基(DNS)開始,一層一層往上蓋到屋頂(Swagger),蓋完你就知道整個 request 怎麼從使用者的瀏覽器跑到你的 FastAPI endpoint。
Let’s build 🏗️
🏗️ Floor 0:起點 — 三個 service,三個 port
在一切開始之前,先看看你手上有什麼。
你有三個 FastAPI service,各自跑在不同的 port:
user-service→localhost:8001order-service→localhost:8002notification-service→localhost:8003
開發環境一切正常。三個 terminal 分別跑 uvicorn,想測哪個就打哪個 port。爽。
但是,你總不能叫使用者記住三個 port 吧?
「欸,你要查訂單的話打
api.mycompany.com:8002,要收通知的話打api.mycompany.com:8003,記得不要打錯喔!」
這聽起來就像一間餐廳有三個門,吃牛排走左邊那個門、吃義大利麵走中間、喝飲料走右邊。客人走錯門就吃不到東西。
正常的做法是:一個大門進去,裡面再分流。
現狀:使用者要記住三個 port,很痛苦
所以我們的目標是:
api.mycompany.com/users/... → user-service
api.mycompany.com/orders/... → order-service
api.mycompany.com/notifications/... → notification-service
一個 domain,用 URL path 分流到不同 service。
要達成這件事,我們需要蓋好幾層樓。從最底層的 DNS 開始。
為什麼不能直接讓使用者用不同 port 存取不同 service?
暴露多個 port 意味著使用者要記住你的內部架構、防火牆要開多個口、SSL 憑證要配多份。正確做法是用一個入口統一接收,內部再分流。這也是 encapsulation(封裝)的精神。
正確答案是 B
暴露多個 port 意味著使用者要記住你的內部架構、防火牆要開多個口、SSL 憑證要配多份。正確做法是用一個入口統一接收,內部再分流。這也是 encapsulation(封裝)的精神。
🏗️ Floor 1:DNS — 門牌號碼
蓋房子第一步:你的地址要能被找到。
你跟公司申請了 api.mycompany.com 這個 domain。但 domain name 只是一串人類看得懂的文字,電腦不認識。電腦認識的是 IP 位址,像 34.120.56.78。
DNS(Domain Name System) 就是負責把 domain name 翻譯成 IP 位址的系統。
當使用者在瀏覽器打 api.mycompany.com/users/123,第一件事不是連到你的 server,而是去問 DNS:
「
api.mycompany.com的 IP 是什麼?」
DNS 回答:34.120.56.78。
然後瀏覽器才真正連到 34.120.56.78 這台 server。
DNS 把 domain name 翻譯成 IP,瀏覽器才知道要連去哪
你需要做什麼?
去你的 DNS 管理介面(Cloudflare、Route 53、GoDaddy 等),新增一筆 A Record:
api.mycompany.com → A → 34.120.56.78
就這樣。DNS 這一層的工作就是「讓 domain 指向你的 server」,它不管你 server 上跑幾個 service,也不管 URL path 是什麼。它只負責把人導到正確的大樓門口。
Clawd 偷偷講:
DNS 還有一種叫 CNAME 的記錄,是「指向另一個 domain」而不是直接指向 IP。常見於用 CDN 或 cloud provider 的時候。但概念一樣 —— 最終都是為了讓 domain name 能被解析成一個 IP。
DNS 在整個架構中負責什麼?
DNS 的唯一工作是把 domain name 解析成 IP。它不知道你的 URL path 是什麼,也不知道你有幾個 service。分流是上層的工作(Ingress / reverse proxy)。
正確答案是 B
DNS 的唯一工作是把 domain name 解析成 IP。它不知道你的 URL path 是什麼,也不知道你有幾個 service。分流是上層的工作(Ingress / reverse proxy)。
🏗️ Floor 2:Ingress — 大樓的大門警衛
OK,DNS 把使用者帶到你的大樓門口了(IP 位址)。
但大樓門口不能只有一扇門直通一個房間。你有三個 service,使用者打不同的 URL path 應該進不同的房間。
這就是 Ingress 的工作。
在 Kubernetes 的世界裡,Ingress 是一個 API 物件,定義了「哪些外部 request 要被導到哪個 internal service」。
它的邏輯大概長這樣(概念版,不是真的 YAML):
如果 path 開頭是 /users → 轉給 user-service
如果 path 開頭是 /orders → 轉給 order-service
如果 path 開頭是 /notifications → 轉給 notification-service
Ingress 根據 URL path prefix 把 request 分配到不同 service
Ingress 不是自己跑的
一個很重要的概念:Ingress 本身只是一個「規則定義」,它需要一個 Ingress Controller 來真正執行這些規則。
常見的 Ingress Controller:
- NGINX Ingress Controller — 最老牌、最多人用
- Traefik — 自動化程度高、設定比較直覺
- HAProxy — 效能取向
Ingress Controller 就是那個「真的站在門口指路的警衛」,Ingress 是「警衛手上的名單」。
Clawd 嘀咕一下:
很多人第一次接觸 Kubernetes 的時候都搞混 Ingress 和 Ingress Controller。Ingress 是你寫的規則(YAML),Ingress Controller 是執行規則的那個程式。你不能只寫規則不裝 Controller,就像你不能只寫員工手冊但不請警衛一樣。
Ingress 也處理 TLS
Ingress 通常也負責 TLS termination —— 就是 HTTPS 的那個 S。
使用者用 https://api.mycompany.com 連進來,Ingress 負責解密(因為 SSL 憑證掛在 Ingress 上),然後用 HTTP 把 request 轉給內部的 service。
所以你的 FastAPI service 不需要自己處理 SSL,交給 Ingress 就好。
以下哪個描述最正確?
Ingress 是 Kubernetes 的 API 物件,定義了路由規則。但它需要 Ingress Controller(如 NGINX)來實際執行這些規則。Ingress 也可以處理 TLS(HTTPS),通常 SSL 憑證就掛在 Ingress 上。
正確答案是 B
Ingress 是 Kubernetes 的 API 物件,定義了路由規則。但它需要 Ingress Controller(如 NGINX)來實際執行這些規則。Ingress 也可以處理 TLS(HTTPS),通常 SSL 憑證就掛在 Ingress 上。
🏗️ Floor 3:Istio — 大樓的智慧管理系統
Ingress 讓你可以根據 URL path 分流。很好,夠用了嗎?
如果你的需求只是「path A 去 service A、path B 去 service B」,那 Ingress 就夠了。收工回家。
但如果你的需求是這些呢?
- 新版 API 只先開放 10% 的 traffic(canary deployment)
- service A 呼叫 service B 的時候自動重試 3 次(retry policy)
- service 之間的通訊全部加密(mTLS)
- 我想看每個 request 的延遲、錯誤率(observability)
- 某個 service 掛了,自動把 traffic 導走(circuit breaking)
這些事情 Ingress 做不到。你需要更強大的東西:Istio。
Istio 的核心概念:Sidecar
Istio 最特別的設計是 sidecar proxy。
它在每個 service 旁邊塞一個小小的 proxy(通常是 Envoy),所有進出這個 service 的 traffic 都會經過這個 proxy。
不是這樣: User → Service A → Service B
而是這樣: User → [Proxy A] → Service A → [Proxy A] → [Proxy B] → Service B
這些 proxy 會自動做加密、重試、記錄延遲… 你的 code 完全不用改。
Istio 在每個 service 旁邊放一個 Envoy proxy,管理所有 traffic
Istio 取代 Ingress?
嚴格來說,如果你用了 Istio,Istio Gateway + VirtualService 可以取代 Kubernetes Ingress 的功能。它做的事一樣(根據 host 和 path 分流),但功能更強大。
不過「可以取代」不代表「一定要取代」。這個 trade-off 我們留到 Boss Floor 再講。
Clawd 碎碎念:
Istio 的學習曲線是出了名的陡。很多團隊裝了 Istio 之後才發現,其實他們 80% 的需求用 Ingress 就搞定了。剩下 20% 的 canary deployment,用 Argo Rollouts 也能做。所以裝 Istio 之前請三思。
Istio sidecar proxy 的運作方式是?
Istio 的 sidecar 模式是在每個 Pod 旁邊注入一個 Envoy proxy container。所有進出該 service 的 traffic 都會被這個 proxy 攔截,由它來執行加密、重試、觀測等功能。你的 application code 完全不用改。
正確答案是 B
Istio 的 sidecar 模式是在每個 Pod 旁邊注入一個 Envoy proxy container。所有進出該 service 的 traffic 都會被這個 proxy 攔截,由它來執行加密、重試、觀測等功能。你的 application code 完全不用改。
🏗️ Floor 4:FastAPI × Swagger × root_path — 每個 service 的「室內裝潢」
好,外部的大樓結構蓋好了(DNS → Ingress/Istio)。從這層開始,我們要處理每個 service 內部的事情。
這一層東西比較多,所以我們拆成四個小節慢慢來。
🔹 Floor 4-0:FastAPI 是什麼?— 每個 service 的骨架
在蓋「室內裝潢」之前,先搞清楚你的 service 是用什麼蓋的。
FastAPI 是一個 Python web framework,專門用來寫 API。你的三個 service —— user-service、order-service、notification-service —— 每一個都是用 FastAPI 寫的。
一個最簡單的 FastAPI service 長這樣:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{user_id}")
def get_user(user_id: int):
return {"id": user_id, "name": "Alice"}
就這樣。五行 code,你就有一個 API endpoint:GET /users/123 會回傳 {"id": 123, "name": "Alice"}。
但 FastAPI 最殺手級的功能不是「寫 API 很快」—— 而是它自動幫你生成一份互動式 API 文件。
啟動 service 之後,打開 http://localhost:8001/docs,你會看到這個畫面:
FastAPI 看你的 code,自動生成互動式 Swagger UI 文件
Swagger UI 是開發者的好朋友 —— 前端工程師看它知道要怎麼串 API、你自己開發時可以直接在上面測試。
到目前為止一切美好。但當你的 service 被放到 Ingress 後面(也就是我們 Floor 2 和 3 建的那個大樓結構),問題就來了。
🔹 Floor 4-1:路徑錯位 — Ingress 轉進來的 path,FastAPI 認不認得?
你的 user-service 在本地跑的時候,endpoint 是:
http://localhost:8001/users/123 ✅ 正常運作
現在掛到 Ingress 後面,使用者打的是:
https://api.mycompany.com/users/123
Ingress 看到 /users 開頭,知道要轉給 user-service。但問題來了:
Ingress 轉給 FastAPI 的 path 到底是
/users/123還是/123?
這取決於 Ingress 有沒有做 path rewrite(路徑改寫)。
情況一:不改寫 path
Ingress 把 /users/123 原封不動地轉給 user-service。
FastAPI 收到的是 /users/123,那你的 code 要這樣寫:
@app.get("/users/{user_id}") # ← 帶 /users prefix
def get_user(user_id: int):
return {"id": user_id}
情況二:改寫 path(strip prefix)
Ingress 把 /users/123 的 /users prefix 剝掉,只把 /123 轉給 user-service。
FastAPI 收到的是 /123,code 可以寫得比較乾淨:
@app.get("/{user_id}") # ← 不需要 /users prefix
def get_user(user_id: int):
return {"id": user_id}
Ingress 有沒有做 path rewrite,決定了 FastAPI endpoint 怎麼寫
大多數團隊的做法是「改寫」(strip prefix),因為這樣每個 service 不用知道自己掛在哪個 path 底下,更好維護。
到這裡 API routing 已經通了。但故事還沒完 —— 你打開 Swagger UI 試了一下,發現怪怪的…
Ingress 做 path rewrite(strip prefix)的好處是?
Strip prefix 讓 service 只需要關心自己的 endpoint(如 /{user_id}),不需要知道自己被掛在 /users 底下。如果以後要把 prefix 從 /users 改成 /accounts,只需要改 Ingress 設定,service 的 code 完全不用動。
正確答案是 B
Strip prefix 讓 service 只需要關心自己的 endpoint(如 /{user_id}),不需要知道自己被掛在 /users 底下。如果以後要把 prefix 從 /users 改成 /accounts,只需要改 Ingress 設定,service 的 code 完全不用動。
🔹 Floor 4-2:root_path — 「嘿 FastAPI,你被掛在 /users 底下」
你選了「Ingress 做 path rewrite」,API routing 一切正常。
然後你打開 https://api.mycompany.com/users/docs 看 Swagger UI,點了 GET /{user_id} 的 “Try it” 按鈕,填了 user_id = 123,按下 Execute…
❌ 404 Not Found
蛤?API 明明能用,為什麼 Swagger 的 “Try it” 壞了?
看一下 Swagger UI 實際送出的 request:
GET https://api.mycompany.com/123 ← 😱 少了 /users!
正確應該是:
GET https://api.mycompany.com/users/123 ← ✅ 這才對
問題在哪?
FastAPI 生成 Swagger UI 的時候,它不知道自己被 Ingress 掛在 /users 底下。它以為自己就是住在根目錄 /。所以 Swagger 的 “Try it” 會直接打 /123,而不是 /users/123。
解法:設定 root_path。
app = FastAPI(root_path="/users") # ← 告訴 FastAPI:你被掛在 /users 底下
@app.get("/{user_id}")
def get_user(user_id: int):
return {"id": user_id}
加了 root_path="/users" 之後:
- API routing 完全不受影響 —
@app.get("/{user_id}")還是只 match/123 - Swagger UI 知道了 — “Try it” 會正確地送
GET /users/123
root_path 讓 Swagger UI 知道真實的 base URL,Try it 才會打對地方
延伸閱讀
- Lv-10: 一個 URL 的旅程 — 從你按 Enter 到畫面出現,瀏覽器到底在幹嘛
- CP-23: Deno Sandbox:把 API Secret 藏在看不見的地方
- CP-187: Gemini API 終於能設花費上限了,CI 跟 agents 比較敢放手玩
Clawd 認真說:
root_path是 ASGI 標準(不是 FastAPI 獨有的)。它只影響 OpenAPI schema 裡的servers欄位,不影響 routing。簡單說:root_path 是給文件看的,不是給 router 看的。技術上,
root_path會讓 FastAPI 生成的openapi.json裡出現"servers": [{"url": "/users"}]。Swagger UI 讀到這個就知道所有 endpoint 都要加上/usersprefix。
🔹 Floor 4-3:完整拼圖 — 推薦做法 + 常見雷
把前面幾小節串起來,大多數團隊的推薦做法是:
- Ingress 做 path rewrite(strip
/usersprefix) - FastAPI 設
root_path="/users"(讓 Swagger 知道真實路徑) - Endpoint 不帶 prefix(乾淨好維護)
# user-service/main.py
from fastapi import FastAPI
app = FastAPI(root_path="/users")
@app.get("/") # 外面打 /users/ → Ingress strip → FastAPI 收到 /
@app.get("/{user_id}") # 外面打 /users/123 → Ingress strip → FastAPI 收到 /123
def get_user(user_id: int):
return {"id": user_id}
# Swagger UI:https://api.mycompany.com/users/docs
# Try it GET /users/123 → ✅ 正確!
常見雷:忘記設 root_path
| 症狀 | 原因 |
|---|---|
| API 正常但 Swagger “Try it” 404 | root_path 沒設,Swagger 送錯 URL |
| Swagger 頁面打得開但 endpoint 列表是空的 | openapi.json 的路徑也被 prefix 影響了 |
| 本地開發沒問題、部署後 Swagger 壞掉 | 本地沒有 Ingress,部署後才有 path prefix 差異 |
Clawd 嘀咕一下:
這個坑真的非常經典。幾乎每個第一次把 FastAPI 放到 reverse proxy 後面的人都會踩到。如果你 Google “FastAPI behind nginx swagger not working”,會看到幾百個 Stack Overflow 問題。答案永遠是:設 root_path。
你的 FastAPI service 被 Ingress 掛在 /users 底下(有 strip prefix)。API 正常但 Swagger 的 Try it 回 404。最可能的原因是?
這是經典的 root_path 問題。API routing 正常代表 Ingress 和 FastAPI 的 path 都對了。但 Swagger UI 不知道 base URL 是 /users,所以 Try it 送出的 request 少了 /users prefix,打到不存在的 endpoint 就 404 了。設 root_path='/users' 即可修復。
正確答案是 B
這是經典的 root_path 問題。API routing 正常代表 Ingress 和 FastAPI 的 path 都對了。但 Swagger UI 不知道 base URL 是 /users,所以 Try it 送出的 request 少了 /users prefix,打到不存在的 endpoint 就 404 了。設 root_path='/users' 即可修復。
🏗️ Floor 5:Swagger / OpenAPI — 屋頂上的導覽地圖
大樓蓋好了,使用者可以正確地打到每個 service。但還有一個問題:
「欸,你們家 API 有文件嗎?我怎麼知道有哪些 endpoint、要帶什麼參數?」
FastAPI 內建 Swagger UI —— 每個 service 都自動生成一份互動式 API 文件:
api.mycompany.com/users/docs→ user-service 的 Swaggerapi.mycompany.com/orders/docs→ order-service 的 Swaggerapi.mycompany.com/notifications/docs→ notification-service 的 Swagger
但你有沒有覺得哪裡怪怪的?
三個 Swagger,三個入口。 每次要查 API 都要記不同的網址。前端工程師會想打你。
統一 Swagger 的做法
核心概念是:每個 FastAPI service 都會在 /openapi.json 自動生成一份 OpenAPI spec(JSON 格式的 API 描述檔)。
你可以寫一個 API Gateway service 或用工具把這些 spec 合併成一份,然後用統一的 Swagger UI 呈現:
api.mycompany.com/docs
├── 包含 user-service 的所有 endpoint
├── 包含 order-service 的所有 endpoint
└── 包含 notification-service 的所有 endpoint
統一 Swagger UI 從每個 service 拉取 OpenAPI spec,合併呈現
常見做法
- 各自獨立:每個 service 有自己的
/docs,不合併。適合 service 之間差異大、團隊獨立運作的情況。 - 手動合併:寫一個 gateway 去拉各 service 的
openapi.json然後合併。 - 用工具:像 Swagger UI 的
urls選項 可以在一個頁面切換多個 spec。 - API Gateway 整合:Kong、AWS API Gateway 等自帶統一文件功能。
Clawd 碎碎念:
說實話,很多團隊根本不合併 Swagger,就讓每個 service 各自有 /docs。因為合併的維護成本不低,而且 spec 格式不一致的時候合併會爆炸。如果你的團隊只有 3-5 個 service,各自獨立就好,不用硬合併。人生苦短。
統一 Swagger UI 的核心做法是?
每個 FastAPI service 都會自動生成 /openapi.json。統一 Swagger 的做法就是把這些 spec 收集起來(拉取或合併),用一個統一的 Swagger UI 頁面呈現。不需要改動 service 的程式碼。
正確答案是 B
每個 FastAPI service 都會自動生成 /openapi.json。統一 Swagger 的做法就是把這些 spec 收集起來(拉取或合併),用一個統一的 Swagger UI 頁面呈現。不需要改動 service 的程式碼。
🏗️ Boss Floor:Trade-off 分析
恭喜你蓋到頂樓了!現在你知道每一層是什麼。
但 Tech Lead 真正在意的不是「這個東西是什麼」,而是「什麼時候該用什麼」。
這就是 trade-off 的世界。
Trade-off 1:Ingress vs Istio
| 純 Ingress | Istio | |
|---|---|---|
| 路由 | ✅ path / host 分流 | ✅ 更細緻(header、weight) |
| TLS | ✅ 外部 TLS | ✅ 外部 + 內部 mTLS |
| Canary | ❌ 要搭配其他工具 | ✅ 原生支援 weight-based routing |
| Observability | ❌ 自己接 | ✅ 內建 metrics、tracing |
| 學習曲線 | 🟢 低 | 🔴 高 |
| 資源消耗 | 🟢 低 | 🔴 每個 Pod 多一個 sidecar |
| Debug 難度 | 🟢 單純 | 🔴 多了一層 proxy 要查 |
結論:
- 3-5 個 service、小團隊 → 純 Ingress。別裝 Istio,你會後悔。
- 10+ 個 service、需要 canary、mTLS、統一 observability → 上 Istio,但要有專人維護。
- 中間地帶 → 用 Ingress + Argo Rollouts(canary)+ Linkerd(比 Istio 輕量的 service mesh)。
Clawd 的 murmur:
我看過太多團隊「因為 Istio 很潮」就裝了,結果 debug 一個 503 要查 Envoy proxy 的 log、Istio control plane 的設定、destination rule 的 mTLS mode… 原本 5 分鐘能解決的問題變成 2 小時。技術選型不是追流行,是解決問題。
Trade-off 2:URL prefix 設計原則
你的 URL 要怎麼切?這裡有幾個常見的 pattern:
Pattern A:按 resource 切(最常見)
/users/...
/orders/...
/notifications/...
每個 prefix 對應一個 service。直覺、好懂。
Pattern B:按版本切
/v1/users/...
/v2/users/...
version prefix 在最前面。適合需要同時維護多版本 API 的情況。
Pattern C:按 domain 切
users.api.mycompany.com/...
orders.api.mycompany.com/...
用 subdomain 而不是 path prefix。好處是每個 service 完全獨立(不同 DNS、不同 TLS cert),壞處是 DNS 和 cert 管理變複雜。
怎麼選?
- 大多數情況 → Pattern A。簡單、一個 Ingress 搞定。
- 需要版本管理 → Pattern B。但考慮用 header(
Accept: application/vnd.myco.v2+json)可能比 URL 版本更優雅。 - service 團隊完全獨立、想各自管理部署 → Pattern C。
Trade-off 3:要不要統一 Swagger?
| 各自獨立 | 統一合併 | |
|---|---|---|
| 維護成本 | 🟢 零 | 🔴 需要維護合併邏輯 |
| 使用者體驗 | 🟡 要記多個網址 | 🟢 一個入口看所有 API |
| 適合 | 內部用、service 少 | 對外 API、service 多 |
完整架構回顧
最後,讓我們把整棟大樓從下到上看一遍:
完整架構:DNS → Ingress → FastAPI → Swagger,每一層各司其職
你的團隊有 3 個 FastAPI service,5 個工程師。Tech Lead 問你要不要用 Istio。你的建議是?
3 個 service + 5 人團隊,Ingress 完全足夠。Istio 的學習曲線和維護成本很高(每個 Pod 多一個 sidecar、debug 複雜度增加),在 service 數量少的時候弊大於利。當 service 數量成長到 10+ 且有 canary、mTLS 等需求時,再考慮導入 Istio 或更輕量的 Linkerd。
正確答案是 B
3 個 service + 5 人團隊,Ingress 完全足夠。Istio 的學習曲線和維護成本很高(每個 Pod 多一個 sidecar、debug 複雜度增加),在 service 數量少的時候弊大於利。當 service 數量成長到 10+ 且有 canary、mTLS 等需求時,再考慮導入 Istio 或更輕量的 Linkerd。
🎓 恭喜通關!
你從 Floor 0 的「三個 port」一路蓋到了 Boss Floor 的「trade-off 分析」。回顧一下每一層學了什麼:
| Floor | 學到了什麼 |
|---|---|
| Floor 0 | 多 port 暴露 → 不好管理,需要統一入口 |
| Floor 1 | DNS 把 domain 翻譯成 IP,是最底層的地基 |
| Floor 2 | Ingress 根據 URL path 分流到不同 service |
| Floor 3 | Istio 是進階的 service mesh,管 traffic、mTLS、observability |
| Floor 4 | FastAPI 的 root_path 讓 Swagger 路徑正確顯示 |
| Floor 5 | OpenAPI spec 可以統一或各自獨立呈現 |
| Boss Floor | 小團隊用 Ingress 就好,Istio 等真的需要再上 |
記住這篇的核心心法:
概念搞懂、trade-off 想清楚,implementation details 讓 AI 幫你寫。
下一篇 Level-Up 見 🍄 ( •̀ ω •́ )✧