Update swarm and mesos chapter

This commit is contained in:
Baohua Yang
2017-05-02 23:17:58 +08:00
parent 2568854736
commit 5786333a3b
25 changed files with 1234 additions and 553 deletions

View File

@@ -1,100 +1,108 @@
## Swarm 过滤器
swarm 的调度器(scheduler)在选择节点运行容器的时候支持几种过滤器 (filter)Constraint,Affinity,Port,Dependency,Health
## Swarm 中的过滤器
可以在执行 `swarm manage` 命令的时候通过 `--filter` 选项来设置
Swarm 的调度器可以按照指定调度策略自动分配容器到节点。但有些时候希望能对这些分配加以干预。比如说,让 IO 敏感的容器分配到安装了 SSD 的节点上;让计算敏感的容器分配到 CPU 核数多的机器上;让网络敏感的容器分配到高带宽的机房;让某些容器尽量放同一个节点……
###Constraint Filter
constraint 是一个跟具体节点相关联的键值对可以看做是每个节点的标签这个标签可以在启动docker daemon的时候指定比如
```bash
sudo docker -d --label label_name=label01
这可以通过过滤器filter来实现目前支持 `Constraint``Affinity``Port``Dependency``Health` 等五种过滤器。
### Constraint 过滤器
Constraint 过滤器是绑定到节点的键值对,相当于给节点添加标签。
可在启动 Docker 服务的时候指定,例如指定某个节点颜色为 `red`
```sh
$ sudo docker daemon --label color=red -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
```
可以写在docker的配置文件里面在ubuntu上面`/etc/default/docker`)。
同样的,可以写在 Docker 服务的配置文件里面(以 Ubuntu 14.04 为例,`/etc/default/docker`)。
在本次试验中给083添加标签--label label_name=083,084添加标签--label label_name=084,124添加标签--label label_name=124,
以083为例打开/etc/default/docker文件修改DOCKER_OPTS
```bash
DOCKER_OPTS="-H 0.0.0.0:2375 -H unix:///var/run/docker.sock --label label_name=083"
```sh
DOCKER_OPTS="--label color=red -H 0.0.0.0:2375 -H unix:///var/run/docker.sock"
```
使用docker run命令启动容器的时候使`-e constarint:key=value` 的形式,可以指定container运行的节点。
使用 Swarm 启动容器的时候,采`-e constarint:key=value` 的形式,可以过滤选择出匹配条件的节点。
比如我们想在84上面启动一个 redis 容器
```bash
rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_1 -d -e constraint:label_name==084 redis
fee1b7b9dde13d64690344c1f1a4c3f5556835be46b41b969e4090a083a6382d
```
注意,是**两个**等号,不是一个等号,这一点会经常被忽略。
例如,我们将 `192.168.0.2` 节点打上红色标签,`192.168.0.3` 节点打上绿色标签
接下来再在084这台机器上启动一个redis 容器
```bash
rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_2 -d -e constraint:label_name==084 redis 4968d617d9cd122fc2e17b3bad2f2c3b5812c0f6f51898024a96c4839fa000e1
```
然后再在083这台机器上启动另外一个 redis 容器。
```bash
rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_3 -d -e constraint:label_name==083 redis 7786300b8d2232c2335ac6161c715de23f9179d30eb5c7e9c4f920a4f1d39570
然后,分别启动两个容器,指定使用过滤器分别为红色和绿色
```sh
$ docker -H 192.168.0.2:12375 run -d -e constraint:color==red ubuntu:14.04 ping 127.0.0.1
252ffb48e64e9858c72241f5eedf6a3e4571b1ad926faf091db3e26672370f64
$ docker -H 192.168.0.2:12375 run -d -e constraint:color==green ubuntu:14.04 ping 127.0.0.1
3d6f8d7af8583416b17061d038545240c9e5c3be7067935d3ef2fbddce4b8136
```
现在来看下执行情况:
```bash
rio@085:~$ sudo docker -H 192.168.1.83:2376 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7786300b8d22 redis:latest "/entrypoint.sh redi 15 minutes ago Up 53 seconds 6379/tcp 083/redis_3
4968d617d9cd redis:latest "/entrypoint.sh redi 16 minutes ago Up 2 minutes 6379/tcp 084/redis_2
fee1b7b9dde1 redis:latest "/entrypoint.sh redi 19 minutes ago Up 5 minutes 6379/tcp 084/redis_1
*注:指定标签中间是两个等号*
查看它们将被分配到指定节点上。
```sh
$ docker -H 192.168.0.2:12375 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
252ffb48e64e ubuntu:14.04 "ping 127.0.0.1" 1 minutes ago Up 1 minutes Host-2/sick_galileo
3d6f8d7af858 ubuntu:14.04 "ping 127.0.0.1" 2 minutes ago Up 2 minutes Host-3/compassionate_ritchie
```
可以看到,执行结果跟预期的一样
另外Docker 内置了一些常见的过滤器,包括 `node``storagedriver``executiondriver``kernelversion``operatingsystem` 等。这些值可以通过 `docker info` 命令查看
但是如果指定一个不存在的标签的话来运行容器会报错。
```bash
rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_0 -d -e constraint:label_name==0 redis
FATA[0000] Error response from daemon: unable to find a node that satisfies label_name==0
例如,目前集群中各个节点的信息为:
```sh
$ docker -H 192.168.0.2:12375 info
Containers: 5
Images: 39
Role: primary
Strategy: spread
Filters: health, port, dependency, affinity, constraint
Nodes: 2
Host-2: 192.168.0.2:2375
└ Containers: 4
└ Reserved CPUs: 0 / 4
└ Reserved Memory: 1 GiB / 4.053 GiB
└ Labels: color=red, executiondriver=native-0.2, kernelversion=3.16.0-43-generic, operatingsystem=Ubuntu 14.04.3 LTS, storagedriver=aufs
Host-3: 192.168.0.3:2375
└ Containers: 1
└ Reserved CPUs: 0 / 8
└ Reserved Memory: 0 B / 16.46 GiB
└ Labels: color=green, 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: 946d65606f7c
```
###Affinity Filter
通过使用 Affinity Filter可以让一个容器紧挨着另一个容器启动也就是说让两个容器在同一个节点上面启动
### Affinity 过滤器
Affinity 过滤器允许用户在启动一个容器的时候,让它分配到某个已有容器的节点上
例如,下面我们将启动一个 nginx 容器,让它分配到已经运行某个 ubuntu 容器的节点上。
在 Constraint 过滤器的示例中,我们分别启动了两个 ubuntu 容器 `sick_galileo``compassionate_ritchie`,分别在 Host-2 和 Host-3 上。
现在其中一台机器上面启动一个 redis 容器
```bash
rio@085:~$ sudo docker -H 192.168.1.83:2376 run -d --name redis redis
ea13eddf667992c5d8296557d3c282dd8484bd262c81e2b5af061cdd6c82158d
rio@085:~$ sudo docker -H 192.168.1.83:2376 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea13eddf6679 redis:latest /entrypoint.sh redis 24 minutes ago Up Less than a second 6379/tcp 083/redis
现在启动一个 nginx 容器,让它跟容器 `sick_galileo` 放在一起,都放到 Host-2 节点上。可以通过 `-e affinity:container==<name or id>` 参数来实现
```sh
$ docker -H 192.168.0.2:12375 run -d -e affinity:container==sick_galileo nginx
```
然后再次启动个 redis 容器。
```bash
rio@085:~$ sudo docker -H 192.168.1.83:2376 run -d --name redis_1 -e affinity:container==redis redis
bac50c2e955211047a745008fd1086eaa16d7ae4f33c192f50412e8dcd0a14cd
rio@085:~$ sudo docker -H 192.168.1.83:2376 run -d --name redis_1 -e affinity:container==redis redis
bac50c2e955211047a745008fd1086eaa16d7ae4f33c192f50412e8dcd0a14cd
```
现在来查看下运行结果,可以看到三个容器都是在一台机器上运行
```bash
rio@085:~$ sudo docker -H 192.168.1.83:2376 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
449ed25ad239 redis:latest /entrypoint.sh redis 24 minutes ago Up Less than a second 6379/tcp 083/redis_2
bac50c2e9552 redis:latest /entrypoint.sh redis 25 minutes ago Up 10 seconds 6379/tcp 083/redis_1
ea13eddf6679 redis:latest /entrypoint.sh redis 28 minutes ago Up 3 minutes 6379/tcp 083/redis
```
通过 `-e affinity:image=image_name` 命令可以指定只有已经下载了`image_name`镜像的机器才运行容器
```bash
sudo docker H 192.168.1.83:2376 run name redis1 d e affinity:image==redis redis
```
redis1 这个容器只会在已经下载了 redis 镜像的节点上运行。
然后启动个 redis 容器,让它跟容器 `compassionate_ritchie` 放在一起,都放到 Host-3 节点上
```bash
sudo docker -H 192.168.1.83:2376 run -d --name redis -e affinity:image==~redis redis
```
这条命令达到的效果是:在有 redis 镜像的节点上面启动一个名字叫做 redis 的容器,如果每个节点上面都没有 redis 容器,就按照默认的策略启动 redis 容器。
###Port Filter
Port 也会被认为是一个唯一的资源
```bash
sudo docker -H 192.168.1.83:2376 run -d -p 80:80 nginx
```sh
$ docker -H 192.168.0.2:12375 run -d -e affinity:container==compassionate_ritchie redis
```
执行完这条命令,之后任何使用 80 端口的容器都是启动失败。
查看所有容器运行情况。
```sh
$ docker -H 192.168.0.2:12375 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0a32f15aa8ee redis "/entrypoint.sh redis" 2 seconds ago Up 1 seconds 6379/tcp Host-3/awesome_darwin
d2b9a53e67d5 nginx "nginx -g 'daemon off" 29 seconds ago Up 28 seconds 80/tcp, 443/tcp Host-2/fervent_wilson
252ffb48e64e ubuntu:14.04 "ping 127.0.0.1" 2 minutes ago Up 2 minutes Host-2/sick_galileo
3d6f8d7af858 ubuntu:14.04 "ping 127.0.0.1" 3 minutes ago Up 3 minutes Host-3/compassionate_ritchie
```
### 其它过滤器
其它过滤器的使用方法也是大同小异,例如通过 `-e affinity:image==<name or id>` 来选择拥有指定镜像的节点;通过 `-e affinity:label_name==value` 来选择拥有指定标签的容器所允许的节点。
此外当容器端口需要映射到宿主机指定端口号的时候Swarm 也会自动分配容器到指定宿主机端口可用的节点。
当不同容器之间存在数据卷或链接依赖的时候Swarm 会分配这些容器到同一个节点上。