Как установить плагины в файловую систему приложения до запуска контейнера приложения? - PullRequest
1 голос
/ 17 марта 2020

У меня есть приложение, упакованное как docker изображение. Приложение имеет несколько плагинов по умолчанию, установленных в /opt/myapp/plugins/. Я хочу установить несколько дополнительных плагинов, что в основном означает копирование плагинов по указанному выше пути приложения:

cp /path/to/more-plugins/* /opt/myapp/plugins/

Как мне это сделать? initContainers полезно в таких случаях? Имеет ли init-container доступ к файловой системе app-контейнера, чтобы можно было выполнить указанную выше команду? Я попытался использовать busybox в initContainers и запустил ls -lR /opt/myapp, чтобы посмотреть, существует ли такой путь. Но, похоже, у контейнера init нет доступа к файловой системе приложения.

Так, каковы различные решения этой проблемы? А какой самый лучший?

Ответы [ 2 ]

3 голосов
/ 17 марта 2020

Я не эксперт по контейнерам, но, насколько я понимаю, лучший способ сделать это - создать новый контейнер на основе вашего текущего docker изображения, который будет копировать файлы на место. Ваше изображение с вашими плагинами и конфигами - это то, что k8s загружает и управляет.

FROM my/oldimage:1.7.1
COPY more-plugins/* /opt/myapp/plugins/
$ docker build -t my/newimage:1.7.1 .
1 голос
/ 17 марта 2020

Так, каковы различные решения этой проблемы? И какой из них самый лучший?

Лучшее решение уже предоставлено @PaulProgrammer, и до тех пор, пока нет противопоказаний, вы должны сделать свои плагины приложения неотъемлемой частью вашего docker изображение . Рассуждение в пользу таких решений было уже хорошо объяснено @Matt:

Я бы сделал копию только в сборке образа контейнера. Это означает, что у вас всегда есть полный, воспроизводимый артефакт того, что работает. - Мэтт

Я полностью согласен с этим, и я также настоятельно рекомендую вам перестроить ваше изображение docker, чтобы решить эту проблему на уровне kubernetes .

Однако, чтобы завершить эту тему и дать вам ответы на дополнительные вопросы, а также устранить все возможные сомнения, я хотел бы добавить несколько слов к уже написанному.

Я хотел бы еще раз подчеркнуть, что это не оптимальное решение , но с технической точки зрения это также возможно сделать с помощью init-контейнеров в kubernetes . Кроме того, я даже попытаюсь объяснить, почему это не лучшее решение или, более конкретно, почему оно не применимо в вашем конкретном случае использования.

Как мне это сделать? Помогает ли initContainers в таких случаях? Имеет ли init-container доступ к файловой системе app-контейнера, чтобы можно было выполнить указанную выше команду? Я попытался использовать busybox в initContainers и запустил ls -lR / opt / myapp, чтобы посмотреть, существует ли такой путь. Но, похоже, у контейнера init нет доступа к файловой системе приложения.

Имейте в виду, что контейнеры init всегда запускаются до контейнеров приложения запускаются и не могут изменять исходную файловую систему контейнера приложения , поскольку при запуске она даже не существует. Однако их можно использовать для предварительного заполнения дополнительного тома, который впоследствии можно установить в контейнере приложения . Посмотрите на приведенный ниже пример:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: debian
  template:
    metadata:
      labels:
        app: debian
    spec:
      containers:
      - name: debian
        image: debian
        command: ['sh', '-c', 'sleep 3600']
        volumeMounts:
         - mountPath: "/app/data"
           name: my-volume
           readOnly: true
      volumes:
      - name: my-volume
        persistentVolumeClaim:
          claimName: example-pvc
      initContainers:
      - name: init-myservice
        image: busybox
        command: ['sh', '-c', 'echo "Content of my file" > /mnt/my_file']
        volumeMounts:
         - mountPath: "/mnt"
           name: my-volume

В этом примере мы заполняем каталог /app/data контейнера приложения некоторым содержимым с помощью контейнера init . command здесь не очень важно. Это может быть что угодно - от получения контента с помощью wget до клонирования git repo или scp некоторого контента с удаленного сервера. Обратите внимание, что вы не можете добавить таким образом дополнительный контент к уже существующему. Если каталог уже существует и в нем уже есть какой-либо контент, он стирается и заполняется новым. На самом деле это не с технической точки зрения. Каталог используется как новая точка монтирования для другого тома. Поскольку он указывает теперь на другой диск и его содержимое, исходное содержимое каталога больше не доступно с нашей точки зрения.

Так, каков типичный вариант использования? Для чего это может быть полезно?

Если вашему приложению требуются какие-то данные для обработки, вы обычно не хотите делать его неотъемлемой частью вашего docker изображения . Представьте, что он меняется довольно часто, и вам всегда нужно загружать его самую последнюю версию. Таким образом, вам не нужно каждый раз перестраивать изображения.

Но это не применимо в вашем случае. Во-первых, потому что вам нужно добавить некоторые данные (дополнительные плагины) в то, что уже является неотъемлемой частью образа контейнера вашего приложения. В этой ситуации init container не очень поможет. Во-вторых, вы скорее хотите иметь единообразное воспроизводимое изображение, содержащее все необходимые плагины.

Как я уже сказал, технически это выполнимо, поскольку вы можете загрузить куда-нибудь все нужные вам плагины (включая оригинальные, которые уже есть). в базовом изображении) и скопируйте весь контент, используя init контейнер . Преимущество такого подхода заключается в том, что не требует от вас создания пользовательских изображений при выпуске новой версии базового приложения. Вы только измените тег image и init контейнер позаботятся о заполнении каталога /opt/myapp/plugins/ всеми необходимыми плагинами, которые вы хотите, и убедитесь, что он не содержит ничего кроме них .

Я надеюсь, что он привнес что-то новое в этот поток и немного прояснил, в каких ситуациях стоит использовать init контейнер для заполнения вашего приложения данными и в каких ситуациях лучше придерживаться вашего custom docker image .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...