接以前的文章:node
容器技術|Docker三劍客之docker-machinelinux
Swarm是Docker官方提供的一款集羣管理工具,其主要做用是把若干臺Docker主機抽象爲一個總體,而且經過一個入口統一管理這些Docker主機上的各類Docker資源。Swarm和Kubernetes比較相似,可是更加輕,具備的功能也較kubernetes更少一些。
swarm集羣提供給用戶管理集羣內全部容器的操做接口與使用一臺Docker主機基本相同。
Swarm集羣目前有兩個版本:V一、V2算法
一、Swarm v1它是master-slave架構。須要經過服務發現來選舉出管理節點,其它各個節點經過運行agent來接受管理節點的統一管理
二、Swarm v2集羣是自動經過Raft協議分佈式選舉出管理節點,不須要配置發現服務,從而避免發現服務的單點故障問題。且它自帶了DNS負載均衡和對外部負載均衡機制的支持docker
一、Swarm
使用swarmkit嵌入docker Engine中的集羣管理和編排功能。docker容器初始化啓動的一種模式json
二、Node
節點,是一個已加入到docker swarm集羣中的一個容器實例。vim
三、Service
服務主要是在工做節點上執行任務,建立服務時,須要指定容器的鏡像。瀏覽器
四、Task
任務是在容器中執行的命令bash
一、節點服務器
二、服務、任務、容器
三、任務與調度
四、服務副本與全局服務
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 都會調用調度機制篩選出匹配約束條件的服務器,並在這上面運行容器。
1)發現 Docker 集羣中的各個節點,收集節點狀態、角色信息,並監視節點狀態的變化
2)初始化內部調度(scheduler)模塊
3)建立並啓動 API 監聽服務模塊
一旦建立好這個 cluster,就能夠用命令 docker service 批量對集羣內的容器進行操做,在啓動容器後,docker 會根據當前每一個 swarm 節點的負載判斷,在負載最優的節點運行這個 task 任務,用」docker service ls」 和」docker service ps + taskID」能夠看到任務運行在哪一個節點上。容器啓動後,有時須要等待一段時間才能完成容器建立。
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:試驗特性,用於多應用部署
複製代碼
[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配置同上一致便可
複製代碼
具體安裝過程參考前面的文章
配置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)
複製代碼
[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
複製代碼
[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地址與管理節點通信,上面也提示了其它節點如何加入集羣的命令。
複製代碼
[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 #當前節點的信息,這個*表示當前鏈接在這個節點上 複製代碼
[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"
#注意服務器時間同步問題,解決便可。
複製代碼
[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"
}
}
]
複製代碼
[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
複製代碼
瀏覽器訪問
[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
複製代碼
[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
複製代碼
[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上運行兩個容器
複製代碼
[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除,而後利用自身的負載均衡及調度功能,將服務調度到其它節點上
複製代碼
除了上面使用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
#將全部節點上的全部容器所有刪除,任務也將所有刪除複製代碼