- Docker Compose 簡化了本地環境和測試;Kubernetes 透過自動擴縮容、滾動更新和自我修復功能,大規模地協調工作負載。
- Compose 可在單一主機上運行,並支援 Docker;K8s 支援多種運行時、多節點叢集和雲端部署。
- Kompose 加速了從 Compose 到 Kubernetes 的遷移;它支援提供程式、替代物件和標籤來微調服務。
- 使用情境:Compose 用於開發/持續整合;Kubernetes 用於生產、物聯網/邊緣運算、大數據/機器學習以及多雲/混合雲場景。
如果你從事容器開發,遲早會遇到一個關鍵問題:Docker Compose還是 Kubernetes?這兩種工具都用於容器化應用的生命週期管理,但它們的設計初衷並非解決完全相同的問題,也並非在相同的場景下使用。本文將深入比較這兩種工具,並提供實際案例、真實場景以及從一種工具平滑遷移到另一種工具的技巧。
除了技術層面的考量,這項決策還會影響日常營運:部署時間、可擴展性、彈性、安全性以及成本。它還會影響典型的資料工程用例——管道、資料庫、流程處理、批次、資料格式和治理——在這些用例中,編排對於提高生產力至關重要。
Docker 和 Docker Compose 是什麼(它們真正的用途是什麼)?
當我們談論 Docker 時,我們實際上是在談論一個生態系統:Docker Engine、Docker Hub、Dockerfile、Docker Compose …引擎從映像建立和運行容器;Hub 讓共用容器變得容易;而 Compose 允許你在 YAML 檔案中定義堆疊的多個部分,以便使用單一命令啟動它們。
Compose 的誕生是為了讓我們擺脫無休止的腳本和孤立的命令。只需一個 docker-compose.yml 文件,即可描述服務、網路和磁碟區,然後透過一條「docker compose up」(或 V1 版本中的「docker-compose up」)指令即可啟動並執行所有服務。它非常適合本地開發、整合測試、演示或CI 環境。
Compose 的典型範例可能是這樣的,它包含一個 API 和一個 Postgres 資料庫。請注意依賴項、變數和連接埠是如何在一個易於閱讀的程式碼區塊中聲明的:
version: '3.8'
services:
db:
image: postgres:latest
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=postgres
ports:
- '5432:5432'
volumes:
- db:/var/lib/postgresql/data
networks:
- mynet
my-api:
container_name: my-api
build:
context: ./
image: my-api
depends_on:
- db
ports:
- '8080:8080'
environment:
DB_HOST: db
DB_PORT: 5432
DB_USER: postgres
DB_PASSWORD: postgres
DB_NAME: postgres
networks:
- mynet
networks:
mynet:
driver: bridge
volumes:
db:
driver: local
要在 Compose 中手動擴展,可以使用服務的擴展選項。在 Compose V2 中,通常使用 `up --scale` 指令(在 V1 中是 `docker-compose scale`):
docker compose up -d --scale my-api=3
請注意其限制:Compose 是為單一主機設計的,它不會在節點之間進行負載平衡或自動擴縮容,更新通常是使用「build」和「up -d」手動重新建立容器。
什麼是 Kubernetes?它相比 Compose 有哪些優勢?
Kubernetes (K8s) 是一個分散式容器編排平台。它利用 Pod、Deployment 和 Service 等概念,在多節點叢集上大規模管理部署,以運行生產工作負載。
在 Kubernetes 中,你不管理單一容器,而是管理 Pod(一個 Pod 可以包含一個或多個容器)。控制平面負責調度每個 Pod 的運作位置、暴露服務、分配流量、進行水平擴展以及監控工作負載的健康狀況。
一個基本的部署可能如下所示,其中包含 3 個 Web 服務副本。定義模板、標籤和暴露的連接埠:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: my-web-image
ports:
- containerPort: 8000
為了實現負載平衡,雲端通常會使用 LoadBalancer 服務。選擇器會根據 Pod 的標籤來路由流量。
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 8000
type: LoadBalancer
在生產環境中,Kubernetes 的優勢在於其高效能自動化 (HPA)、捲動更新和自我恢復等功能。 HPA會根據指標(例如 CPU 使用率)調整副本數量:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
minReplicas: 1
maxReplicas: 10
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-deployment
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
容器健康狀況透過探針進行監控;如果探針失效,Kubernetes 會重新啟動容器。這就是「自癒」的基礎:
apiVersion: v1
kind: Pod
metadata:
name: web-pod
spec:
containers:
- name: web
image: my-web-image
ports:
- containerPort: 8000
livenessProbe:
httpGet:
path: /healthcheck
port: 8000
initialDelaySeconds: 15
periodSeconds: 15

