Docker Swarm: 过滤器

过滤器

原文链接:https://docs.docker.com/swarm/scheduler/filter/
中文翻译:https://docs.docker.com/swarm/scheduler/filter/

Docker Swam调度器具有多个过滤器。

当将容器安排在节点的子集(部分)时,可以使用以下过滤器:

    • Constraint(強制)

 

    • Affinity(親密さ)

 

    • Port(ポート)

 

    • Dependency(依存性)

 

    Health(ヘルス)

当您想要使用某种筛选器时,请使用swam manage的–filter标志。

约束筛选器

约束将键值对关联到特定节点。这些约束可以通过节点标签进行查看。

在创建容器时,您可以选择节点的子集。这是为了调度而选择特定节点或者应该与键值对相匹配的节点。

这种方法有几种特定的使用方式:

    • ホスト・プロパティを指定した選択(storage=ssd のように、特定のハードウェアにコンテナをスケジュールするため)

 

    • 物理的な場所をノードの土台とタグ付けする(region=us-ease のように、指定した場所でコンテナを強制的に実行)

 

    論理的なクラスタの分割(environment=production のように、プロパティの違いによりクラスタをサブクラスに分割)

在docker启动选项中,至少需要一个–label指定来对节点进行标记,以特定的键值对方式。

比如,我们启动节点-1时,可以尝试给它加上存储=固态硬盘的标签。

$ docker -d --label storage=ssd
$ swarm join --advertise=192.168.0.42:2375 token://XXXXXXXXXXXXXXXXXX

请再次启动 node-2,但这次使用 storage=disk。

$ docker -d --label storage=disk
$ swarm join --advertise=192.168.0.43:2375 token://XXXXXXXXXXXXXXXXXX

当节点被注册到集群后,主节点会获取每个节点的标签,并在调度新容器时进行相应的反映。

让我们启动MySQL服务器,并将其放在具有良好I/O性能的闪存驱动器上可用:

$ docker run -d -P -e constraint:storage==ssd --name db mysql
f8b693db9cd6

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED                  STATUS              PORTS                           NODE        NAMES
f8b693db9cd6        mysql:latest        "mysqld"            Less than a second ago   running             192.168.0.42:49178->3306/tcp    node-1      db

在这个例子中,主节点会从所有被选中的节点上强制应用事先指定的存储=ssd的资源管理。node-1被选择作为在闪存驱动器上运行的主机。

接下来,我们将尝试在集群上运行 Nginx 前端。但是由于要将日志大量写入磁盘,我们不想使用闪存驱动器。

$ docker run -d -P -e constraint:storage==disk --name frontend nginx
963841b138d8

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED                  STATUS              PORTS                           NODE        NAMES
963841b138d8        nginx:latest        "nginx"             Less than a second ago   running             192.168.0.43:49177->80/tcp      node-2      frontend
f8b693db9cd6        mysql:latest        "mysqld"            Up About a minute        running             192.168.0.42:49178->3306/tcp    node-1      db

调度器将在已启动的node-2上附加磁盘存储(storage=disk)并启动。

限制的标准

此外,即使在启动节点时没有特别指定,也可以使用容器调度所使用的默认约束集合。这些标签可以在”docker info”命令中确认,目前可用的有:

    • ノード ID またはノード名(”node” をキーに用いる)

 

    • storagedriver(ストレージ・ドライバ)

 

    • executiondriver(実行ドライバ)

 

    • kernelversion(カーネルバージョン)

 

    operatingsystem(オペレーティング・システム)

亲和性(亲密度)筛选器

可以使用”–affinity:<过滤器>”在创建容器时”吸引”容器之间的关系。例如,您可以指定容器在执行时的位置,并将具有特定映像或标签的容器放置在其旁边。通过这种吸引功能,确保容器在相同的网络节点上运行,而无需了解它们在哪个节点上运行。

容器的亲和性

