Docker Swarm 是建立伺服器叢集用的工具。把一堆伺服器綁到一塊兒用,讓它們看起來像是一台伺服器,通過統一的介面在這些伺服器上運行應用。
叢集裡的伺服器之間相互知道彼此,它們也知道哪些伺服器上運行了什麼樣的服務,如果訪問的服務在伺服器上不存在,它會把訪問轉移到叢集裡的正確的伺服器上去處理。一個服務可以用多個容器來支援,這些容器運行在叢集裡的不同的伺服器上,請求可以均衡的分布給這些容器。當有伺服器掛掉以後,在它上面啟動並執行服務會被轉移到其它的伺服器上運行。
Docker Swarm 只需要幾行命令就可以為應用建立一個強大的叢集,為你的應用提供高可用的服務。寧皓網的 《 Docker:叢集 》介紹了使用 Docker Swarm 建立叢集伺服器的方法。
類比叢集環境
如果你已經有了幾台伺服器,安裝 Docker 以後就可以去建立一個伺服器叢集了,如果你想在本地測試 Docker Swarm 的功能,可以類比一個叢集環境,也就是在本地建立幾台 Linux 系統的虛擬機器,安裝 Docker ,配置叢集。下面介紹使用 Vagrant 建立虛擬機器的方法。
安裝 Virtualbox:虛擬機器軟體
安裝 Vagrant:管理虛擬機器用的工具,它可以管理 Virtualbox 虛擬機器
安裝 Vagrant Hostmanager 外掛程式
Windows 如果啟用了 Hyper-v 以後,就不能再使用 Virtualbox 或者其它的虛擬軟體了。
Vagrant Hostmanager 是 Vagrant 的一個外掛程式,設定了虛擬機器的主機名稱以後,這個外掛程式可以協助我們設定虛擬機器中的 /etc/hosts 檔案,在裡面添加正確的主機記錄,這樣如果建立了多台虛擬機器,這些虛擬機器之間可以使用虛擬機器的主機名稱來訪問到對方,這個外掛程式並不是必須的,不過它很有用,它也可以設定本地主機上的 hosts 檔案,這樣你在本地主機上也可以直接使用虛擬機器的主機名稱來訪問到它。
# 建立項目目錄
cd ~/desktop
mkdir docker-swarm
cd docker-swarm
# 初始化項目,使用 centos/7 這個 box
vagrant init centos/7
# 用編輯器開啟項目目錄
atom ./
編輯一下項目根目錄下的 Vagrantfile,替換成下面的代碼,它可以建立三台虛擬機器,node1,node2,node3。
Vagrant.configure(2) do |config|
config.vm.box = "centos/7"
# 請安裝 vagrant-hostmanager 外掛程式
# https://github.com/devopsgroup-io/vagrant-hostmanager
config.hostmanager.enabled = true
config.hostmanager.manage_host = true
config.hostmanager.manage_guest = true
config.vm.define "node1" do |node1|
node1.vm.network "private_network", ip: "192.168.33.11"
node1.vm.hostname="node1"
end
config.vm.define "node2" do |node2|
node2.vm.network "private_network", ip: "192.168.33.12"
node2.vm.hostname="node2"
end
config.vm.define "node3" do |node3|
node3.vm.network "private_network", ip: "192.168.33.13"
node3.vm.hostname="node3"
end
end
啟動虛擬機器
vagrant up
安裝 Docker
虛擬機器啟動以後,登入到這些虛擬機器,然後在上面安裝 Docker:
curl -fsSL https://test.docker.com/ | sh
sudo systemctl enable docker
sudo systemctl start docker
建立叢集
叢集裡的伺服器有兩種身份,一個是 manager (管理員),一種是 worker(工人),在管理員伺服器上可以建立服務,擴充服務,更新服務,管理員伺服器本身也可以運行服務。先去初始化一個叢集伺服器,比如我想在 node1 這台伺服器上初始化一下,先登入到這台伺服器。
# 登入到 node1 伺服器
vagrant ssh node1
# 初始化 Swarm 叢集
docker swarm init --listen-addr node1:2377
這樣 node1 預設就會是這個叢集裡的管理員,現在叢集裡只有一個節點伺服器,可以查看一下:
docker node ls
在初始化叢集的時候用了 --listen-addr,指定了一下這個叢集管理員的地址還有連接埠號碼,預設地址應該是 0.0.0.0 ,這裡我用了一個主機名稱來表示,node1。列出這個選項是讓展示一下你可以自由的設定伺服器的監聽地址與連接埠號碼,如果使用主機名稱,你要保證叢集裡的其它的伺服器可以使用這個主機名稱訪問到這台伺服器。
加入叢集
有了叢集以後,你要讓其它的伺服器加入進來:
# 登入到 node2
vagrant ssh node2
# 讓 node2 加入到叢集
docker swarm join --listen-addr node2:2377 node1:2377
# 登入到 node3
vagrant ssh node3
# 讓 node3 加入到叢集
docker swarm join --listen-addr node3:2377 node1:2377
現在叢集裡一共有三台伺服器了,在叢集的 manager 裡面可以查看一下伺服器的列表:
docker node ls
讓伺服器加入叢集的時候,也用到了 --listen-addr 選項,設定了這台伺服器監聽的地址與連接埠,其它的伺服器會使用這個地址與連接埠跟它進行交流。後面又指定了讓這台伺服器加入到的那個叢集,也就是通知一下叢集裡的管理員伺服器。
建立叢集網路
叢集裡的伺服器使用一種 overlay 類型的網路,我們可以建立一種這樣的網路,然後在叢集裡運行服務的時候可以指定使用這個網路。在叢集的 manager 上(node1),執行:
docker network create --driver overlay skynet
這樣會建立一個名字是 skynet 的 overlay 類型的網路。
建立服務
在叢集的 manger 節點上,可以去建立運行應用的服務,執行一下:
docker service create --name web --network skynet --publish 3000:3000 --replicas 1 ninghao/node
上面命令會基於寧皓網的 ninghao/node 鏡像建立一個名字是 web 的服務,使用 skynet 這個名字的網路,發布的連接埠是 3000 。--replicas 指定了這個服務用一個容器來運行。完成以後,可以開啟瀏覽器,訪問一下:
http://node1:3000
http://node2:3000
http://node3:3000
雖然 web 這個服務只有一個容器運行,它會在叢集裡的某台伺服器上,很可能是 node1 這個伺服器,不管它在哪個伺服器上運行,訪問叢集裡的所有的伺服器,都可以正常開啟服務提供的頁面,你應該會在頁面上看到一個 hello ,還有運行這個應用的容器的 id 號。
擴充服務
現在我要用多個容器來運行應用,這些容器會在叢集裡的不同的伺服器上運行。擴充運行服務的容器的數量,在叢集的 manager 節點上執行一下:
docker service scale web=6
上面的命令會用 6 個容器同時運行 web 這個服務,這 6 個容器會分布在不同的伺服器上,查看運行服務的任務,執行一下:
docker service tasks web
你會看到在哪些伺服器上運行了 web 這個服務。在不同的瀏覽器上再訪問一下應用的頁面,你會發現,運行應用的容器的 id 號會有變化,也就是使用者對應用的請求會被均衡的分布在不同的伺服器上。
更新服務
服務被建立以後,可以更新它,比如服務的連接埠號碼,資料卷,網路,鏡像,這些東西都可以更新。我要更新一下 web 服務用的鏡像,在叢集的 manager 上執行:
docker service update web --image ninghao/node:hola
它會讓 web 服務基於新的鏡像 ninghao/node:hola 去建立,更新完成以後,重新開啟瀏覽器,訪問一下應用的頁面,頁面上顯示的內容會有變化。