james@james-CW65:~ > docker swarm init --advertise-addr 192.168.99.1
Swarm initialized: current node (5n1l6261akogeuxysrgn2ipxz) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-2bgkinnbc0rmlj6kpotyrlj0uz51l2ikinttsk960dxro558x4-6zajfnahtv9ye39momddh5kru 192.168.99.1:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
james@james-CW65:~ > docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
5n1l6261akogeuxysrgn2ipxz * james-CW65 Ready Active Leader
nodeId旁边的*号表示你当前连接到的节点。
docker引擎的swarm模式自动使用宿主机的主机名作为节点名。
将节点加入到swarm集群中
一旦前面的创建swarm集群完成,你就可以加入工作节点了。
ssh到要加入集群的节点上,我们要加入worker1.
运行创建swarm集群时候产生的命令来将woker1加入到集群中:
docker@default:~$ docker swarm join --token SWMTKN-1-2bgkinnbc0rmlj6kpotyrlj0uz51l2ikinttsk960dxro558x4-6zajfnahtv9ye39momd
dh5kru 192.168.99.1:2377
This node joined a swarm as a worker.
如果你找不到加入命令了,可以在管理节点运行下列命令找回加入命令:
james@james-CW65:~ > docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-2bgkinnbc0rmlj6kpotyrlj0uz51l2ikinttsk960dxro558x4-6zajfnahtv9ye39momddh5kru 192.168.99.1:2377
ssh到worker2
运行加入集群的命令来将worker2加入到集群:
Boot2Docker version 17.12.0-ce, build HEAD : 378b049 - Wed Dec 27 23:39:20 UTC 2017
Docker version 17.12.0-ce, build c97c6d6
docker@lab:~$ docker swarm join --token SWMTKN-1-2bgkinnbc0rmlj6kpotyrlj0uz51l2ikinttsk960dxro558x4-6zajfnahtv9ye39momddh5k
ru 192.168.99.1:2377
This node joined a swarm as a worker.
ssh到manager节点运行docker node ls命令来查看集群节点情况:
james@james-CW65:~ > docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
k89s71elf81vbn7pytwszmgr5 default Ready Active
5n1l6261akogeuxysrgn2ipxz * james-CW65 Ready Active Leader
ye5x8hci1chmo8nyjx8y4thhy lab Ready Active
MANAGER列表明了集群中的管理节点。worker节点的空意味着它们是工作节点
在swarm集群上部署一个服务
在创建一个swarm集群后,就可以部署服务了。本教程中你也可以加入工作节点,但是不是必须的。
ssh到manager节点
运行如下命令:
james@james-CW65:~ > docker service create --replicas 1 --name helloworld alpine ping docker.com
060zo3u0g3mjdmrilezzbckbe
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
docker service create用来创建服务
--name表明服务名字是helloworld
--replicas 表示期望1个服务实例
alpine ping docker.com 表示运行镜像是alpine,命令是ping
运行docker service ls来查看运行的服务:
james@james-CW65:~ > docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
060zo3u0g3mj helloworld replicated 1/1 alpine:latest
检查Swarm集群上的服务
在你部署服务到Swarm集群上后,可以使用命令行来检查运行的服务
ssh到管理节点
运行命令docker service inspect --pretty 来查看优化显示的服务详情
james@james-CW65:~ > docker service inspect --pretty 060zo3u0g3mj
ID: 060zo3u0g3mjdmrilezzbckbe
Name: helloworld
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: alpine:latest@sha256:7b848083f93822dd21b0a2f14a110bd99f6efb4b838d499df6d04a49d0debf8b
Args: ping docker.com
Resources:
Endpoint Mode: vip
去掉--pretty选项将以json格式输出
运行docker service ps 将查看到哪些节点在运行该服务实例:
james@james-CW65:~ > docker service ps 060zo3u0g3mj
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
cbiq1ne3ij9a helloworld.1 alpine:latest james-CW65 Running Running 9 minutes ago
服务可能运行在管理或工作节点上,默认的管理节点可以像工作节点一样运行任务。
该命令也显示服务期望的状态DESIRED STATE ,和实际的状态CURRENT STATE。
在运行任务的节点上运行docker ps也能看到这个任务运行的容器
james@james-CW65:~ > docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cad59e7398de alpine:latest "ping docker.com" 2 minutes ago Up 2 minutes helloworld.1.ngbknb89dzyxdas81emw0jz63
james@james-CW65:~ > docker service scale 060zo3u0g3mj=3
060zo3u0g3mj scaled to 3
overall progress: 3 out of 3 tasks
1/3: running [==================================================>]
2/3: running [==================================================>]
3/3: running [==================================================>]
verify: Waiting 1 seconds to verify that tasks are stable...
verify: Service converged
运行以下命令来查看更新的任务列表:
james@james-CW65:~ > docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
060zo3u0g3mj helloworld replicated 3/3 alpine:latest
james@james-CW65:~ > docker service ps 060zo3u0g3mj
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ngbknb89dzyx helloworld.1 alpine:latest james-CW65 Running Running 9 minutes ago
cbiq1ne3ij9a \_ helloworld.1 alpine:latest james-CW65 Shutdown Failed 9 minutes ago "task: non-zero exit (1)"
3fl3mfrvubu1 helloworld.2 alpine:latest default Running Running about a minute ago
hy5pqcmqfw67 helloworld.3 alpine:latest lab Running Running about a minute ago
可以看到这3个任务被分布到了集群中的不同节点
ssh到运行服务的主机上运行docker ps查看运行的容器:
docker@default:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cad897086027 alpine:latest "ping docker.com" 4 minutes ago Up 4 minutes helloworld.2.3fl3mfrvubu1hf16argabe5qt
从swarm集群上删除应用
接下来删除应用
ssh到管理节点
运行docker service rm helloworld来删除服务:
james@james-CW65:~ > docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
060zo3u0g3mj helloworld replicated 3/3 alpine:latest
james@james-CW65:~ > docker service rm 060zo3u0g3mj
060zo3u0g3mj
james@james-CW65:~ > docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
运行docker service inspect 会发现服务不存在了
james@james-CW65:~ > docker service inspect 060zo3u0g3mj
[]
Status: Error: no such service: 060zo3u0g3mj, Code: 1
默认的当一个更新任务返回RUNNING状态后,调度器才调度另一个更新任务,直到所有任务都更新了。如果更新过程中任何任务返回了FAILED,调度器就会停止更新。你可以给命令docker service create or docker service update配置配置--update-failure-action,来配置这个行为。
查看redis服务:
james@james-CW65:~ > docker service inspect --pretty ghost
ID: tynb9d9pu0nqm7f1vmmffy9j0
Name: ghost
Service Mode: Replicated
Replicas: 2
Placement:
UpdateConfig:
Parallelism: 1
Delay: 10s
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: ghost:0.11.12@sha256:45811b5a50254bdf0a05d683ddf1dd9eb1be98640305fb82317bcaa35a00c20e
Resources:
Endpoint Mode: vip
james@james-CW65:~ > docker service update --image ghost:1.21.3 ghost
ghost
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
调度器依照以下步骤来滚动更新:
停止第一个任务
对停止的任务进行更新
对更新的任务进行启动
如果更新的任务返回RUNNING,等待特定间隔后启动下一个任务
如果在任何更新的时间,任务返回了FAILED,则停止更新。
运行命令docker service inspect --pretty redis来查看新镜像的期望状态,可以看到显示了UpdateStatus完成。
james@james-CW65:~ > docker service inspect --pretty ghost
ID: tynb9d9pu0nqm7f1vmmffy9j0
Name: ghost
Service Mode: Replicated
Replicas: 2
UpdateStatus:
State: completed
Started: 2 minutes ago
Completed: 2 minutes ago
Message: update completed
Placement:
UpdateConfig:
Parallelism: 1
Delay: 10s
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: ghost:1.21.3@sha256:4c8868f41180589583e6eb208a8529ca8dad3d18bddf56834740b715f3e6b691
Resources:
Endpoint Mode: vip
james@james-CW65:~ >
如果中间有升级失败的,则会显示如下信息:
$ docker service inspect --pretty redis
ID: 0u6a4s31ybk7yw2wyvtikmu50
Name: redis
...snip...
Update status:
State: paused
Started: 11 seconds ago
Message: update paused due to failure or early termination of task 9p7ith557h8ndf0ui9s0q951b
...snip...
重新开始一个升级过程:docker service update
为了避免重复失败升级,要重新配置服务服务,添加适当的参数在运行docker service update
运行docker service ps 来查看本次滚动更新的过程:
james@james-CW65:~ > docker service ps ghost
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
5ae8hwemegrg ghost.1 ghost:1.21.3 james-CW65 Running Running 54 seconds ago
akwqfsarjvy1 \_ ghost.1 ghost:0.11.12 james-CW65 Shutdown Shutdown 54 seconds ago
hzzq00ckovdg ghost.2 ghost:1.21.3 default Running Running 41 seconds ago
ivtd60xuggk0 \_ ghost.2 ghost:0.11.12 default Shutdown Shutdown 42 seconds ago
james@james-CW65:~ >
注意升级后老的容器只是停止了,并没有删除
docker@default:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f855c00da7b7 ghost:1.21.3 "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 2368/tcp ghost.2.hzzq00ckovdgb48373lwn8xp6
c151f3535a3b ghost:0.11.12 "docker-entrypoint.s…" 32 minutes ago Exited (0) 6 minutes ago ghost.2.ivtd60xuggk0y56oguehtirni
james@james-CW65:~ > docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
k89s71elf81vbn7pytwszmgr5 default Ready Active
5n1l6261akogeuxysrgn2ipxz * james-CW65 Ready Active Leader
如果弄的redis服务还没有从滚动更新中起来,需要启动起来:
运行docker service ps redis查看管理节点如何分配任务到不同节点:
james@james-CW65:~ > docker service ps ghost
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
5ae8hwemegrg ghost.1 ghost:1.21.3 james-CW65 Running Running 19 minutes ago
akwqfsarjvy1 \_ ghost.1 ghost:0.11.12 james-CW65 Shutdown Shutdown 19 minutes ago
hzzq00ckovdg ghost.2 ghost:1.21.3 default Running Running 19 minutes ago
ivtd60xuggk0 \_ ghost.2 ghost:0.11.12 default Shutdown Shutdown 19 minutes ago
james@james-CW65:~ > docker service ps ghost
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
5ae8hwemegrg ghost.1 ghost:1.21.3 james-CW65 Running Running 21 minutes ago
akwqfsarjvy1 \_ ghost.1 ghost:0.11.12 james-CW65 Shutdown Shutdown 21 minutes ago
lefwcfo1s44k ghost.2 ghost:1.21.3 james-CW65 Running Running 22 seconds ago
hzzq00ckovdg \_ ghost.2 ghost:1.21.3 default Shutdown Shutdown 22 seconds ago
ivtd60xuggk0 \_ ghost.2 ghost:0.11.12 default Shutdown Shutdown 21 minutes ago
运行docker node update --availability active 来重新active该节点:
james@james-CW65:~ > docker node update --availability active default
default
james@james-CW65:~ > docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
k89s71elf81vbn7pytwszmgr5 default Ready Active
5n1l6261akogeuxysrgn2ipxz * james-CW65 Ready Active Leader
james@james-CW65:~ > docker service create --name ghostBlog --publish published=80,target=2368 --replicas 1 ghost:1.21.3
xpnc3ga8yvh71zx5dvq94fbsn
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
james@james-CW65:~ > docker service ps ghostBlog
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
5a0tepfqasqu ghostBlog.1 ghost:1.21.3 default Running Running 18 seconds ago
global
log /dev/log local0
log /dev/log local1 notice
...snip...
# Configure HAProxy to listen on port 80
frontend http_front
bind *:80
stats uri /haproxy?stats
default_backend http_back
# Configure HAProxy to route requests to swarm nodes on port 8080
backend http_back
balance roundrobin
server node1 192.168.99.100:8080 check
server node2 192.168.99.101:8080 check
server node3 192.168.99.102:8080 check
如果不使用路由网络,配置--endpoint-mode的值为dnsrr,而不是vip。在本例子中没有一个固定的虚拟IP。Docker为服务做了DNS注册,这样一个服务的DNS查询会返回一系列IP地址。客户端就可以直接连接其中一个节点。你负责提供这一系列的IP地址,开放端口给你的负载均衡器。参考Configure service discovery.