mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-03-25 03:05:32 +00:00
Update swarm and mesos chapter
This commit is contained in:
297
swarm/usage.md
297
swarm/usage.md
@@ -1,170 +1,181 @@
|
||||
## 使用
|
||||
在使用 swarm 管理集群前,需要把集群中所有的节点的 docker daemon 的监听方式更改为 `0.0.0.0:2375`。
|
||||
## 使用 Swarm
|
||||
前面演示了基于 consel 服务发现后端来配置一个本地 Swarm 集群。其中,consel 也可以被替换为 etcd、zookeeper 等。
|
||||
|
||||
可以有两种方式达到这个目的,第一种是在启动docker daemon的时候指定
|
||||
```bash
|
||||
sudo docker -H 0.0.0.0:2375&
|
||||
另外一个更方便的方式是直接使用 DockerHub 提供的免费服务发现后端。
|
||||
|
||||
下面使用这种方式来演示 Swarm 的主要操作,包括:
|
||||
|
||||
* create:创建一个集群;
|
||||
* list:列出集群中的节点;
|
||||
* manage:管理一个集群;
|
||||
* join:让节点加入到某个集群。
|
||||
|
||||
注意,使用 DockerHub 的服务发现后端,需要各个节点能通过公网访问到 DockerHub 的服务接口。
|
||||
|
||||
### 创建集群 id
|
||||
|
||||
在任意一台安装了 Swarm 的机器上执行 `swarm create` 命令来在 DockerHub 服务上进行注册。
|
||||
|
||||
Swarm 会通过服务发现后端(此处为 DockerHub 提供)来获取一个唯一的由数字和字母组成的 token,用来标识要管理的集群。
|
||||
|
||||
```sh
|
||||
$ docker run --rm swarm create
|
||||
946d65606f7c2f49766e4dddac5b4365
|
||||
```
|
||||
|
||||
第二种方式是直接修改 Docker 的配置文件(Ubuntu 上是 `/etc/default/docker`,其他版本的 Linux 上略有不同)
|
||||
注意返回的字符串,这是集群的唯一 id,加入集群的各个节点将需要这个信息。
|
||||
|
||||
在文件的最后添加下面这句代码:
|
||||
```bash
|
||||
DOCKER_OPTS="-H 0.0.0.0:2375 -H unix:///var/run/docker.sock"
|
||||
### 配置集群节点
|
||||
|
||||
在所有要加入集群的普通节点上面执行 `swarm join` 命令,表示把这台机器加入指定集群当中。
|
||||
|
||||
例如某台机器 IP 地址为 `192.168.0.2`,将其加入我们刚创建的 `946d65606f7c2f49766e4dddac5b4365` 集群,则可以通过:
|
||||
|
||||
```sh
|
||||
$ docker run --rm swarm join --addr=192.168.0.2:2375 token://946d65606f7c2f49766e4dddac5b4365
|
||||
time="2015-12-09T08:59:43Z" level=info msg="Registering on the discovery service every 20s..." addr="192.168.0.2:2375" discovery="token://946d65606f7c2f49766e4dddac5b4365"
|
||||
...
|
||||
```
|
||||
|
||||
*注:其中 `--addr` 指定的 IP 地址信息将被发送给服务发现后端,用以区分集群不同的节点。manager 服务必须要通过这个地址可以访问到该节点。*
|
||||
|
||||
需要注意的是,一定要在所有希望被 Swarm 管理的节点上进行的。修改之后要重启 Docker
|
||||
```bash
|
||||
sudo service docker restart
|
||||
通过控制台可以看到,上述命令执行后,默认每隔 20 秒(可以通过 `--heartbeat` 选项指定),会输出一条心跳信息。对于发现服务后端来说,默认如果超过 60 秒(可以通过 `--ttl` 选项指定)没有收到心跳信息,则将节点从列表中删除。
|
||||
|
||||
如果不希望看到输出日志信息,则可以用 `-d` 选项替换 `--rm` 选项,让服务后台执行。
|
||||
|
||||
执行 `swarm join` 命令实际上是通过 agent 把自己的信息注册到发现服务上,因此,此时对于后端的发现服务来说,已经可以看到有若干节点注册上来了。那么,如何管理和使用这些节点呢,这就得需要 Swarm 的 manager 服务了。
|
||||
|
||||
|
||||
### 配置管理节点
|
||||
配置管理节点需要通过 `swarm manage` 命令,该命令将启动 manager 服务,默认监听到 `2375` 端口,所有对集群的管理可以通过该服务接口进行。
|
||||
|
||||
读者可能注意到,manager 服务默认监听的端口跟 Docker 服务监听端口是一样的,这是为了兼容其它基于 Docker 的服务,可以无缝地切换到 Swarm 平台上来。
|
||||
|
||||
仍然在节点 `192.168.0.2` 进行操作。由于我们是采用 Docker 容器形式启动 manager 服务,本地的 `2375` 端口已经被 Docker Daemon 占用。我们将 manager 服务监听端口映射到本地一个空闲的 `12375` 端口。
|
||||
|
||||
```sh
|
||||
$ docker run -d -p 12375:2375 swarm manage token://946d65606f7c2f49766e4dddac5b4365
|
||||
1e1ca8c4117b6b7271efc693f9685b4e907d8dc95324350392b21e94b3cffd18
|
||||
```
|
||||
|
||||
Docker 集群管理需要使用服务发现(Discovery service backend)功能,Swarm支持以下的几种方式:DockerHub 提供的服务发现功能,本地的文件,etcd,consul,zookeeper 和 IP 列表,本文会详细讲解前两种方式,其他的用法都是大同小异的。
|
||||
可以通过 `docker ps` 命令来查看启动的 swarm manager 服务容器。
|
||||
|
||||
先说一下本次试验的环境,本次试验包括三台机器,IP地址分别为192.168.1.84,192.168.1.83和192.168.1.124.利用这三台机器组成一个docker集群,其中83这台机器同时充当swarm manager节点。
|
||||
|
||||
### 使用 DockerHub 提供的服务发现功能
|
||||
|
||||
#### 创建集群 token
|
||||
|
||||
在上面三台机器中的任何一台机器上面执行 `swarm create` 命令来获取一个集群标志。这条命令执行完毕后,Swarm 会前往 DockerHub 上内置的发现服务中获取一个全球唯一的 token,用来标识要管理的集群。
|
||||
```bash
|
||||
sudo docker run --rm swarm create
|
||||
```sh
|
||||
$ docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
1e1ca8c4117b swarm "/swarm manage token:" 11 seconds ago Up 10 seconds 0.0.0.0:12375->2375/tcp jovial_rosalind
|
||||
```
|
||||
|
||||
我们在84这台机器上执行这条命令,输出如下:
|
||||
```bash
|
||||
rio@084:~$ sudo docker run --rm swarm create
|
||||
b7625e5a7a2dc7f8c4faacf2b510078e
|
||||
命令如果执行成功会返回刚启动的 Swarm 容器的 ID,此时一个简单的 Swarm 集群就已经搭建起来了,包括一个普通节点和一个管理节点。
|
||||
|
||||
### 查看集群节点列表
|
||||
|
||||
集群启动成功以后,用户可以在任何一台节点上使用 `swarm list` 命令查看集群中的节点列表。例如
|
||||
|
||||
```sh
|
||||
$ docker run --rm swarm list token://946d65606f7c2f49766e4dddac5b4365
|
||||
192.168.0.2:2375
|
||||
```
|
||||
显示正是之前用 `swarm join` 命令加入集群的节点的地址。
|
||||
|
||||
我们在另外一台节点 `192.168.0.3` 上同样使用 `swarm join` 命令新加入一个节点:
|
||||
```sh
|
||||
$docker run --rm swarm join --addr=192.168.0.3:2375 token://946d65606f7c2f49766e4dddac5b4365
|
||||
time="2015-12-10T02:05:34Z" level=info msg="Registering on the discovery service every 20s..." addr="192.168.0.3:2375" discovery="token://946d65606f7c2f49766e4dddac5b4365"
|
||||
...
|
||||
```
|
||||
|
||||
可以看到我们返回的 token 是 `b7625e5a7a2dc7f8c4faacf2b510078e`,每次返回的结果都是不一样的。这个 token 一定要记住,后面的操作都会用到这个 token。
|
||||
再次使用 `swarm list` 命令查看集群中的节点列表信息,可以看到新加入的节点:
|
||||
|
||||
#### 加入集群
|
||||
|
||||
在所有要加入集群的节点上面执行 `swarm join` 命令,表示要把这台机器加入这个集群当中。在本次试验中,就是要在 83、84 和 124 这三台机器上执行下面的这条命令:
|
||||
```bash
|
||||
sudo docker run -d swarm join --addr=ip_address:2375 token://token_id
|
||||
```sh
|
||||
$ docker run --rm swarm list token://946d65606f7c2f49766e4dddac5b4365
|
||||
192.168.0.3:2375
|
||||
192.168.0.2:2375
|
||||
```
|
||||
其中的 ip_address 换成执行这条命令的机器的 IP,token_id 换成上一步执行 `swarm create` 返回的 token。
|
||||
|
||||
在83这台机器上面的执行结果如下:
|
||||
```bash
|
||||
rio@083:~$ sudo docker run -d swarm join --addr=192.168.1.83:2375 token://b7625e5a7a2dc7f8c4faacf2b510078e
|
||||
3b3d9da603d7c121588f796eab723458af5938606282787fcbb03b6f1ac2000b
|
||||
### 使用集群服务
|
||||
那么,怎么使用 Swarm 提供的服务呢?
|
||||
|
||||
实际上,所有 Docker 客户端可以继续使用,只要指定使用 Swarm manager 服务的监听地址即可。
|
||||
|
||||
例如,manager 服务监听的地址为 `192.168.0.2:12375`,则可以通过指定 `-H 192.168.0.2:12375` 选项来继续使用 Docker 客户端,执行任意 Docker 命令,例如 `ps`、`info`、`run` 等等。
|
||||
|
||||
在任意节点上使用 `docker run` 来启动若干容器,例如
|
||||
|
||||
```sh
|
||||
$docker -H 192.168.0.2:12375:12375 run -d ubuntu ping 127.0.0.1
|
||||
4c9bccbf86fb6e2243da58c1b15e9378fac362783a663426bbe7058eea84de46
|
||||
```
|
||||
这条命令通过 `-d` 参数启动了一个容器,使得83这台机器加入到集群。如果这个容器被停止或者被删除,83这台机器就会从集群中消失。
|
||||
|
||||
#### 启动swarm manager
|
||||
因为我们要使用 83 这台机器充当 swarm 管理节点,所以需要在83这台机器上面执行 `swarm manage` 命令:
|
||||
```bash
|
||||
sudo docker run -d -p 2376:2375 swarm manage token://b7625e5a7a2dc7f8c4faacf2b510078e
|
||||
使用 `ps` 命令查看集群中正在运行的容器。
|
||||
|
||||
```sh
|
||||
$ docker -H 192.168.0.2:12375 ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
4c9bccbf86fb ubuntu "ping 127.0.0.1" About a minute ago Up About a minute clever_wright
|
||||
730061a3801a registry:latest "docker-registry" 2 minutes ago Up 2 minutes 192.168.0.2:5000->5000/tcp Host-1/registry_registry_1
|
||||
72d99f24a06f redis:3.0 "/entrypoint.sh redis" 2 minutes ago Up 2 minutes 6379/tcp Host-1/registry_redis_1,Host-1/registry_registry_1/redis,Host-1/registry_registry_1/redis_1,Host-1/registry_registry_1/registry_redis_1
|
||||
```
|
||||
执行结果如下:
|
||||
```bash
|
||||
rio@083:~$ sudo docker run -d -p 2376:2375 swarm manage token://b7625e5a7a2dc7f8c4faacf2b510078e
|
||||
83de3e9149b7a0ef49916d1dbe073e44e8c31c2fcbe98d962a4f85380ef25f76
|
||||
```
|
||||
这条命令如果执行成功会返回已经启动的 Swarm 的容器的 ID,此时整个集群已经启动起来了。
|
||||
|
||||
现在通过 `docker ps` 命令来看下有没有启动成功。
|
||||
```bash
|
||||
rio@083:~$ sudo docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
83de3e9149b7 swarm:latest "/swarm manage token 4 minutes ago Up 4 minutes 0.0.0.0:2376->2375/tcp stupefied_stallman
|
||||
```
|
||||
可以看到,Swarm 已经成功启动。
|
||||
在执行 `Swarm manage` 这条命令的时候,有几点需要注意的:
|
||||
输出结果中显示目前集群中正在运行的容器(注意不包括 Swarm manager 服务容器),可以在不同节点上使用 `docker ps` 查看本地容器,发现这些容器实际上可能运行在集群中多个节点上(被 Swarm 调度策略进行分配)。
|
||||
|
||||
* 这条命令需要在充当 swarm 管理者的机器上执行
|
||||
* Swarm 要以 daemon 的形式执行
|
||||
* 映射的端口可以使任意的除了 2375 以外的并且是未被占用的端口,但一定不能是 2375 这个端口,因为 2375 已经被 Docker 本身给占用了。
|
||||
使用 info 查看所有节点的信息。
|
||||
|
||||
集群启动成功以后,现在我们可以在任何一台节点上使用 `swarm list` 命令查看集群中的节点了,本实验在 124 这台机器上执行 `swarm list` 命令:
|
||||
```bash
|
||||
rio@124:~$ sudo docker run --rm swarm list token://b7625e5a7a2dc7f8c4faacf2b510078e
|
||||
192.168.1.84:2375
|
||||
192.168.1.124:2375
|
||||
192.168.1.83:2375
|
||||
```
|
||||
输出结果列出的IP地址正是我们使用 `swarm join` 命令加入集群的机器的IP地址。
|
||||
|
||||
现在我们可以在任何一台安装了 Docker 的机器上面通过命令(命令中要指明swarm manager机器的IP地址)来在集群中运行container了。
|
||||
本次试验,我们在 192.168.1.85 这台机器上使用 `docker info` 命令来查看集群中的节点的信息。
|
||||
|
||||
其中 info 也可以换成其他的 Docker 支持的命令。
|
||||
```bash
|
||||
rio@085:~$ sudo docker -H 192.168.1.83:2376 info
|
||||
Containers: 8
|
||||
```sh
|
||||
$ docker -H 192.168.0.2:12375 info
|
||||
Containers: 18
|
||||
Images: 36
|
||||
Role: primary
|
||||
Strategy: spread
|
||||
Filters: affinity, health, constraint, port, dependency
|
||||
Filters: health, port, dependency, affinity, constraint
|
||||
Nodes: 2
|
||||
sclu083: 192.168.1.83:2375
|
||||
└ Containers: 1
|
||||
└ Reserved CPUs: 0 / 2
|
||||
└ Reserved Memory: 0 B / 4.054 GiB
|
||||
sclu084: 192.168.1.84:2375
|
||||
└ Containers: 7
|
||||
└ Reserved CPUs: 0 / 2
|
||||
└ Reserved Memory: 0 B / 4.053 GiB
|
||||
```
|
||||
结果输出显示这个集群中只有两个节点,IP地址分别是 192.168.1.83 和 192.168.1.84,结果不对呀,我们明明把三台机器加入了这个集群,还有 124 这一台机器呢?
|
||||
经过排查,发现是忘了修改 124 这台机器上面改 docker daemon 的监听方式,只要按照上面的步骤修改写 docker daemon 的监听方式就可以了。
|
||||
|
||||
在使用这个方法的时候,使用swarm create可能会因为网络的原因会出现类似于下面的这个问题:
|
||||
```bash
|
||||
rio@227:~$ sudo docker run --rm swarm create
|
||||
[sudo] password for rio:
|
||||
time="2015-05-19T12:59:26Z" level=fatal msg="Post https://discovery-stage.hub.docker.com/v1/clusters: dial tcp: i/o timeout"
|
||||
```
|
||||
|
||||
### 使用文件
|
||||
|
||||
第二种方法相对于第一种方法要简单得多,也不会出现类似于上面的问题。
|
||||
|
||||
第一步:在 swarm 管理节点上新建一个文件,把要加入集群的机器 IP 地址和端口号写入文件中,本次试验就是要在83这台机器上面操作:
|
||||
```bash
|
||||
rio@083:~$ echo 192.168.1.83:2375 >> cluster
|
||||
rio@083:~$ echo 192.168.1.84:2375 >> cluster
|
||||
rio@083:~$ echo 192.168.1.124:2375 >> cluster
|
||||
rio@083:~$ cat cluster
|
||||
192.168.1.83:2375
|
||||
192.168.1.84:2375
|
||||
192.168.1.124:2375
|
||||
```
|
||||
|
||||
第二步:在083这台机器上面执行 `swarm manage` 这条命令:
|
||||
```bash
|
||||
rio@083:~$ sudo docker run -d -p 2376:2375 -v $(pwd)/cluster:/tmp/cluster swarm manage file:///tmp/cluster
|
||||
364af1f25b776f99927b8ae26ca8db5a6fe8ab8cc1e4629a5a68b48951f598ad
|
||||
```
|
||||
使用`docker ps`来查看有没有启动成功:
|
||||
```bash
|
||||
rio@083:~$ sudo docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
364af1f25b77 swarm:latest "/swarm manage file: About a minute ago Up About a minute 0.0.0.0:2376->2375/tcp happy_euclid
|
||||
```
|
||||
可以看到,此时整个集群已经启动成功。
|
||||
|
||||
在使用这条命令的时候需要注意的是注意:这里一定要使用-v命令,因为cluster文件是在本机上面,启动的容器默认是访问不到的,所以要通过-v命令共享。
|
||||
|
||||
接下来的就可以在任何一台安装了docker的机器上面通过命令使用集群,同样的,在85这台机器上执行docker info命令查看集群的节点信息:
|
||||
```bash
|
||||
rio@s085:~$ sudo docker -H 192.168.1.83:2376 info
|
||||
Containers: 9
|
||||
Strategy: spread
|
||||
Filters: affinity, health, constraint, port, dependency
|
||||
Nodes: 3
|
||||
atsgxxx: 192.168.1.227:2375
|
||||
└ Containers: 0
|
||||
Host-1: 192.168.0.2:2375
|
||||
└ Containers: 15
|
||||
└ Reserved CPUs: 0 / 4
|
||||
└ Reserved Memory: 0 B / 2.052 GiB
|
||||
sclu083: 192.168.1.83:2375
|
||||
└ Containers: 2
|
||||
└ Reserved CPUs: 0 / 2
|
||||
└ Reserved Memory: 0 B / 4.054 GiB
|
||||
sclu084: 192.168.1.84:2375
|
||||
└ Containers: 7
|
||||
└ Reserved CPUs: 0 / 2
|
||||
└ Reserved Memory: 0 B / 4.053 GiB
|
||||
└ Reserved Memory: 1 GiB / 4.053 GiB
|
||||
└ Labels: executiondriver=native-0.2, kernelversion=3.16.0-43-generic, operatingsystem=Ubuntu 14.04.3 LTS, storagedriver=aufs
|
||||
Host-2: 192.168.0.3:2375
|
||||
└ Containers: 3
|
||||
└ Reserved CPUs: 0 / 8
|
||||
└ Reserved Memory: 0 B / 16.46 GiB
|
||||
└ Labels: executiondriver=native-0.2, kernelversion=3.16.0-30-generic, operatingsystem=Ubuntu 14.04.3 LTS, storagedriver=aufs
|
||||
CPUs: 12
|
||||
Total Memory: 20.51 GiB
|
||||
Name: 1e1ca8c4117b
|
||||
```
|
||||
结果输出显示这个集群目前只有两个节点,地址分别是 `192.168.0.2` 和 `192.168.0.3`。
|
||||
|
||||
类似的,也可以通过 Compose 模板来启动多个服务。不过请注意,要想让服务分布到多个 Swarm 节点上,需要采用版本 2 的写法。
|
||||
|
||||
### 使用网络
|
||||
Swarm 为了支持跨主机的网络,默认采用了 `overlay` 网络类型,实现上通过 vxlan 来构建联通整个 Swarm 集群的网络。
|
||||
|
||||
首先,在集群中所有节点上,添加配置 Docker daemon 选项:
|
||||
|
||||
```
|
||||
--cluster-store=<DISCOVERY_HOST:PORT> --cluster-advertise=<DOCKER_DAEMON_HOST:PORT>
|
||||
```
|
||||
|
||||
以 consul 服务为例,可能类似:
|
||||
|
||||
```sh
|
||||
--cluster-store=consul://<consul 服务地址>:8500 --cluster-advertise=192.168.0.3:2375
|
||||
```
|
||||
|
||||
之后重启 Docker 服务。
|
||||
|
||||
首先,创建一个网络。
|
||||
|
||||
```sh
|
||||
$ docker -H 192.168.0.2:12375 network create swarm_network
|
||||
```
|
||||
|
||||
查看网络,将看到一个 overlay 类型的网络。
|
||||
|
||||
```sh
|
||||
$ docker -H 192.168.0.2:12375 network ls
|
||||
NETWORK ID NAME DRIVER
|
||||
6edf2d16ec97 swarm_network overlay
|
||||
```
|
||||
|
||||
此时,所有添加到这个网络上的容器将自动被分配到集群中的节点上,并且彼此联通。
|
||||
Reference in New Issue
Block a user