关于marathon的分配策略

本文主要翻译自 https://mesosphere.github.io/marathon/docs/constraints.html

我司从2015年就开始使用Mesos+marathon的集群框架,应该说这套系统还是相当的成熟,至于后面跟K8s比,那得看在什么层面上了。至少稳定性比K8s强太多了。

由于我们现有的集群都是在云上面的。这在同一城市会分布很多的机房,从A一直到H都有。因此当我们进行部署分布式任务的时候最好就分布到A到H之间的3个机房。

这样的好处就是保证了一个机房宕掉而不影响全局。而从mesos 1.5版本开始就已经支持domain,region这样的参数了。 具体可以参考http://mesos.apache.org/documentation/latest/fault-domains/

所以这个文档其实是要基于mesos1.5之后说的。现在mesos已经到1.9.0了,但是生产环境建议还是1.7.2

好了,开始了。特别注意CLUSTER, LIKE这样的操作符都是大写,不能小写。

  1. 这个表示启动的3个实例都要运行在rack-1这个机架上的机器。当然这个rack就是一种命名,你可以把它当做机房,自己租idc那就是机架吧。

    1
    2
    3
    4
    5
    6
    $ curl -X POST -H "Content-type: application/json" localhost:8080/v2/apps -d '{
    "id": "sleep-cluster",
    "cmd": "sleep 60",
    "instances": 3,
    "constraints": [["rack_id", "CLUSTER", "rack-1"]]
    }'
  2. 表示3个实例都要运行在同一个机架上,但是没有指定特定机架。

    1
    2
    3
    4
    5
    6
    $ curl -X POST -H "Content-type: application/json" localhost:8080/v2/apps -d '{
    "id": "sleep-cluster",
    "cmd": "sleep 60",
    "instances": 3,
    "constraints": [["rack_id", "CLUSTER"]]
    }'
  3. 这个也是我司常用的,指定机器。3个实例都要运行在一个机器上。

    1
    2
    3
    4
    5
    6
    $ curl -X POST -H "Content-type: application/json" localhost:8080/v2/apps -d '{
    "id": "sleep-cluster",
    "cmd": "sleep 60",
    "instances": 3,
    "constraints": [["hostname", "CLUSTER", "a.specific.node.com"]]
    }'
  4. 表示3个实例都要运行在一个机器上,但是具体哪个机器不指定。

    1
    2
    3
    4
    5
    6
    $ curl -X POST -H "Content-type: application/json" localhost:8080/v2/apps -d '{
    "id": "sleep-cluster",
    "cmd": "sleep 60",
    "instances": 3,
    "constraints": [["hostname", "CLUSTER"]]
    }'
  5. LIKE操作符,这个是支持正则的。如
    表示3个实例可以运行在rack1,rack2,rack3上,可以是其中一个,也可以是其中3个都运行。

    1
    2
    3
    4
    5
    6
    $ curl -X POST -H "Content-type: application/json" localhost:8080/v2/apps -d '{
    "id": "sleep-group-by",
    "cmd": "sleep 60",
    "instances": 3,
    "constraints": [["rack_id", "LIKE", "rack-[1-3]"]]
    }'

下面这个就表示可以运行在rack1,rack2, rack6,rack7. 关于正则你可以想出更多玩法,这个也是我司最多用的操作符。

1
2
3
4
5
6
$ curl -X POST -H "Content-type: application/json" localhost:8080/v2/apps -d '{
"id": "sleep-group-by",
"cmd": "sleep 60",
"instances": 3,
"constraints": [["rack_id", "LIKE", "rack-([1-2]|[6-7]"]]
}'
  1. UNLIKE操作符,这个也是支持正则的。如:
    只有rack7-9不行,其他都可以运行。

    1
    2
    3
    4
    5
    6
    $ curl -X POST -H "Content-type: application/json" localhost:8080/v2/apps -d '{
    "id": "sleep-group-by",
    "cmd": "sleep 60",
    "instances": 3,
    "constraints": [["rack_id", "UNLIKE", "rack-[7-9]"]]
    }'
  2. MAX_PER操作符。这里就表示单个rack最多只能运行2个。

    1
    2
    3
    4
    5
    6
    $ curl -X POST -H "Content-type: application/json" localhost:8080/v2/apps -d '{
    "id": "sleep-group-by",
    "cmd": "sleep 60",
    "instances": 3,
    "constraints": [["rack_id", "MAX_PER", "2"]]
    }'
  3. UNIQUE操作符。表示只能唯一。rack唯一或者hostname唯一,这也就强制一个机器或者一个集群只能起一个这个服务。

    1
    2
    3
    4
    5
    6
    $ curl -X POST -H "Content-type: application/json" localhost:8080/v2/apps -d '{
    "id": "sleep-unique",
    "cmd": "sleep 60",
    "instances": 3,
    "constraints": [["hostname", "UNIQUE"]]
    }'
  4. GROUP_BY操作符,这个原文写的有点复杂。下面可以解释下

    1
    2
    3
    4
    5
    6
    $ curl -X POST -H "Content-type: application/json" localhost:8080/v2/apps -d '{
    "id": "sleep-group-by",
    "cmd": "sleep 60",
    "instances": 3,
    "constraints": [["rack_id", "GROUP_BY", "3"]]
    }'

    上面这个表示3个实例都平均分到3个rack中,假设有rack1,rack2,rack3, 如果暂时没有找到rack3,那marathon就分配2个实例到rack1,rack2上,会留一个实例等着rack3。
    假设上面实例数改成了9,也是有rack1,2,3, 但是暂时3脱离了,那marathon就把8个给平均分配到rack1,2上,给rack3留一个

  5. IS操作符,这个是可以进行比较的。
    它支持浮点数,整数,文字。但是注意下浮点数只支持到千分位。比如 0.8 和 0.80001 是相等的

    1
    2
    3
    4
    5
    6
    $ curl -X POST -H "Content-type: application/json" localhost:8080/v2/apps -d '{
    "id": "sleep-cluster",
    "cmd": "sleep 60",
    "instances": 3,
    "constraints": [["rack_id", "IS", "rack-1"]]
    }'

    也可以操作mesos-slave的其他自定义属性如:

    1
    [["level", "IS", "0.8"]]