docker_practice/swarm/filter.md

84 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

## Swarm 过滤器
swarm的调度器(scheduler)在选择节点运行containers的时候支持几种过滤器 (filter)Constraint,Affinity,Port,Dependency,Health
这些选项可以在执行swarm manage命令的时候通过--filter选项来设置。
###Constraint Filter
constraint 是一个跟具体节点相关联的键值对可以看做是每个节点的标签这个标签可以在启动docker daemon的时候指定比如
<pre><code>
sudo docker -d --label label_name=label01
</code></pre>
也可以写在docker的配置文件里面在ubuntu上面是/etc/default/docker
在本次试验中给083添加标签--label label_name=083,084添加标签--label label_name=084,124添加标签--label label_name=084,
以083为例打开/etc/default/docker文件修改DOCKER_OPTS
<pre><code>
DOCKER_OPTS="-H 0.0.0.0:2375 -H unix:///var/run/docker.sock --label label_name=083"
</code></pre>
在使用docker run命令启动container的时候使用 -e constarint:key=value的形式可以指定container运行的节点,比如我们想在84上面启动一个redis container
<pre><code>
rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_1 -d -e constraint:label_name==084 redis
fee1b7b9dde13d64690344c1f1a4c3f5556835be46b41b969e4090a083a6382d
</code></pre>
主要,是**两个**等号,不是一个等号,这一点会经常被忽略。
接下来再在084这台机器上启动一个redis container
<pre><code>
rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_2 -d -e constraint:label_name==084 redis 4968d617d9cd122fc2e17b3bad2f2c3b5812c0f6f51898024a96c4839fa000e1
</code></pre>
然后再在083这台机器上启动另外一个redis container
<pre><code>
rio@085:~$ sudo docker -H 192.168.1.83:2376 run --name redis_3 -d -e constraint:label_name==083 redis 7786300b8d2232c2335ac6161c715de23f9179d30eb5c7e9c4f920a4f1d39570
</code></pre>
现在来看下执行情况:
<pre><code>
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
</code></pre>
可以看到,执行结果跟预期的一样。
但是如果指定一个不存在的标签的话来运行container会报错。
<pre><code>
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
</code></pre>
###Affinity Filter
通过使用Affinity Filter可以让一个container紧挨着另一个container启动也就是说让两个container在同一个节点上面启动。
现在其中一台机器上面启动一个redis
<pre><code>
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
</code></pre>
然后再次启动两台redis
<pre><code>
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
</code></pre>
现在来查看下运行结果,可以看到三个container都是在一台机器上运行
<pre><code>
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
</code></pre>
通过-e affinity:image=image_name命令可以指定只有已经下载了image_name的机器才运行容器
<pre><code>
sudo docker H 192.168.1.83:2376 run name redis1 d e affinity:image==redis redis
</code></pre>
redis1这个container只会在已经下载了redis镜像的节点上运行。
<pre><code>
sudo docker -H 192.168.1.83:2376 run -d --name redis -e affinity:image==~redis redis
</code></pre>
这条命令达到的效果是在有redis镜像的节点上面启动一个名字叫做redis的容器如果每个节点上面都没有redis容器就按照默认的策略启动redis容器。
###Port Filter
Port也会被认为是一个唯一的资源
<pre><code>
sudo docker -H 192.168.1.83:2376 run -d -p 80:80 nginx
</code></pre>
执行完这条命令之后任何使用80端口的容器都是启动失败。