Выполнить процесс в контейнере Runc через Garden API

У меня установлен Cloud Foundry Bosh Lite с поддержкой Garden/Runc на моей локальной машине разработчика с приложением, размещенным на нем. Я могу ssh в ячейку Diego VM и выполнить

cell_z1/0# runc exec 5f9c8b67-9170-4c53-4bab-bbb2e6a3acdf /usr/bin/printenv

Это даст следующий результат:

INSTANCE_GUID=5f9c8b67-9170-4c53-4bab-bbb2e6a3acdf
INSTANCE_INDEX=0
CF_INSTANCE_GUID=5f9c8b67-9170-4c53-4bab-bbb2e6a3acdf
CF_INSTANCE_INDEX=0
LANG=en_US.UTF-8
CF_INSTANCE_CERT=/etc/cf-instance-credentials/instance.crt
CF_INSTANCE_KEY=/etc/cf-instance-credentials/instance.key
HOME=/root

Я предполагал, что смогу добиться того же с помощью API Garden, вызвав

cell_z1/0# curl -X POST -d '{"path":"/usr/bin/printenv"}' localhost:7777/containers/5f9c8b67-9170-4c53-4bab-bbb2e6a3acdf/processes

Тем не менее, это вернется

{"Type":"","Message":"EOF","Handle":""}

что, к сожалению, ничего не говорит мне. Я пытался добавить "user":"vcap" в полезной нагрузке JSON, но результат тот же. Когда я добавлю -H "Content-Type: application/json" -d я получил

curl: (56) Problem (2) in the Chunked-Encoded data

Вопрос: как я могу выполнить произвольную команду внутри контейнера через Garden API и получить ее вывод?

1 ответ

Решение

Перейти Библиотека

Поддерживаемый способ выполнения команд в контейнере Garden - через клиентскую библиотеку Go. Например:

gdnClient := client.New(connection.New("tcp", "127.0.0.1:7777"))

container, err := gdnClient.Create(garden.ContainerSpec{})
if err != nil {
  os.Exit(1)
}

buffer := &bytes.Buffer{}
process, err := container.Run(garden.ProcessSpec{
  Path: "/usr/bin/printenv",
}, garden.ProcessIO{
  Stdout: buffer,
  Stderr: buffer,
})
if err != nil {
  os.Exit(1)
}

exitCode, err := process.Wait()
if err != nil {
  os.Exit(1)
}

fmt.Printf("Exit code: %d, Process output %s", exitCode, buffer.String())

Gaol CLI

Если вы предпочитаете не писать код Go, вы можете использовать неподдерживаемый (но очень полезный) интерфейс командной строки Gaol. Например:

gaol create -n myContainer
gaol run -c "/usr/bin/printenv" myContainer

Убедитесь, что вы установили свой GAOL_TARGET например, 10.244.16.6:7777 на bosh-lite, если вы работаете с вашего компьютера разработчика.

HTTP клиенты

Наконец, технически выполнимо работать со всем API-интерфейсом Garden через любой HTTP-клиент, но поддерживаемые клиент-серверные библиотеки могут перехватывать некоторые соединения, что может привести к путанице. В частности, запуск процесса является наиболее сложным взаимодействием API.

Сначала делается запрос к конечной точке выполнения, а затем соединение перехватывается. Садовый клиент начинает потоковую передачу stdio для процесса, используя перехваченное соединение для stdin и достигая двух других конечных точек.

Не должно быть слишком сложно запустить процесс в контейнере, требующий только кодирования json garden.ProcessSpec в теле запроса, но потоковый вывод немного сложнее.

Другие вопросы по тегам