Docker Swarm 作為 Docker 原生叢集管理工具,提供簡潔易用的容器協調方案。相較於 Kubernetes 的複雜性,Swarm 更易於學習和佈署,尤其對於已熟悉 Docker 命令的開發者而言,能快速將既有應用容器化並佈署至叢集環境。本文除了比較 Swarm 與 Kubernetes 的特性差異外,更著重於 Swarm 的實際操作,涵蓋叢集建立、服務佈署、網路組態、擴充套件服務以及 Ansible 自動化管理等導向,藉由逐步的程式碼範例與解說,引導讀者掌握 Swarm 的核心功能。
在容器化應用日益普及的今日,選擇合適的容器協調工具至關重要。Docker Swarm 以其簡潔易用和與 Docker 生態系的緊密整合,成為許多團隊的首選。本文探討了 Docker Swarm 的架構、工作原理以及實際操作步驟,涵蓋了叢集的建立、服務的佈署和擴充套件、網路的組態以及 Ansible 的自動化管理等方面。透過具體的程式碼示例和詳細的解說,讀者可以快速掌握 Docker Swarm 的核心功能,並將其應用於實際的專案中。文章還比較了 Docker Swarm 和 Kubernetes 的差異,幫助讀者根據自身需求做出最佳選擇。對於想要快速上手容器協調技術的開發者和維運人員來說,本文提供了寶貴的實踐。
容器叢集與擴充套件服務的抉擇:Docker Swarm 與 Kubernetes 的比較
在容器化技術的領域中,叢集管理和服務擴充套件是至關重要的議題。Docker Swarm 和 Kubernetes 是兩款主流的容器協調工具,它們各自有不同的設計理念和應用場景。本文將探討這兩者的差異,並分析如何根據實際需求進行選擇。
Docker Swarm 與 Kubernetes 的根本差異
Docker Swarm 的設計理念是與 Docker API 高度相容,使得使用者能夠無縫地將原本在單一主機上的 Docker 命令套用到叢集環境中。這種相容性大大降低了學習曲線和使用門檻。然而,這種設計也意味著 Swarm 的功能受限於 Docker API。如果 Docker API 不支援某項功能,那麼 Swarm 也難以實作該功能。
反觀 Kubernetes,則是根據 Google 的容器管理經驗所開發,具有更強大的功能和靈活性。Kubernetes 不僅支援 Docker,還能與其他容器執行時(如 containerd)協同工作。它的設計更為複雜,但也提供了更豐富的功能,例如自動容錯移轉(automatic failover)。
網路和持久化儲存的挑戰
在早期的 Docker 版本中,跨主機的容器網路連線和持久化儲存是兩個主要的挑戰。Docker 1.9 之後,引入了多主機網路和持久化儲存功能,這些功能的加入大大縮小了 Kubernetes 和 Swarm 之間的差距。
Kubernetes 從早期開始就支援網路和持久化儲存解決方案,如 Flannel 和 Persistent Volumes。隨著 Docker 1.9 的發布,這些功能也被整合到 Docker 中,使得 Swarm 使用者也能享受到這些好處。
自動容錯移轉:Kubernetes 的優勢
Kubernetes 在自動容錯移轉方面具有明顯的優勢。當容器或節點發生故障時,Kubernetes 能夠自動偵測並在健康的節點上重新啟動容器。然而,這種自動化的解決方案也有其侷限性,因為它無法涵蓋所有可能的故障場景,例如需要人工干預的複雜故障。
Swarm 雖然不具備內建的自動容錯移轉功能,但其“包含電池但可更換”的哲學允許使用者根據需求開發自定義的容錯移轉策略。
如何選擇 Docker Swarm 或 Kubernetes
選擇 Docker Swarm 或 Kubernetes 時,需要考慮以下因素:
- 是否依賴 Docker 的發展:如果希望依賴 Docker 官方對叢集管理的支援,那麼 Swarm 是更好的選擇。
- 是否需要克服 Docker 的限制:如果需要更強大的叢集管理功能和靈活性,那麼 Kubernetes 可能更適合。
推薦:Docker Swarm
根據目前的發展趨勢和功能比較,Docker Swarm 是更容易上手和使用的選擇。它與 Docker API 的高度相容性,使得使用者能夠保留現有的命令和組態,無需額外的學習成本。雖然 Kubernetes 在某些方面具有優勢,但隨著 Docker 的不斷進步,這些差距正在逐漸縮小。
實作 Docker Swarm
要設定 Docker Swarm,需要選擇一個服務發現工具,如 Consul。Consul 是一個優秀的工具,與 Swarm 協同工作效果良好。下面是一個簡單的步驟,展示如何設定一個包含三個伺服器的 Swarm 叢集,其中一個作為主節點,另外兩個作為叢集節點。
# 初始化 Swarm 叢集
docker swarm init --advertise-addr <主節點IP>
# 在工作節點上加入 Swarm 叢集
docker swarm join --token <由主節點生成的token> <主節點IP>:2377
內容解密:
docker swarm init命令用於初始化一個新的 Swarm 叢集。--advertise-addr引數指定了主節點的 IP 地址,用於叢集內部通訊。docker swarm join命令用於將工作節點加入到現有的 Swarm 叢集中。--token引數需要填入由主節點生成的 token,以確保工作節點的安全加入。
透過以上步驟,可以快速建立一個基本的 Docker Swarm 叢集,並開始進行容器化應用的佈署和管理。隨著對 Swarm 的深入瞭解,可以進一步探索其高階功能,如服務發現、負載平衡和滾動更新等,以滿足複雜的生產環境需求。
Docker Swarm叢集管理與服務擴充套件
Docker Swarm是一種容器協調工具,能夠跨多台主機管理Docker容器。本章節將介紹如何使用Docker Swarm進行叢集管理和服務擴充套件。
Docker Swarm架構
Docker Swarm使用主從架構,其中主節點(Swarm Master)負責管理和協調叢集中的容器佈署,而從節點(Swarm Node)則負責執行容器。
圖示:Docker Swarm叢集架構
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 圖示:Docker Swarm叢集架構
rectangle "管理" as node1
rectangle "註冊" as node2
rectangle "服務發現" as node3
node1 --> node2
node2 --> node3
@enduml
此圖示展示了Docker Swarm叢集的架構,其中Swarm Master負責管理Swarm Node,而Swarm Node則向Consul註冊自己的資訊。
Docker Swarm工作原理
當我們向Swarm Master發出佈署容器的指令時,Swarm Master會根據當前的叢集狀態和佈署策略選擇一個合適的Swarm Node進行佈署。
內容解密:
- 佈署策略:Swarm支援多種佈署策略,例如Spread策略,會將容器佈署到目前容器數量最少的節點上。
- Consul服務發現:Consul負責維護叢集中各節點和服務的資訊,當新節點加入或舊節點離開時,Consul會將這些資訊同步給Swarm Master。
設定Docker Swarm
為了示範Docker Swarm的使用,我們將建立一個由四台虛擬機器組成的叢集,分別是cd、swarm-master、swarm-node-1和swarm-node-2。
程式碼:建立虛擬機器
vagrant up cd swarm-master swarm-node-1 swarm-node-2
內容解密:
- Vagrant:使用Vagrant工具建立和管理虛擬機器。
- 虛擬機器角色:cd節點用於協調,而swarm-master和swarm-node-*則組成Docker Swarm叢集。
使用Ansible組態Docker Swarm
使用Ansible工具對叢集進行組態和管理。
程式碼:執行Ansible Playbook
vagrant ssh cd
ansible-playbook /vagrant/ansible/swarm.yml -i /vagrant/ansible/hosts/prod
內容解密:
- Ansible Playbook:使用Ansible的Playbook自動化組態和管理Docker Swarm叢集。
- swarm.yml:定義了Docker Swarm叢集的組態和管理任務。
Docker Swarm 叢集與服務擴充套件技術解析
Docker Swarm 為 Docker 提供原生叢集管理功能,實作跨多主機的容器協調與排程。本文將探討 Docker Swarm 的組態、佈署及管理流程,並結合實際案例進行技術剖析。
Docker Swarm 組態與佈署
在 Ansible playbook swarm.yml 中定義了 Swarm 叢集的組態,主要涉及 swarm_master 和 swarm_master_ip 變數的設定。根據伺服器角色(master 或 node),Docker 組態檔案會被設定為 docker-swarm-master.service 或 docker-swarm-node.service。
Master 節點 Docker 組態
Master 節點的 ExecStart 設定如下:
ExecStart=/usr/bin/docker daemon -H fd:// \
--insecure-registry 10.100.198.200:5000 \
--registry-mirror=http://10.100.198.200:5001 \
--cluster-store=consul://{{ ip }}:8500/swarm \
--cluster-advertise={{ ip }}:2375 {{ docker_extra }}
內容解密:
- 允許不安全的私有倉函式庫註冊:
--insecure-registry 10.100.198.200:5000指定私有 Docker 倉函式庫的位置。 - 使用 Consul 作為叢集儲存:
--cluster-store=consul://{{ ip }}:8500/swarm設定 Swarm 使用 Consul 進行服務發現和叢集狀態儲存。 - 宣告 Swarm Master 地址:
--cluster-advertise={{ ip }}:2375使 Swarm Master 在指定 IP 的 2375 連線埠上宣告其存在。
Node 節點 Docker 組態
Node 節點的 ExecStart 設定如下:
ExecStart=/usr/bin/docker daemon -H fd:// \
-H tcp://0.0.0.0:2375 \
-H unix:///var/run/docker.sock \
--insecure-registry 10.100.198.200:5000 \
--registry-mirror=http://10.100.198.200:5001 \
--cluster-store=consul://{{ ip }}:8500/swarm \
--cluster-advertise={{ ip }}:2375 {{ docker_extra }}
內容解密:
- 多重通訊協定支援:
-H tcp://0.0.0.0:2375和-H unix:///var/run/docker.sock使 Docker daemon 同時監聽 TCP 連線埠和 Unix socket。 - 加入 Swarm 叢集: 與 Master 節點類別似,Node 也使用 Consul 進行服務發現,並在 2375 連線埠上宣告其存在。
Swarm 角色任務定義
在 roles/swarm/tasks/main.yml 中定義了 Swarm master 和 node 的容器啟動任務:
- name: Swarm node is running
docker:
name: swarm-node
image: swarm
command: join --advertise={{ ip }}:2375 consul://{{ ip }}:8500/swarm
env:
SERVICE_NAME: swarm-node
when: not swarm_master is defined
tags: [swarm]
- name: Swarm master is running
docker:
name: swarm-master
image: swarm
ports:
- "2375:2375"
command: manage consul://{{ ip }}:8500/swarm
env:
SERVICE_NAME: swarm-master
when: swarm_master is defined
tags: [swarm]
內容解密:
- Node 加入叢集: 使用
join命令使 Node 加入由 Consul 管理的 Swarm 叢集。 - Master 管理叢集: 使用
manage命令啟動 Swarm Master,負責管理整個叢集。
驗證 Swarm 叢集狀態
執行 docker info 命令可檢視叢集的詳細資訊:
export DOCKER_HOST=tcp://10.100.192.200:2375
docker info
輸出結果顯示了叢集的整體狀態,包括節點數量、容器分佈、CPU 和記憶體資源等資訊。
內容解密:
- 叢集概覽:
docker info提供整個叢集的綜合資訊,而非單一主機的狀態。 - 節點詳細資訊: 列出所有節點的健康狀態、容器數量、資源預留情況等。
叢集與擴充套件服務的 Docker Swarm 實踐
在前面的章節中,我們已經建立了一個 Docker Swarm 叢集,並驗證了 Docker 命令在遠端伺服器(swarm-master)上的執行效果。現在,我們將進一步探討如何使用 Docker Swarm 佈署和擴充套件服務。
驗證 Docker Swarm 叢集狀態
首先,讓我們檢查 Docker 映像檔和容器狀態,以確認叢集的運作狀況。
docker images
docker ps -a
執行上述命令後,我們可以看到兩個映像檔被提取到叢集中,並且四個容器正在執行(兩個伺服器上各有兩個容器)。唯一的視覺差異是,執行中的容器名稱以其所在伺服器的名稱為字首。
內容解密:
docker images:列出本地 Docker 映像檔。docker ps -a:列出所有容器(包括停止的容器)。
佈署 Books-MS 服務
接下來,我們將佈署 Books-MS 服務。首先,克隆 Books-MS 儲存函式庫並進入該目錄。
git clone https://github.com/vfarcic/books-ms.git
cd books-ms
然後,使用 Docker Compose 啟動服務。
docker-compose up -d app
由於 app 目標與 db 相關聯,Docker Compose 將同時啟動這兩個服務。
內容解密:
git clone:克隆 Git 儲存函式庫。docker-compose up -d app:在背景啟動app服務及其相關服務。
檢查容器狀態
檢查由 Docker Compose 建立的容器狀態。
docker ps --filter name=books --format "table {{.Names}}"
輸出結果顯示,兩個容器都執行在同一個節點上(例如 swarm-node-2)。
內容解密:
docker ps:列出正在執行的容器。--filter name=books:過濾名稱包含books的容器。--format "table {{.Names}}":格式化輸出,僅顯示容器名稱。
無連結佈署
由於 app 和 db 之間的連結限制了 Docker Swarm 的排程決策,我們需要移除連結並重新佈署服務。使用 docker-compose-no-links.yml 檔案來定義無連結的服務佈署。
app:
image: 10.100.198.200:5000/books-ms
ports:
- 8080
db:
image: mongo
使用以下命令啟動無連結的服務。
docker-compose -f docker-compose-no-links.yml up -d db app
docker ps --filter name=books --format "table {{.Names}}"
輸出結果顯示,db 和 app 容器現在執行在不同的節點上(例如 swarm-node-1 和 swarm-node-2)。
內容解密:
docker-compose -f docker-compose-no-links.yml up -d db app:使用指定的 Compose 檔案啟動db和app服務。- 這種無連結的佈署方式允許 Docker Swarm 更靈活地排程容器,提高資源利用率。
叢集與擴充套件服務
在前面的範例中,Swarm 將每個容器放置在不同的伺服器上。這是因為 Swarm 嘗試將容器分散到不同的節點上,以達到負載平衡的效果。然而,這種做法也引入了一個新的問題:容器之間的通訊。
為瞭解決這個問題,我們可以使用 Docker 的網路功能。Docker 網路允許容器之間進行通訊,而不需要使用連結(linking)。連結在 Docker 1.9 版本之後已經被棄用,取而代之的是網路功能。
使用 Docker 網路
首先,我們需要建立一個 Docker 網路。
docker network create my-network
docker network ls
輸出結果如下:
NETWORK ID NAME DRIVER
5fc39aac18bf swarm-node-2/host host
aa2c17ae2039 swarm-node-2/bridge bridge
267230c8d144 my-network overlay
bfc2a0b1694b swarm-node-2/none null
b0b1aa45c937 swarm-node-1/none null
613fc0ba5811 swarm-node-1/host host
74786f8b833f swarm-node-1/bridge bridge
我們可以看到,my-network 網路已經被建立,並且它的驅動程式是 overlay。這意味著這個網路可以跨越多個主機。
使用 Docker 網路進行容器通訊
現在,我們可以使用這個網路來啟動容器。
docker run -d --name books-ms-db \
--net my-network \
mongo
docker run -d --name books-ms \
--net my-network \
-e DB_HOST=books-ms-db \
-p 8080 \
10.100.198.200:5000/books-ms
內容解密:
docker run -d --name books-ms-db:啟動一個名為books-ms-db的容器。--net my-network:將容器加入到my-network網路中。mongo:使用mongo映象啟動容器。docker run -d --name books-ms:啟動一個名為books-ms的容器。--net my-network:將容器加入到my-network網路中。-e DB_HOST=books-ms-db:設定環境變數DB_HOST為books-ms-db。-p 8080:將容器的 8080 連線埠對應到主機的連線埠。10.100.198.200:5000/books-ms:使用指定的映象啟動容器。
現在,我們可以進入 books-ms 容器,檢視 /etc/hosts 檔案。
docker exec -it books-ms bash
cat /etc/hosts
exit
輸出結果如下:
10.0.0.2 3166318f0f9c
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.0.0.2 books-ms-db
10.0.0.2 books-ms-db.my-network
內容解密:
- Docker 偵測到
books-ms-db容器使用相同的網路,因此更新了/etc/hosts檔案。 - 新增了
books-ms-db和books-ms-db.my-network的別名,方便容器之間的通訊。
透過這種方式,我們可以輕鬆地實作容器之間的通訊,而不需要使用連結。同時,這種方式也允許我們將容器分散到不同的節點上,以達到負載平衡的效果。
結合代理服務和負載平衡
在實際應用中,我們通常會結合代理服務和負載平衡來實作服務的擴充套件。如圖 14-12 所示,我們可以使用代理服務來提供負載平衡和安全功能,同時使用 Docker 網路來實作容器之間的通訊。
這樣,我們就可以輕鬆地擴充套件服務,同時保持容器之間的通訊。