您好,登錄后才能下訂單哦!
文章首發于微信公眾號《程序員果果》
地址:https://mp.weixin.qq.com/s/RSNL-V4jLE8YVMSWZlJ_Vw
Swarm 在 Docker 1.12 版本之前屬于一個獨立的項目,在 Docker 1.12 版本發布之后,該項目合并到了 Docker 中,成為 Docker 的一個子命令。目前,Swarm 是 Docker 社區提供的唯一一個原生支持 Docker 集群管理的工具。它可以把多個 Docker 主機組成的系統轉換為單一的虛擬 Docker 主機,使得容器可以組成跨主機的子網網絡。
Docker Swarm 是一個為 IT 運維團隊提供集群和調度能力的編排工具。用戶可以把集群中所有 Docker Engine 整合進一個「虛擬 Engine」的資源池,通過執行命令與單一的主 Swarm 進行溝通,而不必分別和每個 Docker Engine 溝通。在靈活的調度策略下,IT 團隊可以更好地管理可用的主機資源,保證應用容器的高效運行。
Swarm的基本架構如下圖所示:
任何規模都有高性能表現
對于企業級的 Docker Engine 集群和容器調度而言,可拓展性是關鍵。任何規模的公司——不論是擁有五個還是上千個服務器——都能在其環境下有效使用 Swarm。
經過測試,Swarm 可拓展性的極限是在 1000 個節點上運行 50000 個部署容器,每個容器的啟動時間為亞秒級,同時性能無減損。
靈活的容器調度
Swarm 幫助 IT 運維團隊在有限條件下將性能表現和資源利用最優化。Swarm 的內置調度器(scheduler)支持多種過濾器,包括:節點標簽,親和性和多種容器部策略如 binpack、spread、random 等等。
服務的持續可用性
Docker Swarm 由 Swarm Manager 提供高可用性,通過創建多個 Swarm master 節點和制定主 master 節點宕機時的備選策略。如果一個 master 節點宕機,那么一個 slave 節點就會被升格為 master 節點,直到原來的 master 節點恢復正常。
此外,如果某個節點無法加入集群,Swarm 會繼續嘗試加入,并提供錯誤警報和日志。在節點出錯時,Swarm 現在可以嘗試把容器重新調度到正常的節點上去。
和 Docker API 及整合支持的兼容性
Swarm 對 Docker API 完全支持,這意味著它能為使用不同 Docker 工具(如 Docker CLI,Compose,Trusted Registry,Hub 和 UCP)的用戶提供無縫銜接的使用體驗。
Docker Swarm 為 Docker 化應用的核心功能(諸如多主機網絡和存儲卷管理)提供原生支持
開發的 Compose 文件能(通過 docker-compose up )輕易地部署到測試服務器或 Swarm 集群上。Docker Swarm 還可以從 Docker Trusted Registry 或 Hub 里 pull 并 run 鏡像。
有兩種類型的節點: managers 和 workers.
管理節點用于 Swarm 集群的管理,docker swarm 命令基本只能在管理節點執行(節點退出集群命令 docker swarm leave 可以在工作節點執行)。一個 Swarm 集群可以有多個管理節點,但只有一個管理節點可以成為 leader,leader 通過 raft 協議實現。
為了利用swarm模式的容錯功能,Docker建議您根據組織的高可用性要求實現奇數個節點。當您擁有多個管理器時,您可以從管理器節點的故障中恢復而無需停機。
重要說明:添加更多管理節點并不意味著可擴展性更高或性能更高。一般而言,情況正好相反。
工作節點是任務執行節點,管理節點將服務 (service) 下發至工作節點執行。管理節點默認也作為工作節點。你也可以通過配置讓服務只運行在管理節點。下圖展示了集群中管理節點與工作節點的關系。
任務 (Task)是 Swarm 中的最小的調度單位,目前來說就是一個單一的容器。
服務 (Services) 是指一組任務的集合,服務定義了任務的屬性。服務有兩種模式:
兩種模式通過 docker service create 的 --mode 參數指定。下圖展示了容器、任務、服務的關系。
本文通過docker-machine使用VirtualBox驅動程序創建3個VM (已經有Linux主機或虛擬機的跳過此步):
docker-machine create --driver virtualbox myvm-1
docker-machine create --driver virtualbox myvm-2
docker-machine create --driver virtualbox myvm-3
列出虛擬機并獲取其IP地址:
docker-machine ls
以下是此命令的示例輸出:
$docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm-1 - virtualbox Running tcp://192.168.99.100:2376 v18.09.1-beta2
myvm-2 - virtualbox Running tcp://192.168.99.101:2376 v18.09.1-beta2
myvm-3 - virtualbox Running tcp://192.168.99.102:2376 v18.09.1-beta2
把第一臺機器myvm-1充當管理節點,第二臺myvm-2 、第三臺myvm-3為工作節點。
使用 docker-machine ssh 連接 myvm-1,Linux主機直接ssh連接就行。
docker-machine ssh myvm-1
初始化swarm
docker swarm init --advertise-addr 192.168.99.100
Swarm initialized: current node (4a8mo8cekpe0vpk0ze963avw9) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-4lzr2216s61ecbyayyqynjwybmxy5y5th6ru8aal2a0d1t2vn3-ekdgf4swlz8fiq4nnzgnbhr5u 192.168.99.100:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
上面輸出的這一段就是工作節點加入集群的命令:
docker swarm join --token SWMTKN-1-4lzr2216s61ecbyayyqynjwybmxy5y5th6ru8aal2a0d1t2vn3-ekdgf4swlz8fiq4nnzgnbhr5u 192.168.99.100:2377
如果你的 Docker 主機有多個網卡,擁有多個 IP,必須使用 --advertise-addr 指定 IP。
執行 docker swarm init 命令的節點自動成為管理節點。
命令 docker info 可以查看 swarm 集群狀態:
Server Version: 18.09.1-beta2
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: active
NodeID: ib1498ex2q18i7gznb2zgicqq
Is Manager: true
ClusterID: fbyxxjzrtcxc53op35jnyzl7t
Managers: 3
Nodes: 3
Default Address Pool: 10.0.0.0/8
命令 docker node ls 可以查看集群節點信息:
$docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ib1498ex2q18i7gznb2zgicqq * myvm-1 Ready Active Leader 18.09.1-beta2
連接機器myvm-2
docker-machine ssh myvm-2
加入 swarm 集群
$docker swarm join \
--token SWMTKN-1-4lzr2216s61ecbyayyqynjwybmxy5y5th6ru8aal2a0d1t2vn3-ekdgf4swlz8fiq4nnzgnbhr5u \
192.168.99.100:2377
This node joined a swarm as a worker.
節點myvm-3,執行myvm-2相同的操作加入集群。
集群的大部分命令需要在管理節點中才能運行
我們進入管理節點 myvm-1 ,查看集群的節點信息。
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ib1498ex2q18i7gznb2zgicqq * myvm-1 Ready Active Leader 18.09.1-beta2
vels0fe3eh6s5cxj1s573v9wx myvm-2 Ready Active 18.09.1-beta2
obxnnqelh5p16wajrwvyn6j8v myvm-3 Ready Active 18.09.1-beta2
為了高可用,我們升級工作節點為管理節點。
docker node promote myvm-2
docker node promote myvm-3
這時我們再看集群的節點信息
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ib1498ex2q18i7gznb2zgicqq * myvm-1 Ready Active Leader 18.09.1-beta2
vels0fe3eh6s5cxj1s573v9wx myvm-2 Ready Active Reachable 18.09.1-beta2
obxnnqelh5p16wajrwvyn6j8v myvm-3 Ready Active Reachable 18.09.1-beta2
myvm-2、myvm-3的 集群狀態變為 Reachable(選舉者),因為集群中節點Leader只能有一個,這個類似zookeeper,只不過zookeepers用的算法是paxos,Swarm用的算法是raft。
如果 Manager 想要退出 Swarm 集群, 在 Manager Node 上執行如下命令:
docker swarm leave
如果集群中還存在其它的 Worker Node,還希望 Manager 退出集群,則加上一個強制選項,命令行如下所示:
docker swarm leave --force
工作節點進行退出集群,需要在工作節點上執行命令:
docker swarm leave
退出后的節點,依然可以使用 上面的 docker swarm join --token 重新加入集群。
命令
$ docker service create --replicas 1 --name 別名 鏡像ID
replicas 指定運行服務的數量。
創建一個alpine服務(alpine是一個小型liunx系統)
#運行一個alpine鏡像,并執行ping命令
docker service create --replicas 1 --name test1 alpine ping docker.com
查看集群上的服務
$docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
rnu10rprrwzv test1 replicated 1/1 alpine:latest
以下命令將nginx容器中的端口80發布到群集中任何節點的端口8080
docker service create \
--name my-web \
--publish published=8080,target=80 \
--replicas 2 \
nginx
查看集群上的服務
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
q6wfiizzosmd nginx replicated 3/3 nginx:latest *:8080->80/tcp
rnu10rprrwzv test1 replicated 1/1 alpine:latest
service 通過 ingress load balancing 來發布服務,且 swarm 集群中所有 node 都參與到 ingress 路由網格(ingress routing mesh) 中,訪問任意一個 node+PublishedPort 即可訪問到服務。
當訪問任何節點上的端口8080時,Docker將您的請求路由到活動容器。在群節點本身,端口8080可能并不實際綁定,但路由網格知道如何路由流量,并防止任何端口沖突的發生。
路由網格在發布的端口上監聽分配給節點的任何IP地址。對于外部可路由的IP地址,該端口可從主機外部獲得。對于所有其他IP地址,只能從主機內部訪問。
所以訪問 192.169.99.100:8080、192.169.99.101:8080、192.169.99.102:8080 ,都可以訪問到nginx,這樣就實現了負載均衡。因為我們指定--replicas 3 啟動了3個運行nginx的容器 ,所以三個節點myvm-1、myvm-2、myvm-3 上都運行了一個 nginx 的容器,可以通過改其中一個節點上的nginx的歡迎頁 ,然后再訪問,來檢查是否實現了負載均衡。
可以通過scale 來指定運行容器的數量。
docker service scale nginx=2
我通過docker service ls 可以看出 nginx 的副本變成了2個
$docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
q6wfiizzosmd nginx replicated 2/2 nginx:latest *:8080->80/tcp
初始化swarm或將Docker主機加入現有swarm時,會在該Docker主機上創建兩個新網絡:
在管理節點上查看網絡
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
cb0ccb89a988 bridge bridge local
0174fb113496 docker_gwbridge bridge local
541b62778c0e host host local
8n7xppn5z4j2 ingress overlay swarm
369d459f340d none null local
overlay網絡驅動程序會創建多個Docker守護主機之間的分布式網絡。該網絡位于(覆蓋)特定于主機的網絡之上,允許連接到它的容器(包括群集服務容器)安全地進行通信。Docker透明地處理每個數據包與正確的Docker守護程序主機和正確的目標容器的路由。
創建用于swarm服務的overlay網絡,使用如下命令:
docker network create -d overlay my-overlay
我們再次查看網絡,發現可以看到自定義 overlay了。
$docker network ls
NETWORK ID NAME DRIVER SCOPE
cb0ccb89a988 bridge bridge local
0174fb113496 docker_gwbridge bridge local
541b62778c0e host host local
8n7xppn5z4j2 ingress overlay swarm
a23htz7n0pvp my-overlay overlay swarm
369d459f340d none null local
集群中部署了兩個服務 nginx、alpine,現在我們進入alpine,去訪問nginx。
docker exec -it test1.1.oonwl8c5g4u3p17x8anifeubi bash
/ # ping nginx
ping: bad address 'nginx'
wget 192.168.99.100:8080
Connecting to 192.168.99.100:8080 (192.168.99.100:8080)
index.html 100% |*************************************************************************************************************| 612 0:00:00 ETA
我們發現集群中的各個服務不能用名稱訪問的,只能用集群服務發現的路由網絡訪問,那么集群中的服務怎么能通過名稱進行訪問呢,這就需要用到上面自定義的 overlay 網絡。
刪除我們啟動的服務,重新創建指定使用自定義網絡的服務。
docker service rm nginx test1
docker service create --name nginx -p 8080:80 --network my-overlay --replicas 3 nginx
docker service create --name test1 --network my-overlay alpine ping www.baidu.com
進入test1容器中,重新測試下:
/ # ping nginx
PING nginx (10.0.0.2): 56 data bytes
64 bytes from 10.0.0.2: seq=0 ttl=64 time=0.120 ms
64 bytes from 10.0.0.2: seq=1 ttl=64 time=0.094 ms
64 bytes from 10.0.0.2: seq=2 ttl=64 time=0.108 ms
/ # wget nginx
Connecting to nginx (10.0.0.2:80)
index.html 100% |*************************************************************************************************************| 612 0:00:00 ETA
發現可以通過名稱進行集群中的容器間的訪問了。
歡迎關注我的公眾號《程序員果果》,關注有驚喜~~
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。