Так, каковы различные решения этой проблемы? И какой из них самый лучший?
Лучшее решение уже предоставлено @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 .