主要異同點(直奔主題,不拐彎抹角)
它們的共同點在於:都使用容器,並透過 YAML 定義部署。這兩種方案對開發人員和維運人員都很有用,並且在開發到生產的工作流程中能夠很好地互補。
關鍵區別在於範圍:Compose 以 Docker 為中心,並且是單主機的;Kubernetes 支援多種運行時和多節點集群,並可直接整合到雲端和託管服務中。
更重要的差異在於:Kubernetes 提供自動擴縮容、滾動更新和自我修復功能;而 Compose 則不具備這些功能。 Kubernetes 使用 Pod 進行抽象化;Compose 則直接與 Docker 容器互動。
此外,Kubernetes 還包含用於執行一次性任務或定時任務的 Jobs 和 CronJobs。這避免了系統定時任務和額外的容器化進程,使該平台成為定義自動化流程的天然場所。
在本地部署方面,Compose 的優勢在於速度和簡易性。但對於擴展到數百個節點或多雲環境,Kubernetes 才是更合理的選擇。 Compose 可以利用 Docker Swarm 進行多主機部署,但其普及率和功能與 Kubernetes 的生態系統和成熟度相比仍有差距。
為什麼需要管弦樂編排(以及每種編排方式最適合何時使用)
一個好的編排器可以為您提供:統一的配置和部署、定時啟動、服務間的通訊、負載平衡,以及透過對每個服務進行額外的治理來增強安全性。
Compose 以簡潔易懂的方式涵蓋了基礎知識,使其成為開發、測試和演示的理想工具。然而,當您需要多節點、原生負載平衡和自動擴展,或無需停機即可進行增量部署時,它的限制就會顯現出來。
另一方面,Kubernetes 是負載成長時的「平台」:多節點、自動擴展、高可用性和龐大的生態系統,原生支援 AWS、Azure、GCP 和託管選項。
實際應用案例(開發、數據等)
Compose 在以下方面表現出色:可重現的本地環境、端到端測試、持續整合/持續交付 (CI/CD) 和培訓。使用 YAML 定義整個技術堆疊並透過單一命令啟動,可以消除許多冗餘資訊。
Kubernetes 非常適合以下應用場景:生產應用、物聯網和邊緣運算、大數據和機器學習,以及多雲/混合雲環境。它能夠管理對延遲、彈性和可觀測性要求較高的分散式工作負載。
在資料工程領域,K8s 非常適合串流和批次管道、資料庫、佇列和分析引擎,具有每個 pod 的資源控制和峰值自動擴展功能。
如果你的專案規模較小,只需一台主機即可運行,那麼 Compose 就能輕鬆勝任。但當你的用戶群不斷成長,需要強大的容錯能力和負載平衡功能時,就該考慮 Kubernetes 了。
網路、擴充與升級:實用性比較
Compose 會為每個專案建立一個網絡,並解析每個服務的名稱。在專案內部與容器通訊非常簡單且安全,但外部負載平衡和多主機託管並非其原生功能。
在 Kubernetes 中,Service 提供叢集內部的DNS 發現和負載平衡;向外,您可以使用 LoadBalancer、NodePort 或 Ingress 來路由 HTTP/S 流量。
擴展性:Compose 只能手動在單一主機上擴展。 Kubernetes 可以透過 HPA 進行水平擴展,也可以透過指標和/或事件進行編程式擴展。如果叢集允許,它還可以擴展到更多節點。
更新:在 Compose 中,這些通常是手動重新建立。而 Kubernetes 採用滾動更新,並帶有進度控制(kubectl rollout),而且如果出現問題,還可以回滾,從而最大限度地減少影響。
自癒能力:Compose 可以重新啟動容器,但無法解決主機或執行時崩潰問題。 Kubernetes會將 Pod 遷移到健康的節點,整個流程對使用者透明。
開發人員生產力與營運經驗
Compose 是 Docker 之上的一個輕量級層。它易於學習,反饋循環即時,非常適合迭代開發。
Kubernetes 引進了新的概念(Pod、Deployment、Service、Ingress、ConfigMap、PVC 等)。雖然學習曲線較為陡峭,但作為回報,您可以獲得對部署、安全性、可觀測性和可擴展性的精細控制。
在相容性方面,Compose 優先考慮 Docker。 Kubernetes支援多種執行時間環境,並可與雲端服務供應商集成,這對於採用多雲或混合雲策略的公司至關重要。
如何順利地從 Docker Compose 遷移到 Kubernetes
何時遷移?當您的應用程式不再是「小」時,您需要多節點、可觀測性、可擴展性和高可用性,或者您被要求進行金絲雀部署和藍綠部署。
典型挑戰:繪製服務網路圖、設計帶有 PV/PVC 的儲存、將配置分離為 ConfigMaps/Secrets 以及審查每個容器的健康狀況和就緒模式。
架構也需要重新考慮:Pod 作為部署單元,服務用於暴露端點,以及每個容器的資源(CPU/記憶體),以便調度程序能夠完成其工作。
Kompose:幾步即可從 Compose 過渡到 K8s
Kompose 可以將 docker-compose.yml 檔案轉換為 Kubernetes 或 OpenShift 清單檔案。這是啟動遷移的最直接方法,無需手動重寫所有 YAML 檔案。
在開始之前,您需要一個 Kubectl 叢集並配置 kubectl。如果您要測試任何有狀態的功能,建議至少使用兩個工作節點(而非控制平面節點)。使用 `kubectl version` 指令檢查您的 kubectl 版本。
安裝:建議的方法是從最新的 GitHub 發布版本下載二進位。您也可以使用 tar 包、macOS 上的 Homebrew 或“go get”(最後一種方法使用包含開發更改的 master 分支)。
基本轉換:導航到 docker-compose.yml 目錄並運行:
kompose convert
kubectl apply -f <archivos-generados>
Kompose 預設會產生 Deployment 和 Service。日誌通常會列出已建立的每個文件,套用變更後,您將在叢集中看到已「建立」的 Deployment 和 Service。
存取:如果您使用 Minikube,可以輕鬆地暴露或查詢服務。在雲端,勾選「LoadBalancer Ingress」即可取得 LoadBalancer 服務的公用 IP 位址;使用 NodePort,您將在節點上開啟一個連接埠。
清理:測試完成後,請移除已套用的資源。保持集群清潔,避免迭代之間發生衝突。
Kompose 進階選項(提供者、物件和標籤)
Kompose 支援 Kubernetes 和 OpenShift。如果您不指定「--provider」參數,則預設使用 Kubernetes。對於 OpenShift,它可以產生 DeploymentConfigs 和 ImageStreams,如果您使用建置指令,甚至可以產生 BuildConfigs。
它還支援多種輸出格式:使用「-j」參數的 JSON、複製控制器 (ReplicationControllers)、守護程式集 (DaemonSets) 或 Helm Charts。 「--replicas」標誌可讓您變更複製控制器中的副本數量;對於 Helm,它會產生基本的圖表結構。
Kompose 特有的標籤會影響 compose 流程中的轉換。例如,您可以定義 Service 類型,或是否透過 Ingress/Route公開端點。
| 標籤 | 值 |
|---|---|
| kompose.service.type | 節點連接埠/叢集IP/負載平衡器 |
| kompose.service.expose | true / 主機名 |
需要注意的細節:名稱中帶有“_”的將轉換為“-”(K8s 不允許下劃線),並且,如果服務使用卷,則部署策略將更改為“重新創建”,以避免與多個寫入器發生衝突。
Kompose 支援多個版本和文件
Kompose 支援 Compose V1、V2 和 V3(由於 2.1 和 3.2 仍處於實驗階段,因此支援有限)。如果您一次傳遞多個 docker-compose 文件,它們將被合併,並且公共元素將被最新的文件覆蓋,就像您使用覆蓋命令一樣。
在 Kubernetes 轉換過程中,如果存在不相容的金鑰,您會看到類似「警告:不支援的金鑰建置 - 已忽略」的訊息。請放心,該工具會繼續處理它能夠識別的部分,其餘部分留待稍後手動調整。
Kompose 之外:Move2Kube 和手動遷移
如果您需要更精細的控制,可以使用像 Move2Kube 這樣的工具,它們可以分析您的 Compose 檔案並產生更優化的 Kubernetes 工件。當您想要藉鏡平台中的業務模式或範本時,這些工具非常有用。
手動遷移完全可行,並且在初始遷移之後幾乎總是建議手動遷移。典型步驟包括:將服務轉換為 Deployment/StatefulSet,將網路轉換為 Services/Ingress,以及將磁碟區轉換為具有儲存類別的 PV/PVC。
將 Compose 服務轉換為 Deployment 的一個最簡範例可能如下所示:將連接埠、鏡像和標籤傳輸到 Pod 範本:
# docker-compose.yml
version: '3'
services:
web:
build: .
ports:
- '8000:8000'
depends_on:
- db
# Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: my-web-image
ports:
- containerPort: 8000
對於狀態管理(資料庫、佇列),請考慮使用 StatefulSet 和 PersistentVolumes。並非所有在 Compose 中「一起」部署的內容都應該放在同一個 Pod 中;應分離職責,並使用 Service 在組件之間進行通訊。
資料場景:串流、批次和治理
在複雜的資料管道中,K8s 非常適用:Jobs 用於批次處理,CronJobs 用於時間窗口,Deployment 用於 API,Operator 用於 Kafka、Spark 或 Flink 等系統。
對於串流媒體和資料庫,社區運營商和圖表有助於啟動。與單一主機解決方案相比,服務網格網路和資源控制可確保更可預測的延遲和服務等級目標 (SLO)。
在資料治理和安全性方面,Kubernetes 提供了命名空間、策略和基於角色的存取控制 (RBAC) 機制,用於稽核和隔離環境。這比 Compose 的本地部署方式更具實用優勢。
最佳實務和一些小操作技巧
在 Compose 中:保持 YAML 檔案簡潔模組化;使用環境變數和 .env 檔案;記錄連接埠和依賴項;並在 CI 中反映本地運行的內容。
在 Kubernetes 中:定義CPU 和記憶體請求/限制,使用就緒/存活探測,將組態分離到 ConfigMap/Secret 中,並為每個服務套用適當的部署策略。
對於 Kubectl 的更新:使用 `kubectl set image` 和 `kubectl rollout status` 指令來監控進度,並在出現問題時回滾。這將防止生產環境停機。
如果你需要在 Compose 中執行特定的任務,你可以模擬它們,但在 Kubernetes 中使用 CronJobs/Jobs 會更簡潔;你不會用額外的進程或主機 cron 來污染容器。
快速常見問題解答,避免混淆
Compose 能取代 Kubernetes 嗎?不能。 Compose 簡化了單一主機上的多容器堆疊;Kubernetes 則以叢集規模進行編排,並具有高可用性。
Compose 現在還在用嗎?是的,用得非常多。它是一款理想的開發和測試工具,只需幾個指令就能建立完整的開發環境。
Kubernetes 比 Docker 「更好」嗎?它們是不同的東西:Docker 是容器平台;Kubernetes 則在叢集中編排容器並新增進階操作。
我可以在不手動重寫的情況下將我的 Compose 配置遷移到 Kubernetes 嗎?可以,透過 Kompose 或 Docker Desktop 整合即可。這可以讓你快速踏出第一步,之後你可以逐步完善。
細節:程式設計、OpenShift 和其他轉換方案
K8s 不僅僅是持續部署:Jobs 和 CronJobs 可以處理一次性或計劃性任務,而無需您管理系統 cron。
在 OpenShift 中,Kompose 可以產生DeploymentConfigs 和 ImageStreams,如果 Compose 有與 Git 倉庫關聯的構建,甚至可以產生 BuildConfigs。 “--build-repo”和“--build-branch”標誌用於調整來源。
如果您需要不同的輸出格式,Kompose 允許使用DaemonSet、ReplicationController 或 Helm Chart,而不是預設的 Deployment 和 Service。它還可以生成 JSON 文件,而不僅僅是 YAML 文件。
相容性、警告和一些小問題
Kompose 支援 Compose V1/V2/V3(2.1 和 3.2 版本有一些限制)。不支援的鍵會被忽略並顯示警告訊息,以便使用者手動調整。
如果您的服務包含卷,Kompose 會將策略變更為“重新建立”,以避免對相同磁碟區的並發存取。這對於有狀態服務來說是正常的。
名稱中的底線會被轉換為連字符。這是 Kubernetes 對物件名稱的限制,因此請確保在 Compose 中正確命名,以免轉換過程中出現意外情況。
若要從外部訪問,請檢查服務類型:ClusterIP(內部)、NodePort(節點連接埠)或 LoadBalancer(雲端公網 IP)。使用 Ingress,您將擁有清晰的 HTTP/S 路由和集中式 TLS。
如果在 Minikube 中進行測試,類似「minikube service <svc> --url」這樣的指令會回傳一個快速 URL。在 Cloud 中,請查看描述 Service 時的「LoadBalancer Ingress」欄位。
一個有趣的現像是:在社群中,你會發現有關 Kubernetes 相關職位薪資和生產環境採用率接近 88% 的資訊。這並不奇怪:它已成為事實上的標準。
總的來說,Kubernetes 的功能遠遠超越 HTTP:服務網格、Operator 和 CRD進一步擴展了 Kubernetes 的應用範圍。如果您之前使用過 Compose,一開始可能會感到不知所措,但這額外的功能最終會帶來更強大的運維能力。
重置策略:有用的等效項
Compose 允許設定“restart: always/on-failure/no”。在 Kubernetes 中,根據具體情況,您將擁有具有相應重新啟動策略的獨立 Pod 或控制器(Deployment 或 RC)。
| docker-compose restart | K8s 中的對象 | 重啟策略 |
|---|---|---|
| 「「 / 總是 | 控制器(部署/RC) | 總是 |
| 失敗時 | 下 | 失敗時 |
| 沒有 | 下 | 決不 |
如果在 Compose 中有「計算」容器或臨時任務(例如快速計算「π」),只需在 K8s 中將其實現為 Job 或 CronJob,並設定相應的策略,一切就緒。
選擇 Compose 實現快速本地部署,當您的環境需要更強大的功能時,請選擇 Kubernetes:它支援多節點、自動擴縮容、無縫部署,並具備真正的彈性。借助 Compose、Move2Kube 和一些必要的配置,過渡過程將非常順暢。
最終,選擇取決於規模和複雜性:Compose 非常適合開發、測試和單主機堆疊;Kubernetes 是企業、多雲部署以及需要高級自動化、高可用性和擁有數千個整合的生態系統的團隊的理想選擇。
