Как прозрачно запустить скрипт перед точкой входа в докер?

Я автоматизирую развертывание java-приложения в контейнере докеров в шаблонах cloudformation. Мне нужно настроить переменную env для журналов сбоев java, но мне нужно сохранить уникальный путь для каждого контейнера. Я не могу изменить образ докера или файл докера.

Для этого я использую $HOSTNAME из док-контейнера, который достаточно уникален. Проблема в том, что я не могу использовать ее как обычную переменную среды докера, потому что она устанавливается после запуска контейнера. Обойти это можно, изменив точку входа, установив переменную env и после этого запустив исходную точку входа.

EntryPoint: 
            - /bin/sh
            - -c
            - export JAVA_OPTS="$JAVA_OPTS -XX:HeapDumpPath=/mnt/crashdumps/java_$HOSTNAME.hprof" 
&& ./entrypoint.sh

(это облачный шаблон YAML для AWS::ECS::TaskDefinition, но то же самое можно выразить в docker cli)

Он работал нормально, пока провайдер контейнера java не изменил размещение сценария оболочки точки входа. Теперь внедрение оболочки выглядит очень грязным в коде, потому что мне нужно проверить, существует ли файл и требует дополнительного обслуживания (например, если путь к точке входа или имя файла будут снова изменены).

Есть ли лучший способ:

  1. динамически настроить путь с именем контейнера, используя метод, отличный от точки входа модификации; или же
  2. ввести только команду «экспорт» и запустить исходную точку входа, независимо от имени и пути?



Ответы (1)


Если вам нужен динамически генерируемый путь для ваших журналов сбоев Java, я бы предложил динамически генерировать уникальное имя в самом скрипте точки входа в докер.

Как этот, который я проверил и отлично работает.

#!/bin/sh

# Create some random file in /tmp
filename=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo '')
touch /tmp/$filename
cat /tmp/$filename
export filename=$filename

Каждый раз, когда я запускаю этот скрипт, это будет происходить, когда вы создадите несколько таких контейнеров. Он будет генерировать файлы в /tmp со случайными именами.

$ ls /tmp/
DzJXInMvJAgvN  f0rgIMIt115h7  sSgVDXj2zvRTh  x4dBEciezQnix

Таким образом, в этом случае точка входа будет генерировать уникальное имя при каждом вызове, поэтому не будет необходимости вызывать что-либо до docker entrypoint.

Надеюсь это поможет.

Обновить

Пока я понимаю, что вы хотите переопределить путь к файлу журналов сбоев java без редактирования файла dockerfile или сценария точки входа. Вариант -XX:HeapDumpPath из JAVA_OPTS, если я прав.

Вы можете попробовать это

$ docker run -itd --env JAVA_OPTS="$JAVA_OPTS -XX:HeapDumpPath=/mnt/crashdumps/java_$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo '').hprof" alpine sh
$ docker exec -it 75f062ff8906 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=75f062ff8906
TERM=xterm
JAVA_OPTS= -XX:HeapDumpPath=/mnt/crashdumps/java_MyRZcSKxFtZaF.hprof
HOME=/root

Как видите, JAVA_OPTS переопределяется соответствующим именем файла. Надеюсь, это поможет, дайте мне знать.

person mchawre    schedule 19.06.2019
comment
Спасибо за Ваш ответ! Проблема в том, что я не могу изменить файл dockerfile или сценарий точки входа, так как на этапе развертывания он не виден. Я только скачиваю образ и запускаю его. Если бы только был умный способ добавить этот код в существующий сценарий оболочки точки входа, который бы работал. - person msu; 19.06.2019
comment
Ох, я понял. Позвольте мне проверить это. - person mchawre; 19.06.2019
comment
Но вы все еще можете обновить параметр -XX:HeapDumpPath в вашей команде docker run, я прав? Если да, то не могли бы вы предоставить мне команду docker run. - person mchawre; 19.06.2019
comment
было невозможно просто добавить команду «выполнить», так как кластер настраивается из шаблона cloudformation TaskDefinition. Наконец, мы решили эту проблему, убедившись, что контейнер Docker запускает приложение с помощью exec, что разрешает переменную. Спасибо за ваши советы, они помогли нам лучше разобраться в вопросе! - person msu; 01.07.2019