swarm调度
Swarm filters
Configure the available filters
过滤器分为两类,即节点过滤器和容器配置过滤器。 节点过滤器对Docker主机的特性或Docker守护程序的配置进行操作。 容器配置过滤器根据容器的特性或主机上image的可用性进行操作。
每个过滤器都有一个标识它的名称。 节点过滤器是:
constraint
health
containerslots
The container configuration filters are:
affinity
dependency
port
当您使用swarm manage命令启动Swarm管理器时,将启用所有过滤器。 如果要限制Swarm可用的过滤器,请通过传递--filter标志和名称来指定一个过滤器子集:
$ swarm manage --filter=health --filter=dependency
注意:应用过滤器时,容器配置过滤器将匹配所有容器,包括已停止的容器。 要释放容器使用的节点,必须从节点中删除该容器。
Node filters
创建容器或构建iimage时,您可以使用constraint
或health
过滤器来选择要计划的节点子集。 如果Swarm群集中的节点具有带有containerslots
和数字值的标签,Swarm将不会启动比给定号码更多的容器。
Use a constraint filter
节点约束可以指Docker的默认标签或自定义标签。 默认标签来自docker info。 通常它们与Docker主机的属性有关。 目前,默认标签包括:
node
to refer to the node by ID or namestoragedriver
executiondriver
kernelversion
operatingsystem
Custom node labels you apply when you start the docker daemon
, for example:
$ docker daemon --label com.example.environment="production" --label com.example.storage="ssd"
然后,当您在群集上启动容器时,可以使用这些默认标签或自定义标签设置约束。 Swarm调度程序在集群上查找匹配的节点,并在那里启动容器。 这种方法有几个实际应用:
- 基于特定主机属性进行计划,例如,storage = ssd在特定硬件上调度容器。
- 强制容器在给定位置运行,例如region = us-east。
- 通过将集群分成具有不同属性的子集群(例如environment = production)来创建逻辑集群分区。
Example node constraints
To specify custom label for a node, pass a list of --label
options at docker
startup time. For instance, to start node-1
with the storage=ssd
label:
$ docker daemon --label storage=ssd
$ swarm join --advertise=192.168.0.42:2375 token://XXXXXXXXXXXXXXXXXX
You might start a different node-2
with storage=disk
:
$ docker daemon --label storage=disk
$ swarm join --advertise=192.168.0.43:2375 token://XXXXXXXXXXXXXXXXXX
一旦节点连接到群集,Swarm manager将拉出各自的标签。 展望未来,在安排新container时,manager会考虑标签。
继续上一个示例,假设您的群集具有node-1和node-2,您可以在群集上运行MySQL服务器容器。 运行容器时,可以使用约束来确保数据库获得良好的I / O性能。 您可以通过使用闪存驱动器的节点进行过滤:
$ docker tcp://<manager_ip:manager_port> run -d -P -e constraint:storage==ssd --name db mysql
f8b693db9cd6 $ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f8b693db9cd6 mysql:latest "mysqld" Less than a second ago running 192.168.0.42:49178->3306/tcp node-1/db
在此示例中,管理员选择了满足storage = ssd约束的所有节点,并在其上面应用了资源管理。 只有节点1被选中,因为它是唯一的主机运行闪存。 假设你想在一个集群中运行一个Nginx前端。 在这种情况下,您不需要闪存驱动器,因为前端主要将日志写入磁盘。
调度程序选择node-2,因为它是以storage = disk标签启动的。 最后,构建args可以用于将节点约束应用于docker构建。 再次,你会避免闪存驱动器。
$ mkdir sinatra
$ cd sinatra
$ echo "FROM ubuntu:14.04" > Dockerfile
$ echo "RUN apt-get update && apt-get install -y ruby ruby-dev" >> Dockerfile
$ echo "RUN gem install sinatra" >> Dockerfile
$ docker build --build-arg=constraint:storage==disk -t ouruser/sinatra:v2 .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM ubuntu:14.04
---> a5a467fddcb8
Step 2 : RUN apt-get update && apt-get install -y ruby ruby-dev
---> Running in 26c9fbc55aeb
---> 30681ef95fff
Removing intermediate container 26c9fbc55aeb
Step 3 : RUN gem install sinatra
---> Running in 68671d4a17b0
---> cd70495a1514
Removing intermediate container 68671d4a17b0
Successfully built cd70495a1514
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dockerswarm/swarm manager 8c2c56438951 2 days ago 795.7 MB
ouruser/sinatra v2 cd70495a1514 35 seconds ago 318.7 MB
ubuntu 14.04 a5a467fddcb8 11 days ago 187.9 MB
Use the health filter
节点健康过滤器防止调度程序在不健康的节点上运行容器。 如果节点关闭或无法与集群存储通信,则节点被认为是不健康的。
Use the containerslots filter
You may give your Docker nodes the containerslots label
$ docker daemon --label containerslots=3
如果所有节点都为“满”,Swarm将在此节点运行多达3个容器,则会抛出错误,指示找不到合适的节点。 如果该值不可转换为整数或不存在,则容器数量不会有限制。
Container filters
When creating a container, you can use three types of container filters:
Use an affinity filter
使用亲和过滤器在容器之间创建“景点”。 例如,您可以运行一个容器,并指示Swarm根据这些亲和力将其安排在另一个容器旁边:
- container name or ID
- an image on the host
- a custom label applied to the container
这些亲和性确保容器运行在同一个网络节点上,而无需知道每个节点正在运行。
Example name affinity
您可以根据容器名称或ID来安排新容器运行到另一个容器。 例如,您可以启动一个名为frontend
运行nginx的容器:
$ docker tcp://<manager_ip:manager_port> run -d -p 80:80 --name frontend nginx
87c4376856a8
$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS 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值来计划第二个容器来定位并运行在名为frontend的容器旁
$ docker tcp://<manager_ip:manager_port> run -d --name logger -e affinity:container==frontend logger
87c4376856a8
$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS 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/logger
由于名称相关性,记录器容器与前端容器一起结束在节点1上。 您可以提供其ID,而不是frontend
名称,如下所示:
$ docker tcp://<manager_ip:manager_port> run -d --name logger -e affinity:container==87c4376856a8
Example image affinity
您可以安排一个容器仅在已经拉出特定图像的节点上运行。 例如,假设您将一个redis映像拖放到两个主机和一个mysql映像到三分之一。
$ docker -H node-1:2375 pull redis
$ docker -H node-2:2375 pull mysql
$ docker -H node-3:2375 pull redis
只有节点1和节点3具有redis映像。 指定-e affinity:image == redis过滤器以安排在这些节点上运行的多个附加容器。
$ docker tcp://<manager_ip:manager_port> run -d --name redis1 -e affinity:image==redis redis
$ docker tcp://<manager_ip:manager_port> run -d --name redis2 -e affinity:image==redis redis
$ docker tcp://<manager_ip:manager_port> run -d --name redis3 -e affinity:image==redis redis
$ docker tcp://<manager_ip:manager_port> run -d --name redis4 -e affinity:image==redis redis
$ docker tcp://<manager_ip:manager_port> run -d --name redis5 -e affinity:image==redis redis
$ docker tcp://<manager_ip:manager_port> run -d --name redis6 -e affinity:image==redis redis
$ docker tcp://<manager_ip:manager_port> run -d --name redis7 -e affinity:image==redis redis
$ docker tcp://<manager_ip:manager_port> run -d --name redis8 -e affinity:image==redis redis
$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS 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镜像的节点上。 您可以指定image ID而不是image名称。
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
redis latest 06a1f75304ba 2 days ago 111.1 MB
$ docker tcp://<manager_ip:manager_port> run -d --name redis1 -e affinity:image==06a1f75304ba redis
Example label affinity
标签亲和性允许您根据自定义容器标签进行过滤。 例如,您可以运行一个nginx容器并应用com.example.type = frontend自定义标签。
$ docker tcp://<manager_ip:manager_port> run -d -p 80:80 --label com.example.type=frontend nginx
87c4376856a8
$ docker tcp://<manager_ip:manager_port> ps --filter "label=com.example.type=frontend"
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
87c4376856a8 nginx:latest "nginx" Less than a second ago running 192.168.0.42:80->80/tcp node-1/trusting_yonath
Then, use -e affinity:com.example.type==frontend
to schedule a container next to the container with the com.example.type==frontend
label.
$ docker tcp://<manager_ip:manager_port> run -d -e affinity:com.example.type==frontend logger
The
87c4376856a8 $ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS 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 runninglogger
container ends up onnode-1
because its affinity with thecom.example.type==frontend
label.
Use a dependency filter
容器依赖过滤器在相同的节点上调度相关容器。 目前,依赖关系声明如下:
--volumes-from=dependency
(shared volumes)--link=dependency:alias
(links)--net=container:dependency
(shared network stacks)
Swarm尝试将依赖容器同时放置在同一个节点上。 如果不能完成(因为从属容器不存在,或因为节点没有足够的资源),它将阻止容器创建。
如果可能,多个依赖关系的组合将得到尊重。 例如,如果指定--volumes-from = A --net = container:B,则调度程序将尝试将与A和B相同节点上的容器进行共同定位。如果这些容器在不同的节点上运行,则Swarm 不安排容器。
Use a port filter
启用端口过滤器后,将使用容器的端口配置作为唯一约束。 Docker Swarm选择一个特定端口可用并且被其他容器或进程占用的节点。 可以通过映射主机端口或使用主机网络并使用容器配置暴露端口来指定所需的端口。
Example in bridge mode
默认情况下,容器在Docker的网桥上运行。 要将端口过滤器与桥接网络一起使用,请运行以下容器。
$ docker tcp://<manager_ip:manager_port> run -d -p 80:80 nginx
87c4376856a8
$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID IMAGE COMMAND PORTS NAMES
87c4376856a8 nginx:latest "nginx" 192.168.0.42:80->80/tcp node-1/prickly_engelbart
Docker Swarm选择端口80可用并且被其他容器或进程占用的节点,在本例中为节点-1。 尝试运行另一个使用主机端口80的容器导致Swarm选择不同的节点,因为端口80已在节点1上占用:
$ docker tcp://<manager_ip:manager_port> run -d -p 80:80 nginx
963841b138d8
$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID IMAGE COMMAND PORTS 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
再次,重复相同的命令将导致节点3的选择,因为端口80在节点1和节点2上都不可用:
$ docker tcp://<manager_ip:manager_port> run -d -p 80:80 nginx
963841b138d8
$ docker tcp://<manager_ip:manager_port> ps
CONTAINER ID IMAGE COMMAND PORTS 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
最后,Docker Swarm将拒绝运行另一个需要端口80的容器,因为它在集群中的任何节点上都不可用:
$ docker tcp://<manager_ip:manager_port> run -d -p 80:80 nginx
2014/10/29 00:33:20 Error response from daemon: no resources available to schedule container
当容器创建时,每个容器在其驻留节点上占用端口80,并在容器被删除时释放端口。 退出状态的容器仍然拥有端口。 如果节点1上的prickly_engelbart已停止但未被删除,
则尝试启动需要端口80的节点1上的另一个容器将失败,因为端口80与prickly_engelbart相关联。 要增加nginx的运行实例,可以重新启动prickly_engelbart,也可以在删除prickly_englbart后启动另一个容器。
Node port filter with host networking
运行于--net = host的容器与默认bridge模式不同,因为主机模式不执行任何端口绑定。 相反,主机模式要求您显式公开一个或多个端口号。 您在Dockerfile中使用EXPOSE公开端口或在命令行上使用--expose。
Swarm使用此信息与主机模式一起选择新容器的可用节点。
例如,以下命令在3节点集群上启动nginx。
$ docker tcp://<manager_ip:manager_port> run -d --expose=80 --net=host nginx
640297cb29a7
$ docker tcp://<manager_ip:manager_port> run -d --expose=80 --net=host nginx
7ecf562b1b3f
$ docker tcp://<manager_ip:manager_port> run -d --expose=80 --net=host nginx
09a92f582bc2
端口绑定信息通过docker ps命令不可用,因为所有节点都是使用host网络启动的。
$ docker tcp://<manager_ip:manager_port> 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
尝试实例化第4个容器时,Swarm拒绝操作。
$ docker tcp://<manager_ip:manager_port> 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 tcp://<manager_ip:manager_port> run -d -p 81:80 nginx:latest
832f42819adc
$ docker tcp://<manager_ip:manager_port> 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
How to write filter expressions
要应用节点约束或容器关联过滤器,必须使用过滤器表达式在容器上设置环境变量,例如:
$ docker tcp://<manager_ip:manager_port> run -d --name redis1 -e affinity:image==~redis redis
Each expression must be in the form:
<filter-type>:<key><operator><value>
<filter-type>是affinity或constraint关键字。 它标识您要使用的类型过滤器。
<key>是一个字母数字,必须以字母或下划线开头。 <key>对应于以下之一:
- the
container
keyword - the
node
keyword - a default tag (node constraints)
- a custom metadata label (nodes or containers).
<operator>是==或!=。 默认情况下,表达式运算符被强制执行。 如果表达式不完全满足,则管理器不调度容器。 您可以使用〜(波浪号)创建“软”表达式。 调度程序尝试匹配一个软表达式。 如果不满足表达式,则调度程序将丢弃该过滤器并根据调度程序的策略调度该容器。
<value>是一个字母数字字符串,点,连字符和下划线组成以下之一:
- A globbing pattern, for example,
abc*
. - A regular expression in the form of
/regexp/
. See re2 syntax for the supported regex syntax.
以下示例说明了一些可能的表达式:
constraint:node==node1
matches nodenode1
.constraint:node!=node1
matches all nodes, exceptnode1
.constraint:region!=us*
matches all nodes outside with aregion
tag prefixed withus
.constraint:node==/node[12]/
matches nodesnode1
andnode2
.constraint:node==/node\d/
matches all nodes withnode
+ 1 digit.constraint:node!=/node-[01]/
matches all nodes, exceptnode-0
andnode-1
.constraint:node!=/foo\[bar\]/
matches all nodes, exceptfoo[bar]
. You can see the use of escape characters here.constraint:node==/(?i)node1/
matches nodenode1
case-insensitive. SoNoDe1
orNODE1
also match.affinity:image==~redis
tries to match for nodes running container with aredis
image.constraint:region==~us*
searches for nodes in the cluster belonging to theus
region.affinity:container!=~redis*
schedules a newredis5
container to a node without a container that satisfiesredis*
.
swarm调度的更多相关文章
- Docker三剑客之Swarm介绍
DockOne技术分享(二十): 我用swarm在多台物理机调度管理容器,用ovs实现跨主机的容器互联问题 [编者的话]Swarm项目是Docker公司发布三剑客中的一员,用来提供容器集群服务,目的是 ...
- 基于 Consul 的 Docker Swarm 服务发现
Docker 是一种新型的虚拟化技术,它的目标在于实现轻量级操作系统的虚拟化.相比传统的虚拟化方案,Docker 虚拟化技术有一些很明显的优势:启动容器的速度明显快于传统虚拟化技术,同时创建一台虚拟机 ...
- docker swarm 简易版
节点名称 相关服务 ip地址 master1/node1 swarm manager(master) / consul 192.168.132.131 master2/node2 swarm mana ...
- Swarm基于多主机容器网络 - overlay networks 梳理
前面介绍了Docker管理工具-Swarm部署记录,下面重点说下Swarm基于多主机容器通信的覆盖网络 在Docker版本1.12之后swarm模式原生支持覆盖网络(overlay networks) ...
- DockOne技术分享(二十):Docker三剑客之Swarm介绍
[编者的话]Swarm项目是Docker公司发布三剑客中的一员,用来提供容器集群服务,目的是更好的帮助用户管理多个Docker Engine,方便用户使用,像使用Docker Engine一样使用容器 ...
- Docker三剑客之Docker Swarm
一.什么是Docker Swarm Swarm是Docker公司推出的用来管理docker集群的平台,几乎全部用GO语言来完成的开发的,代码开源在https://github.com/docker/s ...
- Swarm使用原生的overlay网络
一.Swarm Overlay Network Swarm有Service的概念.一个Service是指使用相同镜像.同时运行的多个容器,多个容器同时一起对外提供服务,多个容器之间负载均衡.每个Ser ...
- 实战Docker容器调度
目录 一.前言 二.Docker Compose 2.1.简介 2.2.下载安装 2.3.小实验 2.4.小实验的细节 2.5.Compose file的编写规则 三.Docker Swarm 3.1 ...
- Docker Swarm(四)Volume 数据(挂载)持久化
前言 为了获得最佳的性能和可移植性,应该避免将重要数据直接写入容器的可写层,而应使用数据卷或绑定挂载. 可以为集群中的服务创建两种类型的挂载,数据卷挂载(volume mounts)或绑定挂载(bin ...
随机推荐
- ubuntu:在ubuntu上安装vmware12
在ubuntu上安装vmware12 下载vmware12 https://pan.baidu.com/s/1i5BQEmL 官方的 密匙 5A02H-AU243-TZJ49-GTC7K-3C ...
- 5.4完成其他模块的xadmin后台注册
courses adminx.py from .models import Course, Lesson, Video, CourseResource import xadmin class Cou ...
- Android listview自定义分割线宽度
代码很简单防止以后忘记 <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:an ...
- Leetcode 1024. Video Stitching
class Solution: def helper(self,l,r,clips)->int: maxL,maxR=0,0 iL,iR=-1,-1 for i,c in enumerate(c ...
- 常量池之字符串常量池String.intern()
运行时常量池是方法区(PermGen)的一部分. 需要提前了解: 1. JVM内存模型. 2. JAVA对象在JVM中内存分配 常量池的好处 常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现 ...
- asp.net 操作word 权限
1.先安装office 2.在“DCOM配置”中,为IIS账号配置操作Word(其他Office对象也一样)的权限: 开始>运行>输入 dcomcnfg >确定 具体操作:“组件 ...
- 深入理解java虚拟机,内存管理部分
1,对象回收前会调用finalize()方法,尝试自救,只能调用一次 2,上面横向对比c++的析构函数,但是java有良好的内存管理,而且try/catch做得比较好 3,回收一个常量,1,对象的实例 ...
- bzoj 1002 [FJOI2007]轮状病毒——打表找规律
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1002 看 Zinn 的博客:https://www.cnblogs.com/Zinn/p/9 ...
- SQL2008如何清空压缩数据库日志
SQL2008如何清空压缩数据库日志 编写人:左丘文 2015-4-10 近期在给一系统初始化资料时,不断的导入导出,因此一不小心,就将数据的SQL(sql2008R2)的是日志档弄得比数据库还大,给 ...
- Makefile编写 三 伪目标的作用
本节我们讨论一个Makefile中的一个重要的特殊目标:伪目标. 伪目标是这样一个目标:它不代表一个真正的文件名,在执行make时可以指定这个目标来执行其所在规则定义的命令,有时我们也可以将一个伪目标 ...