Kubernetes 對外公開架構
巴尼巴比人
此文件說明 在沒有公網 IP 或無法 Port Forward 的情況下,如何使用 Cloudflare Tunnel 將 Kubernetes 叢集(RKE2、K3s、k8s)中的服務安全地公開到網際網路,並整合 HTTPS 憑證(使用 cert-manager + Cloudflare DNS-01)。
本架構特別適合:
- Home Lab、辦公室、NAS、Docker/K8s 等私有環境
- 公網 IP 不是在 Kubernetes 節點上
- 不能 Port Forward
- 想安全、免暴露 IP 對外服務
1. 架構概觀
巴尼巴比人
Cloudflare Tunnel 讓 你的節點主動連到 Cloudflare Edge network,
外部使用者的流量將由 Cloudflare 反向代理到你的 Kubernetes。
完整視覺化架構
Internet Users (HTTPS)
|
v
Cloudflare Edge
(憑證、WAF、Proxy、CDN)
|
v
Cloudflare Tunnel
(你的 Node 主動建立 outbound 連線)
|
=================================
| |
v v
RKE2 Control-Plane RKE2 Worker Node
(cert-manager) (Ingress Controller)
2. Cloudflare Tunnel 運作方式
巴尼巴比人
Cloudflare Tunnel(cloudflared)在你的 Kubernetes Node 內以 Deployment 或 Pod 形式運作。
它會:
- 主動連線到 Cloudflare Edge
- 建立反向代理 Channel
- Cloudflare 將網路請求導入此 Tunnel
- 將 HTTPS 傳給你的 Ingress Controller
- Ingress Controller 決定轉給哪個 Service/Pod
不需要公網 IP,不需要 Port Forward,不會暴露你的家庭 IP。
3. Cloudflare Tunnel 安裝方式
巴尼巴比人
建議方式:在 Kubernetes 中部署 cloudflared(Deployment + Secret + ConfigMap)
你需要以下資訊:
- Cloudflare Tunnel ID
- Cloudflare Tunnel Secret
- Cloudflare zone / domain
- Cloudflare API Token(若你用 cert-manager DNS-01)
我可以生成完整 YAML,如果你需要(請告訴我 domain)。
4. Cloudflare Tunnel Config(多路由支援)
巴尼巴比人
Config 範例(config.yaml):
tunnel: <YOUR_TUNNEL_ID>
credentials-file: /etc/cloudflared/creds/credentials.json
ingress:
- hostname: app.example.com
service: http://traefik.kube-system.svc.cluster.local:80
- hostname: api.example.com
service: http://api-service.default.svc.cluster.local:8080
- service: http_status:404
此方式支援:
- 多 domain
- 多 application
- 多 Ingress Service
- 同一條 Tunnel 處理所有對外公開
5. Kubernetes Ingress 設定(公開服務)
巴尼巴比人
仍然使用標準 Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp
spec:
ingressClassName: traefik
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
number: 80
Tunnel 會接管 domain → Ingress → Service 的路線。
6. HTTPS 憑證(cert-manager + Cloudflare DNS-01)
巴尼巴比人
由於 Tunnel 是反向代理,Ingress 不需要公開給外網,
但仍可以使用 Let's Encrypt(DNS-01)取得合法 HTTPS:
Cloudflare API Token Secret
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-token-secret
type: Opaque
stringData:
api-token: "<YOUR_CF_API_TOKEN>"
ClusterIssuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-dns01
spec:
acme:
email: you@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: acme-private-key
solvers:
- dns01:
cloudflare:
apiTokenSecretRef:
name: cloudflare-api-token-secret
key: api-token
Certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: myapp-cert
spec:
secretName: myapp-tls
dnsNames:
- app.example.com
issuerRef:
name: letsencrypt-dns01
kind: ClusterIssuer
7. 流量流程(公開模式)
巴尼巴比人
1. 外部使用者 → https://app.example.com
2. Cloudflare Edge 終止 SSL、WAF、防攻擊
3. 流量透過 Cloudflare Tunnel 傳入
4. Tunnel 導至 Kubernetes
5. Ingress Controller 分流
6. Service → Pod
8. Cloudflare 與 Kubernetes 各自負責什麼?
巴尼巴比人
| 項目 | Cloudflare | Kubernetes |
|---|---|---|
| DNS | ✔ | ❌ |
| SSL Termination | ✔(Edge) | ❌(可 optional 在 K8s 用 mTLS) |
| WAF | ✔ | ❌ |
| Proxy / CDN | ✔ | ❌ |
| 實際服務運行 | ❌ | ✔ |
| Routing | ✔(Tunnel) | ✔(Ingress) |
Kubernetes 不需要公網曝光,整個環境完全封閉。
9. 適用場景
巴尼巴比人
| 適用 | 描述 |
|---|---|
| 沒公網 IP | 家用、公司內網、NAT 後、自架虛機 |
| 不想暴露家庭 IP | Tunnel 隱藏來源 |
| 想用 Cloudflare 的 WAF/CDN | Tunnel 支援 |
| 想公開 Kubernetes 服務 | 完美搭配 |
10. 小結
巴尼巴比人
使用 Cloudflare Tunnel 整合 Kubernetes:
- ✔ 不需要公網 IP
- ✔ 不需要 Port Forward
- ✔ 不需暴露真實家庭 IP
- ✔ 支援多 domain、多服務
- ✔ 與 cert-manager 完美搭配
- ✔ 與 Ingress Controller 完全相容
這是最安全、最現代化、最適合 Home Lab 與企業 Lab 的公開方式。