如何在自动重启后在自动扩展docker架构中保留唯一的容器标识符?

时间:2017-08-29 15:38:23

标签: docker

我的应用程序包括设置了自动重启的相同微服务的多个实例。当一个实例重新启动时,它必须在数据库中需要时执行一些健全性检查和清理,但只有它自己的。

我使用的解决方案是在docker文件中声明一个环境变量来区分实例。假设我有两个实例,docker-file-for-instance-1包含:

ENV INSTANCE=1

和docker-file-for-instance-2包含:

ENV INSTANCE=2

使用此技巧,实例可以在重新启动后检查其自身工作的数据,该数据在列实例的帮助下记录在数据库中,该列获取环境变量INSTANCE的值。

但这种情况很严重。

  • 第一个想法是为每个实例提供一个docker文件,因此没有INSTANCE环境变量。但是,如何区分数据库中写的是哪个实例?
  • 第二个想法是使用一个orchestrator来管理docker文件中的实例值。我还不知道这些技术。有可能吗?

编辑:在下面添加Tarun Lalwani解决方案以检查两个容器的UUID行为

test.sh

#!/bin/bash

echo "Building Image"
docker build -t c1i . > /dev/null

echo "Killing existing container if any"
for c in c1 c2; do
  if [[ `docker ps --filter "name=$c" --format "{{.Names}}"` == $c ]]; then docker kill $c; docker rm $c; fi;
  echo "Starting container $c in background"
  docker run -d --name $c c1i > /dev/null
  docker ps -a
  echo "Restarting container $c"
  docker restart $c > /dev/null
  docker ps -a
done;

for c in c1 c2; do
  echo "Restarting container $c again"
  docker restart $c > /dev/null
  docker ps -a
done;

for c in c1 c2; do
  echo "Checking container $c logs"
  docker logs $c
done;

docker ps -a

for c in c1 c2; do
  echo "Checking container $c UUID"
  docker exec $c cat /etc/environment.container
done;

echo "Killing containers"
for c in c1 c2; do
  if [[ `docker ps --filter "name=$c" --format "{{.Names}}"` == $c ]]; then docker kill $c; docker rm $c; fi;
done;

init.sh

#!/bin/sh

ENV_FILE=/etc/environment.container
#cat $ENV_FILE



if [ -f $ENV_FILE ]; then
   . $ENV_FILE
fi

if [ -z "${CONTAINER_UUID}" ]; then
   echo "Starting container for the first time"
   CONTAINER_UUID=$(uuidgen -r)
   echo "CONTAINER_UUID=$CONTAINER_UUID" >> $ENV_FILE
   echo "UUID of new container is $CONTAINER_UUID"
else
   CONTAINER_UUID=${CONTAINER_UUID}
   echo "Restarting container with $CONTAINER_UUID"
fi

echo "------------------ END OF CONTAINER INIT ----------------"
exec tail -f /dev/null

exit 0

dockerfile是一样的。

这是控制台输出:

$ ./test.sh 
Building Image
Killing existing container if any
Starting container c1 in background
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS                  PORTS               NAMES
1cd1b7961f5a        c1i                 "/bin/sh -c /init.sh"   2 seconds ago       Up Less than a second                       c1
Restarting container c1
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS                  PORTS               NAMES
1cd1b7961f5a        c1i                 "/bin/sh -c /init.sh"   14 seconds ago      Up Less than a second                       c1
Starting container c2 in background
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS                  PORTS               NAMES
f8654d93936e        c1i                 "/bin/sh -c /init.sh"   2 seconds ago       Up Less than a second                       c2
1cd1b7961f5a        c1i                 "/bin/sh -c /init.sh"   16 seconds ago      Up 2 seconds                                c1
Restarting container c2
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS                  PORTS               NAMES
f8654d93936e        c1i                 "/bin/sh -c /init.sh"   15 seconds ago      Up Less than a second                       c2
1cd1b7961f5a        c1i                 "/bin/sh -c /init.sh"   29 seconds ago      Up 14 seconds                               c1
Restarting container c1 again
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS                  PORTS               NAMES
f8654d93936e        c1i                 "/bin/sh -c /init.sh"   27 seconds ago      Up 12 seconds                               c2
1cd1b7961f5a        c1i                 "/bin/sh -c /init.sh"   41 seconds ago      Up Less than a second                       c1
Restarting container c2 again
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS                  PORTS               NAMES
f8654d93936e        c1i                 "/bin/sh -c /init.sh"   39 seconds ago      Up Less than a second                       c2
1cd1b7961f5a        c1i                 "/bin/sh -c /init.sh"   53 seconds ago      Up 12 seconds                               c1
Checking container c1 logs
Starting container for the first time
UUID of new container is 432bfc77-e186-4ca2-bb9a-450b370d05a3
------------------ END OF CONTAINER INIT ----------------
Restarting container with 432bfc77-e186-4ca2-bb9a-450b370d05a3
------------------ END OF CONTAINER INIT ----------------
Restarting container with 432bfc77-e186-4ca2-bb9a-450b370d05a3
------------------ END OF CONTAINER INIT ----------------
Checking container c2 logs
Starting container for the first time
UUID of new container is 9eae8f6c-c332-422a-a35a-6ec1d59b6e6c
------------------ END OF CONTAINER INIT ----------------
Restarting container with 9eae8f6c-c332-422a-a35a-6ec1d59b6e6c
------------------ END OF CONTAINER INIT ----------------
Restarting container with 9eae8f6c-c332-422a-a35a-6ec1d59b6e6c
------------------ END OF CONTAINER INIT ----------------
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS                  PORTS               NAMES
f8654d93936e        c1i                 "/bin/sh -c /init.sh"   39 seconds ago      Up Less than a second                       c2
1cd1b7961f5a        c1i                 "/bin/sh -c /init.sh"   53 seconds ago      Up 12 seconds                               c1
Checking container c1 UUID
CONTAINER_UUID=432bfc77-e186-4ca2-bb9a-450b370d05a3
Checking container c2 UUID
CONTAINER_UUID=9eae8f6c-c332-422a-a35a-6ec1d59b6e6c
Killing containers

