HostPath с minikube - Kubernetes

ОБНОВЛЕНИЕ: я подключился к minikubevm, и я вижу, что мой каталог хоста смонтирован, но там нет файлов. Кроме того, когда я создаю файл, его не будет на моем хост-компьютере. Любая связь между ними

Я пытаюсь смонтировать каталог хоста для разработки моего приложения с помощью кубернетов.

Как рекомендовано в документе, я использую minikube для запуска кластера Kubernetes на моем компьютере. Цель - создать среду разработки с докером и кубернетами для разработки моего приложения. Я хочу смонтировать локальный каталог, чтобы мой докер мог читать код приложения оттуда. Но это не работает. Любая помощь будет очень признательна.

мое тестовое приложение (server.js):

var http = require('http');
var handleRequest = function(request, response) {
response.writeHead(200);
response.end("Hello World!");
}
var www = http.createServer(handleRequest);
www.listen(8080);

мой Dockerfile:

FROM node:latest
WORKDIR /code
ADD code/ /code
EXPOSE 8080
CMD server.js

моя конфигурация pod kubernetes: (pod-configuration.yaml)

apiVersion: v1
kind: Pod
metadata:
  name: apiserver
spec:
  containers:
  - name: node
    image: myusername/nodetest:v1
    ports:
    - containerPort: 8080
    volumeMounts:
    - name: api-server-code-files
      mountPath: /code
  volumes:
  - name: api-server-code-files
    hostPath:
      path: /home/<myuser>/Projects/nodetest/api-server/code

моя папка:

/home/<myuser>/Projects/nodetest/
- pod-configuration.yaml
- api-server/
    - Dockerfile
    - code/
        - server.js

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

Любая идея ? почему мне не удается смонтировать локальный каталог?

Спасибо за помощь.


person Eliel Haouzi    schedule 31.07.2016    source источник


Ответы (3)


РЕДАКТИРОВАТЬ: Похоже, решение состоит в том, чтобы использовать привилегированный контейнер, или вручную смонтировать домашнюю папку, чтобы виртуальная машина MiniKube могла читать из вашего hostPath - https://github.com/boot2docker/boot2docker#virtualbox-guest-additions. (Благодарим Элиэль за то, что он это выяснил).

Абсолютно возможно настроить том hostPath с помощью minikube, но есть много причуд, и нет очень хорошей поддержки для этой конкретной проблемы.

Попробуйте удалить ADD code/ /code из Dockerfile. Инструкция Docker «ДОБАВИТЬ» копирует код с вашего хост-компьютера на ваш каталог /code контейнера. Вот почему восстановление образа успешно обновляет ваш код.

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

Также не забудьте проверить права доступа к каталогу code/ на вашем хост-компьютере.

Моя единственная другая мысль связана с монтированием в корневой каталог. У меня возникли проблемы при монтировании томов Kubernetes hostPath в / из каталогов в корневом каталоге (я предполагаю, что это было связано с разрешениями). Итак, что-то еще, что можно попробовать, - это mountPath, например /var/www/html.

Вот пример функционального тома hostPath:

apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  volumes:
    - name: example-volume
      hostPath:
        path: '/Users/example-user/code'
  containers:
    - name: example-container
      image: example-image
      volumeMounts:
        - mountPath: '/var/www/html'
          name: example-volume
