1

我有一个Cloud Foundry Bosh Lite安装,在我的本地开发机器上运行了Garden/Runc 支持,并在其上托管了一个应用程序。我可以 ssh 进入 Diego cell 虚拟机并执行

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

我以为我可以通过调用Garden API来实现同样的目的

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 在容器内执行任意命令并检索其输出?

4

1 回答 1

2

去图书馆

在 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())

监狱 CLI

如果您不想编写任何 Go 代码,您可以使用不受支持(但非常有用)的Gaol CLI。例如:

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

GAOL_TARGET如果您在开发机器上运行,请确保在 bosh-lite 上设置适当的例如 10.244.16.6:7777。

HTTP 客户端

最后,通过任何 HTTP 客户端使用整个 Garden API 在技术上是可行的,但是受支持的客户端/服务器库会进行一些连接劫持,这可能会造成混淆。特别是,运行一个进程是最复杂的 API 交互。

首先,向运行端点发出请求,然后连接被劫持。Garden 客户端通过使用被劫持的 stdin 连接并访问其他两个端点来开始为该进程流式传输stdio 。

让一个进程在容器中运行应该不难,只需要garden.ProcessSpec在请求正文中编码一个 json,但流式传输输出有点棘手。

于 2017-03-06T12:33:52.590 回答