docker swarm service的container如何获取自己task的信息

docker swarm service的container如何获取自己task的信息

背景

Docker swarm启动service的时候,如果设置了--replicas大于1,那么一个service会有多个container实例,在每个container对应一个task;现在的问题是,多个container如何标记谁是谁呢,例如有些工作只需要第一个task去做,其他task主要读取就行,那么container如何标识自己是不是第一个task呢。

举个例子来说:
创建一个replicas=4的service:

$ docker service create  --name my_service  --replicas=4 my_image 

查看service信息:

$ docker service ps my_service 
ID                  NAME                IMAGE    ...
pf7l70cormgi        my_service.1       my_image  ...
wb4w57a3th5k        my_service.2       my_image  ...
p6olyrhij5mw        my_service.3       my_image  ...
q87wxtsx3lwg        my_service.4       my_image  ...

查看container信息:

$ docker ps | grep my_service
CONTAINER ID        IMAGE            ...  NAMES
234ba9f6035a        my_image:latest  ...  my_service.3.p6olyrhij5mw5pjhxjby4w29c
d8f85a31e5b3        my_image:latest  ...  my_service.4.q87wxtsx3lwgedui78ek66x5h
3bf23184df3e        my_image:latest  ...  my_service.1.pf7l70cormgiltla2z237icgm
5a39c2172633        my_image:latest  ...  my_service.2.wb4w57a3th5kbveqqnq2tp8id

现在的问题是,如何在container内部得到自己对应的service标号呢,是my_service.1,my_service.2,my_service.3,还是my_service.4呢?

遗憾的是目前docker并没有提供这样的机制简单获取这个值。

方法1

使用container的环境变量HOSTNAME,因为环境变量HOSTNAME是内置的,不同的container其值不一样,而这个值正好就是container的id (如果用户没有显示的修改过HOSTNAME值)。

接着我们可以使用docker inspect得到这个container的详细信息,然后从container信息里面我们又能获取task的信息,具体内容看如下脚本:

#/bin/bash
...
TASKID=$(docker inspect --format '{{index .Config.Labels "com.docker.swarm.task.id"}}' ${HOSTNAME})
TASKSLOT=$(docker inspect --format '{{.Slot}}' ${TASKID})
echo "TASKSLOT=${TASKSLOT}"
...

这个段代码在container内部执行。

  1. 需要一个环境变量HOSTNAME,就是内置的container ID
  2. 先从container inspect信息里面得到TASKID
  3. 再根据taskid得到task inspect信息,最后从task inspect信息里面提取slot值即可。
    这个TASKSLOT就用来区分当前的task,其值是:1,2,3,和4。于是我们就区分了谁是谁的问题。

方法2

这个方法是最近刚刚发现的。
就是在创建service的时候配置一个环境变量,然后在container里面就可以直接使用了,例如:

$ docker service create \
    --name my_service \
    --replicas=2 \
    --env MY_TASK_SLOT={{.Task.Slot}} \
    my_image

这样在container里面就可以直接访问MY_TASK_SLOT得到当前task的slot值,是不是很方便。

变量{{...}}中总共可以设置如下值:它的定义是在https://github.com/docker/swarmkit/blob/master/template/context.go

{{.Service.Name}}
{{.Node.Hostname}}
{{.Service.Slot}}
...

type Context struct {
    Service struct {
        ID     string
        Name   string
        Labels map[string]string
    }

    Node struct {
        ID       string
        Hostname string
        Platform Platform
    }

    Task struct {
        ID   string
        Name string
        Slot string
    }
}

你可能感兴趣的:(docker swarm service的container如何获取自己task的信息)