在运行新容器之后,您可以在旁边运行具有其他名称或ID的容器。例如,您可以使用名称为”frontend”的nginx容器来运行:

$ docker run -d -p 80:80 --name front nginx
 87c4376856a8


$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED                  STATUS              PORTS                           NODE        NAMES
87c4376856a8        nginx:latest        "nginx"             Less than a second ago   running             192.168.0.42:80->80/tcp         node-1      frontend

然后,使用-e affinity:container==frontend标志,在第二个容器旁边调度计划。

$ docker run -d --name logger -e affinity:container==frontend logger
 87c4376856a8

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED                  STATUS              PORTS                           NODE        NAMES
87c4376856a8        nginx:latest        "nginx"             Less than a second ago   running             192.168.0.42:80->80/tcp         node-1      frontend
963841b138d8        logger:latest       "logger"            Less than a second ago   running                                             node-1      logge

logger 容器将在与前端容器相同的 node-1 容器上运行,这取决于亲和性的名称。除了使用前端的名称外,还可以使用标识符进行指定,如下所示:

docker run -d --name logger -e affinity:container==87c4376856a8`

形象的亲和度

只能在已下载的节点上调度特定的映像来启动容器。

$ docker -H node-1:2375 pull redis
$ docker -H node-2:2375 pull mysql
$ docker -H node-3:2375 pull redis

node-1和node-3都拥有Redis镜像。使用“-e affinity:image==redis”过滤器,在这些节点上进行调度。

$ docker run -d --name redis1 -e affinity:image==redis redis
$ docker run -d --name redis2 -e affinity:image==redis redis
$ docker run -d --name redis3 -e affinity:image==redis redis
$ docker run -d --name redis4 -e affinity:image==redis redis
$ docker run -d --name redis5 -e affinity:image==redis redis
$ docker run -d --name redis6 -e affinity:image==redis redis
$ docker run -d --name redis7 -e affinity:image==redis redis
$ docker run -d --name redis8 -e affinity:image==redis redis

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED                  STATUS              PORTS                           NODE        NAMES
87c4376856a8        redis:latest        "redis"             Less than a second ago   running                                             node-1      redis1
1212386856a8        redis:latest        "redis"             Less than a second ago   running                                             node-1      redis2
87c4376639a8        redis:latest        "redis"             Less than a second ago   running                                             node-3      redis3
1234376856a8        redis:latest        "redis"             Less than a second ago   running                                             node-1      redis4
86c2136253a8        redis:latest        "redis"             Less than a second ago   running                                             node-3      redis5
87c3236856a8        redis:latest        "redis"             Less than a second ago   running                                             node-3      redis6
87c4376856a8        redis:latest        "redis"             Less than a second ago   running                                             node-3      redis7
963841b138d8        redis:latest        "redis"             Less than a second ago   running                                             node-1      redis8

在这里可以看到,只有具有 redis 图像的节点才会安排容器。除了图像名称,还可以指定特定的图像 ID。

$ docker images
REPOSITORY                         TAG                       IMAGE ID            CREATED             VIRTUAL SIZE
redis                              latest                    06a1f75304ba        2 days ago          111.1 MB

$ docker run -d --name redis1 -e affinity:image==06a1f75304ba redis

标签的亲和力

通过标签亲和性,可以使用容器标签来引导并设置容器。例如,为 nginx 容器加上 com.example.type=frontend 标签来启动。

用中文直接表达这个句子:
运行命令:$ docker run -d -p 80:80 –label com.example.type=frontend nginx。容器ID为87c4376856a8。

$ docker ps  --filter "label=com.example.type=front"
CONTAINER ID        IMAGE               COMMAND             CREATED                  STATUS              PORTS                           NODE        NAMES
87c4376856a8        nginx:latest        "nginx"             Less than a second ago   running             192.168.0.42:80->80/tcp         node-1      trusting_yonath

然后,使用-e affinity:com.example.type==frontend,在具有com.example.type==fronten标签的容器旁边进行调度。

$ docker run -d -e affinity:com.example.type==frontend logger
 87c4376856a8

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED                  STATUS              PORTS                           NODE        NAMES
87c4376856a8        nginx:latest        "nginx"             Less than a second ago   running             192.168.0.42:80->80/tcp         node-1      trusting_yonath
963841b138d8        logger:latest       "logger"            Less than a second ago   running                                             node-1      happy_hawking

日志记录容器最终将放置在节点1上。这是因为它具有与com.example.type==frontend标签的亲和性。

语法表达

亲和性和约束通过键值对的组合来表示。键遵循英数字的模式,但首字符必须为字母或下划线。

价值的定义如下:

    • 英数字の文字列、ドット、ハイフン、アンダースコア

 

    • 部分一致、例えば abc*

/regexp/ 形式の正規表現

Go 支持正则表达式语法。

目前的 Swarm 在亲和性约束上支持运算符 == 和 !=。

假设

constraint:node==node1 は、ノード node1 にマッチ

constraint:node!=node1 は、node1 をのぞく全てのノードにマッチ

constraint:region!=us* は、us が付いているリージョン以外のノードにマッチ

constraint:node==/node[12]/ は、node1 と node2 にマッチ

constraint:node==/node\d/ は、node + 10進数の1文字にマッチ

constraint:node!=/node-[01]/ は、node-0 と node-1 以外の全てのノードにマッチ

constraint:node!=/foo\[bar\]/ は、foo[var] 以外の全てのノードにマッチ

constraint:node==/(?i)node1/ は、大文字・小文字を区別しない node1 にマッチします。そのため、NoDe1 や NODE1 もマッチします。

柔性的亲和力/限制

默认情况下,亲和性和约束是硬性强制的。如果没有亲和性或约束,容器将不会被调度。如果存在软性亲和性/约束,则调度程序会尝试寻找与其匹配的规则进行调度。如果没有匹配,则调度程序会丢弃过滤器,并按照调度程序策略对容器进行调度。

软性亲和性/约束可以用~来表达。例如:

$ docker run -d --name redis1 -e affinity:image==~redis redis

如果集群中没有带有 Redis 镜像的节点,则调度器将放弃亲和性并根据策略进行调度。

$ docker run -d --name redis2 -e constraint:region==~us* redis

如果群集中没有属于美国区域的节点,则调度器将放弃限制并按照策略进行调度。

$ docker run -d --name redis5 -e affinity:container!=~redis* redis

亲和过滤器将新的redis5容器调度到没有包含指定redis*容器的节点上。如果集群的每个节点都有redis*容器,则调度程序将放弃亲和规则,并按照策略进行调度。

端口过滤器

这个端口过滤器被认为是一个独特的资源。

$ docker run -d -p 80:80 nginx
87c4376856a8

$ docker ps
CONTAINER ID    IMAGE               COMMAND         PORTS                       NODE        NAMES
87c4376856a8    nginx:latest        "nginx"         192.168.0.42:80->80/tcp     node-1      prickly_engelbart

从Docker集群中选择一个可以使用公共端口80的节点,并安排容器执行。在这个示例中,node-1就是符合条件的节点。

如果你想在另一个容器上使用公共端口80启动,由于node-1已经正在使用中,将会选择另一个节点。

$ docker run -d -p 80:80 nginx
963841b138d8

$ docker ps
CONTAINER ID        IMAGE          COMMAND        PORTS                           NODE        NAMES
963841b138d8        nginx:latest   "nginx"        192.168.0.43:80->80/tcp         node-2      dreamy_turing
87c4376856a8        nginx:latest   "nginx"        192.168.0.42:80->80/tcp         node-1      prickly_engelbart

如果尝试再次执行相同的命令,将选择使用端口80的不是node-1或node-2,而是node-3。

$ docker run -d -p 80:80 nginx
963841b138d8

$ docker ps
CONTAINER ID   IMAGE               COMMAND        PORTS                           NODE        NAMES
f8b693db9cd6   nginx:latest        "nginx"        192.168.0.44:80->80/tcp         node-3      stoic_albattani
963841b138d8   nginx:latest        "nginx"        192.168.0.43:80->80/tcp         node-2      dreamy_turing
87c4376856a8   nginx:latest        "nginx"        192.168.0.42:80->80/tcp         node-1      prickly_engelbart

当集群中没有可用的节点端口80时,Docker Swam 将拒绝容器执行。

$ docker run -d -p 80:80 nginx
2014/10/29 00:33:20 Error response from daemon: no resources available to schedule container

只需一种选项,用中文将以下内容改述为华文:在主机模式下的端口过滤

使用 Docker 的 –net=host 参数进行主机模式运行时,与默认的桥接模式不同,无法进行端口绑定。因此,需要明确指定一个或多个端口号(可以使用 Dockerfile 中的 EXPOSE 或命令行中的 –expose)。在选择为新容器分配节点时,Swarm 会使用主机模式的这些信息。

例如,下面的命令在三个节点集群中启动了nginx。

$ docker run -d --expose=80 --net=host nginx
640297cb29a7
$ docker run -d --expose=80 --net=host nginx
7ecf562b1b3f
$ docker run -d --expose=80 --net=host nginx
09a92f582bc2

通过docker ps命令,可以获取端口绑定的信息。这是因为所有节点都以主机模式启动。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED                  STATUS              PORTS               NAMES
640297cb29a7        nginx:1             "nginx -g 'daemon of   Less than a second ago   Up 30 seconds                           box3/furious_heisenberg
7ecf562b1b3f        nginx:1             "nginx -g 'daemon of   Less than a second ago   Up 28 seconds                           box2/ecstatic_meitner
09a92f582bc2        nginx:1             "nginx -g 'daemon of   46 seconds ago           Up 27 seconds                           box1/mad_goldstine

即使您尝试准备第四个容器,Swarm也会拒绝。

$  docker run -d --expose=80 --net=host nginx
FATA[0000] Error response from daemon: unable to find a node with port 80/tcp available in the Host mode

可以选择绑定不同的端口,比如端口81。

$  docker run -d -p 81:80 nginx:latest
832f42819adc
$  docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED                  STATUS                  PORTS                                 NAMES
832f42819adc        nginx:1             "nginx -g 'daemon of   Less than a second ago   Up Less than a second   443/tcp, 192.168.136.136:81->80/tcp   box3/thirsty_hawking
640297cb29a7        nginx:1             "nginx -g 'daemon of   8 seconds ago            Up About a minute                                             box3/furious_heisenberg
7ecf562b1b3f        nginx:1             "nginx -g 'daemon of   13 seconds ago           Up About a minute                                             box2/ecstatic_meitner
09a92f582bc2        nginx:1             "nginx -g 'daemon of   About a minute ago       Up About a minute                                             box1/mad_goldstine

依存过滤器

このフィルタは同じノード上でのコンテナ依存性をスケジュールします。

現時点では、次の依存性を宣言できます:

    • ボリューム共有:–volumes-from=dependency

リンク: –link=dependency:alias

共有ネットワーク層:–net=container:dependency

Swarm は同じノード上で依存性のあるコンテナを設置しようとします。もし実行できなそうであれば(依存性のコンテナが存在しなかったり、ノードに十分なリソースが無い場合)、コンテナは作成されません。

可能であれば、複数の依存性を組み合わせることもできます。例えば、–volumes-from=A –net=container:B は、A と B と同じノード上にコンテナを置こうとします。これらのコンテナが別々のノードで動いているなら、Swarm はコンテナのスケジューリングを行いません。

ヘルス・フィルタ

筛选出发生障碍的节点。

广告
将在 10 秒后关闭
bannerAds