【问题标题】:how know container name with marathon rest API如何使用 marathon rest API 知道容器名称
【发布时间】:2015-04-25 05:11:46
【问题描述】:

我正在使用 Apache Mesos + Marathon + Zookeeper 来部署我的 rails 应用程序。 我需要在 Rails 应用程序和其他容器之间共享数据。我在这里找到了一些关于马拉松的参考,如下所示:

marathon/docs/native-docker.html

{
"id": "privileged-job",
"container": {
    "docker": {
        "image": "mesosphere/inky"
        "privileged": true,
        "parameters": [
            { "key": "hostname", "value": "a.corp.org" },
            { "key": "volumes-from", "value": "another-container" },
            { "key": "lxc-conf", "value": "..." }
        ]
    },
    "type": "DOCKER",
    "volumes": []
},
"args": ["hello"],
"cpus": 0.2,
"mem": 32.0,
"instances": 1
}

但是我找不到找到我的 rails 应用程序容器名称的方法,因为 marathon 使用以下格式分配名称:“mesos-uuid”。有什么办法解决吗?或其他方式与 marathon 共享容器中的容量?

【问题讨论】:

    标签: docker mesos mesosphere marathon


    【解决方案1】:

    答案可能会帮助其他正在寻找它的人。

    使用docker inspect 并在JSON 中搜索键值为“MESOS_TASK_ID”的环境设置。

    现在您有了匹配的 CONTAINER_IDMESOS_TASK_ID 对。

    希望这会有所帮助。

    更新

    为了以自动方式确定,首先确保您的 docker 守护程序可以远程访问。 注意:这可能会引起安全问题

    编辑 /etc/default/docker 并添加 DOCKER_OPTS="-H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375" 并重新启动 docker - 在所有 mesos 从站上。

    使用以下代码,获取MESOS_SLAVE CONTAINER_ID MESOS_TASK_ID 映射

    #!/bin/bash
    HOSTS=($(curl -s -X GET -H "Accept: text/plain" http://mesosmaster:8080/v2/tasks | tail -n1 | cut -f3-))
    hosts=()
    for i in "${HOSTS[@]}"
    do
    hosts+=($(echo $i | awk -F":" '{print $1}'))
    done
    host=($(printf "%s\n" "${hosts[@]}" | sort -u))
    for host in "${host[@]}"
    do
    INSTANCES=($(docker -H $host:2375 ps -q))
    for container_id in "${INSTANCES[@]}"
    do
    mesos_id=$(docker -H $host:2375 inspect $container_id | grep MESOS_TASK_ID | awk -F '[="]' '{print $3}')
    printf "$host\t$container_id\t$mesos_id\n"
    done
    done
    

    希望这会对你有所帮助。

    【讨论】:

    • thks @Shan,但我需要一种自动方式来发现 CONTAINER_ID 或 MESOS_TASK_ID。
    • @kikicarbonell,我目前正在研究它(基于 Python 的脚本),它将在 htttp://marathon:8080/v2/tasks 上查询 Marathon REST API并读取appIdid 值(键id 存储MESOS_TASK_ID)。然后在所有现有 docker 上运行 docker inspect 命令并匹配 MESOS_TASK_ID 并生成 CONTAINER_ID 对。完成后我会分享
    • @kikicarbonell,现在,您可以使用我在上述答案中添加的 shell 脚本。由于工作量大,我无法处理 Python 脚本。而且我在 Python 中处理 JSON 非常糟糕。当然,一旦完成,我会在这里分享。
    【解决方案2】:

    您可以将constraints 添加到您的应用中,以将它们强制到特定主机上。

    在一个简单的情况下,您可以执行以下操作将应用强制到特定主机上:

    {
     "instances": 1,
     "constraints": [["hostname", "LIKE", "worker-1"]]
    }
    

    下一个选项会引入属性。 您可以使用一些自定义标记来标记已知数量的主机(比如说 3 个)。

    那么您的应用定义可能如下所示:

    {
     "instances": 3,
     "constraints": [
       ["hostname", "UNIQUE"],
       ["your-custom-tag", "GROUP_BY"]
     ]
    }
    

    您需要将此添加到您的两个应用的应用定义中,从而导致每个实例在您标记的所有三个从属设备上运行。

    请参阅reference doc 设置属性。

    【讨论】:

    • 我不明白这是如何回答这个问题的。谁能解释一下?
    【解决方案3】:

    我的脚本基于 Shan 的脚本。 将主机名作为第一个参数,将马拉松部署 ID 列表作为其他参数。

    我希望这对某人有帮助;)

    我正在使用 marathon 0.11.1,在此版本中,mesos 容器名称是 volumes-from 参数所需的值。

    #!/bin/bash
    
    find_mesos_id () {
      # Parameters
      HOST="$1"
    
      # All running containers
      CONTAINERS=`docker -H $HOST:2375 ps | sed 1d | awk '{print $1}'`
      CONTAINERS_ARRAY=($CONTAINERS)
    
      # for each get MARATHON_ID & MESOS_ID
      for i in "${CONTAINERS_ARRAY[@]}"
      do  
         MARATHON_APP_ID=$(docker -H $HOST:2375 inspect $i | grep MARATHON_APP_ID | awk -F '[="]' '{print $3}' | awk -F '\/' '{print $2}')
         MESOS_CONTAINER_NAME=$(docker -H $HOST:2375 inspect $i | grep MESOS_CONTAINER_NAME | awk -F '[="]' '{print $3}')
    
         # Print MESOS_ID only for desired container
         if [[ $MARATHON_APP_ID = $2 ]]; then
            printf "{ \"key\": \"volumes-from\", \"value\": \"%s\" }" $MESOS_CONTAINER_NAME
         fi   
      done
    }   
    
    if [ "$#" -lt 2 ]; then
      echo "USAGE: bash gen-data-volumes.sh <host> [<marathon-id>]"
      printf "This script takes at least two arguments (%d given).\n" $#
      echo "exit 1."
      exit 1;
    fi  
    
    if [ "$#" -gt 1 ]; then
      for ((i=2;i<$#+1;i++)) 
        do  
          printf "%s" $(find_mesos_id $1 ${!i})
          if [[ $i -ne $# ]]; then
            printf ", "
          else 
            echo
          fi  
        done
    fi
    

    【讨论】:

      【解决方案4】:

      你可以运行类似的东西来获取容器 ID

      docker ps --filter label=MESOS_TASK_ID=&lt;mesos-task-id&gt; -q

      【讨论】:

        【解决方案5】:

        找回你的真实需求,我不认为使用 container_id 与其他容器通信比使用 ipaddress 更好。虽然你用的是zookeeper,但你可以把它当做name service server——当“rails app container”启动时,它可以在zk的特定节点注册自己,然后其他容器中的其他应用程序可以在那里找到他们想要的东西.

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-11-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-17
          • 1970-01-01
          • 2015-10-04
          相关资源
          最近更新 更多