讓外部流量安全、精準地導向正確的微服務。
在 Kubernetes 中,ClusterIP 只能在叢集內溝通;LoadBalancer 雖然可以對外,但每個服務都配一顆公有 IP,錢包會哭。
Ingress 就像大樓的總機:只需要一個公有 IP,就能根據網址 (Host) 或路徑 (Path) 把外部流量精準導向不同的微服務。而 Ingress 只是「規則」,真正執行規則的是 Ingress Controller——我們用最主流的 Nginx Ingress Controller。
這是 production 的流量入口(Helm 模板渲染後的樣子):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: k8sdemo-ingress
namespace: k8sdemo
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- wafer.carrot-atelier.online
secretName: wafer-bi-tls
rules:
- host: wafer.carrot-atelier.online
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-gateway-service
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: wafer-frontend-svc
port:
number: 80
流程如下:
wafer.carrot-atelier.online/api → 送去 api-gateway(Node.js)/ → 送去 wafer-frontend(React 畫面)關於這個網域:現在連不上了,但設定是真的
這份設定當初真的跑在對外環境上,不過現在去戳這個網址會連不上——背後的雲端環境已經收掉了。Day 9 記錄過那次雲端評估的完整過程,後來這個系列的實作重心搬回本機,那座叢集連同它的 LoadBalancer 也就跟著退場。
這裡有件事值得順手記一筆:叢集砍掉了,DNS 紀錄不會自己消失。域名供應商那邊的 A record 還好端端指著一個已經被回收的位址,而那個位址之後會配給別人。真正要收掉一個環境的時候,DNS 紀錄要記得跟著一起清,這是雲端資源生命週期裡很容易被漏掉的一步。
憑證也是類似的道理:Let's Encrypt 的效期 90 天,靠 cert-manager 自動續約。cert-manager 跟著叢集一起沒了之後,那張憑證自然就停在最後一次簽發的狀態。
第 3 節的實測不依賴這個網域,用的是本機的
wafer.local,在自己的 Docker Desktop 上照著做就能重現。
直接在 Docker Desktop 的 K8S 裝一套 ingress-nginx 來驗證(一行 helm 搞定):
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx --create-namespace
裝完之後 LoadBalancer 會綁到 localhost:80。接著套用 Ingress 規則(host 用 wafer.local),然後用 curl 驗證分流:

▲ Ingress 路由實測:/api 到 Node.js Gateway、其他路徑到 Python FastAPI、Host 不符直接 404
這三個測試就看得出 Ingress 在做什麼:
/api/healthz → 回來的是 Node.js Gateway 的 JSON/meta → 回來的是 Python FastAPI 的晶圓資料Host: wafer.local → Nginx 直接 404,不認識的流量一律擋在門外同一個 localhost:80,不同路徑進到完全不同語言寫的服務。
這系統強化了一些資安的政策。Annotations 裡的 cert-manager.io/cluster-issuer: "letsencrypt-prod" 會觸發叢集內的 cert-manager 去跟 Let's Encrypt 免費申請憑證,流程全自動:
wafer-bi-tls 這個 Secretssl-redirect: "true" 把所有 HTTP 導向 HTTPS還記得 Day 10 說的 CRD 依賴嗎?ClusterIssuer 就是 cert-manager 的 CRD,所以叢集要先裝 cert-manager,我們的 Chart 才裝得起來,順序不能反。
上面這五步當初是真的跑完的——但也正因為第 5 步「自動續約」是靠 cert-manager 持續運作,環境收掉之後憑證就停在最後一次簽發的狀態,90 天後自然過期。自動化不是「設定一次就永遠有效」,是「有個東西持續在替你做這件事」——那個東西停了,效果就停了。
流量的門面搞定了。但還有一個問題沒解決:Python Pod 一重啟,Delta Lake 資料就沒了。明天來解決容器的「失憶症」——PV 與 PVC 持久化存儲。