Swarm是Docker公司推出的用來管理docker集羣的平臺,幾乎所有用GO語言來完成的開發的,代碼開源在https://github.com/docker/swarm, 它是將一羣Docker宿主機變成一個單一的虛擬主機,Swarm使用標準的Docker API接口做爲其前端的訪問入口,換言之,各類形式的Dockerhtml
Client(compose,docker-py等)都可以直接與Swarm通訊,甚至Docker自己均可以很容易的與Swarm集成,這大大方便了用戶將本來基於單節點的系統移植到Swarm上,同時Swarm內置了對Docker網絡插件的支持,用戶也很容易的部署跨主機的容器集羣服務。前端
Docker Swarm 和 Docker Compose 同樣,都是 Docker 官方容器編排項目,但不一樣的是,Docker Compose 是一個在單個服務器或主機上建立多個容器的工具,而 Docker Swarm 則能夠在多個服務器或主機上建立容器集羣服務,對於微服務的部署,顯然 Docker Swarm 會更加適合。node
從 Docker 1.12.0 版本開始,Docker Swarm 已經包含在 Docker 引擎中(docker swarm),而且已經內置了服務發現工具,咱們就不須要像以前同樣,再配置 Etcd 或者 Consul 來進行服務發現配置了。nginx
Swarm deamon只是一個調度器(Scheduler)加路由器(router),Swarm本身不運行容器,它只是接受Docker客戶端發來的請求,調度適合的節點來運行容器,這就意味着,即便Swarm因爲某些緣由掛掉了,集羣中的節點也會照常運行,放Swarm從新恢復運行以後,他會收集重建集羣信息。git
在結構圖能夠看出 Docker Client使用Swarm對 集羣(Cluster)進行調度使用。github
上圖能夠看出,Swarm是典型的master-slave結構,經過發現服務來選舉manager。manager是中心管理節點,各個node上運行agent接受manager的統一管理,集羣會自動經過Raft協議分佈式選舉出manager節點,無需額外的發現服務支持,避免了單點的瓶頸問題,同時也內置了DNS的負載均衡和對外部負載均衡機制的集成支持web
1.Swarm 集羣的管理和編排是使用嵌入docker引擎的SwarmKit,能夠在docker初始化時啓動swarm模式或者加入已存在的swarm 2.Node 一個節點是docker引擎集羣的一個實例。您還能夠將其視爲Docker節點。您能夠在單個物理計算機或雲服務器上運行一個或多個節點,但生產羣集部署一般包括分佈在多個物理和雲計算機上的Docker節點。 要將應用程序部署到swarm,請將服務定義提交給 管理器節點。管理器節點將稱爲任務的工做單元分派 給工做節點。 Manager節點還執行維護所需羣集狀態所需的編排和集羣管理功能。Manager節點選擇單個領導者來執行編排任務。 工做節點接收並執行從管理器節點分派的任務。默認狀況下,管理器節點還將服務做爲工做節點運行,但您能夠將它們配置爲僅運行管理器任務而且是僅管理器節點。代理程序在每一個工做程序節點上運行,並報告分配給它的任務。工做節點向管理器節點通知其分配的任務的當前狀態,以便管理器能夠維持每一個工做者的指望狀態。 3.Service 一個服務是任務的定義,管理機或工做節點上執行。它是羣體系統的中心結構,是用戶與羣體交互的主要根源。建立服務時,你須要指定要使用的容器鏡像。 4.Task 任務是在docekr容器中執行的命令,Manager節點根據指定數量的任務副本分配任務給worker節點 ------------------------------------------使用方法------------------------------------- docker swarm:集羣管理,子命令有init, join, leave, update。(docker swarm --help查看幫助) docker service:服務建立,子命令有create, inspect, update, remove, tasks。(docker service--help查看幫助) docker node:節點管理,子命令有accept, promote, demote, inspect, update, tasks, ls, rm。(docker node --help查看幫助) node是加入到swarm集羣中的一個docker引擎實體,能夠在一臺物理機上運行多個node,node分爲: manager nodes,也就是管理節點 worker nodes,也就是工做節點 1)manager node管理節點:執行集羣的管理功能,維護集羣的狀態,選舉一個leader節點去執行調度任務。 2)worker node工做節點:接收和執行任務。參與容器集羣負載調度,僅用於承載task。 3)service服務:一個服務是工做節點上執行任務的定義。建立一個服務,指定了容器所使用的鏡像和容器運行的命令。 service是運行在worker nodes上的task的描述,service的描述包括使用哪一個docker 鏡像,以及在使用該鏡像的容器中執行什麼命令。 4)task任務:一個任務包含了一個容器及其運行的命令。task是service的執行實體,task啓動docker容器並在容器中執行任務。
1. Node算法
2. Servicedocker
3. 任務與調度shell
4. 服務副本與全局服務
Swarm在調度(scheduler)節點(leader節點)運行容器的時候,會根據指定的策略來計算最適合運行容器的節點,目前支持的策略有:spread, binpack, random. 1)Random 顧名思義,就是隨機選擇一個Node來運行容器,通常用做調試用,spread和binpack策略會根據各個節點的可用的CPU, RAM以及正在運 行的容器的數量來計算應該運行容器的節點。 2)Spread 在同等條件下,Spread策略會選擇運行容器最少的那臺節點來運行新的容器,binpack策略會選擇運行容器最集中的那臺機器來運行新的節點。 使用Spread策略會使得容器會均衡的分佈在集羣中的各個節點上運行,一旦一個節點掛掉了只會損失少部分的容器。 3)Binpack Binpack策略最大化的避免容器碎片化,就是說binpack策略儘量的把還未使用的節點留給須要更大空間的容器運行,儘量的把容器運行在 一個節點上面。
1)批量建立服務 創建容器以前先建立一個overlay的網絡,用來保證在不一樣主機上的容器網絡互通的網絡模式 2)強大的集羣的容錯性 當容器副本中的其中某一個或某幾個節點宕機後,cluster會根據本身的服務註冊發現機制,以及以前設定的值--replicas n, 在集羣中剩餘的空閒節點上,從新拉起容器副本。整個副本遷移的過程無需人工干預,遷移後本來的集羣的load balance依舊好使! 不難看出,docker service其實不只僅是批量啓動服務這麼簡單,而是在集羣中定義了一種狀態。Cluster會持續檢測服務的健康狀態 並維護集羣的高可用性。 3)服務節點的可擴展性 Swarm Cluster不光只是提供了優秀的高可用性,同時也提供了節點彈性擴展或縮減的功能。當容器組想動態擴展時,只需經過scale 參數便可複製出新的副本出來。 仔細觀察的話,能夠發現全部擴展出來的容器副本都run在原先的節點下面,若是有需求想在每臺節點上都run一個相同的副本,方法 其實很簡單,只須要在命令中將"--replicas n"更換成"--mode=global"便可! 複製服務(--replicas n) 將一系列複製任務分發至各節點當中,具體取決於您所須要的設置狀態,例如「--replicas 3」。 全局服務(--mode=global) 適用於集羣內所有可用節點上的服務任務,例如「--mode global」。若是你們在 Swarm 集羣中設有 7 臺 Docker 節點,則所有節點之上都將存在對應容器。 4. 調度機制 所謂的調度其主要功能是cluster的server端去選擇在哪一個服務器節點上建立並啓動一個容器實例的動做。它是由一個裝箱算法和過濾器 組合而成。每次經過過濾器(constraint)啓動容器的時候,swarm cluster 都會調用調度機制篩選出匹配約束條件的服務器,並在這上面運行容器。 ------------------Swarm cluster的建立過程包含如下三個步驟---------------------- 1)發現Docker集羣中的各個節點,收集節點狀態、角色信息,並監視節點狀態的變化 2)初始化內部調度(scheduler)模塊 3)建立並啓動API監聽服務模塊 一旦建立好這個cluster,就能夠用命令docker service批量對集羣內的容器進行操做,很是方便! 在啓動容器後,docker 會根據當前每一個swarm節點的負載判斷,在負載最優的節點運行這個task任務,用"docker service ls" 和"docker service ps + taskID" 能夠看到任務運行在哪一個節點上。容器啓動後,有時須要等待一段時間才能完成容器建立。
舒適提示:
機器環境(三臺機器,centos系統)
IP:192.168.31.43 主機名:manager43 擔任角色:swarm manager
IP:192.168.31.188 主機名:node188 擔任角色:swarm node
IP:192.168.31.139 主機名:node139 擔任角色:swarm node
一、準備工做
1) 修改主機名 # 192.168.31.43 主機上執行 [root@manager43 ~]# hostnamectl set-hostname manager43 # 192.168.31.188 主機上執行 [root@node188 ~]# hostnamectl set-hostname node188 # 192.168.31.139 主機上執行 [root@node139 ~]# hostnamectl set-hostname node139 2)配置hosts文件(可配置可不配置) [root@manager43 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.31.43 manager43 192.168.31.188 node188 192.168.31.139 node139 # 使用scp複製到node主機 [root@manager43 ~]# scp /etc/hosts root@192.168.31.188:/etc/hosts [root@manager43 ~]# scp /etc/hosts root@192.168.31.139:/etc/hosts 3) 設置防火牆 關閉三臺機器上的防火牆。若是開啓防火牆,則須要在全部節點的防火牆上依次放行2377/tcp(管理端口)、7946/udp(節點間通訊端口)、4789/udp(overlay 網絡端口)端口。 [root@manager43 ~]# systemctl disable firewalld.service [root@manager43 ~]# systemctl stop firewalld.service 4) 安裝docker並配置加速器(在三臺主機都要安裝喲...) [root@manager43 ~]# yum -y install docker [root@node188 ~]# yum -y install docker [root@node139 ~]# yum -y install docker
也能夠安裝最新版docker,可查考:docker安裝教程
加速器配置,可查考:docker加速器配置教程
二、建立Swarm並添加節點
1) 建立Swarm集羣 [root@manager43 ~]# docker swarm init --advertise-addr 192.168.31.43 Swarm initialized: current node (z2n633mty5py7u9wyl423qnq0) is now a manager. To add a worker to this swarm, run the following command: # 這就是添加節點的方式(要保存初始化後token,由於在節點加入時要使用token做爲通信的密鑰) docker swarm join --token SWMTKN-1-2lefzq18zohy9yr1vskutf1sfb2a590xz9d0mjj2m15zu9eprw-2938j5f50t35ycut0vbj2sx0s 192.168.31.43:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. 上面命令執行後,該機器自動加入到swarm集羣。這個會建立一個集羣token,獲取全球惟一的 token,做爲集羣惟一標識。後續將其餘節點加入集羣都會用到這個token值。 其中,--advertise-addr參數表示其它swarm中的worker節點使用此ip地址與manager聯繫。命令的輸出包含了其它節點如何加入集羣的命令。 這裏無心中遇到了一個小小的問題: # 在次執行上面的命令,回報下面的錯誤 [root@manager43 ~]# docker swarm init --advertise-addr 192.168.31.43 Error response from daemon: This node is already part of a swarm. Use "docker swarm leave" to leave this swarm and join another one. # 解決方法 [root@manager43 ~]# docker swarm leave -f 這裏的leave就是在集羣中刪除節點,-f參數強制刪除,執行完在從新執行OK 2) 查看集羣的相關信息 [root@manager43 ~]# docker info 上面的命令執行後 找到Swarm的關鍵字,就能夠看到相關信息了 [root@manager43 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 3jcmnzjh0e99ipgshk1ykuovd * manager43 Ready Active Leader 18.06.0-ce 上面的命令是查看集羣中的機器(注意上面node ID旁邊那個*號表示如今鏈接到這個節點上) 3) 添加節點主機到Swarm集羣 上面咱們在建立Swarm集羣的時候就已經給出了添加節點的方法 # 192.168.31.188 主機上執行 [root@node188 ~]# docker swarm join --token SWMTKN-1-2lefzq18zohy9yr1vskutf1sfb2a590xz9d0mjj2m15zu9eprw-2938j5f50t35ycut0vbj2sx0s 192.168.31.43:2377 This node joined a swarm as a worker. # 192.168.31.139 主機上執行 [root@node139 ~]# docker swarm join --token SWMTKN-1-2lefzq18zohy9yr1vskutf1sfb2a590xz9d0mjj2m15zu9eprw-2938j5f50t35ycut0vbj2sx0s 192.168.31.43:2377 This node joined a swarm as a worker. 若是想要將其餘更多的節點添加到這個swarm集羣中,添加方法如上一致 在manager43主機上咱們能夠看一下集羣中的機器及狀態 [root@manager43 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 3jcmnzjh0e99ipgshk1ykuovd * manager43 Ready Active Leader 18.06.0-ce vww7ue2xprzg46bjx7afo4h04 node139 Ready Active 18.06.1-ce c5klw5ns4adcvumzgiv66xpyj node188 Ready Active 18.06.1-ce -------------------------------------------------------------------------------------------------------------------- 舒適提示:更改節點的availablity狀態 swarm集羣中node的availability狀態能夠爲 active或者drain,其中: active狀態下,node能夠接受來自manager節點的任務分派; drain狀態下,node節點會結束task,且再也不接受來自manager節點的任務分派(也就是下線節點) [root@manager43 ~]# docker node update --availability drain node139 # 將node139節點下線。若是要刪除node139節點,命令是"docker node rm --force node139" node139 [root@manager43 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 3jcmnzjh0e99ipgshk1ykuovd * manager43 Ready Active Leader 18.06.0-ce vww7ue2xprzg46bjx7afo4h04 node139 Ready Drain 18.06.1-ce c5klw5ns4adcvumzgiv66xpyj node188 Ready Active 18.06.1-ce 如上,當node1的狀態改成drain後,那麼該節點就不會接受task任務分發,就算以前已經接受的任務也會轉移到別的節點上。 再次修改成active狀態(及將下線的節點再次上線) [root@manager43 ~]# docker node update --availability active node139 node139 [root@manager43 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 3jcmnzjh0e99ipgshk1ykuovd * manager43 Ready Active Leader 18.06.0-ce vww7ue2xprzg46bjx7afo4h04 node139 Ready Active 18.06.1-ce c5klw5ns4adcvumzgiv66xpyj node188 Ready Active 18.06.1-ce
三、在Swarm中部署服務(nginx爲例)
Docker 1.12版本提供服務的Scaling、health check、滾動升級等功能,並提供了內置的dns、vip機制,實現service的服務發現和負載均衡能力 1) 建立網絡在部署服務 # 建立網絡 [root@manager43 ~]# docker network create -d overlay nginx_net a52jy33asc5o0ts0rq823bf0m [root@manager43 ~]# docker network ls | grep nginx_net a52jy33asc5o nginx_net overlay swarm # 部署服務 [root@manager43 ~]# docker service create --replicas 1 --network nginx_net --name my_nginx -p 80:80 nginx # 就建立了一個具備一個副本(--replicas 1 )的nginx服務,使用鏡像nginx olexfmtdf94sxyeetkchwhehg overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged 在manager-node節點上使用上面這個覆蓋網絡建立nginx服務: 其中,--replicas 參數指定服務由幾個實例組成。 注意:不須要提早在節點上下載nginx鏡像,這個命令執行後會自動下載這個容器鏡像(好比此處建立tomcat容器,就將下面命令中的鏡像改成tomcat鏡像)。 # 使用 docker service ls 查看正在運行服務的列表 [root@manager43 ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS olexfmtdf94s my_nginx replicated 1/1 nginx:latest *:80->80/tcp 2) 查詢Swarm中服務的信息 -pretty 使命令輸出格式化爲可讀的格式,不加 --pretty 能夠輸出更詳細的信息: [root@manager43 ~]# docker service inspect --pretty my_nginx ID: zs7fw4ereo5w7ohd4n9ii06nt Name: my_nginx Service Mode: Replicated Replicas: 1 Placement: UpdateConfig: Parallelism: 1 On failure: pause Monitoring Period: 5s Max failure ratio: 0 Update order: stop-first RollbackConfig: Parallelism: 1 On failure: pause Monitoring Period: 5s Max failure ratio: 0 Rollback order: stop-first ContainerSpec: Image: nginx:latest@sha256:b73f527d86e3461fd652f62cf47e7b375196063bbbd503e853af5be16597cb2e Init: false Resources: Networks: nginx_net Endpoint Mode: vip Ports: PublishedPort = 80 Protocol = tcp TargetPort = 80 PublishMode = ingress # 查詢到哪一個節點正在運行該服務。以下該容器被調度到manager-node節點上啓動了,而後訪問http://192.168.31.43便可訪問這個容器應用(若是調度到其餘節點,訪問也是如此) [root@manager43 ~]# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS yzonph0zu7km my_nginx.1 nginx:latest manager43 Running Running about an hour ago 舒適提示:若是上面命令執行後,上面的 STATE 字段中剛開始的服務狀態爲 Preparing,須要等一會才能變爲 Running 狀態,其中最費時間的應該是下載鏡像的過程 有上面命令可知,該服務在manager-node節點上運行。登錄該節點,能夠查看到nginx容器在運行中 [root@manager43 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0dc7103f8030 nginx:latest "nginx -g 'daemon of…" About an hour ago Up About an hour 80/tcp my_nginx.1.yzonph0zu7km0211uj0ro5brj 3) 在Swarm中動態擴展服務(scale) 固然,若是隻是經過service啓動容器,swarm也算不上什麼新鮮東西了。Service還提供了複製(相似kubernetes裏的副本)功能。能夠經過 docker service scale 命令來設置服務中容器的副本數 好比將上面的my_nginx容器動態擴展到4個 [root@manager43 ~]# docker service scale my_nginx=4 my_nginx scaled to 4 overall progress: 4 out of 4 tasks 1/4: running [==================================================>] 2/4: running [==================================================>] 3/4: running [==================================================>] 4/4: running [==================================================>] verify: Service converged 和建立服務同樣,增長scale數以後,將會建立新的容器,這些新啓動的容器也會經歷從準備到運行的過程,過一分鐘左右,服務應該就會啓動完成,這時候能夠再來看一下 nginx 服務中的容器 [root@manager43 ~]# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS yzonph0zu7km my_nginx.1 nginx:latest manager43 Running Running about an hour ago mlprstt9ds5x my_nginx.2 nginx:latest node139 Running Running 52 seconds ago y09lk90tdzdp my_nginx.3 nginx:latest node139 Running Running 52 seconds ago clolfl3zlvj0 my_nginx.4 nginx:latest node188 Running Running 2 minutes ago 能夠看到,以前my_nginx容器只在manager-node節點上有一個實例,而如今又增長了3個實例。 這4個副本的my_nginx容器分別運行在這三個節點上,登錄這三個節點,就會發現已經存在運行着的my_nginx容器 4) 模擬宕機node節點 特別須要清楚的一點: 若是一個節點宕機了(即該節點就會從swarm集羣中被踢出),則Docker應該會將在該節點運行的容器,調度到其餘節點,以知足指定數量的副本保持運行狀態。 好比: 將node139宕機後或將node139的docker服務關閉,那麼它上面的task實例就會轉移到別的節點上。當node139節點恢復後,它轉移出去的task實例不會主動轉移回來, 只能等別的節點出現故障後轉移task實例到它的上面。使用命令"docker node ls",發現node139節點已不在swarm集羣中了(狀態爲:Down)。 [root@node139 ~]# systemctl stop docker [root@manager43 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION ppk7q0bjond8a58xja7in1qid * manager43 Ready Active Leader 18.06.0-ce mums8azgbrffnecp3q8fz70pl node139 Down Active 18.06.1-ce z3n36maf03yjg7odghikuv574 node188 Ready Active 18.06.1-ce 而後過一會查詢服務的狀態列表 [root@manager43 ~]# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS yzonph0zu7km my_nginx.1 nginx:latest manager43 Running Running about an hour ago wb1cpk9k22rl my_nginx.2 nginx:latest node188 Running Running about a minute ago mlprstt9ds5x \_ my_nginx.2 nginx:latest node139 Shutdown Running 4 minutes ago rhbj4bcr4t2c my_nginx.3 nginx:latest manager43 Running Running about a minute ago y09lk90tdzdp \_ my_nginx.3 nginx:latest node139 Shutdown Running 4 minutes ago clolfl3zlvj0 my_nginx.4 nginx:latest node188 Running Running 6 minutes ago 上面咱們能夠發現node139故障後,它上面以前的兩個task任務已經轉移到node188和manager43節點上了 登錄到node188和manager43節點上,能夠看到這兩個運行的task任務。當訪問192.168.31.188和192.168.31.43節點的80端口,swarm的負載均衡會把請求路由到一個任意節點的可用的容器上 [root@manager43 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ae4c5c2e6f3f nginx:latest "nginx -g 'daemon of…" 4 minutes ago Up 4 minutes 80/tcp my_nginx.3.rhbj4bcr4t2c3y2f8vyfmbi21 0dc7103f8030 nginx:latest "nginx -g 'daemon of…" About an hour ago Up About an hour 80/tcp my_nginx.1.yzonph0zu7km0211uj0ro5brj [root@node188 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a63ef253f7dd nginx:latest "nginx -g 'daemon of…" 3 minutes ago Up 3 minutes 80/tcp my_nginx.2.wb1cpk9k22rl1ydab7aozl2b5 74a1a1db81d4 nginx:latest "nginx -g 'daemon of…" 8 minutes ago Up 8 minutes 80/tcp my_nginx.4.clolfl3zlvj0ewmh85c2ljnza 再次在node188和manager43節點上將從node139上轉移過來的兩個task關閉 [root@manager43 ~]# docker stop my_nginx.3.rhbj4bcr4t2c3y2f8vyfmbi21 my_nginx.3.rhbj4bcr4t2c3y2f8vyfmbi21 [root@node188 ~]# docker stop my_nginx.2.wb1cpk9k22rl1ydab7aozl2b5 my_nginx.2.wb1cpk9k22rl1ydab7aozl2b5 再次查詢服務的狀態列表,發現這兩個task又轉移到node139上了 [root@manager43 ~]# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS yzonph0zu7km my_nginx.1 nginx:latest manager43 Running Running 2 hours ago j2q61f8jtzba my_nginx.2 nginx:latest node188 Running Running 24 seconds ago wb1cpk9k22rl \_ my_nginx.2 nginx:latest node188 Shutdown Complete 29 seconds ago mlprstt9ds5x \_ my_nginx.2 nginx:latest node139 Shutdown Running 11 minutes ago oz9wyjuldw1t my_nginx.3 nginx:latest manager43 Running Running 40 seconds ago rhbj4bcr4t2c \_ my_nginx.3 nginx:latest manager43 Shutdown Complete 45 seconds ago y09lk90tdzdp \_ my_nginx.3 nginx:latest node139 Shutdown Running 11 minutes ago clolfl3zlvj0 my_nginx.4 nginx:latest node188 Running Running 12 minutes ago 結論:即在swarm cluster集羣中啓動的容器,在worker node節點上刪除或停用後,該容器會自動轉移到其餘的worker node節點上 5) Swarm 動態縮容服務(scale) 同理,swarm還能夠縮容,一樣是使用scale命令 以下,將my_nginx容器變爲1個 [root@manager43 ~]# docker service scale my_nginx=1 my_nginx scaled to 1 overall progress: 1 out of 1 tasks 1/1: verify: Service converged [root@manager43 ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS zs7fw4ereo5w my_nginx replicated 1/1 nginx:latest *:80->80/tcp [root@manager43 ~]# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS yzonph0zu7km my_nginx.1 nginx:latest manager43 Running Running 11 hours ago wb1cpk9k22rl my_nginx.2 nginx:latest node188 Shutdown Complete 9 hours ago mlprstt9ds5x \_ my_nginx.2 nginx:latest node139 Shutdown Shutdown 29 seconds ago rhbj4bcr4t2c my_nginx.3 nginx:latest manager43 Shutdown Complete 9 hours ago y09lk90tdzdp \_ my_nginx.3 nginx:latest node139 Shutdown Shutdown 29 seconds ago 經過docker service ps my_nginx 能夠看到node節點上已經爲Shutdown狀態了 在登陸到node節點主機上查看 [root@node188 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f93c0a27374a nginx:latest "nginx -g 'daemon of…" 9 hours ago Exited (0) 44 seconds ago my_nginx.2.j2q61f8jtzba9kb3unupkhl25 a63ef253f7dd nginx:latest "nginx -g 'daemon of…" 9 hours ago Exited (0) 9 hours ago my_nginx.2.wb1cpk9k22rl1ydab7aozl2b5 [root@node139 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e8ac2e44f5c4 nginx:latest "nginx -g 'daemon of…" 9 hours ago Exited (0) 9 hours ago my_nginx.2.mlprstt9ds5xi48u1rzscgfdk 5b031aa5a2cc nginx:latest "nginx -g 'daemon of…" 9 hours ago Exited (0) 9 hours ago my_nginx.3.y09lk90tdzdp8cwj6mm5oyr3f 登陸node節點,使用docker ps -a 查看,會發現容器被stop而非rm 6) 除了上面使用scale進行容器的擴容或縮容以外,還可使用docker service update 命令。 可對 服務的啓動 參數 進行 更新/修改。 [root@manager43 ~]# docker service update --replicas 3 my_nginx my_nginx overall progress: 3 out of 3 tasks 1/3: running [==================================================>] 2/3: running [==================================================>] 3/3: running [==================================================>] verify: Service converged [root@manager43 ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS zs7fw4ereo5w my_nginx replicated 3/3 nginx:latest *:80->80/tcp [root@manager43 ~]# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS yzonph0zu7km my_nginx.1 nginx:latest manager43 Running Running 11 hours ago j3hduzd9pret my_nginx.2 nginx:latest node188 Running Running 18 seconds ago wb1cpk9k22rl \_ my_nginx.2 nginx:latest node188 Shutdown Complete 9 hours ago mlprstt9ds5x \_ my_nginx.2 nginx:latest node139 Shutdown Shutdown 4 minutes ago gng96vc5vqpv my_nginx.3 nginx:latest node139 Running Running 18 seconds ago rhbj4bcr4t2c \_ my_nginx.3 nginx:latest manager43 Shutdown Complete 9 hours ago y09lk90tdzdp \_ my_nginx.3 nginx:latest node139 Shutdown Shutdown 4 minutes ago docker service update 命令,也可用於直接 升級 鏡像等 [root@manager43 ~]# docker service update --image nginx:new my_nginx [root@manager43 ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS zs7fw4ereo5w my_nginx replicated 3/3 nginx:new *:80->80/tcp 注意IMAGE列 變成了nginx:new 7) 爲了下面的直觀顯示,我這裏把my_nginx服務直接刪除了 [root@manager43 ~]# docker service rm my_nginx 這樣就會把全部節點上的全部容器(task任務實例)所有刪除了
四、Swarm中使用Volume(掛在目錄,mount命令)
1) 查看volume的幫助信息 [root@manager43 ~]# docker volume --help Usage: docker volume COMMAND Manage volumes Commands: create Create a volume inspect Display detailed information on one or more volumes ls List volumes prune Remove all unused local volumes rm Remove one or more volumes Run 'docker volume COMMAND --help' for more information on a command. 2) 建立一個volume [root@manager43 ~]# docker volume create --name testvolume testvolume # 查看建立的volume [root@manager43 ~]# docker volume ls DRIVER VOLUME NAME local testvolume # 查看volume詳情 [root@manager43 ~]# docker volume inspect testvolume [ { "CreatedAt": "2018-10-21T10:50:02+08:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/testvolume/_data", "Name": "testvolume", "Options": {}, "Scope": "local" } ] 3) 建立新的服務並掛載testvolume(nginx爲例) [root@manager43 ~]# docker service create --replicas 3 --mount type=volume,src=testvolume,dst=/zjz --name test_nginx nginx sh7wc8yzcvr0xaedo4tnraj7l overall progress: 3 out of 3 tasks 1/3: running [==================================================>] 2/3: running [==================================================>] 3/3: running [==================================================>] verify: Service converged 舒適提示: 參數src寫成source也能夠;dst表示容器內的路徑,也能夠寫成target # 查看建立服務 [root@manager43 ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS sh7wc8yzcvr0 test_nginx replicated 3/3 nginx:latest [root@manager43 ~]# docker service ps test_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS m7m41kwt4q6w test_nginx.1 nginx:latest node188 Running Running 56 seconds ago kayh81q1o1kx test_nginx.2 nginx:latest node139 Running Running 56 seconds ago eq11v0rcwy38 test_nginx.3 nginx:latest manager43 Running Running 56 seconds ago # 查看有沒有掛載成功(登陸各個節點的容器看看有沒有指定的目錄並建立文件測試) # 容器中操做 [root@manager43 ~]# docker exec -it 63451219cb4e /bin/bash root@63451219cb4e:/# cd /zjz/ root@63451219cb4e:/zjz# ls root@63451219cb4e:/zjz# echo "gen wo xue docker" > docker.txt root@63451219cb4e:/zjz# ls docker.txt 執行docker volume inspect testvolume 能夠看到本地的路徑(上面已經執行過了) 本地路徑:/var/lib/docker/volumes/testvolume/_data [root@manager43 ~]# cd /var/lib/docker/volumes/testvolume/_data [root@manager43 _data]# ls docker.txt [root@manager43 _data]# cat docker.txt gen wo xue docker 還能夠將node節點機上的volume數據目錄作成軟連接 [root@manager43 _data]# ln -s /var/lib/docker/volumes/testvolume/_data /zjz [root@manager43 _data]# cd /zjz/ [root@manager43 zjz]# ls docker.txt [root@manager43 zjz]# echo "123" > 1.txt [root@manager43 zjz]# ll 總用量 8 -rw-r--r-- 1 root root 4 10月 21 11:04 1.txt -rw-r--r-- 1 root root 18 10月 21 11:00 docker.txt # 容器中查看 [root@manager43 zjz]# docker exec -it 63451219cb4e /bin/bash root@63451219cb4e:/# cd /zjz/ root@63451219cb4e:/zjz# ls 1.txt docker.txt root@63451219cb4e:/zjz# cat 1.txt 123 root@63451219cb4e:/zjz# cat docker.txt gen wo xue docker # 還有一種掛載方式簡單說一下吧,上面的會了下面的確定簡單 命令格式: docker service create --mount type=bind,target=/container_data/,source=/host_data/ 其中,參數target表示容器裏面的路徑,source表示本地硬盤路徑 # 示例建立並掛載並使用網絡 [root@manager43 ~]# docker service create --replicas 1 --mount type=bind,target=/usr/share/nginx/html/,source=/opt/web/ --network nginx_net --name zjz_nginx -p 8880:80 nginx
五、多服務Swarm集羣部署
問:上面咱們只是對單獨的一個nginx服務進行的集羣部署,那若是要統一編排多個服務呢?
答:docker 三劍客中有個compose 這個就是對單機進行統一編排的,它的實現是經過docker-compose.yml的文件,這裏咱們就能夠結合compose和swarm進行多服務的編排(docker compose教程)
舒適提示: 咱們這裏要部署的服務有三個(nginx服務,visualizer服務,portainer服務) 都是集羣 GUI 管理服務 docker service部署的是單個服務,咱們可使用docker stack進行多服務編排部署 1) 編寫docker-compose.yml文件 [root@manager43 ~]# mkdir testswarm [root@manager43 ~]# cd testswarm/ [root@manager43 testswarm]# cat docker-compose.yml version: "3" services: nginx: image: nginx ports: - 8888:80 deploy: mode: replicated replocas: 3 visualizer: image: dockersamples/visualizer ports: - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock" deploy: replicas: 1 placement: constraints: [node.role == manager] portainer: image: portainer/portainer ports: - "9000:9000" volumes: - "/var/run/docker.sock:/var/run/docker.sock" deploy: replicas: 1 placement: constraints: [node.role == manager] 2) 經過這個yml文件部署服務 [root@manager43 testswarm]# docker stack deploy -c docker-compose.yml deploy_deamon Creating network deploy_deamon_default Creating service deploy_deamon_portainer Creating service deploy_deamon_nginx Creating service deploy_deamon_visualizer 經過上面的執行過程能夠看出這樣建立會默認建立一個網絡並使用它,名字都是咱們給的名字的前綴加上服務名 # 查看建立服務 [root@manager43 testswarm]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS xj2f1t5ax3nm deploy_deamon_nginx replicated 3/3 nginx:latest *:8888->80/tcp ky9qpldr5abb deploy_deamon_portainer replicated 1/1 portainer/portainer:latest *:9000->9000/tcp r47ff177x1ir deploy_deamon_visualizer replicated 1/1 dockersamples/visualizer:latest *:8080->8080/tcp [root@manager43 testswarm]# docker service ps deploy_deamon_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS z3v4uc1ujsnq deploy_deamon_nginx.1 nginx:latest node139 Running Running about a minute ago jhg3ups0cko5 deploy_deamon_nginx.2 nginx:latest manager43 Running Running about a minute ago 3e6guv791x21 deploy_deamon_nginx.3 nginx:latest node188 Running Running about a minute ago [root@manager43 testswarm]# docker service ps deploy_deamon_portainer ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS whyuvy82cvvw deploy_deamon_portainer.1 portainer/portainer:latest manager43 Running Running about a minute ago [root@manager43 testswarm]# docker service ps deploy_deamon_visualizer ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS wge5w1eqykg3 deploy_deamon_visualizer.1 dockersamples/visualizer:latest manager43 Running Starting 7 seconds ago
測試
在Docker版本1.12以後swarm模式原生支持覆蓋網絡(overlay networks),能夠先建立一個覆蓋網絡,而後啓動容器的時候啓用這個覆蓋網絡, 這樣只要是這個覆蓋網絡內的容器,無論在不在同一個宿主機上都能相互通訊,即跨主機通訊!不一樣覆蓋網絡內的容器組之間是相互隔離的(相互ping不通)。 swarm模式的覆蓋網絡包括如下功能: 1)能夠附加多個服務到同一個網絡。 2)默認狀況下,service discovery爲每一個swarm服務分配一個虛擬IP地址(vip)和DNS名稱,使得在同一個網絡中容器之間可使用服務名稱爲互相鏈接。 3)能夠配置使用DNS輪循而不使用VIP 4)爲了可使用swarm的覆蓋網絡,在啓用swarm模式之間你須要在swarm節點之間開放如下端口: 5)TCP/UDP端口7946 – 用於容器網絡發現 6)UDP端口4789 – 用於容器覆蓋網絡 實例以下: -----------在Swarm集羣中建立overlay網絡------------ [root@manager-node ~]# docker network create --driver overlay --opt encrypted --subnet 10.10.19.0/24 ngx_net 參數解釋: –opt encrypted 默認狀況下swarm中的節點通訊是加密的。在不一樣節點的容器之間,可選的–opt encrypted參數能在它們的vxlan流量啓用附加的加密層。 --subnet 命令行參數指定overlay網絡使用的子網網段。當不指定一個子網時,swarm管理器自動選擇一個子網並分配給網絡。 [root@manager-node ~]# docker network ls NETWORK ID NAME DRIVER SCOPE d7aa48d3e485 bridge bridge local 9e637a97a3b9 docker_gwbridge bridge local b5a41c8c71e7 host host local 7f4fx3jf4dbr ingress overlay swarm 3x2wgugr6zmn ngx_net overlay swarm 0808a5c72a0a none null local 由上可知,Swarm當中擁有2套覆蓋網絡。其中"ngx_net"網絡正是咱們在部署容器時所建立的成果。而"ingress"覆蓋網絡則爲默認提供。 Swarm 管理節點會利用 ingress 負載均衡以將服務公佈至集羣以外。 在將服務鏈接到這個建立的網絡以前,網絡覆蓋到manager節點。上面輸出的SCOPE爲 swarm 表示將服務部署到Swarm時可使用此網絡。 在將服務鏈接到這個網絡後,Swarm只將該網絡擴展到特定的worker節點,這個worker節點被swarm調度器分配了運行服務的任務。 在那些沒有運行該服務任務的worker節點上,網絡並不擴展到該節點。 ------------------將服務鏈接到overlay網絡------------------- [root@manager-node ~]# docker service create --replicas 5 --network ngx_net --name my-test -p 80:80 nginx 上面名爲"my-test"的服務啓動了3個task,用於運行每一個任務的容器均可以彼此經過overlay網絡進行通訊。Swarm集羣將網絡擴展到全部任務處於Running狀態的節點上。 [root@manager-node ~]# docker service ls ID NAME REPLICAS IMAGE COMMAND dsaxs6v463g9 my-test 5/5 nginx 在manager-node節點上,經過下面的命令查看哪些節點有處於running狀態的任務: [root@manager-node ~]# docker service ps my-test ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 8433fuiy7vpu0p80arl7vggfe my-test.1 nginx node2 Running Running 2 minutes ago f1h7a0vtojv18zrsiw8j0rzaw my-test.2 nginx node1 Running Running 2 minutes ago ex73ifk3jvzw8ukurl8yu7fyq my-test.3 nginx node1 Running Running 2 minutes ago cyu73jd8psupfhken23vvmpud my-test.4 nginx manager-node Running Running 2 minutes ago btorxekfix4hcqh4v83dr0tzw my-test.5 nginx manager-node Running Running 2 minutes ago 可見三個節點都有處於running狀態的任務,因此my-network網絡擴展到三個節點上。 能夠查詢某個節點上關於my-network的詳細信息: [root@manager-node ~]# docker network inspect ngx_net [ { "Name": "ngx_net", "Id": "3x2wgugr6zmn1mcyf9k1du27p", "Scope": "swarm", "Driver": "overlay", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "10.10.19.0/24", "Gateway": "10.10.19.1" } ] }, "Internal": false, "Containers": { "00f47e38deea76269eb03ba13695ec0b0c740601c85019546d6a9a17fd434663": { "Name": "my-test.5.btorxekfix4hcqh4v83dr0tzw", "EndpointID": "ea962d07eee150b263ae631b8a7f8c1950337c11ef2c3d488a7c3717defd8601", "MacAddress": "02:42:0a:0a:13:03", "IPv4Address": "10.10.19.3/24", "IPv6Address": "" }, "957620c6f7abb44ad8dd2d842d333f5e5c1655034dc43e49abbbd680de3a5341": { "Name": "my-test.4.cyu73jd8psupfhken23vvmpud", "EndpointID": "f33a6e9ddf1dd01bcfc43ffefd19e19514658f001cdf9b2fbe23bc3fdf56a42a", "MacAddress": "02:42:0a:0a:13:07", "IPv4Address": "10.10.19.7/24", "IPv6Address": "" } }, "Options": { "com.docker.network.driver.overlay.vxlanid_list": "257" }, "Labels": {} } ] 從上面的信息能夠看出在manager-node節點上,名爲my-test的服務有一個名爲my-test.5.btorxekfix4hcqh4v83dr0tzw和 my-test.4.cyu73jd8psupfhken23vvmpud的task鏈接到名爲ngx_net的網絡上(另外兩個節點node1和node2一樣能夠用上面命令查看) [root@node1 ~]# docker network inspect ngx_net ....... "Containers": { "7d9986fad5a7d834676ba76ae75aff2258f840953f1dc633c3ef3c0efd2b2501": { "Name": "my-test.3.ex73ifk3jvzw8ukurl8yu7fyq", "EndpointID": "957ca19f3d5480762dbd14fd9a6a1cd01a8deac3e8e35b23d1350f480a7b2f37", "MacAddress": "02:42:0a:0a:13:06", "IPv4Address": "10.10.19.6/24", "IPv6Address": "" }, "9e50fceada1d7c653a886ca29d2bf2606debafe8c8a97f2d79104faf3ecf8a46": { "Name": "my-test.2.f1h7a0vtojv18zrsiw8j0rzaw", "EndpointID": "b1c209c7b68634e88e0bf5e100fe03435b3096054da6555c61e6c207ac651ac2", "MacAddress": "02:42:0a:0a:13:05", "IPv4Address": "10.10.19.5/24", "IPv6Address": "" } }, ......... [root@node2 web]# docker network inspect ngx_net ........ "Containers": { "4bdcce0ee63edc08d943cf4a049eac027719ff2dc14b7c3aa85fdddc5d1da968": { "Name": "my-test.1.8433fuiy7vpu0p80arl7vggfe", "EndpointID": "df58de85b0a0e4d128bf332fc783f6528d1f179b0f9f3b7aa70ebc832640d3bc", "MacAddress": "02:42:0a:0a:13:04", "IPv4Address": "10.10.19.4/24", "IPv6Address": "" } }, 能夠經過查詢服務來得到服務的虛擬IP地址,以下: [root@manager-node ~]# docker service inspect --format='{{json .Endpoint.VirtualIPs}}' my-test [{"NetworkID":"7f4fx3jf4dbrp97aioc05pul4","Addr":"10.255.0.6/16"},{"NetworkID":"3x2wgugr6zmn1mcyf9k1du27p","Addr":"10.10.19.2/24"}] 由上結果可知,10.10.19.2其實就是swarm集羣內部的vip,整個網絡結構以下圖所示:
加入ngx_net網絡的容器彼此之間能夠經過IP地址通訊,也能夠經過名稱通訊。
[root@node2 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4bdcce0ee63e nginx:latest "nginx -g 'daemon off" 22 minutes ago Up 22 minutes 80/tcp my-test.1.8433fuiy7vpu0p80arl7vggfe [root@node2 ~]# docker exec -ti 4bdcce0ee63e /bin/bash root@4bdcce0ee63e:/# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 1786: eth0@if1787: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default link/ether 02:42:0a:ff:00:08 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.255.0.8/16 scope global eth0 valid_lft forever preferred_lft forever inet 10.255.0.6/32 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::42:aff:feff:8/64 scope link valid_lft forever preferred_lft forever 1788: eth1@if1789: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet 172.18.0.3/16 scope global eth1 valid_lft forever preferred_lft forever inet6 fe80::42:acff:fe12:3/64 scope link valid_lft forever preferred_lft forever 1791: eth2@if1792: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default link/ether 02:42:0a:0a:13:04 brd ff:ff:ff:ff:ff:ff link-netnsid 2 inet 10.10.19.4/24 scope global eth2 valid_lft forever preferred_lft forever inet 10.10.19.2/32 scope global eth2 valid_lft forever preferred_lft forever inet6 fe80::42:aff:fe0a:1304/64 scope link valid_lft forever preferred_lft forever root@4bdcce0ee63e:/# ping 10.10.19.3 PING 10.10.19.3 (10.10.19.3): 56 data bytes 64 bytes from 10.10.19.3: icmp_seq=0 ttl=64 time=0.890 ms 64 bytes from 10.10.19.3: icmp_seq=1 ttl=64 time=0.622 ms .....- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.622/0.756/0.890/0.134 ms root@4bdcce0ee63e:/# ping 10.10.19.6 PING 10.10.19.6 (10.10.19.6): 56 data bytes 64 bytes from 10.10.19.6: icmp_seq=0 ttl=64 time=0.939 ms 64 bytes from 10.10.19.6: icmp_seq=1 ttl=64 time=0.590 ms ----------------------------使用swarm模式的服務發現-------------------------- 默認狀況下,當建立了一個服務並鏈接到某個網絡後,swarm會爲該服務分配一個VIP。此VIP根據服務名映射到DNS。在網絡上的容器共享該服務的DNS映射, 因此網絡上的任意容器能夠經過服務名訪問服務。 在同一overlay網絡中,不用經過端口映射來使某個服務能夠被其它服務訪問。Swarm內部的負載均衡器自動將請求發送到服務的VIP上,而後分發到全部的 active的task上。 以下示例: 在同一個網絡中添加了一個centos服務,此服務能夠經過名稱my-test訪問前面建立的nginx服務: [root@manager-node ~]# docker service create --name my-centos --network ngx_net centos 查詢centos運行在哪一個節點上(上面建立命令執行後,須要一段時間才能完成這個centos服務的建立) [root@manager-node ~]# docker service ps my-centos ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR e03pqgkjs3l1qizc6v4aqaune my-centos.1 centos node2 Running Preparing 4 seconds ago 登陸centos運行的節點(由上可知是node2節點),打開centos的交互shell: [root@node2 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES e4554490d891 centos:latest "/bin/bash" About an hour ago Up About an hour my-centos.1.9yk5ie28gwk9mw1h1jovb68ki [root@node2 ~]# docker exec -ti my-centos.1.9yk5ie28gwk9mw1h1jovb68ki /bin/bash root@4bdcce0ee63e:/# nslookup my-test Server: 127.0.0.11 Address 1: 127.0.0.11 Name: my-test Address 1: 10.10.19.2 10.10.19.2 從centos容器內部,使用特殊查詢 查詢DNS,來找到my-test服務的全部容器的IP地址: root@4bdcce0ee63e:/# nslookup tasks.my-test Server: 127.0.0.11 Address 1: 127.0.0.11 Name: tasks.my-test Address 1: 10.10.19.4 my-test.1.8433fuiy7vpu0p80arl7vggfe Address 2: 10.10.19.5 my-test.2.f1h7a0vtojv18zrsiw8j0rzaw Address 3: 10.10.19.6 my-test.3.ex73ifk3jvzw8ukurl8yu7fyq Address 2: 10.10.19.7 my-test.4.cyu73jd8psupfhken23vvmpud Address 3: 10.10.19.3 my-test.5.btorxekfix4hcqh4v83dr0tzw 從centos容器內部,經過wget來訪問my-test服務中運行的nginx網頁服務器 root@4bdcce0ee63e:/# wget -O- my-test Connecting to my-test (10.10.19.2:80) <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ... Swarm的負載均衡器自動將HTTP請求路由到VIP上,而後到一個active的task容器上。它根據round-robin選擇算法將後續的請求分發到另外一個active的task上。 -----------------------------------爲服務使用DNS round-robin----------------------------- 在建立服務時,能夠配置服務直接使用DNS round-robin而無需使用VIP。這是經過在建立服務時指定 --endpoint-mode dnsrr 命令行參數實現的。 當你想要使用本身的負載均衡器時可使用這種方式。 以下示例(注意:使用DNS round-robin方式建立服務,不能直接在命令裏使用-p指定端口) [root@manager-node ~]# docker service create --replicas 3 --name my-dnsrr-nginx --network ngx_net --endpoint-mode dnsrr nginx [root@manager-node ~]# docker service ps my-dnsrr-nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 65li2zbhxvvoaesndmwjokouj my-dnsrr-nginx.1 nginx node1 Running Running 2 minutes ago 5hjw7wm4xr877879m0ewjciuj my-dnsrr-nginx.2 nginx manager-node Running Running 2 minutes ago afo7acduge2qfy60e87liz557 my-dnsrr-nginx.3 nginx manager-node Running Running 2 minutes ago 當經過服務名稱查詢DNS時,DNS服務返回全部任務容器的IP地址: root@4bdcce0ee63e:/# nslookup my-dnsrr-nginx Server: 127.0.0.11 Address 1: 127.0.0.11 Name: my-dnsrr-nginx Address 1: 10.10.19.10 my-dnsrr-nginx.3.0sm1n9o8hygzarv5t5eq46okn.my-network Address 2: 10.10.19.9 my-dnsrr-nginx.2.b3o1uoa8m003b2kk0ytl9lawh.my-network Address 3: 10.10.19.8 my-dnsrr-nginx.1.55za4c83jq9846rle6eigiq15.my-network 須要注意的是:必定要確認VIP的連通性 一般Docker官方推薦使用dig,nslookup或其它DNS查詢工具來查詢經過DNS對服務名的訪問。由於VIP是邏輯IP,ping並非確認VIP連通性的正確的工具。