我尝试过其他两种解决方案,但没有设法让它们发挥作用:

Dockerfile(替代方案1 - 不起作用)

FROM ubuntu:16.04
RUN apt-get update -y && apt-get install uuid-runtime -y
COPY ./init2.sh /etc/init.d/init.sh
CMD chmod a+x /etc/init.d/init.sh

Dockerfile(替代方案2 - 不起作用)

FROM ubuntu:16.04
RUN apt-get update -y && apt-get install uuid-runtime -y
COPY ./init.sh /etc/rc.local
CMD chmod a+x /etc/rc.local

init2.sh(替代方案 - 无效)

#! /bin/sh
PATH=/sbin:/bin
do_start () {
    ENV_FILE=/etc/environment.container
    echo "exec init.sh on container :"
    cat $ENV_FILE   
    if [ -f $ENV_FILE ]; then
       . $ENV_FILE
    fi    
    if [ -z "${CONTAINER_UUID}" ]; then
       echo "Starting container for the first time"
       CONTAINER_UUID=$(uuidgen -r)
       echo "CONTAINER_UUID=$CONTAINER_UUID" >> $ENV_FILE
       echo "UUID of new container is $CONTAINER_UUID"
    else
       CONTAINER_UUID=${CONTAINER_UUID}
       echo "Restarting container with $CONTAINER_UUID"
    fi    
    echo "------------------ END OF CONTAINER INIT ----------------"
    #exec tail -f /dev/null
}

do_status () {
}    
case "$1" in
  start|"")
    do_start
    ;;
  restart|reload|force-reload|stop|status)
    # No-op
    ;;
  *)
    ;;
esac    
exit 0

我在这做错了什么?

1 个答案:

答案 0 :(得分:1)

好吧,我不会在容器外生成容器ID。我只会从容器内部生成它。

我找到了一个效果很好的样本。

<强> Dockerfile

FROM ubuntu:16.04

RUN apt-get update -y && apt-get install uuid-runtime -y
COPY ./init.sh /init.sh
CMD /init.sh

<强> init.sh

#!/bin/sh

ENV_FILE=/etc/environment.container
cat $ENV_FILE

if [ -f $ENV_FILE ]; then
   . $ENV_FILE
fi

if [ -z "${CONTAINER_UUID}" ]; then
   echo "Starting container for the first time"
   CONTAINER_UUID=$(uuidgen -r)
   echo "CONTAINER_UUID=$CONTAINER_UUID" >> $ENV_FILE
   echo "UUID of new container is $CONTAINER_UUID"
else
   CONTAINER_UUID=${CONTAINER_UUID}
   echo "Restarting container with $CONTAINER_UUID"
fi

echo "------------------ END OF CONTAINER INIT ----------------"
exec tail -f /dev/null

然后创建了一个test.sh以查看功能

<强> test.sh

#!/bin/bash

echo "Building Image"
docker build -t c1i . > /dev/null

echo "Killing existing container if any"
docker kill c1 > /dev/null
docker rm c1 > /dev/null

echo "Starting container in background"
docker run -d --name c1 c1i > /dev/null

echo "Restarting container"
docker restart c1 > /dev/null

echo "Restarting container again"
docker restart c1 > /dev/null

echo "Checking container logs"
docker logs c1

以上测试的输出如下

Building Image
Killing existing container if any
Starting container in background
Restarting container
Restarting container again
Checking container logs
Starting container for the first time
UUID of new container is 23615a43-3b59-4369-82c7-0202ad227403
------------------ END OF CONTAINER INIT ----------------
cat: /etc/environment.container: No such file or directory
CONTAINER_UUID=23615a43-3b59-4369-82c7-0202ad227403
Restarting container with 23615a43-3b59-4369-82c7-0202ad227403
------------------ END OF CONTAINER INIT ----------------
CONTAINER_UUID=23615a43-3b59-4369-82c7-0202ad227403
Restarting container with 23615a43-3b59-4369-82c7-0202ad227403
------------------ END OF CONTAINER INIT ----------------

正如您所看到的那样,环境变量始终是唯一的,因为它是基于UUID的,并且在重新启动同一容器后会保持不变