htt
server {
listen 80;
loc
loc
你可以分別用 docker build 與 docker run 手動啟動這些容器,但這相當繁瑣。更優雅的方式是使用 Docker Compose 定義整個應用堆疊,並用單一指令啟動。
此處我們定義了三個 service。Redis 服務使用官方映像,同時掛載一個名為 redis_data 的 volume 以持久化資料。backend 服務會在建置階段讀取 ./backend 目錄中的 Dockerfile,並且設定環境變數讓 Flask 知道 Redis 位於哪個主機名稱(在 Compose 網路中,service 名稱即為 DNS 名稱)。depends_on 搭配 healthcheck 確保 Redis 在 backend 啟動前就緒。
Nginx 服務唯一對外的連接埠是 8080,其他服務則隔離在內網網路中。Frontend 與 backend-net 兩個網段讓 Nginx 可以到達 backend,但 backend 和 Redis 之間則透過 backend-net 連繫。一個小缺點是 Nginx 也同時在 frontend 網段,但它只能存取 backend 已綁定的連接埠,沒有其他資源,因此隔離性足夠。
等待數分鐘後,你就可以使用 curl 或瀏覽器訪問 http://localhost:8080/api/count,每一次存取都會讓 visit_count 增加。透過 docker compose ps 可以查看所有服務的狀態;docker compose logs -f 可以追蹤日誌。
這個多容器堆疊是一套完整的獨立交付單元。如果要擴展 backend 容器數量,只要執行 docker compose up -d --scale backend=3 即可,Nginx 會自動進行負載平衡。但若你的應用需要跨越多台實體機、需要自動伸縮、故障自動恢復,甚至滾動更新,那麼使用 Kubernetes(K8s)才是長久之計。
Docker Compose 雖好用,但它僅限於單一主機上的編排。當你的服務規模成長到需要多節點、需要高可用性、需要集中管理機密與設定時,Kubernetes 便成為標準答案。本節將說明如何把剛才建立的 Docker 容器搬到 K8s 上運行,從映像推送、部署清單撰寫到 Ingress 設定。
假設你的電商網站流量暴增,原本單一 Docker 主機的資源已滿載。你可以在另一台主機上用 Docker Compose 再複製一份堆疊,但兩台主機之間如何共享 Redis 資料?如何統一管理設定?如何做滾動更新而不中斷服務?這些問題在叢集管理平台上都能得到優雅解決。
簡單來說,K8s 是「容器的作業系統」,它讓多台伺服器組成一個資源池,並在此池中智慧地運行與管理容器。而 Docker 映像檔正是 K8s 執行的基本單位,兩者不是競爭關係,而是上下游的整合關係。
要讓 K8s 叢集能拉取你的映像,首先必須將映像推送到一個可存取的倉儲。最常見的是 Docker Hub,但生產環境較推薦使用雲端服務(如 AWS ECR、GCR、GHCR)或私有 Harbor。在此我們以 Docker Hub 為例。
首先確定你的映像已建置並標記了正確的版本。假設你的 Docker Hub 帳號是 jason2026,執行以下指令推送到公開或私人儲存庫:
在進行推送到 Docker Hub 之前,請先思考 2026 年的安全最佳實務:絕不要將帶有高風險漏洞的映像推送到正式倉儲,也不要在 Dockerfile 中存放任何機密。建議在你的 CI/CD 流程(例如 GitHub Actions)中加入映像掃描步驟。Docker Scout 可以監控映像的供應鏈,而 Cosign 能為映像簽署憑證,確保完整性。
如果你的 K8s 叢集需要拉取私有映像,最安全的方法是使用 imagePullSecrets,而不是將密碼寫在 Deployment 清單中。建立 secret 的指令如下:
現在,我們將 Docker Compose 中定義的服務翻譯成 K8s 物件。K8s 清單通常用 YAML 撰寫,並以 kubectl apply -f 套用。建立一個 k8s/ 目錄,並在其中建立以下幾個 YAML 檔案。
這個 Deployment 包含 3 個 Pod 副本。我們設定了資源的 request 與 limit,K8s 會以此為調度依據,避免資源被單一 Pod 壟斷。Liveness probe 用於判斷容器是否存活,若失敗 K8s 會重啟該容器;Readiness probe 用於判斷容器是否可接收流量,若失敗 Service 自動將流量導離該 Pod。
為了在節點異常或 Pod 重排後保留 Redis 資料,我們使用 PVC(Persistent Volume Claim)讓資料掛載到持久化儲存(如 EBS、Cinder、NFS)。如果你的正式環境不需要持久化快取,也可以直接使用 emptyDir。
Nginx 在 K8s 中通常不需要以 Deployment 方式部署,而是採用 Ingress Controller。不過為了延續我們原先的架構,也可以用 Deployment 暴露為 NodePort 或 LoadBalancer。但更進階且標準的做法是直接使用 Kubernetes Ingress 資源,讓叢集內的 Ingress Controller(如 ingress-nginx)統一處理 TLS 終止與路由規則。
以下我們建立一個 Nginx Deployment(但僅作為靜態檔案伺服器)以及獨立的 Ingress 物件,但為了精簡教學,我們會將 Nginx 的內容簡化,並將外部流量直接導向 backend 服務。實際上在雲原生架構中,通常不會用 Nginx container 當作反向代理,而是直接使用 Ingress Controller 來路由,因此在此練習中,我們可以將 Nginx 角色由 Ingress Controller 取代。
但為了讓教學完整,我們保留 Nginx 裝飾性的服務,並演示如何透過 Ingress 路徑將請求導至 Nginx 或 backend。假設訪客請求 / 由 Nginx 回應,請求 /api 轉發至 backend,我們可以這樣設定:
這個 Ingress 接受 demo.example.com 的請求,路徑 / 導向 nginx-static,而 /api/* 導向 backend。你可以使用 kubectl apply -f k8s/ 套用所有清單,然後以 kubectl get pods, svc, ingress 查看狀態。
若你的叢集沒有現成的 Ingress Controller,可以先安裝 ingress-nginx(依版本略有不同,可使用 Helm 安裝),或者直接將 nginx-static Service 改為 LoadBalancer 類型。但這部分細節在真實雲環境中會因人而異,在此不做展開。
到了這個階段,你已成功地將單機 Docker Compose 堆疊移植到了 Kubernetes 叢集。K8s 提供了自動化伸縮、自我修復、統一網關等能力,讓你可以更安心地進行大規模部署。
完成部署只是起點,後續的維運與安全防護才能真正決定系統的長期穩定。尤其進入 2026 年,容器化環境的複雜度只增不減,從映像供應鏈到執行時的縱深防禦,每一個環節都需要謹慎把關。
曾經有安全研究機構發現,大規模開源專案中曾有數百萬個惡意映像被上傳至 Docker Hub,許多開發者會在不知情的情況下拉取到含有挖礦程式的映像。這些攻擊往往源自於不安全的基礎映像或依賴套件。
之後在部署前,可在 CI 中用 cosign verify 驗證。Kubernetes 透過 Kyverno 的 ClusterPolicy 可以設定 signature verification 規則,拒絕未簽署的映像。
容器環境的動態性使得傳統的監控方式變得不夠直觀——Pod 在秒級內可能被建立或刪除,IP 不斷變化。因此,我們需要一套專為雲原生打造的觀測工具。
指標(Metrics):Prometheus 負責收集指標,Kubernetes 本身暴露了豐富的指標,例如 Pod 的 CPU、記憶體、網路流量,以及容器狀態。Application 也可以透過 Prometheus client library 暴露自訂指標,例如每秒請求數、延遲分位數。透過 Grafana 儀表板,我們可以視覺化這些資料,設定告警(例如流量異常飆升或錯誤率超過 5%)。
日誌(Logs):最常用的方案是 EFK/ELK(Elasticsearch + Fluentd/Fluent Bit + Kibana)或 Loki。在 K8s 中,每個 Pod 的 stdout 會被 kubelet 收集,我們可以部署 DaemonSet 來代理日誌推送,確保集中儲存與快速查詢。
追蹤(Traces):OpenTelemetry 成為業界標準,整合 trace 到端到端請求鏈路,定位效能瓶頸。在 2026 年,所有主流微服務框架都已內建 OpenTelemetry 整合,只要在服務中加載 SDK,並搭配 Jaeger 或 Tempo 即可視覺化。
理想的可觀測性架構應該是在 Docker 容器內就已啟動 instrumentation,通過標準的 OTLP 協議輸出,然後由叢集中的 Collector 統一處理,降低對應用程式的侵入性。
Kubernetes 靈活度高的另一面,是成本容易失控。隨便建立一個無 Limit 的 Pod 可能耗盡整個節點資源,久而久之產生高昂的雲端帳單。2026 年的最佳實務絕對包含以下項目:
另外,Dockerfile 的寫法也會影響成本:使用更小體積的基礎映像(例如 alpine 或 distroless)可以減少映像拉取時間、磁碟空間與攻擊面。多階段建置能移除建置工具,讓最終映像僅保留 runtime 所需。
在 2026 年,FinOps 已逐漸成為企業 KPI 的一部分,容器化工程師需要具備將技術決策轉化為財務影響的能力。透過上述技巧,你能在維持效能的同時,大幅降低基礎設施支出。
在 2026 年的技術版圖中,Docker 與 Kubernetes 的整合不再是高深秘訣,而是現代應用部署的標準作業流程。這篇文章,我們從容器化的核心動機談起,逐步走過 Docker Engine 安裝、Dockerfile 撰寫、多階段建置、Docker Compose 編排,最後將整套應用移植到 Kubernetes 叢集,並涵蓋了映像安全、可觀測性與成本控管等維運層面的實踐。
試著回顧一下你現在已掌握的能力:你能獨立撰寫優化的 Dockerfile,能使用 Compose 啟動一套完整的多容器應用,能建立 K8s 的 Deployment、Service、PVC 與 Ingress,也知道如何透過 Cosign 驗證映像、Prometheus 監控叢集。這些技能足以應對多數中大型企業的部署需求。
最後,別忘了理念:容器化是為了讓交付更快速、運行更穩定、開發更敏捷。工具只會不斷演進——可能五年後 Docker 不再是霸主、K8s 被更新的編排框架取代,但「將應用與依賴隔離並自動化管理」的核心思想將恆久不變。將你的時間投資在基礎原理與問題本質上,你就能以不變應萬變。
現在,請開啟你的終端機,把剛才學到的所有手動建置一遍。真正的技術來自於雙手,閱讀只是地圖,而旅行本身就是收穫。祝你在容器化的旅途上,駕輕就熟,部署無往不利!
歡迎在下方留言,分享您的想法、心得或疑問。所有留言都會透過 GitHub 帳號 進行驗證。