承接 Day 5(NFS 準備就緒),今天把 Ingress Controller + cert-manager + DNS 架好,建立對外可用的 TLS 化入口。之後 Selkies 與 Isaac 的訊號交換、UI 都會透過這條入口進出。
為什麼需要 Ingress Controller?
單一入口:讓外部流量統一從 Ingress 進入,不需逐個 NodePort。
TLS 加密:與 cert-manager 整合 ACME/Let’s Encrypt,自動簽發/續期憑證。
DNS 規劃:透過子網域管理不同應用,例如:
isaac.example.com → Isaac Sim Session
lab.example.com → Isaac Lab RL 環境
webrtc.example.com → Selkies Signaling / TURN REST
彈性規則:支援多路徑、多服務、Header Based Routing。
若你後續還要整合 OAuth2 Proxy 或多租戶入口,Ingress 是最自然的放置點。
A. 部署 NGINX Ingress Controller
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
kubectl create ns ingress-nginx || true
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx
-n ingress-nginx
--set controller.replicaCount=2
--set controller.nodeSelector."kubernetes.io/os"=linux
--set controller.admissionWebhooks.patch.nodeSelector."kubernetes.io/os"=linux
replicaCount=2 讓控制器具備最小 HA;若是單節點測試,可降為 1。
測試環境:可用 NodePort。
正式環境:建議用 LoadBalancer(搭配 MetalLB 或雲端 LB)。
範例(values.yaml 片段):
controller:
service:
type: LoadBalancer
loadBalancerIP: 192.168.27.100 # 可選,靜態 IP
B. 安裝 cert-manager(自動 TLS)
helm repo add jetstack https://charts.jetstack.io
helm repo update
kubectl create ns cert-manager || true
helm upgrade --install cert-manager jetstack/cert-manager
-n cert-manager
--set installCRDs=true
HTTP-01 挑戰(建議,最簡單):
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-http
spec:
acme:
email: you@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-http
solvers:
- http01:
ingress:
class: nginx
kubectl apply -f clusterissuer.yaml
email 請換成你的真實信箱,用於接收憑證通知。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-tls
namespace: robotics
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-http"
spec:
ingressClassName: nginx
tls:
若 echo-tls Secret 出現並含有憑證,代表簽發成功。
C. DNS 規劃建議
註冊一個網域(如 example.com)。
在 DNS 管理中,建立子網域 A/AAAA 記錄:
isaac.example.com → Ingress LB IP(例:192.168.27.100)
lab.example.com → 同上(可共用 IP,不同 Ingress Host 區分)
turn.example.com → 指向 TURN 伺服器 IP
若沒有公網 DNS,可用 /etc/hosts 指定:
192.168.27.100 isaac.local lab.local turn.local
或架設內部 DNS(CoreDNS / dnsmasq)。
D. 驗收測試
kubectl run echo-server --image=ealen/echo-server -n robotics --port=80
kubectl expose pod echo-server -n robotics --type=ClusterIP --port=80
套用上文 test-cert.yaml。
確認憑證簽發成功(kubectl describe certificate echo-tls -n robotics)。
瀏覽 https://echo.example.com,看到回應即成功。
E. 架構藍圖
[ 使用者瀏覽器 ]
│ HTTPS (TLS)
▼
[ DNS → Ingress (NGINX) ]
│
├─ isaac.example.com → Isaac Sim Service
├─ lab.example.com → Isaac Lab Service
└─ turn.example.com → TURN/Signaling
│
▼
[ Kubernetes Services ]
│
▼
[ Pod: Selkies + Isaac Containers ]
Ingress 拓樸圖
+--------------------------- 公網 / 內網 DNS ---------------------------+
| |
使用者瀏覽器 ───▶ 解析 isaac.example.com / lab.example.com / echo.example.com ───▶ Ingress LB IP
| |
+---------------------------------------------------------------------+
(80/443)
│
▼
+---------------------------+
| ingress-nginx Controller |
| (Namespace: ingress-nginx)|
+---------------------------+
│ │ │
│ │ │
Host: isaac.example.com Host: lab.example.com Host: echo.example.com
│ │ │
▼ ▼ ▼
Service/isaac Service/lab Service/echo-server
│ │ │
▼ ▼ ▼
Pod: isaac-sandbox Pod: isaac-lab Pod: echo-server
├─ Container: Isaac ├─ Container: Lab
└─ Container: Selkies └─ Container: Selkies
[憑證簽發路徑:HTTP-01]
Let's Encrypt CA ◀── ACME 挑戰 ──▶ ingress-nginx ◀── /.well-known/acme-challenge ── cert-manager
[TURN/Signaling(選擇性獨立域名)]
turn.example.com ──▶ Service/coturn (NodePort/LB) ──▶ Pod: coturn + turn-rest
[負載平衡型態]
• 測試:Ingress Controller Service = NodePort(由外部 L4 轉發器或直接節點 IP 存取)
• 正式:Ingress Controller Service = LoadBalancer(雲端 LB 或 MetalLB 指派 VIP)
小抄:
80 → 443 轉導:建議在 Ingress annotations 開啟自動 HTTP → HTTPS 轉導。
ACME:ClusterIssuer: letsencrypt-http,solver 使用 ingress.class: nginx。
多域名同 IP:不同 Host 對應不同 Service,TLS 憑證以 SAN 覆蓋多個網域。
TURN 位置:TURN/Signaling 常與應用 Ingress 分離,避免與應用共用 443 帶來干擾。
#感想
休日なのに......