返回文章列表

Docker Swarm 叢集管理與服務擴充套件實踐

本文深入比較 Docker Swarm 與 Kubernetes 的差異,並著重於 Docker Swarm 的實踐應用,包含叢集組態、服務佈署、網路設定及擴充套件策略等導向,提供逐步操作與案例解析,協助讀者快速上手 Docker Swarm。

容器技術 DevOps

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

內容解密:

  1. docker swarm init 命令用於初始化一個新的 Swarm 叢集。
  2. --advertise-addr 引數指定了主節點的 IP 地址,用於叢集內部通訊。
  3. docker swarm join 命令用於將工作節點加入到現有的 Swarm 叢集中。
  4. --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進行佈署。

內容解密:

  1. 佈署策略:Swarm支援多種佈署策略,例如Spread策略,會將容器佈署到目前容器數量最少的節點上。
  2. 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

內容解密:

  1. Vagrant:使用Vagrant工具建立和管理虛擬機器。
  2. 虛擬機器角色: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

內容解密:

  1. Ansible Playbook:使用Ansible的Playbook自動化組態和管理Docker Swarm叢集。
  2. swarm.yml:定義了Docker Swarm叢集的組態和管理任務。

Docker Swarm 叢集與服務擴充套件技術解析

Docker Swarm 為 Docker 提供原生叢集管理功能,實作跨多主機的容器協調與排程。本文將探討 Docker Swarm 的組態、佈署及管理流程,並結合實際案例進行技術剖析。

Docker Swarm 組態與佈署

在 Ansible playbook swarm.yml 中定義了 Swarm 叢集的組態,主要涉及 swarm_masterswarm_master_ip 變數的設定。根據伺服器角色(master 或 node),Docker 組態檔案會被設定為 docker-swarm-master.servicedocker-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 }}

內容解密:

  1. 允許不安全的私有倉函式庫註冊: --insecure-registry 10.100.198.200:5000 指定私有 Docker 倉函式庫的位置。
  2. 使用 Consul 作為叢集儲存: --cluster-store=consul://{{ ip }}:8500/swarm 設定 Swarm 使用 Consul 進行服務發現和叢集狀態儲存。
  3. 宣告 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 }}

內容解密:

  1. 多重通訊協定支援: -H tcp://0.0.0.0:2375-H unix:///var/run/docker.sock 使 Docker daemon 同時監聽 TCP 連線埠和 Unix socket。
  2. 加入 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]

內容解密:

  1. Node 加入叢集: 使用 join 命令使 Node 加入由 Consul 管理的 Swarm 叢集。
  2. Master 管理叢集: 使用 manage 命令啟動 Swarm Master,負責管理整個叢集。

驗證 Swarm 叢集狀態

執行 docker info 命令可檢視叢集的詳細資訊:

export DOCKER_HOST=tcp://10.100.192.200:2375
docker info

輸出結果顯示了叢集的整體狀態,包括節點數量、容器分佈、CPU 和記憶體資源等資訊。

內容解密:

  1. 叢集概覽: docker info 提供整個叢集的綜合資訊,而非單一主機的狀態。
  2. 節點詳細資訊: 列出所有節點的健康狀態、容器數量、資源預留情況等。

叢集與擴充套件服務的 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}}":格式化輸出,僅顯示容器名稱。

無連結佈署

由於 appdb 之間的連結限制了 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}}"

輸出結果顯示,dbapp 容器現在執行在不同的節點上(例如 swarm-node-1swarm-node-2)。

內容解密:

  • docker-compose -f docker-compose-no-links.yml up -d db app:使用指定的 Compose 檔案啟動 dbapp 服務。
  • 這種無連結的佈署方式允許 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

內容解密:

  1. docker run -d --name books-ms-db:啟動一個名為 books-ms-db 的容器。
  2. --net my-network:將容器加入到 my-network 網路中。
  3. mongo:使用 mongo 映象啟動容器。
  4. docker run -d --name books-ms:啟動一個名為 books-ms 的容器。
  5. --net my-network:將容器加入到 my-network 網路中。
  6. -e DB_HOST=books-ms-db:設定環境變數 DB_HOSTbooks-ms-db
  7. -p 8080:將容器的 8080 連線埠對應到主機的連線埠。
  8. 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

內容解密:

  1. Docker 偵測到 books-ms-db 容器使用相同的網路,因此更新了 /etc/hosts 檔案。
  2. 新增了 books-ms-dbbooks-ms-db.my-network 的別名,方便容器之間的通訊。

透過這種方式,我們可以輕鬆地實作容器之間的通訊,而不需要使用連結。同時,這種方式也允許我們將容器分散到不同的節點上,以達到負載平衡的效果。

結合代理服務和負載平衡

在實際應用中,我們通常會結合代理服務和負載平衡來實作服務的擴充套件。如圖 14-12 所示,我們可以使用代理服務來提供負載平衡和安全功能,同時使用 Docker 網路來實作容器之間的通訊。

這樣,我們就可以輕鬆地擴充套件服務,同時保持容器之間的通訊。