docker Swarm简介 新旧版本操作不一样docker run --rm swarm create和docker swarm --init
https://www.cnblogs.com/franknihao/p/8490416.html
https://cloud.tencent.com/developer/section/1091940?docker 指令講解
Swarm是Docker官方提供的一款集群管理工具,其主要作用是把若干臺Docker主機抽象為一個整體,并且通過一個入口統一管理這些Docker主機上的各種Docker資源。Swarm和Kubernetes比較類似,但是更加輕,具有的功能也較kubernetes更少一些。
Swarm的基本架構如下圖所示,
這個圖作為一個整體實際上都處于一個所謂的集群中,它可能對應了一到多臺的實際服務器。每臺服務器上都裝有Docker并且開啟了基于HTTP的DockerAPI。這個集群中有一個SwarmManager的管理者,用來管理集群中的容器資源。管理者的管理對象不是服務器層面而是集群層面的,也就是說通過Manager,我們只能籠統地向集群發出指令而不能具體到某臺具體的服務器上要干什么(這也是Swarm的根本所在)。至于具體的管理實現方式,Manager向外暴露了一個HTTP接口,外部用戶通過這個HTTP接口來實現對集群的管理。對于稍微大一點的集群,最好是拿出一臺實際的服務器作為專門的管理者,作為學習而言,也可以把管理者和被管理者放在一臺服務器上。
下面就來講一下如何簡單地通過swarm搭建一個集群
■ 安裝與簡單集群建立
●? 開啟帶有HTTPAPI的Docker服務
我的虛擬機環境是CentOS7的,Docker則是通過yum來安裝的。如要使用swarm,則必須讓Docker開放其HTTP的API。默認情況下這個API沒有開啟,而開啟此API需要在啟動時加入-H參數。
網上有的人說運行/usr/bin/docker的時候直接加,有的又說修改/etc/sysconfig/docker之類的文件,都不適用于我,可能是由于系統以及docker本身的版本的緣故。而我的正確姿勢是修改/lib/systemd/system/docker.service這個文件中的參數,并且用systemctl來管理啟動docker服務。
上述這個文件的ExecStart很明顯是指出了docker的啟動參數,在第一行的后面直接加上:
-H tcp://0.0.0.0:2375? (有些文章也指出對于CentOS6還需要加上-H unix:///var/run/docker.sock)修改完成之后別忘了運行一下systemctl daemon-reload刷新配置
然后再重啟/啟動Docker服務,此時通過netstat -ntlp可以看到一個新開的2375端口,此乃默認的DockerHTTPAPI的端口。如果是一個集群則需要注意集群中所有相關的主機都記得要啟動帶這個端口的Docker服務。
●? 沒有正確退出swarm集群時引發的問題
退出swarm集群用的命令是docker swarm leave,然而存在這樣一種情況:沒有完全退出swarm集群時就關掉了Docker服務。隨后網絡環境變化了(主機的IP變了)。此時若再systemctl start docker將會報錯,通過systemctl status docker -l可以查看完整的報錯信息,提示找不到老IP地址云云。其實這是啟動swarm時報的錯誤。
google了一下之后,發現比較方便的解決辦法是手動修改/var/lib/docker/swarm下面的docker-state.json和state.json兩個文件。把這兩個json文件中原來的老地址都改成現在的新地址。應該就可以順利啟動了。
●? 創建小集群
前面提到的Swarm Manager,其本身其實是一個容器,其他一些swarm的角色基本上也通過容器的方式來實現。Swarm源于Docker而基于Docker。但是Docker在剛安裝的時候是沒有swarm支持的,需要我們docker pull swarm去DockerHub里下載swarm的鏡像。這個鏡像本身不大,最新版的大概15MB左右,一會兒就下載完了。
當然,如果是集群的話那么需要在所有相關的主機上都pull到這個鏡像。
第一步,建立一個集群并且取得集群標志。Swarm支持自動發現功能,如果在一個網絡中存在多個集群,那么就需要每個集群都有一個區別于其他集群的標志來防止混淆。這個標志就是所謂的集群token,在集群創立之初就被指定且無法更改。在被選為管理者角色的服務器上運行命令:
docker run --rm swarm create? 這個命令返回中帶有一串token字符串(以dfb4fb3a8767835d799ce429fb4d7c4d為例),這個信息需要記錄下來,之后所有操作中都需要用到它來指出我們對哪個集群操作。而且目前還沒找到如何查看一個既存集群的token,所以一定要記錄一下。。
創建集群過后實際上并沒有真的增加什么Docker資源,仍然是一個空的集群。
?
第二步,創建集群獲取到集群token之后,目前我們手上拿著的還是一個空集群,接下來就往里面加入節點主機吧。加入節點主機的方法是再各個節點主機上運行這條命令:
docker run -d swarm join --addr=192.168.1.102:2375 token://dfb4fb3a8767835d799ce429fb4d7c4d其中--addr參數指出的是本主機的Docker服務的socket,自然,IP要和各個主機自身的IP一致。另外我嘗試了一下,若在本機指定addr為localhost或者0.0.0.0之類的IP,最終是無法正常工作的。所以即便是在管理者本機,也要老老實實寫出IP。完成后可以在當前主機上docker ps看一下,應該可以看到一個在運行中的swarm容器。這個容器扮演的角色就是向上和管理者容器通信,向下管理所在本機的docker資源,所謂被管理主機的代理。
創建完后,可以通過
docker run -d swarm list token://dfb4fb3a8767835d799ce429fb4d7c4d?
來查看這個指定的集群(由token指出)中存在哪些join進來的節點。需要注意的是,swarm join命令只是簡單的加入集群的聲明,swarm并不會去驗證給出的地址和端口是否真的可以訪問到一個Docker服務。對于沒有發現正常Docker服務的節點,將置狀態為Pending而不是Healthy,這個狀態以及其他節點相關信息怎么看下面會說。
?
? 第三步,開啟管理者容器。上面建立了集群框架,并且往集群中加入了join節點(即被管理主機的代理),但是還沒有出現管理者容器(管理主機的代理)。創建管理者容器的方法是在管理者主機上:
docker run -d -p 8888:2375 swarm manage token://dfb4fb3a8767835d799ce429fb4d7c4d?
同樣,docker ps之后可以看到管理容器。-p表名管理者容器做了一個端口映射。因為2375端口在本機上已經被Docker進程占用(當然啟動時指定的端口不是默認的2375就另當別論了),而管理容器暴露的這個端口要提供出來,實現外界對集群的管理,所以做了一個端口映射。這個8888,也可以換成其他任何合理的端口號。
有了管理容器,并且管理容器給出了8888端口作為管理的入口,我們就可以運行以下這些命令了:
docker -H 192.168.1.101:8888 info docker -H 127.0.0.1:8888 ps docker -H 192.168.1.101:8888 images?
由于這個8888端口就可以看做是一個網絡中的普通端口,在本機上訪問的話自然IP寫127.0.0.1也是可以的。但是注意不能寫成localhost,不然會報錯。。
這三條命令,去掉-H參數的話就是一般的docker用來查看信息的命令。加上-H之后,比如-H 192.168.1.101:8888之后,其意義就變成了,查看一個集群的相關信息。這個集群是192.168.1.101的8888端口對應的管理容器所對應的那個集群。
通過這幾條命令呈現出來的docker資源如容器和鏡像是不強調具體處于那臺主機上的,這就使得集群的概念得以發揚光大。另外通過這個socket得到的集群的信息會把swarm本身除外。比如目前這個狀態通過-H xxx ps看到的容器列表應該是空的。因為我們還沒有讓集群運行任何容器。但是docker ps會有swarm的容器顯示出來。如果想在-H的時候(所謂集群視圖)也看到swarm容器信息可以用ps -a。
順便,info命令的結果和普通的docker info命令結果不太一樣,最主要的是有了nodes這個字段。這個字段包含了各個節點的信息,包括前面提到的節點狀態等信息。
?
■ 集群簡單使用
下面正式使用集群來跑個容器試試看。其實和原生docker命令相比,就是多了個-H參數來指明一個集群管理入口而已:
docker -H 127.0.0.1:8888 run -d -p 10022:22 --name swarmtest tomcatssh:v1?
tomcatssh是我本地一個自定義的鏡像,和docker run類似的,其他的很多命令如docker start/stop/rm等等也都可以通過集群管理的入口來對集群做出。
如果我們的集群中有多態機器用于跑容器,即有多個被管理主機的話,那么通過這樣的方式啟動起來的容器會通過一定的策略選擇一臺合適的主機作為真實的跑容器的平臺來運行容器。策略分成好多種,默認是spread(這個字段在docker -H xxx info中的Strategy中有顯示),具體是指當集群要運行一個新的容器,將會根據算法和收集到的各個被管理主機CPU,內存等信息進行智能的選擇,使得各個運行容器的主機盡量均衡。
既然能夠做到自動選擇一臺主機作為容器運行的寄托,那么自然也可以恢復手動模式。這在swarm中就是所謂的filter功能。filter可以分成多種,
●? 約束過濾器(Constraint Filter)
約束過濾器通過啟動Docker守護進程時指定的標簽label來查找合適的被管理主機。label是通過啟動參數的方式在啟動時被固定的:
--label datacenter=us-east1?
這個參數加入到之前說過的docker.service,或者手動加在啟動docker的命令后面等等。
而在啟動容器時通過這樣的方式來指定過濾器:
docker -H 127.0.0.1:8888 run -e constraint:datacenter==us-east1 -d --name www-use1 nginx?
-e后面跟過濾器,constraint指出了約束過濾器,后面的約束標簽支持==,!=兩種判斷,后面可以寫字符串和正則表達式如us-east*。
●? 親和過濾器(Affinity Filter)
親和過濾器以現有的某個容器為基準,讓新容器運行在/不在已經運行了某個現有容器的主機上運行。
docker run -d -e --name db affinity:container!=www-use1 mysql?
比如上面這條命令說的就是要根據mysql鏡像啟動一個名為db的容器,但是這個容器不能在已經預www-use1容器運行的主機上運行。
●? 端口過濾器
端口過濾器嚴格來說并不是一個真的過濾器。。它只是在啟動容器時通過-p參數來申請對一個主機端口的使用權。如果一臺主機上這個端口正在被使用那么自然是不能把容器放到這個主機上運行的。
除了上述三種,過濾器還有很多,可以通過swarm manage --help或者去官網查。總的來說,過濾器是一種主動指定主機的手段,配合swarm自身的自動分配機制,可以靈活地確定一臺主機來運行容器。
如果當前集群中swarm找不到一臺符合條件的主機來運行容器,那么swarm會明確指出哪個過濾器條件得不到滿足,從而啟動容器失敗。
========================================================================================================
意識到,上面的swarm介紹居然是老版本的!orz
現在的Docker(1.12版本以后的)都是帶了原生的swarm命令,也就是說不需要不需要進行復雜的swarm create之類的操作,僅需要簡單幾條命令即可。
【http://blog.csdn.net/candcplusplus/article/details/53836703】
■ 新版本上構建swarm集群和節點
啟動一個swarm集群十分簡單,只需要執行
docker swarm init --listen-addr 192.168.1.112:8888 --advertise-addr 192.168.1.112? 兩個參數也很好懂,--listen-addr指出的是這個集群暴露給外界調用的HTTPAPI的socket地址。這個就是類似于上面老版本中swarm manage時-p指定的端口。添加--advertise-addr參數的原因是大多數情況下我們的主機都不只有一張網卡。而一個swarm集群需要辨明集群所在的子網絡是哪張網卡的。
另外需要注意,在新版本的swarm下,manage節點自身也作為被worker節點的一個,自動加入建立起來的swarm集群中。
命令運行成功的話會提示一串類似于這樣的信息:
docker swarm join \--token SWMTKN-1-2vndbzp43eff6vaiornhbafew242arz29qngrql0slqg4zmi4j-1hpha7vnelkbg4gg1d293qus4 \192.168.1.112:8888?
這是在說明,通網絡下的被管理主機上,只要運行這串命令就可以將該主機加入集群。如果不小心忘了這個命令那么可以在manager上運行docker swarm join-token manager命令,隨時調取出這部分信息來看。我特意多建了兩臺虛擬機,裝上docker作為被管理機器。為方便下面稱管理者角色的機器為A,另兩臺為B、C。
在B、C上分別運行上面這個命令(有時可以在命令后加上--listen-addr參數,倒不是說被管理主機也需要監聽,而是存在一些將被管理主機升級為管理主機的場景)后,在A上執行命令:
docker node ls?
可以查看swarm各個節點的情況。同樣的docker info 中也會多出Swarm: True以及一系列相關字段。docker node ls的返回類似于:
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 2hzmnrb0vddow7jlr7zdx86s0 localhost.localdomain Ready Active 444w5u9i9tf8h1dmvp404tluy * localhost.localdomain Ready Active Leader 89z0l64mitjyhwijj6o0ps3m3 localhost.localdomain Ready Active?
節點id后的星號據說表示的是你當前連接著的節點。
于是,我們就得到了一個由三個節點組成的swarm小集群。在這個集群中有一個manager節點和三個worker節點(別忘了manager本身自動作為worker一員加入集群)。
相比較于之前還需要手動pull鏡像,然后敲好多docker run命令,新版本下整合到docker內部的swarm明顯就要好多了。然而我們現在也只是搭建了一個小集群,并沒有實質內容在其中運行。
?
■ 構建服務
說到實質內容,由于swarm會自動地做一些如負載均衡,保持容器副本數量等工作,所以swarm對外提供的和k8s類似也是屬于一個“服務”的概念。
docker service create --replicas 1 --name swarmtest tomcatssh:v1?
通過上面這個命令可以創建一個服務(tomcatssh是我自己的鏡像)。--replicas參數指出希望保持這個服務始終有多少容器在運行,name參數指定的是服務的名字而非容器的名字,雖然兩者最終會很像。
創建完成的服務可以在manage節點上通過docker service ls命令查看,可能replicas是0/1,這表示服務仍在創建過程中。稍等一會兒就會變成1/1了。更加詳細的信息,則可以通過docker service inspect --pretty swarmtest來查看。pretty參數使輸出更加友好,不加此參數的輸出是JSON格式的。
同時也可以順便到各臺worker上去docker ps看下容器的運行情況。一般情況下再manager上會出現一個正在運行的容器,如果你停掉或者刪掉這個容器,那么swarm會自動重啟它。
進一步的docker service ps swarmtest,可以查看swarmtest這個Service的各個容器到底在哪個節點上運行且運行狀態如何。比如我剛才建立了一個replicas為3的swarmtest服務,docker service ps swarmtest后的結果是:
?
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR a6ubuiush8l821rncxkd231le \_ swarmtest.1 tomcatssh:v1 localhost.localdomain Shutdown Rejected 8 minutes ago "No such image: tomcatssh:v1" 3sk5cowp4bve0zklvydwdgwba swarmtest.2 tomcatssh:v1 localhost.localdomain Running Running 6 minutes ago 8tku51hecc6pza21urs5oz5zk swarmtest.3 tomcatssh:v1 localhost.localdomain Running Preparing 32 seconds ago?
可以看到,在要求啟動3個容器作為swarmtest服務的支撐時,swarm分別試圖在集群(僵硬的是我集群中三個主機的主機名都是localhost.localdomain。。。意思一下吧,總之知道這里雖然寫的一樣但是里面是三臺不同的機子)中去啟動swarmtest.1,swarmtest.2以及swarmtest.3三個容器,可以看到swarm.1視圖運行的主機上沒有tomcatssh:v1鏡像因此啟動失敗,swarm.2啟動成功,開始運行;swarm.3仍在準備中。可以想到的是,因為swarm.1已經啟動失敗,所以swarm會繼續尋找機會啟動它,盡量保證啟動服務時replicas為3的要求。
另外服務還有一個重要的功能就是伸縮。通過命令:
docker service scale swarmtest=5可以將服務現有的replica為3的狀態擴展到5,期間已經啟動的容器不受影響。
?
對于不需要的服務,可以docker service rm swarmtest來刪除。刪除后所有節點上的相關容器都會被刪除。
對于一個服務來說,常會遇到的一件事是滾動更新,swarm為我們封裝了命令docker service update。只要給這個命令加上--image參數指定一個新鏡像,那么該服務中的所有容器都會被更新成這個新鏡像的內容。但為了保證可用性,必然不能同時更新所有容器。swarm就內置了一個滾動更新的機制,可以讓我們依次更新各個容器從而避免更新期間的不可用。在docker service create 的時候可以指出--upgrade-delay參數,表示更新服務對應的任務或一組任務之間的時間間隔。時間間隔用數字和時間單位表示,m 表示分,h 表示時,所以 10m30s 表示 10 分 30 秒的延時。另外--update-parallelism參數標志配置調度器每次同時更新的最大任務數量,默認情況下此參數值為1,即一個一個容器地更新。
在有了滾動更新的保障之后,再來執行docker service update,比如docker service update --image tomcatssh:v2 swarmtest,則swarm會自動地去按照滾動更新的策略更新各個容器(實際上就是把舊容器關停并啟動新容器)。在更新過程中docker service ps swarmtest可以查看更新的實時情況,最終更新完成后這條命令看到的結果應該是類似于這樣子的:
?
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 5v3purlp28bg93ngkmp9x1dy9 swarmtest.1 tomcatssh:v2 worker1 Running Running 45 seconds ago 055xxourdnlsylmnjgwvs718t \_ swarmtest.1 tomcatssh:v1 worker1 Shutdown Shutdown 49 seconds ago 4b1am22wx1w0abo3ylxt7qcfe swarmtest.2 tomcatssh:v2 localhost.localdomain Running Running 11 seconds ago euyu700dikpqmgzq8hyoijvdq \_ swarmtest.2 tomcatssh:v1 worker2 Shutdown Shutdown 7 minutes ago efgfvp2wd0x655dy136qrt47y swarmtest.3 tomcatssh:v2 worker2 Running Running 7 minutes ago 1m7muogeuitfsllhcyu942ac1 \_ swarmtest.3 tomcatssh:v1 localhost.localdomain Shutdown Shutdown 32 seconds ago過程中,swarm先Shutdown了一臺節點上的老容器并且啟動新容器,如果新容器啟動成功后就再等10秒(創建service時指定的參數),然后開始操作下一臺。另外,如果操作一臺的過程中發生錯誤導致新容器沒有正確運行起來,那么更新任務會到此暫停,不會繼續往下。docker service update后面的--update-failure-action參數可以指定是否要跳過錯誤。
■ 節點管理
之前所有的演示中,三個節點始終都保持著Active的可用性。Swarm管理器會自動根據算法將任務(啟停容器等)分配給Active的節點。
除了Active,其他常見的可用性狀態還有Drain,處于Drain的節點不會被分配新任務,而且當前運行著的容器也都會被停止,swarm管理器則會在其他節點上新建這些任務。
運行命令
docker node update --availability drain worker2可以手動將某個節點的可用性設置為Drain,比如這里將名為worker2的節點設置為drain了之后,可以看到在docker service ps swarmtest中出現的新信息:
anrqum9q6zg0jw12ds5jnloyb swarmtest.3 tomcatssh:v2 localhost.localdomain Running Running 9 seconds ago efgfvp2wd0x655dy136qrt47y \_ swarmtest.3 tomcatssh:v2 worker2 Shutdown Shutdown 7 minutes ago由于worker2不再接受任務并關停現有任務,所以swarmtest.3這個容器被轉移到了localhost(即manage節點所在)。docker node ls或者docker node inspect --pretty worker2就可以看到起可用性的變更了。
如果使用docker node update再次將worker2的可用性設置為active,那么worker2節點就可以再次獲取任務了(剛才被轉移到localhost上的任務是不會有再轉回來的,所以worker2的任務只有在接下來的分配中獲得)。總的來說,一個處于Active狀態的節點在這些情況下可能收到新任務:當服務規模擴大時;滾動更新時;其他節點被設置為Drain而本節點需要擔當時;其他節點上任務啟動失敗時。
?
=======================================
https://blog.csdn.net/weiguang1017/article/details/52386478
自從Dockercon 2016發布Docker 1.12版本以來, 經歷了幾個RC版本后Docker 1.12終于迎來了第一個穩定版.
Docker 1.12展露了docker一統生態的野心。docker engine集成swarmkit, 使得你可以不用安裝額外的軟件包, 就可以用簡單的命令創建和管理docker swarm集群。
同時集成了swarm集群的安全特性和K-V存儲, 你現在也不需要額外去部署etcd或者consul等應用。
?
1.在所有節點上安裝docker1.12
?
## 添加docker repo文件
#?tee /etc/yum.repos.d/docker.repo <<-'EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF
## 安裝 docker package
#?yum install docker-engine -y
## 啟動docker
#?systemctl start docker
#?systemctl enable docker
## 檢查docker版本
#?docker -v
Docker version 1.12.0, build 8eab29e
?
2.在node1節點上安裝docker-compose:
?
#?curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
#?chmod +x /usr/local/bin/docker-compose
#?docker-compose -v
docker-compose version 1.8.0, build f3628c7
?
3.通過docker-compose啟動應用
? 前提是cd到?docker-compose.yml執行
??#?docker-compose up
使用Control+C停止應用,我們使用-d參數后臺啟動應用.
#?docker-compose ps ? //查看運行情況
?
#?docker-compose logs ?//查看應用日志
#?docker-compose logs --tail 10 --follow ?//#滾動輸出應用日志, 每個容器輸出最新10行
注意:日志滾動輸出的時候按Ctrl+S暫停,?Ctrl+Q?繼續輸出,?Ctrl+C退出
#?docker-compose down ?//停止應用
4.通過Scale up擴展應用
?
#?docker-compose ps
# 可以看到我們現在只有一個worker服務
# 增加到2個 worker服務, 使用如下命令
#?docker-compose scale worker=2
Creating and starting dockercoins_worker_2 ... done
?
5.應用的瓶頸
當我們擴展worker為10發現性能并沒有提升上去,原因是我們所有的應用都是跑在一臺服務器上,多個work節點導致服務器資源競爭,所以幾遍增加work節點也不能改善性能,另外也可能是其他節點導致的瓶頸。
瓶頸問題解決:針對第一個work節點的話,我們可以建立docker集群環境,使得worker節點可以分布在不同虛擬機上運行,針對后面其他節點瓶頸問題可以建立多個相關節點來消除瓶頸。
6.創建swarm集群
Docker Engine 1.12及后續版本集成了SwarmKit編排服務,即Swarm Mode。它將服務對象引入到docker中,提供swarm集群管理的原生支持并實現scaling、rolling update、service discovery、load balance、routing mesh等特性。
?
基本概念
-
節點(Node)為swarm集群中的一個Docker Engine實例。其中管理節點(Manager Node)負責swarm集群管理并向工作節點分配任務;工作節點(Work Node)接受并執行來自管理節點的Task。簡單可理解為一個Node就是一臺Docker宿主機,管理節點為領導,工作節點為小兵。
需要注意的是領導也會干小兵的活兒,真是個好領導啊...而且小兵也可以根據需求隨時提拔成領導,真是個好團隊啊...
-
服務(Service)是對在worker nodes所運行一組任務的定義,它是整個swarm的核心,一個Service由多個任務組成。
-
任務(Task)包含Docker容器和容器中運行的命令或應用,它是swarm中被調度的最小單元。簡單可理解為一個Task就是一個容器。
?
Swarm Mode下主要使用三組新的命令行工具創建和管理一個Swarm集群:
-
docker swarm:開啟swarm模式; 加入Swarm集群; 配置集群參數
-
docker node: 查詢集群節點信息; 提升/移除一個管理節點; 管理swarm節點主機
-
docker service: 創建管理service
?
?在node1上初始化swarm集群:
? #docker swarm init --advertise-addr 192.168.0.2
? 備注:
-
你只需要在一個node上初始化swarm集群, 其他node加入這個集群就行了, 所以以上命令只需要在node01上運行。
?
-
--advertise-addr參數, 后面跟你swarm集群的通訊地址, 這里是node01的IP地址。
-
命令輸出的提示很人性化吧,在需要的管理/工作節點復制粘貼運行即可加入到swarm集群中
??
?
?#docker swarm join \
--token SWMTKN-1-4d8z30svnj6wi8y64ttzirpildro5vego1qrrldepj8auwxa6l-3e8p1ojarz8rdq1rx0ves1a9o \
192.168.0.2:2377 ? ? //將node1以manager角色加入swarm集群
?#docker info ? //檢查node1 docker swarm mode信息
?#docker node ls //查看swarm集群node列表
?#docker swarm join \
--token SWMTKN-1-4d8z30svnj6wi8y64ttzirpildro5vego1qrrldepj8auwxa6l-4l4b6o7q1wnjyiwsubkpffkkn \
192.168.0.2:2377 ?//將其他節點加入到集群
?如果你不記得初始化后提示加入swarm集群的命令和密鑰也沒關系,可以使用如下方式查看worker節點和manager節點的加入命令
?
? ? ? ? ? ? #?docker swarm join-token worker
? ? ? ? ? ? #?docker swarm join-token manager
?注意:為了swarm集群的高可用,避免單點故障可以多建立幾個manager節點
? #?docker node promote node02 node03 ?//提升node02和node03節點為manager節點
?此時通過docker node ls可以看到 ?node1是Leader節點, node02和node03是Reachable節點,這是可以通過node02和node03上面管理整個swarm集群。
?
7.在Swarm集群運行Service
??
有了Docker Swarm集群,我們如何把我們的應用跑在Swarm集群上呢?
很簡單,?將我們原來我們使用的docker run命令替換成docker service create就行了,命令后面的格式和選項全都一樣。
#?docker service create --name ping-google alpine ping 8.8.8.8 ?//在swarm集群上, 啟動一個alpine鏡像來執行ping 8.8.8.8命令(如果出錯,swarm集群會不斷幫你重試啟動容器,直到成功為止)
? ?docker service ps?<Service ID or Name>命令可以查看服務到底跑在哪個節點服務器上
?。擴展(Scale)服務
? ? 前面ping-google服務只有一個容器,現在我們想Scale服務到10個副本,可以使用
? ? ??docker service scale?<Service ID or Name>=<replicas No.>
? ? ? 如#docker service scale ping-google=10? ??
?
? ? ? ?#?docker service ls
? ? ? ? ID ? ? ? ? ? ?NAME ? ? ? ? REPLICAS ?IMAGE ? COMMAND
? ? ? ? 9cyy6xrk2n0w ?ping-google ?1/10 ? ? ?alpine ?ping 8.8.8.8
? ? 這里REPLICAS顯示的1/10表示這個service一共有10個副本,現在成功運行了一個,集群正在啟動其他副本?
? ? ?#dockerr service ps ping-goole ?//查看service進程
? ? ? ?等所有的副本都啟動成功了, 你會看到swarm集群會自動編排10個副本到5臺docker宿主機上,而且每個節點會啟動2個容器。
? ? 。開發一個服務端口? ? ? ?
?
? ? ? ? 跟我們在單機使用docker一樣, 你可以將你容器的端口暴露到主機網絡中,從而使得跑在容器中的應用能夠被外部訪問。
? ? ? ?swarm集群的service端口暴露還有如下特性:
-
公共的端口會暴露在每一個swarm集群中的節點服務器上.
-
請求進如公共端口后會負載均衡到所有的sevice實例上.
? ? ? ?發布端口的參數跟單機環境一樣是-p, 就是把docker run -p替換成docker service create -p就行。
? ? ? ?#docker service create --name search --publish 9200:9200 --replicas 7 elasticsearch ? //創建一個elasticsearch服務, 發布9200端口
? ? ? ?可以使用#?watch docker service ps search監控service創建過程
? ? ? ?
? ? ? ?注意DESIRED STATE列, 一個service副本的創建過程,會經歷以下幾個狀態:
-
accepted?任務已經被分配到某一個節點執行
-
preparing?準備資源, 現在來說一般是從網絡拉取image
-
running?副本運行成功
-
shutdown?呃, 報錯,被停止了…
? ? ? ? 當一個任務被終止stoped or killed.., 任務不能被重啟, 但是一個替代的任務會被創建.
? ? ? ??
? ? ? ? ?測試服務端口:
#?curl localhost:9200
{
??"name" : "Rachel Grey",
? "cluster_name" : "elasticsearch",
? "version" : {
? ? "number" : "2.3.4",
? ? "build_hash" : "e455fd0c13dceca8dbbdbb1665d068ae55dabe3f",
? ? "build_timestamp" : "2016-06-30T11:24:31Z",
? ? "build_snapshot" : false,
? ? "lucene_version" : "5.5.0"
? },
? "tagline" : "You Know, for Search"
}
? ? ? ? 反復執行這個命令, 你會看到name會改變, 請求會被分發到不同的service副本.
?
? 。刪除服務
? ? ?使用docker service rm <Service ID or Name>?命令刪除服務
? ? ?#?docker service ls -q | xargs docker service rm ?//刪除所有servcie
?
?8.在Swarm集群上運行應用
? ??為了讓我們的應用跑在swram集群上,我們要解決容器間的網絡通信問題。單節點場景中,我們應用所有的容器都跑在一臺主機上, 所以容器之間的網絡是內部互通的。? ?
?
? ? ?那我們該如何保證不同主機上的容器網絡互通呢?
? ? ?不用擔心,swarm集群已經幫我們解決了這個問題了,那就是overlay network.
? ? ?在docker 1.12以前, swarm集群需要一個額外的key-value存儲(consul, etcd etc)來同步網絡配置, 保證所有容器在同一個網段中。
? ? ?在docker 1.12中已經內置了這個存儲并且集成了overlay networks的支持。至于overlay network的細節, 就不多介紹了。
? ? 。創建一個overlay network
? ? ? ??#?docker network create --driver overlay test ?//創建一個名為test的overlay network
? ? ? ? #docker network ls ?//查看docker network列表
? ? ? ? ??在網絡列表中你可以看到dockercoins網絡的SCOPE是swarm, 表示該網絡是在整個swarm集群生效的, 其他一些網絡是local, 表示本機網絡.
? ? ? ? ??你只需要在manager節點創建overlay network即可,?swarm集群會自動配置到其他的節點。當overlay network在manager節點創建完畢后再查看其他節點的網絡狀態,可以看到各節點的test網絡都已經創建了.:
? ? ? ? ? ? ? ? ? 如:#?ssh node03 docker network ls
? ? ? ? 。在網絡上運行容器
? ? ? ? ? ??直接使用--network <network name>參數, 在指定網絡上創建service.
? ? ? ? ? ??#?docker service create --network test --name redis redis
? ? ? ? ? ??#?docker service create --network test --name hasher localhost:5000/dockercoins_hasher:v0.1 //創建hasher服務
? ? ? ? ? ??#?docker service rm webui ?//刪除webui
? ? ? ? ? ??#?docker service create --network test --name webui -p 8000:80 localhost:5000/dockercoins_webui:v0.1
? ? ? ? ? ??好了, 現在你可以用瀏覽器訪問http://192.168.0.2:8000/index.html?就能看到我們熟悉的webui了.事實上, 你可以通過訪問swarm集群中的所有節點(192.168.0.2 - 192.168.0.6)的8000端口來訪問到我們的webui.
? ? ? ??。擴展(Scaling)應用
? ? ? ? ? ?兩種方式:
? ? ? ? ? ? ? ? ? ? ? ? ? 》#?docker service scale worker=10
? ? ? ? ? ? ? ? ? ? ? ? ? 》通過修改服務的屬性來實現
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#?docker service inspect rng ? //查詢service屬性
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?“Mode": {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "Replicated": {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"Replicas": 1
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #docker service update rng --replicas 5 ?//更新rng服務屬性
?
? ? ? ? ? ? ? ? ??#docker service ls ?//查看服務
? ? ? ? ??。找程序瓶頸
? ? ? ? ? ? ?#?docker service create --network test --name debug --mode global alpine sleep 1000000000
? ? ? ? ? ? ? ??啟動一個臨時容器,?debug使用alpine鏡像, 連接到test網絡中.
-
--mode globle?是啥意思呢?global模式的service, 就是在swarm集群的每個節點創建一個容器副本, 所以如果你想讓一個service分布在集群的每個節點上,可以使用這個模式.
-
sleep 1000000000是為啥呢?因為懶, 想保持這個容器, 方便我們debug.
?
? ? ? ?
? ? ? ? ??隨便進入某個節點中的debug容器,安裝性能測試工具:curl,ab和drill ?-------#apk add --update curl apache2-utils drill
? ? ? ? ??
3.4.1 負載均衡模式
檢查rng服務
/ #?drill rng
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 16923
;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; rng. IN A
;; ANSWER SECTION:
rng. 600 IN A 10.0.0.6
....
可以看到rng服務的IP地址是10.0.0.6。我們一共有5個rng服務, 為啥只有一個IP地址呢?其實這個IP地址是swarm集群分配給所有rng服務負載均衡的VIP(Virtual IP).
?
swarm集群負載均衡service有兩種方式—VIP和DNSRR:
-
VIP模式每個service會得到一個virtual IP地址作為服務請求的入口。基于virtual IP進行負載均衡.
-
DNSRR模式service利用DNS解析來進行負載均衡, 這種模式在舊的Docker Engine下, 經常行為詭異…所以不推薦.
?
?
如何查看service的負載均衡模式呢:
#?docker service inspect rng
...
? ? ? ? ? ? "EndpointSpec": {
? ? ? ? ? ? ? ? "Mode": "vip"
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? "Endpoint": {
? ? ? ? ? ? "Spec": {
? ? ? ? ? ? ? ? "Mode": "vip"
? ? ? ? ? ? },
? ? ? ? ? ? "VirtualIPs": [
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? "NetworkID": "396fwpd5ja6azh93dshalmxro",
? ? ? ? ? ? ? ? ? ? "Addr": "10.0.0.6/24"
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ]
? ? ? ? },
...
?
指定一個service的模式, 可以在創建service的時候使用如下命令:
docker service create --endpoint-mode [vip|dnssrr] <service name>
?
修改一個service的模式, 使用如下命令:
docker service update --endpoint-mode [vip|dnssrr] <service name>
?
3.4.2 rng服務壓力測試
介紹完負載均衡模式, 下面使用ab對我們的rng服務進行簡單的壓力測試.
測試之前, 我們要關掉所有的worker服務, 避免worker服務影響測試結果.
#?docker service scale worker=0
worker scaled to 0
#?docker service ls
ID ? ? ? ? ? ?NAME ? ? ?REPLICAS ?IMAGE ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? COMMAND
...
d7g0estex65u ?worker ? ?0/0 ? ? ? localhost:5000/dockercoins_worker:v0.1
?
回到我們的debug容器中
a.模擬一個客戶端,發送50個請求給rng服務
/ #?ab -c 1 -n 50 http://rng/10
This is ApacheBench, Version 2.3 <$Revision: 1748469 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking rng (be patient).....done
Server Software: ? ? ? ?Werkzeug/0.11.10
Server Hostname: ? ? ? ?rng
Server Port: ? ? ? ? ? ?80
Document Path: ? ? ? ? ?/10
Document Length: ? ? ? ?10 bytes
Concurrency Level: ? ? ?1
Time taken for tests: ? 5.386 seconds
Complete requests: ? ? ?50
Failed requests: ? ? ? ?0
Total transferred: ? ? ?8250 bytes
HTML transferred: ? ? ? 500 bytes
Requests per second: ? ?9.28 [#/sec] (mean)
Time per request: ? ? ? 107.716 [ms] (mean)
Time per request: ? ? ? 107.716 [ms] (mean, across all concurrent requests)
Transfer rate: ? ? ? ? ?1.50 [Kbytes/sec] received
Connection Times (ms)
? ? ? ? ? ? ? min ?mean[+/-sd] median ? max
Connect: ? ? ? ?1 ? ?2 ? 0.6 ? ? ?1 ? ? ? 3
Processing: ? 103 ?106 ? 1.5 ? ?106 ? ? 110
Waiting: ? ? ?102 ?105 ? 1.2 ? ?105 ? ? 109
Total: ? ? ? ?104 ?107 ? 1.7 ? ?107 ? ? 112
WARNING: The median and mean for the initial connection time are not within a normal deviation
? ? ? ? These results are probably not that reliable.
Percentage of the requests served within a certain time (ms)
? 50% ? ?107
? 66% ? ?108
? 75% ? ?108
? 80% ? ?108
? 90% ? ?110
? 95% ? ?110
? 98% ? ?112
? 99% ? ?112
?100% ? ?112 (longest request)
?
b.模擬50個并發客戶端, 發送50個請求
/ #?ab -c 50 -n 50 http://rng/10
This is ApacheBench, Version 2.3 <$Revision: 1748469 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking rng (be patient).....done
Server Software: ? ? ? ?Werkzeug/0.11.10
Server Hostname: ? ? ? ?rng
Server Port: ? ? ? ? ? ?80
Document Path: ? ? ? ? ?/10
Document Length: ? ? ? ?10 bytes
Concurrency Level: ? ? ?50
Time taken for tests: ? 1.105 seconds
Complete requests: ? ? ?50
Failed requests: ? ? ? ?0
Total transferred: ? ? ?8250 bytes
HTML transferred: ? ? ? 500 bytes
Requests per second: ? ?45.23 [#/sec] (mean)
Time per request: ? ? ? 1105.436 [ms] (mean)
Time per request: ? ? ? 22.109 [ms] (mean, across all concurrent requests)
Transfer rate: ? ? ? ? ?7.29 [Kbytes/sec] received
Connection Times (ms)
? ? ? ? ? ? ? min ?mean[+/-sd] median ? max
Connect: ? ? ? ?7 ? ?9 ? 1.3 ? ? ?9 ? ? ?12
Processing: ? 103 ?590 313.4 ? ?627 ? ?1087
Waiting: ? ? ?103 ?589 313.3 ? ?626 ? ?1087
Total: ? ? ? ?115 ?599 312.2 ? ?637 ? ?1095
Percentage of the requests served within a certain time (ms)
? 50% ? ?637
? 66% ? ?764
? 75% ? ?869
? 80% ? ?946
? 90% ? 1050
? 95% ? 1092
? 98% ? 1095
? 99% ? 1095
?100% ? 1095 (longest request)
可以看出,單個客戶端的時候rng的響應時間平均107.716ms, 多并發情況下增加到大約1000ms+.
?
3.4.3 hasher服務壓力測試
hasher的服務測試稍微復雜點, 因為hasher服務需要POST一個隨機的bytes數據.
所以我們需要先通過curl制作一個bytes數據文件:
/ #?curl http://rng/10 > /tmp/random
?
a.模擬單客戶端,發送50個請求給hasher服務
/ #?ab -c 1 -n 50 -T application/octet-stream -p /tmp/random http://hasher/
This is ApacheBench, Version 2.3 <$Revision: 1748469 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking hasher (be patient).....done
Server Software: ? ? ? ?thin
Server Hostname: ? ? ? ?hasher
Server Port: ? ? ? ? ? ?80
Document Path: ? ? ? ? ?/
Document Length: ? ? ? ?64 bytes
Concurrency Level: ? ? ?1
Time taken for tests: ? 5.323 seconds
Complete requests: ? ? ?50
Failed requests: ? ? ? ?0
Total transferred: ? ? ?10450 bytes
Total body sent: ? ? ? ?7250
HTML transferred: ? ? ? 3200 bytes
Requests per second: ? ?9.39 [#/sec] (mean)
Time per request: ? ? ? 106.454 [ms] (mean)
Time per request: ? ? ? 106.454 [ms] (mean, across all concurrent requests)
Transfer rate: ? ? ? ? ?1.92 [Kbytes/sec] received
? ? ? ? ? ? ? ? ? ? ? ? 1.33 kb/s sent
? ? ? ? ? ? ? ? ? ? ? ? 3.25 kb/s total
Connection Times (ms)
? ? ? ? ? ? ? min ?mean[+/-sd] median ? max
Connect: ? ? ? ?1 ? ?1 ? 0.4 ? ? ?1 ? ? ? 3
Processing: ? 103 ?105 ? 0.8 ? ?105 ? ? 107
Waiting: ? ? ?103 ?104 ? 0.8 ? ?104 ? ? 107
Total: ? ? ? ?104 ?106 ? 1.0 ? ?106 ? ? 109
Percentage of the requests served within a certain time (ms)
? 50% ? ?106
? 66% ? ?106
? 75% ? ?106
? 80% ? ?107
? 90% ? ?108
? 95% ? ?108
? 98% ? ?109
? 99% ? ?109
?100% ? ?109 (longest request)
?
b.模擬50個并發客戶端, 發送50個請求
/ #?ab -c 50 -n 50 -T application/octet-stream -p /tmp/random http://hasher/
This is ApacheBench, Version 2.3 <$Revision: 1748469 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking hasher (be patient).....done
Server Software: ? ? ? ?thin
Server Hostname: ? ? ? ?hasher
Server Port: ? ? ? ? ? ?80
Document Path: ? ? ? ? ?/
Document Length: ? ? ? ?64 bytes
Concurrency Level: ? ? ?50
Time taken for tests: ? 0.345 seconds
Complete requests: ? ? ?50
Failed requests: ? ? ? ?0
Total transferred: ? ? ?10450 bytes
Total body sent: ? ? ? ?7250
HTML transferred: ? ? ? 3200 bytes
Requests per second: ? ?144.95 [#/sec] (mean)
Time per request: ? ? ? 344.937 [ms] (mean)
Time per request: ? ? ? 6.899 [ms] (mean, across all concurrent requests)
Transfer rate: ? ? ? ? ?29.59 [Kbytes/sec] received
? ? ? ? ? ? ? ? ? ? ? ? 20.53 kb/s sent
? ? ? ? ? ? ? ? ? ? ? ? 50.11 kb/s total
Connection Times (ms)
? ? ? ? ? ? ? min ?mean[+/-sd] median ? max
Connect: ? ? ? ?5 ? 10 ? 4.8 ? ? ?8 ? ? ?17
Processing: ? 131 ?214 ?71.5 ? ?238 ? ? 323
Waiting: ? ? ?126 ?207 ?72.2 ? ?231 ? ? 322
Total: ? ? ? ?147 ?224 ?67.2 ? ?246 ? ? 328
Percentage of the requests served within a certain time (ms)
? 50% ? ?246
? 66% ? ?249
? 75% ? ?252
? 80% ? ?314
? 90% ? ?324
? 95% ? ?328
? 98% ? ?328
? 99% ? ?328
?100% ? ?328 (longest request)
從結果可以看出, 單客戶端hasher平均響應時間106.454ms, 50并發平均響應時間344.937ms.
hasher服務并發響應時間也慢, 不過比rng的1000+ms卻好太多…
總結
以上是生活随笔為你收集整理的docker Swarm简介 新旧版本操作不一样docker run --rm swarm create和docker swarm --init的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CCRC信息安全服务资质认证简介
- 下一篇: 安徽计算机二级vfp成绩,安徽省计算机二