接之前的文章:
docker-swarm簡介
Swarm是Docker官方提供的一款叢集管理工具,其主要作用是把若干臺Docker主機抽象為一個整體,並且通過一個入口統一管理這些Docker主機上的各種Docker資源。Swarm和Kubernetes比較類似,但是更加輕,具有的功能也較kubernetes更少一些。
swarm叢集提供給使用者管理叢集內所有容器的操作介面與使用一臺Docker主機基本相同。
Swarm叢集目前有兩個版本:V1、V2
1、Swarm v1它是master-slave架構。需要通過服務發現來選舉出管理節點,其它各個節點通過執行agent來接受管理節點的統一管理
2、Swarm v2叢集是自動通過Raft協議分散式選舉出管理節點,不需要配置發現服務,從而避免發現服務的單點故障問題。且它自帶了DNS負載均衡和對外部負載均衡機制的支援
Swarm的基本架構如下圖所示
Swarm一些概念說明
1、Swarm
使用swarmkit嵌入docker Engine中的叢集管理和編排功能。docker容器初始化啟動的一種模式2、Node
節點,是一個已加入到docker swarm叢集中的一個容器例項。3、Service
服務主要是在工作節點上執行任務,建立服務時,需要指定容器的映象。4、Task
任務是在容器中執行的命令
Swarm 工作方式
1、節點
2、服務、任務、容器
3、任務與排程
4、服務副本與全域性服務
Swarm 排程策略
Swarm在scheduler節點(leader 節點)執行容器的時候,會根據指定的策略來計算最適合執行容器的節點,目前支援的策略有:spread, binpack, random.1)Random
顧名思義,就是隨機選擇一個 Node 來執行容器,一般用作除錯用,spread 和 binpack 策略會根據各個節點的可用的 CPU, RAM 以及正在執行的容器的數量來計算應該執行容器的節點。2)Spread
在同等條件下,Spread 策略會選擇執行容器最少的那臺節點來執行新的容器,binpack 策略會選擇執行容器最集中的那臺機器來執行新的節點。使用 Spread 策略會使得容器會均衡的分佈在叢集中的各個節點上執行,一旦一個節點掛掉了只會損失少部分的容器。3)Binpack
Binpack 策略最大化的避免容器碎片化,就是說 binpack 策略儘可能的把還未使用的節點留給需要更大空間的容器執行,儘可能的把容器執行在一個節點上面。
Swarm Cluster模式的特性
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”可以看到任務執行在哪個節點上。容器啟動後,有時需要等待一段時間才能完成容器建立。
Swarm命令列說明
docker swarm:叢集管理
init #初始化叢集
join #將節點加入叢集
join-token #管理加入令牌
leave #從叢集中刪除某個節點,強制刪除加引數--force
update #更新叢集
unlock #解鎖叢集
docker node:節點管理,
demote #將叢集中一個或多個節點降級
inspect #顯示一個或多個節點的詳細資訊
ls #列出叢集中的節點
promote #將一個或多個節點提升為管理節點
rm #從叢集中刪除停止的節點,--force強制刪除引數
ps #列出一個或多個節點上執行的任務
update #更新節點
docker service:服務管理,
create #建立一個新的服務
inspect #列出一個或多個服務的詳細資訊
ps #列出一個或多個服務中的任務資訊
ls #列出服務
rm #刪除一個或多個服務
scale #擴充套件一個或多個服務
update #更新服務
docker stack/deploy:試驗特性,用於多應用部署
複製程式碼
安裝佈署swarm叢集服務
1、修改主機名,配置hosts檔案
[root@manager ~]# cat >>/etc/hosts<<EOF
192.168.22.177 manager
192.168.22.175 node1
192.168.22.178 node2
EOF
[root@manager ~]# tail -3 /etc/hosts
192.168.22.177 manager
192.168.22.175 node1
192.168.22.178 node2
[root@manager ~]# ping node1
PING node1 (192.168.22.175) 56(84) bytes of data.
64 bytes from node1 (192.168.22.175): icmp_seq=1 ttl=64 time=3.64 ms
64 bytes from node1 (192.168.22.175): icmp_seq=2 ttl=64 time=1.64 ms
^C
--- node1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1006ms
rtt min/avg/max/mdev = 1.648/2.644/3.641/0.997 ms
[root@manager ~]# ping node2
PING node2 (192.168.22.178) 56(84) bytes of data.
64 bytes from node2 (192.168.22.178): icmp_seq=1 ttl=64 time=9.70 ms
64 bytes from node2 (192.168.22.178): icmp_seq=2 ttl=64 time=1.95 ms
^C
--- node2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1003ms
rtt min/avg/max/mdev = 1.951/5.826/9.701/3.875 ms
#node1 node2配置同上一致即可
複製程式碼
2、安裝docker環境
具體安裝過程參考前面的文章
配置docker
[root@manager ~]# vim /etc/sysconfig/docker
# /etc/sysconfig/docker
# Modify these options if you want to change the way the docker daemon runs
OPTIONS='-H 0.0.0.0:2375 -H unix:///var/run/docker.sock --selinux-enabled --log-driver=journald --signature-verification=false'
#所有節點加上上面標記的部分,開啟2375埠
[root@manager ~]# systemctl restart docker
[root@manager ~]# ps -ef|grep docker
root 11981 1 1 10:55 ? 00:00:00 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --init-path=/usr/libexec/docker/docker-init-current --seccomp-profile=/etc/docker/seccomp.json -H 0.0.0.0:2375 -H unix:///var/run/docker.sock --selinux-enabled --log-driver=journald --signature-verification=false --storage-driver overlay2
root 11986 11981 0 10:55 ? 00:00:00 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc --runtime-args --systemd-cgroup=true
root 12076 11823 0 10:55 pts/0 00:00:00 grep --color=auto docker
[root@manager ~]# lsof -i :2375
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
dockerd-c 11981 root 5u IPv6 41829 0t0 TCP *:2375 (LISTEN)
複製程式碼
3、所有節點下載swarm映象檔案
[root@manager ~]# docker pull swarm
Using default tag: latest
Trying to pull repository docker.io/library/swarm ...
latest: Pulling from docker.io/library/swarm
d85c18077b82: Pull complete
1e6bb16f8cb1: Pull complete
85bac13497d7: Pull complete
Digest: sha256:406022f04a3d0c5ce4dbdb60422f24052c20ab7e6d41ebe5723aa649c3833975
Status: Downloaded newer image for docker.io/swarm:latest
[root@manager ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/swarm latest ff454b4a0e84 12 days ago 12.7 MB
複製程式碼
4、建立swarm並初始化
[root@manager ~]# docker swarm init --advertise-addr 192.168.22.177
Swarm initialized: current node (elyfa6h1lx5o2s98une5vas4x) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-32h92m334z80z270d4duqdc3ysl1oyrjmxe1upyyfjyln12xxa-4gm603mczorxgh6751n5q7jya \
192.168.22.177:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
#執行上面的命令後,當前的伺服器就加入到swarm叢集中,同時會產生一個唯一的token值,其它節點加入叢集時需要用到這個token。
#--advertise-addr 表示swarm叢集中其它節點使用後面的IP地址與管理節點通訊,上面也提示了其它節點如何加入叢集的命令。
複製程式碼
5、檢視下當前的資訊
[root@manager ~]# docker info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 1
Server Version: 1.13.1
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: journald
Cgroup Driver: systemd
Plugins:
Volume: local
Network: bridge host macvlan null overlay
**Swarm: active
NodeID: elyfa6h1lx5o2s98une5vas4x
Is Manager: true
ClusterID: vi716cgvw33gzicrfqopasf9p
Managers: 1
Nodes: 1
Orchestration:
Task History Retention Limit: 5
Raft:
Snapshot Interval: 10000
Number of Old Snapshots to Retain: 0
Heartbeat Tick: 1
Election Tick: 3
Dispatcher:
Heartbeat Period: 5 seconds
CA Configuration:
Expiry Duration: 3 months
Node Address: 192.168.22.177
Manager Addresses:
192.168.22.177:2377
Runtimes: docker-runc runc
Default Runtime: docker-runc
Init Binary: /usr/libexec/docker/docker-init-current
containerd version: (expected: aa8187dbd3b7ad67d8e5e3a15115d3eef43a7ed1)
runc version: e9c345b3f906d5dc5e8100b05ce37073a811c74a (expected: 9df8b306d01f59d3a8029be411de015b7304dd8f)
init version: 5b117de7f824f3d3825737cf09581645abbe35d4 (expected: 949e6facb77383876aeff8a6944dde66b3089574)
Security Options:
seccomp
WARNING: You're not using the default seccomp profile
Profile: /etc/docker/seccomp.json
Kernel Version: 3.10.0-693.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
Number of Docker Hooks: 3
CPUs: 1
Total Memory: 2.238 GiB
Name: manager
ID: 653Y:7CME:GFPW:35SX:IGZL:UJP7:YSPZ:4OMV:J4EV:Z6FS:WFW2:YYHS
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: bridge-nf-call-ip6tables is disabled
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Registries: docker.io (secure)
[root@manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
elyfa6h1lx5o2s98une5vas4x * manager Ready Active Leader
#當前節點的資訊,這個*表示當前連線在這個節點上
複製程式碼
6、將node1,node2加入到叢集中
[root@node1 ~]# docker swarm join --token SWMTKN-1-32h92m334z80z270d4duqdc3ysl1oyrjmxe1upyyfjyln12xxa-4gm603mczorxgh6751n5q7jya 192.168.22.177:2377
This node joined a swarm as a worker.
[root@node2 ~]# docker swarm join --token SWMTKN-1-32h92m334z80z270d4duqdc3ysl1oyrjmxe1upyyfjyln12xxa-4gm603mczorxgh6751n5q7jya 192.168.22.177:2377
This node joined a swarm as a worker.
#如果加入叢集時報錯如下
[root@node1 ~]# docker swarm join --token SWMTKN-1-32h92m334z80z270d4duqdc3ysl1oyrjmxe1upyyfjyln12xxa-4gm603mczorxgh6751n5q7jya 192.168.22.177:2377
Error response from daemon: rpc error: code = 13 desc = connection error: desc = "transport: x509: certificate has expired or is not yet valid"
#注意伺服器時間同步問題,解決即可。
複製程式碼
7、管理節點檢視叢集節點狀態
[root@manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
elyfa6h1lx5o2s98une5vas4x * manager Ready Active Leader
tcuv2p8wd6rvmwg39pdav5ozk node1 Ready Active
twytwc5dlp77vu1b7cakks9w2 node2 Ready Active
#swarm叢集中node的AVAILABILITY狀態有兩種:Active、drain。其中actice狀態的節點可以接受管理節點的任務指派;drain狀態的節點會結束任務,也不會接受管理節點的任務指派,節點處於下線狀態。
[root@manager ~]# docker node update --availability drain node2
node2
[root@manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
elyfa6h1lx5o2s98une5vas4x * manager Ready Active Leader
tcuv2p8wd6rvmwg39pdav5ozk node1 Ready Active
twytwc5dlp77vu1b7cakks9w2 node2 Ready Drain
[root@manager ~]# docker node update --availability active node2
node2
[root@manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
elyfa6h1lx5o2s98une5vas4x * manager Ready Active Leader
tcuv2p8wd6rvmwg39pdav5ozk node1 Ready Active
twytwc5dlp77vu1b7cakks9w2 node2 Ready Active
#在manager節點上檢視狀態資訊
[root@manager ~]# docker node inspect self
[
{
"ID": "elyfa6h1lx5o2s98une5vas4x",
"Version": {
"Index": 9
},
"CreatedAt": "2018-06-14T15:01:19.850821157Z",
"UpdatedAt": "2018-06-14T15:01:20.472379584Z",
"Spec": {
"Role": "manager",
"Availability": "active"
},
"Description": {
"Hostname": "manager",
"Platform": {
"Architecture": "x86_64",
"OS": "linux"
},
"Resources": {
"NanoCPUs": 1000000000,
"MemoryBytes": 2402566144
},
"Engine": {
"EngineVersion": "1.13.1",
"Plugins": [
{
"Type": "Network",
"Name": "bridge"
},
{
"Type": "Network",
"Name": "host"
},
{
"Type": "Network",
"Name": "macvlan"
},
{
"Type": "Network",
"Name": "null"
},
{
"Type": "Network",
"Name": "overlay"
},
{
"Type": "Volume",
"Name": "local"
}
]
}
},
"Status": {
"State": "ready",
"Addr": "127.0.0.1"
},
"ManagerStatus": {
"Leader": true,
"Reachability": "reachable",
"Addr": "192.168.22.177:2377"
}
}
]
複製程式碼
Swarm 的Web管理
[root@manager ~]# docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
Unable to find image 'portainer/portainer:latest' locally
Trying to pull repository docker.io/portainer/portainer ...
latest: Pulling from docker.io/portainer/portainer
d1e017099d17: Pull complete
0d90a7ef0797: Pull complete
Digest: sha256:2933caa6e578e94b5d91429ea7f47ae9741ee11b71d7cb740e76c5f234cc1d87
Status: Downloaded newer image for docker.io/portainer/portainer:latest
798b3bea009792321519f5b7144e357ce9c5cea3b9341b5276a4d29f7571684a
[root@manager ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
798b3bea0097 portainer/portainer "/portainer" 6 seconds ago Up 5 seconds 0.0.0.0:9000->9000/tcp amazing_snyder
複製程式碼
瀏覽器訪問
docker-swarm佈署服務
1、佈署服務前建立於個用於叢集內不同主機之間容器通訊的網路
[root@manager ~]# docker network create -d overlay dockernet
pmn1fi6lj421hn1nk7652m41h
[root@manager ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
d913c7a275fe bridge bridge local
c737cf269524 docker_gwbridge bridge local
pmn1fi6lj421 dockernet overlay swarm
eac1d68d35d7 host host local
wxshzhdvq52y ingress overlay swarm
c5986aec6119 none null local
複製程式碼
2、建立服務(nginx為例)
[root@manager ~]# docker service create --replicas 1 --network dockernet --name nginx-cluster -p 80:80 nginx
k7lupo9xu0cnd5ng1g4f7i7jx
#--replicas 指定副本數量
[root@manager ~]# docker service ls
ID NAME MODE REPLICAS IMAGE
k7lupo9xu0cn nginx-cluster replicated 1/1 nginx:latest
[root@manager ~]# docker service ps nginx-cluster
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
7t7xjpmao533 nginx-cluster.1 nginx:latest manager Running Running 17 seconds ago
[root@manager ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a9d78079fdc7 nginx@sha256:3e2ffcf0edca2a4e9b24ca442d227baea7b7f0e33ad654ef1eb806fbd9bedcf0 "nginx -g 'daemon ..." 22 seconds ago Up 22 seconds 80/tcp nginx-cluster.1.7t7xjpmao5335zaa8wp0c896a
複製程式碼
3、線上動態擴容服務
[root@manager ~]# docker service scale nginx-cluster=5
nginx-cluster scaled to 5
[root@manager ~]# docker service ps nginx-cluster
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
7t7xjpmao533 nginx-cluster.1 nginx:latest manager Running Running 2 hours ago
vitsgxpdf3bn nginx-cluster.2 nginx:latest manager Running Running 2 seconds ago
o9w529mmttsw nginx-cluster.3 nginx:latest node1 Running Preparing 2 seconds ago
cfz8dkx9p6ih nginx-cluster.4 nginx:latest node2 Running Preparing 2 seconds ago
9p35iunijoro nginx-cluster.5 nginx:latest node2 Running Preparing 2 seconds ago
#從輸出結果可以看出已經將服務動態擴容至5個,也就是5個容器執行著相同的服務
[root@node2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f3a4fb24480a nginx@sha256:3e2ffcf0edca2a4e9b24ca442d227baea7b7f0e33ad654ef1eb806fbd9bedcf0 "nginx -g 'daemon ..." 3 minutes ago Up 3 minutes 80/tcp nginx-cluster.5.9p35iunijorol1d2ikhyj11oi
f8b0b2e514eb nginx@sha256:3e2ffcf0edca2a4e9b24ca442d227baea7b7f0e33ad654ef1eb806fbd9bedcf0 "nginx -g 'daemon ..." 3 minutes ago Up 3 minutes 80/tcp nginx-cluster.4.cfz8dkx9p6ih40lwwwvd96xdg
#登入node2檢視正在執行的容器,發現與管理節點上顯示的結果相同,node2上執行兩個容器
複製程式碼
4、節點故障
[root@manager ~]# docker service ps nginx-cluster
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
7t7xjpmao533 nginx-cluster.1 nginx:latest manager Running Running 2 hours ago
vitsgxpdf3bn nginx-cluster.2 nginx:latest manager Running Running 10 minutes ago
f13cun1wyxlt nginx-cluster.3 nginx:latest manager Running Running 9 minutes ago
q60fo5mja1ab \_ nginx-cluster.3 nginx:latest node1 Shutdown Failed 9 minutes ago "starting container failed: sh…"
mao4htxp7afr \_ nginx-cluster.3 nginx:latest node1 Shutdown Failed 9 minutes ago "starting container failed: sh…"
fhiecco742y4 \_ nginx-cluster.3 nginx:latest node1 Shutdown Failed 10 minutes ago "starting container failed: sh…"
8qp5kryo62ha \_ nginx-cluster.3 nginx:latest node1 Shutdown Failed 10 minutes ago "starting container failed: sh…"
cfz8dkx9p6ih nginx-cluster.4 nginx:latest node2 Running Running 9 minutes ago
9p35iunijoro nginx-cluster.5 nginx:latest node2 Running Running 9 minutes ago
#如果叢集中節點發生故障,會從swarm叢集中被T除,然後利用自身的負載均衡及排程功能,將服務排程到其它節點上
複製程式碼
5、其它常用命令介紹
除了上面使用scale來實現線上動態擴容、縮容之外,還可以使用update來對服務進行調整
[root@manager ~]# docker service ls
ID NAME MODE REPLICAS IMAGE
k7lupo9xu0cn nginx-cluster replicated 5/5 nginx:latest
[root@manager ~]# docker service update --replicas 2 nginx-cluster
nginx-cluster
[root@manager ~]# docker service ls
ID NAME MODE REPLICAS IMAGE
k7lupo9xu0cn nginx-cluster replicated 2/2 nginx:latest
#將服務縮減到2個
[root@manager ~]# docker service update --image nginx:new nginx-cluster
#更新服務的映象版本
[root@manager ~]# docker service --help
Usage: docker service COMMAND
Manage services
Options:
--help Print usage
Commands:
create Create a new service
inspect Display detailed information on one or more services
ls List services
ps List the tasks of a service
rm Remove one or more services
scale Scale one or multiple replicated services
update Update a service
Run 'docker service COMMAND --help' for more information on a command.
[root@manager ~]# docker rm nginx-cluster
#將所有節點上的所有容器全部刪除,任務也將全部刪除複製程式碼