前文回顾
接上文,本文一共在虚拟机上运行了三个节点。它们都是管理节点。然后对service做了一些简单的增删查操作
1 | docker node ls |
在这3个节点上,本文就要开始做多节点方面的操作
Task
什么是task
大意就是服务的执行者,一个服务通过多个task来执行服务
swarm的task之于service相当于:
面向对像的object之于class;
docker的container之于images;
一个服务可有多个task,并且通过内部算法,部署在一个或多个node上
处理各类任务的,也是这些task
设置task个数的参数为replicas
,即复制品或副本…
那么我们来试一下
创建多task的service并指定node
现在,我们一共3个节点,创建服务时将replicas
设为2
分别按以下条件指定--constraint
参数
由于遇到一些问题,此时再次查看一下node数量
1 | docker node ls |
swarmworker2因为遇到了问题,前后执行了两次leave,导致id发生了变化。从status
看,只有3个是ready
的
不指定条件
1 | service create --replicas 2 --name hello_without_constraint alpine ping docker.com |
经多次设置,task应该是通过某种算法均匀分布在所有node上的。表现为尽可能给所有节点平滩。据经验,分配方式肯定可以配置的,比如设权重之类的
指定hostname
1 | docker service create --replicas 2 --constraint node.hostname==swarmworker1 --name hello alpine ping docker.com |
可见,分配到指定hostname的节点上了
多个节点的hostname理论上是可以重复的,这个有空再说吧
指定节点类型
节点类型就两种,worker和manager
那么本次我们先将worker2降级成worker类型,那么,有两个管理节点和一个工作节点
1 | docker node demote swarmworker2 |
键入以下命令将服务的task分布在管理节点
1 | docker service create --replicas 4 --constraint node.role==manager --name hello_by_role alpine ping docker.com |
指定label
就不多做了,内容都差不多。。官网看吧
https://docs.docker.com/engine/swarm/services/#placement-constraints
关于端口
一般情况,我们用http来提供无状态的服务,就会涉及到端口的暴露和分布的问题
1 | ## 目前有两个节点,下面我们建一个replicas=1的nginx服务,暴露端口为8080,容器内部端口为80,即8080转发到80 |
即内部有一套流量转发机制
引用官方
https://docs.docker.com/engine/swarm/services/#publish-ports
You don’t need to know which nodes are running the tasks; connecting to port 8080 on any of the 10 nodes connects you to one of the three nginx tasks. You can test this using curl. The following example assumes that localhost is one of the swarm nodes. If this is not the case, or localhost does not resolve to an IP address on your host, substitute the host’s IP address or resolvable host name.
大意是访问任何节点的该端口都会转发运行该服务的task的节点上(官方是10个节点,在3个节点上运行nginx,即–replicas 3)。
机缘巧合发现个问题
另外,我发现个问题
由于第3个节点swarmworker2的没有配置代理,也没有提前去pull image
当我在执行 docker service create ..... --replicas=2 ......
的时候,恰好给swarmworker2分配了一个task
1 | docker service create --replicas 2 --name hello_without_constraint alpine ping docker.com |
这个问题我我也去了解了一下,就是节点只会用自己本地的image,不会用其它节点的。为什么不设计成节点共享呢,哪怕给个命令手动互相copy也行啊。
尤其对一些用于本地测试的私有image而言来说,就必须把image publish到仓库才行
怎么解决呢,要么手动 export/import
要么就自己搭个中转仓库
具体的情况,再搜搜吧
既然已经出了这档问题,顺便测试一下,直接将该节点剔除,看是什么反应
1 | # 剔除之前 |
由此可见 swarmworker2 关闭了,又从swarmmanger 启动了一个task
小结
在多个节点中:
要运行指定个数的task变得简单
对于使用网络端口对外作为服务的task,不用考虑task具体运行在哪些节点上,每个节点都能访问到task
如果某些task因为某些原因挂掉了,系统会自动帮忙重新运行新的task,并且在此节点池内,总个数不会变化
考虑到特定情况,将指定task运行在符合条件的node上也很容易