我在我的本地开发计算机上运行了Cloud Foundry Bosh Lite Garden/Runc support,并在其上托管了应用。我可以直接进入迭戈单元虚拟机并执行
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":""}
不幸的是什么也没告诉我。我尝试在JSON有效负载中添加"user":"vcap"
但结果是相同的。当我添加-H "Content-Type: application/json" -d
时,我得到了
curl: (56) Problem (2) in the Chunked-Encoded data
问题:如何通过Garden API在容器内执行任意命令并检索它的输出?
答案 0 :(得分:2)
转到图书馆
在Garden容器中执行命令的支持方式是通过Go client library。例如:
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 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交互。
首先,对运行端点进行request,然后连接为hijacked。花园客户端通过使用被劫持的stdin连接并命中另外两个streaming来启动endpoints stdio进程。
在容器中运行进程并不是太难,在请求体中只需要json编码garden.ProcessSpec
,但输出流是相当棘手的。