Доступ к файлу в докере с использованием JavaScript / Node - PullRequest
0 голосов
/ 06 февраля 2019

Есть ли способ программного доступа к файлу в контейнере (докере) во время выполнения.Я попытался использовать node-docker-api, чтобы сначала настроить все и установить соединение:

const docker = new Docker({
    "host": "tcp://docker:port"
});

// List
docker.container.list()
// Inspect
    .then(containers => containers[0].status())
    .then(container => container.top())
    .then(processes => console.log(processes))
    .catch(error => console.log(error));

, где "port" - это 4-значный номер порта.Но я получаю это сообщение об ошибке:

{ Error: connect ECONNREFUSED 127.0.0.1:80
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1081:14)
  errno: 'ECONNREFUSED',
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 80 }

ОБНОВЛЕНИЕ: Я сделал что-то подобное в Java с dockerjava, используя https://github.com/docker-java/docker-java/issues/253 и httphijack - https://gist.github.com/missedone/76517e618486db746056

ExecCreateCmdResponse execCreateResp = dck.execCreateCmd(cid).withCmd("bash")
        .withAttachStderr().withAttachStdout().withAttachStdin().withTty(false).exec();

HashMap<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");

HttpHijack ws = new HttpHijack(new URI("http://127.0.0.1:2376/v1.19/exec/" + execCreateResp.getId() + "/start"));
String payload = "{\"Detach\": false,\"Tty\": false}";
ws.post(headers, payload);

изатем скопировать файл из контейнера, используя:

try (TarArchiveInputStream tarStream = new TarArchiveInputStream(
    docker.copyArchiveFromContainerCmd(containerId, "/home/seluser/Downloads/" + fileName).exec())) {
    unTar(tarStream, new File(filePath));
    return;
}catch(NotFoundException e){
    e.printStackTrace();
}

Но я не могу найти подход для достижения вышеизложенного с использованием javascript / node

1 Ответ

0 голосов
/ 06 февраля 2019

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

Лучше всего использовать тома докера для хранения данных.В вашем случае, если вы можете хранить файлы в томе докера, вы можете запустить свой код из другого контейнера и просмотреть эти файлы из него.Таким образом, контейнеры будут совместно использовать одно и то же хранилище, которое не является эфемерным и переживет перезапуск контейнера.

Если тома докера не в вашем случае, то единственная идея, на мой взгляд, это играть с Docker REST API и особенно с помощью метода Exec .

Используя этот метод, вы можете выполнять команды Linux в контейнере.


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

Пример: docker run -v /host/folder:/container/folder <your_image>

Таким образом, любое изменение в папке Docker будет отражено в папке на вашем хост-компьютере - так что вы сможете получить к ним доступ.

Подробнее


ОБНОВЛЕНИЕ 2: Вы можете использовать Docker REST API для выполнения команд внутри контейнера докера следующим образом:

  1. Включите TCP-доступ к REST API: Редактируйте /lib/systemd/system/docker.service и измените следующую строку: ExecStart=/usr/bin/dockerd -g /data/docker -H fd:// на ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 и сохраните файл.Тогда systemctl daemon-reload и service docker restart.Теперь у вас должна быть возможность доступа к API на http://127.0.0.1:2375 - в ответ вы должны получить { "message": "page not found" }.

  2. Создать объект Exec с помощью REST API, пример:

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"AttachStdout": true,"AttachStderr": true,"Cmd": ["date"]}' \
http://127.0.0.1:2375/v{dockerVersion}/containers/{containerId}/exec 

Здесь:

  • dockerVersion - версия вашего механизма докера, может быть получена с помощью команды docker version (см. Версиюдля сервера в моем случае это 1,38 - поэтому в URL это будет выглядеть как v1.38 не забудьте v)
  • containerId - идентификатор вашего контейнера в докере, может быть получен с помощью следующей команды: curl http://127.0.0.1:2375/v{dockerVersion}/containers/json

В ответ на /containers/{containerId}/exec вы должны получить что-то вроде: {"Id": "{objectId}"}

Выполнить ранее созданную команду:
curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"Detach": false,"Tty": false}' \
http://127.0.0.1:2375/v{dockerVersion}/exec/{objectId}/start

Здесь:

  • objectId - идентификатор, возвращенный из API докера на предыдущем шаге (ШАГ 2)

В качестве ответа вы должны получить простой текст - вывод вашей команды.

ПРИМЕЧАНИЕ: * * * * * В теле JSON Cmdмассив, так что вы можете указать несколько команд.

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