Docker Swarm 项目

Docker Swarm 是 Docker 官方三剑客项目之一,提供 Docker 容器集群服务,是 Docker 官方对容器云生态进行支持的核心方案。

使用它,用户可以将多个 Docker 主机封装为单个大型的虚拟 Docker 主机,快速打造一套容器云平台。

注意:Docker 1.12.0+ Swarm mode 已经内嵌入 Docker 引擎,成为了 docker 子命令 docker swarm,绝大多数用户已经开始使用 Swarm mode,Docker 引擎 API 已经删除 Docker Swarm。Swarm mode 内置 kv 存储功能,提供了众多的新特性,比如:具有容错能力的去中心化设计、内置服务发现、负载均衡、路由网格、动态伸缩、滚动更新、安全传输等。使得 Docker 原生的 Swarm 集群具备与 Mesos、Kubernetes 竞争的实力。

基本概念

节点

运行 Docker 的主机可以主动初始化一个 Swarm 集群或者加入一个已存在的 Swarm 集群,这样这个运行 Docker 的主机就成为一个 Swarm 集群的节点 (node) 。

节点分为管理 (manager) 节点和工作 (worker) 节点。

管理节点用于 Swarm 集群的管理,docker swarm 命令基本只能在管理节点执行(节点退出集群命令 docker swarm leave 可以在工作节点执行)。一个 Swarm 集群可以有多个管理节点,但只有一个管理节点可以成为 leader,leader 通过 raft 协议实现。

工作节点是任务执行节点,管理节点将服务 (service) 下发至工作节点执行。管理节点默认也作为工作节点。你也可以通过配置让服务只运行在管理节点。

服务和任务

任务 (Task)是 Swarm 中的最小的调度单位,目前来说就是一个单一的容器。

服务 (Services) 是指一组任务的集合,服务定义了任务的属性。服务有两种模式:

1
2
3
replicated services 按照一定规则在各个工作节点上运行指定个数的任务。
global services 每个工作节点上运行一个任务
两种模式通过 docker service create 的 --mode 参数指定。

创建 Swarm 集群

创建好docker主机后,在管理主机上初始化集群。

1
2
3
4
5
6
7
8
9
10
11
12
$ docker-machine ssh manager #进入该docker主机

docker@manager:~$ docker swarm init --advertise-addr 192.168.99.100
Swarm initialized: current node (dxn1zf6l61qsb1josjja83ngz) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join \
--token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
192.168.99.100:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

增加工作节点

创建主机

$ docker-machine create -d virtualbox worker1

进入虚拟主机 worker1

$ docker-machine ssh worker1

1
2
3
4
5
6
7
$ docker-machine ssh worker1

docker@worker1:~$ docker swarm join \
--token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
192.168.99.100:2377

This node joined a swarm as a worker.

查看集群

经过上边的两步,我们已经拥有了一个最小的 Swarm 集群,包含一个管理节点和两个工作节点。

在管理节点使用 docker node ls 查看集群。

$ docker node ls

命令 docker info 可以查看 swarm 集群状态

部署服务

新建服务

进入集群管理节点:

docker-machine ssh manager1

使用 docker 中国镜像:docker pull registry.docker-cn.com/….

在Swarm 集群中运行一个名为 nginx 服务。

$ docker service create –replicas 3 -p 80:80 –name nginx nginx:1.13.7-alpine ping baidu.com

现在我们使用浏览器,输入任意节点 IP ,即可看到 nginx 默认页面。

命令解释

1
2
3
4
docker service create 命令创建一个服务
--name 服务名称命名为 nginx
--replicas 设置启动的示例数
alpine指的是使用的镜像名称,ping 指的是容器运行的bash

查看服务

使用 docker service ls 来查看当前 Swarm 集群运行的服务。

1
2
3
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
kc57xffvhul5 nginx replicated 3/3 nginx:1.13.7-alpine *:80->80/tcp

使用 docker service ps 来查看某个服务的详情。

1
2
3
4
5
$ docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
pjfzd39buzlt nginx.1 nginx:1.13.7-alpine swarm2 Running Running about a minute ago
hy9eeivdxlaa nginx.2 nginx:1.13.7-alpine swarm1 Running Running about a minute ago
36wmpiv7gmfo nginx.3 nginx:1.13.7-alpine swarm3 Running Running about a minute ago

使用 docker service logs 来查看某个服务的日志。

1
2
3
4
5
6
7
$ docker service logs nginx
nginx.3.36wmpiv7gmfo@swarm3 | 10.255.0.4 - - [25/Nov/2017:02:10:30 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:58.0) Gecko/20100101 Firefox/58.0" "-"
nginx.3.36wmpiv7gmfo@swarm3 | 10.255.0.4 - - [25/Nov/2017:02:10:30 +0000] "GET /favicon.ico HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:58.0) Gecko/20100101 Firefox/58.0" "-"
nginx.3.36wmpiv7gmfo@swarm3 | 2017/11/25 02:10:30 [error] 5#5: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 10.255.0.4, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.99.102"
nginx.1.pjfzd39buzlt@swarm2 | 10.255.0.2 - - [25/Nov/2017:02:10:26 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:58.0) Gecko/20100101 Firefox/58.0" "-"
nginx.1.pjfzd39buzlt@swarm2 | 10.255.0.2 - - [25/Nov/2017:02:10:27 +0000] "GET /favicon.ico HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:58.0) Gecko/20100101 Firefox/58.0" "-"
nginx.1.pjfzd39buzlt@swarm2 | 2017/11/25 02:10:27 [error] 5#5: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 10.255.0.2, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.99.101"

