|
| 1 | +## Swarm 过滤器 |
| 2 | +swarm的调度器(scheduler)在选择节点运行containers的时候支持几种过滤器 (filter):Constraint,Affinity,Port,Dependency,Health |
| 3 | +这些选项可以在执行swarm manage命令的时候通过--filter选项来设置。 |
| 4 | +###Constraint Filter |
| 5 | +constraint 是一个跟具体节点相关联的键值对,可以看做是每个节点的标签,这个标签可以在启动docker daemon的时候指定,比如 |
| 6 | +<pre><code> |
| 7 | +sudo docker -d --label label_name=label01 |
| 8 | +</code></pre> |
| 9 | +也可以写在docker的配置文件里面,在ubuntu上面是/etc/default/docker |
| 10 | +在本次试验中,给083添加标签--label label_name=083,084添加标签--label label_name=084,124添加标签--label label_name=084, |
| 11 | +以083为例,打开/etc/default/docker文件,修改DOCKER_OPTS: |
| 12 | +<pre><code> |
| 13 | +DOCKER_OPTS="-H 0.0.0.0:2375 -H unix:///var/run/docker.sock --label label_name=083" |
| 14 | +</code></pre> |
| 15 | +在使用docker run命令启动container的时候使用 -e constarint:key=value的形式,可以指定container运行的节点,比如我们想在84上面启动一个redis container, |
| 16 | +<pre><code> |
| 17 | +rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_1 -d -e constraint:label_name==084 redis |
| 18 | +fee1b7b9dde13d64690344c1f1a4c3f5556835be46b41b969e4090a083a6382d |
| 19 | +</code></pre> |
| 20 | +主要,是**两个**等号,不是一个等号,这一点会经常被忽略。 |
| 21 | +接下来再在084这台机器上启动一个redis container |
| 22 | +<pre><code> |
| 23 | +rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_2 -d -e constraint:label_name==084 redis 4968d617d9cd122fc2e17b3bad2f2c3b5812c0f6f51898024a96c4839fa000e1 |
| 24 | +</code></pre> |
| 25 | +然后再在083这台机器上启动另外一个redis container |
| 26 | +<pre><code> |
| 27 | +rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_3 -d -e constraint:label_name==083 redis 7786300b8d2232c2335ac6161c715de23f9179d30eb5c7e9c4f920a4f1d39570 |
| 28 | +</code></pre> |
| 29 | +现在来看下执行情况: |
| 30 | +<pre><code> |
| 31 | +rio@085:~$ sudo docker -H 192.168.1.83:2376 ps |
| 32 | +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| 33 | +7786300b8d22 redis:latest "/entrypoint.sh redi 15 minutes ago Up 53 seconds 6379/tcp 083/redis_3 |
| 34 | +4968d617d9cd redis:latest "/entrypoint.sh redi 16 minutes ago Up 2 minutes 6379/tcp 084/redis_2 |
| 35 | +fee1b7b9dde1 redis:latest "/entrypoint.sh redi 19 minutes ago Up 5 minutes 6379/tcp 084/redis_1 |
| 36 | +</code></pre> |
| 37 | +可以看到,执行结果跟预期的一样。 |
| 38 | +但是如果指定一个不存在的标签的话来运行container会报错。 |
| 39 | +<pre><code> |
| 40 | +rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_0 -d -e constraint:label_name==0 redis |
| 41 | +FATA[0000] Error response from daemon: unable to find a node that satisfies label_name==0 |
| 42 | +</code></pre> |
| 43 | + |
| 44 | +###Affinity Filter |
| 45 | +通过使用Affinity Filter,可以让一个container紧挨着另一个container启动,也就是说让两个container在同一个节点上面启动。 |
| 46 | +现在其中一台机器上面启动一个redis |
| 47 | +<pre><code> |
| 48 | +rio@085:~$ sudo docker -H 192.168.1.83:2376 run -d --name redis redis |
| 49 | +ea13eddf667992c5d8296557d3c282dd8484bd262c81e2b5af061cdd6c82158d |
| 50 | +rio@085:~$ sudo docker -H 192.168.1.83:2376 ps |
| 51 | +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| 52 | +ea13eddf6679 redis:latest /entrypoint.sh redis 24 minutes ago Up Less than a second 6379/tcp 083/redis |
| 53 | +</code></pre> |
| 54 | +然后再次启动两台redis |
| 55 | +<pre><code> |
| 56 | +rio@085:~$ sudo docker -H 192.168.1.83:2376 run -d --name redis_1 -e affinity:container==redis redis |
| 57 | +bac50c2e955211047a745008fd1086eaa16d7ae4f33c192f50412e8dcd0a14cd |
| 58 | +rio@085:~$ sudo docker -H 192.168.1.83:2376 run -d --name redis_1 -e affinity:container==redis redis |
| 59 | +bac50c2e955211047a745008fd1086eaa16d7ae4f33c192f50412e8dcd0a14cd |
| 60 | +</code></pre> |
| 61 | +现在来查看下运行结果,可以看到三个container都是在一台机器上运行 |
| 62 | +<pre><code> |
| 63 | +rio@085:~$ sudo docker -H 192.168.1.83:2376 ps |
| 64 | +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| 65 | +449ed25ad239 redis:latest /entrypoint.sh redis 24 minutes ago Up Less than a second 6379/tcp 083/redis_2 |
| 66 | +bac50c2e9552 redis:latest /entrypoint.sh redis 25 minutes ago Up 10 seconds 6379/tcp 083/redis_1 |
| 67 | +ea13eddf6679 redis:latest /entrypoint.sh redis 28 minutes ago Up 3 minutes 6379/tcp 083/redis |
| 68 | +</code></pre> |
| 69 | +通过-e affinity:image=image_name命令可以指定只有已经下载了image_name的机器才运行容器 |
| 70 | +<pre><code> |
| 71 | +sudo docker –H 192.168.1.83:2376 run –name redis1 –d –e affinity:image==redis redis |
| 72 | +</code></pre> |
| 73 | +redis1这个container只会在已经下载了redis镜像的节点上运行。 |
| 74 | +<pre><code> |
| 75 | +sudo docker -H 192.168.1.83:2376 run -d --name redis -e affinity:image==~redis redis |
| 76 | +</code></pre> |
| 77 | +这条命令达到的效果是:在有redis镜像的节点上面启动一个名字叫做redis的容器,如果每个节点上面都没有redis容器,就按照默认的策略启动redis容器。 |
| 78 | +###Port Filter |
| 79 | +Port也会被认为是一个唯一的资源 |
| 80 | +<pre><code> |
| 81 | +sudo docker -H 192.168.1.83:2376 run -d -p 80:80 nginx |
| 82 | +</code></pre> |
| 83 | +执行完这条命令,之后任何使用80端口的容器都是启动失败。 |
0 commit comments