person springle    schedule 02.08.2016
comment
Я обновляю свой pod.yaml, как вы предлагаете, с помощью mountPath до / var / www / html, но он по-прежнему не работает. Что это странно, так это то, что в предыдущем примере, когда я пытался подключиться к / code, когда я подключаюсь к minikube через ssh, я вижу в домашнем каталоге виртуальной машины смонтированный путь (/ home / ‹myuser› / Projects / nodetest / api -server / code), но без файла server.js - априори говорят, что это не проблема разрешения - person Eliel Haouzi; 02.08.2016
comment
Я вижу, что вы работаете на Mac OS. мой хост - ubuntu 16.04. Это может быть связано? - person Eliel Haouzi; 02.08.2016
comment
Определенно есть некоторые различия между MacOS и Ubuntu, но это не должно менять конфигурацию здесь. Интересно видеть, что он монтируется правильно, но не может поделиться фактическими файлами. Я помню, как боролся с hostPaths на minikube, но тот пример, который я привел, был моим рабочим решением. Итак, чтобы подтвердить - если вы запустите kubectl exec -it apiserver -- ls <mountPath>, это пустой каталог? - person springle; 02.08.2016
comment
Статус узла apiserver - CrashLoopBackOff, поскольку этот узел выдает исключение, поскольку он не видит server.js, а затем команда kubectl exec -it apiserver -- ls <mountPath> говорит мне error: error executing remote command: error executing command in container: container not found ("node"), но когда я делаю minikube ssh, я вижу ‹mountpath›, но без файлов .. - person Eliel Haouzi; 02.08.2016
comment
В целях тестирования, можете ли вы отредактировать команду в файле докера на CMD ["sleep", "1000"], чтобы она не вылетала при запуске? - person springle; 02.08.2016
comment
Хорошо, мы продвигаемся вперед, когда я запускаю kubectl exec -it apiserver -- ls <mountpath>, я пробую его с / code и с / var / www / html, в обоих случаях он показывает мне пустой каталог. но он правильно монтирует путь ... это довольно странно - person Eliel Haouzi; 02.08.2016
comment
Еще одна интересная вещь заключается в том, что когда я запускаю touch server.js в minikube hostPath, он говорит, что мне отказано в разрешении ... (я думаю, что проблема здесь). Я хотел знать, помещаю ли я туда вручную server.js он будет в моем модуле, когда я его создам - person Eliel Haouzi; 02.08.2016
comment
Что, если вы запустите kubectl exec -it apiserver -- bash, чтобы открыть сеанс оболочки в модуле, и попытаетесь создать его там? Это определенно похоже на проблему с разрешениями. - person springle; 02.08.2016
comment
Ok ! когда я меняю разрешение hostPath в minikube на docker: staff и добавляю вручную server.js, он работает! НО проблема, которая не связана с моим хостом server.js .. - person Eliel Haouzi; 02.08.2016
comment
Единственная проблема теперь - как связать его с моим hostPath - person Eliel Haouzi; 02.08.2016
comment
В документе hostPath есть предложение о привилегиях root, но я могу понять, как оно может решить проблему: ›каталоги, созданные на базовых хостах, доступны для записи только root, вам нужно либо запустить свой процесс как root в привилегированном контейнере, либо изменить права доступа к файлам на хосте, чтобы иметь возможность писать на том hostPath - person Eliel Haouzi; 03.08.2016
comment
Итак, я нашел решение, вы должны вручную смонтировать свою домашнюю папку, чтобы виртуальная машина minikube могла читать из вашего hostPath, как говорится в документе boot2docker: github.com/boot2docker/boot2docker#virtualbox-guest-additions Ваш ответ и комментарии были наиболее полезными, поэтому отредактируйте свой ответ с помощью решения, и я одобряю это (и вы получите награду :)) - person Eliel Haouzi; 03.08.2016
comment
Отличная работа, чтобы понять это, и спасибо, что поделились решением! Я отредактировал ответ выше, и, надеюсь, это поможет другим двигаться вперед. - person springle; 03.08.2016
comment
Позвольте нам продолжить это обсуждение в чате. - person Eliel Haouzi; 03.08.2016
comment
Привет, Элиэль Хаузи, это обсуждение было очень полезным. Вы знаете, как сделать hostPath родственником? Docs говорит, что на данный момент это невозможно, но, может быть, для этого есть какие-то хаки? - person Zhorzh Alexandr; 11.05.2018