删除服务

使用 docker service rm 来从 Swarm 集群移除某个服务。

$ docker service rm nginx

查看加入集群manager管理节点的命令

1
2
3
4
5
6
7
8
9
10
11
#docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3sp9uxzokgr252u1jauoowv74930s7f8f5tsmm5mlk5oim359e-7tdlpdnkyfl1bnq34ftik9wxw 192.168.139.175:2377

查看加入集群worker节点的命令

# docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3sp9uxzokgr252u1jauoowv74930s7f8f5tsmm5mlk5oim359e-dk52k5uul50w49gbq4j1y7zzb 192.168.139.175:2377
```
### 查docker swarm的管理网络

#docker network ls
NETWORK ID NAME DRIVER SCOPE
05efca714d2f bridge bridge local
c9cd9c37edd7 docker_gwbridge bridge local
10ac9e48d81b host host local
n60tdenc5jy7 ingress overlay swarm
a9284277dc18 none null local

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
## 服务伸缩
我们可以使用 docker service scale 对一个服务运行的容器数量进行伸缩。当业务处于高峰期时,我们需要扩展服务运行的容器数量。

$ docker service scale nginx=5

当业务平稳时,我们需要减少服务运行的容器数量。

$ docker service scale nginx=2

调整实例个数 调整 nginx 的服务实例数为2个

docker service update --replicas 2 nginx

## 监控集群状态

登录管理节点 manager1:docker-machine ssh manager1

运行 docker service inspect --pretty <SERVICE-ID> 查询服务概要状态,以 nginx 服务为例:

docker@manager1:~$ docker service inspect –pretty nginx

1
2
3
4
### 查询服务详细信息
docker service inspect nginx
### 查看那个节点正在运行服务
运行docker service ps <SERVICE-ID>

docker@manager1:~$ docker service ps helloworld

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
### 在工作节点查看任务的执行情况
首先进入docker-machine ssh worker1

再在节点执行docker ps 查看容器的运行状态。

### 查看容器的运行状态
docker@worker1:~$ docker ps


这样的话,我们在 Swarm 集群中成功的运行了一个 helloworld 服务,根据命令可以看出在 worker1 节点上运行。


### 退出 Swarm 集群

如果 Manager 想要退出 Swarm 集群, 在 Manager Node 上执行如下命令:

docker swarm leave

就可以退出集群,如果集群中还存在其它的 Worker Node,还希望 Manager 退出集群,则加上一个强制选项,命令行如下所示:

docker swarm leave --force

在 Worker2 上进行退出测试,登录 worker2 节点

docker-machine ssh worker2

执行退出命令

docker swarm leave

重新搭建命令,使用 VirtualBox 做测试的时候,如果想重复实验可以将实验节点删掉再重来。

#停止虚拟机
docker-machine stop [arg…] #一个或多个虚拟机名称

docker-machine stop manager1 worker1 worker2
#移除虚拟机
docker-machine rm [OPTIONS] [arg…]

docker-machine rm manager1 worker1 worker2
停止、删除虚拟主机后,再重新创建即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14

排空节点上的集群容器 。
docker node update --availability drain g36lvv23ypjd8v7ovlst2n3yt

主动离开集群,让节点处于down状态,才能删除
docker swarm leave

删除指定节点 (管理节点上操作)
docker node rm g36lvv23ypjd8v7ovlst2n3yt

管理节点,解散集群
docker swarm leave --force

解散集群步骤:

[root@server2 ~]# docker swarm leave #server2对应的node节点离开集群
[root@server3 ~]# docker swarm leave #server3对应的node节点离开集群
[root@server1 ~]# docker swarm leave –force #必须使用参数–force,强制离开集群,否则会报错
[root@server1 ~]# docker node ls #此时再次查看集群的节点,会报错。这是因为i集群已经散了,该节点不再是manager节点,而只有manager节点才能查看集群的节点。

1
2
3

# Portainer
使用Portainer管理集群

#docker service create
–name portainer
–publish 9000:9000
–constraint ‘node.role == manager’
–mount type=bind,src=//var/run/docker.sock,dst=/var/run/docker.sock
portainer/portainer
-H unix:///var/run/docker.sock
#docker images |grep portainer
portainer/portainer latest 07cde96d4789 2 weeks ago 10.4MB

#docker service ls ###查看集群列表
ID NAME MODE REPLICAS IMAGE PORTS
p5bo3n0fmqgz portainer replicated 1/1 portainer/portainer:latest *:9000->9000/tcp

这就部署好了  浏览器输入http://localhost:9000