Теперь они дали minikube mount, который работает во всех средах

https://github.com/kubernetes/minikube/blob/master/docs/host_folder_mount.md

Пробовал на Mac:

$ minikube mount ~/stuff/out:/mnt1/out
Mounting /Users/macuser/stuff/out into /mnt1/out on the minikube VM
This daemon process needs to stay alive for the mount to still be accessible...
ufs starting

И в пакете:

apiVersion: v1
kind: Pod
metadata:
  name: myServer
spec:
  containers:
  - name: myServer
    image: myImage
    volumeMounts:
    - mountPath: /mnt1/out
      name: volume
    # Just spin & wait forever
    command: [ "/bin/bash", "-c", "--" ]
    args: [ "while true; do sleep 30; done;" ]
  volumes:
  - name: volume
    hostPath:
      path: /mnt1/out
person enator    schedule 21.06.2018
comment
Приятно спасибо! Это значительно ускоряет мою отладку! ^^ - person Kamafeather; 28.10.2020

Лучше всего встраивать код в ваше изображение, вы не должны запускать изображение с кодом, только что поступающим с диска. Ваш Dockerfile должен выглядеть примерно так:

FROM node:latest COPY /code/server.js /code/server.js EXPOSE 8080 CMD /code/server.js

Затем вы запускаете образ в Kubernetes без каких-либо томов. Вам необходимо перестраивать образ и обновлять модуль каждый раз, когда вы обновляете код.

Кроме того, в настоящее время я не знаю, что minikube позволяет монтировать виртуальную машину, которую он создает, и хост, на котором она запущена.

Если вам действительно нужен чрезвычайно быстрый цикл обратной связи при изменении кода во время работы контейнера, вы можете использовать только Docker с -v /path/to/host/code:/code без Kubernetes, а затем, как только вы будете готовы, создать образ, развернуть и протестировать его на minikube. Однако я не уверен, что это сработает, если вы изменяете основной файл .js своего приложения node.

person puja    schedule 02.08.2016
comment
Благодарю за ответ. Преимущество локального запуска Kubernetes в том, что ваша среда разработки похожа на вашу prod env. подключение локальных каталогов к модулям значительно улучшит опыт разработчика. Если в качестве примера моему проекту нужен экземпляр Redis, я хочу запустить его также в моем dev env с kubernetes, чтобы проверить, что они хорошо связаны. Я ищу способ смонтировать hostPath от minikube Vm к моему хосту. В этой проблеме с minikube говорится, что возможно github.com/kubernetes/minikube/issues/2 но я не знаю как. - person Eliel Haouzi; 02.08.2016
comment
Конечно, я понимаю, что вам нужен паритет разработки продуктов. Тем не менее, проблема, о которой вы говорите, остается открытой и еще не решена. Единственный способ - смонтировать NFS с вашего хоста на виртуальную машину, как описано в проблеме здесь: github.com/kubernetes/minikube/issues/2#issuecomment-233629375 - person puja; 03.08.2016
comment
Мой вопрос все еще остается, AFAIK в node.js нет горячей замены кода, поэтому вам все равно придется перезапускать. Почему бы вам не встроить код в свой образ? - person puja; 03.08.2016
comment
Вы правы насчет сервера nodejs, его нужно перезапускать вручную при обновлении кода, но это было только для примера, мое настоящее приложение - это приложение на Python, которое автоматически перезагружается при изменении кода. Моей целью было запустить один и тот же env в env dev и prod. Тем не менее, спасибо за попытку найти решение. - person Eliel Haouzi; 03.08.2016
comment
Хорошо, с python и автоматической перезагрузкой я могу понять вариант использования. Кстати, есть хорошая бродячая установка, которая монтирует NFS с хоста и является многоузловой. Возможно, вам будет удобнее иметь паритет продуктов разработчика: github.com/pires/kubernetes- vagrant-coreos-cluster - person puja; 04.08.2016