我有一个应用程序,除其他功能外,它还允许您在api的帮助下使用自定义的运行代码启动docker容器,该api也已被dockerized。
因此从API容器执行:
exec(`curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d \'{"Image": "botimage", "ExposedPorts": {"${PORT}/tcp": {"HostPort": "${PORT}"}}, "HostConfig": {"Binds": ["${dirPath}/bots/api/bots/strategies:/usr/src/bots/strategies", "${dirPath}/bots/api/database:/usr/src/bots/database", "${dirPath}/postgres/data:/usr/src/bots/data"], "NetworkMode": "bitmex_backend"}, "PortBindings": { "${PORT}/tcp": [{ "HostPort": "${PORT}" }] }, "Env": ["TOPIC=${TOPIC}","BOTNAME=${BOT_NAME}","EXEC_ENV=${EXEC_ENV}","BITMEX_KEYS=${BITMEX_KEYS}","TIME_FRAME=${TIME_FRAME}","PORT=${PORT}"], "Cmd": ["node", "app.js"]}\' -X POST http:/v1.24/containers/create?name=${BOT_NAME}`,
(err, stdout, stderr) => {
if (err) {
console.error(err)
return;
}
var id = JSON.parse(stdout).Id;
// Would this work with the name too?
logEvent(LOG_LEVELS.info, RESPONSE_CODES.LOG_MESSAGE_ONLY, `Initializing containerised strategy `)
exec(`curl --unix-socket /var/run/docker.sock -X POST http:/v1.24/containers/${id}/start`, (err, stdout, stderr) => {
if (err) {
console.error(err)
return;
}
});
});
然后它又动态地旋转了一个新的容器。
[我不知道如何将这个新容器从另一个容器中取出。
从本地主机,我可以简单地做:
curl --unix-socket /var/run/docker.sock -X POST http:/v1.24/containers/test/stop
curl --unix-socket /var/run/docker.sock -X DELETE http:/v1.24/containers/test
但是,当我尝试通过以下方式从另一个Docker容器执行此操作时:
exec(`curl --unix-socket /var/run/docker.sock -X POST http:/v1.24/containers/test/stop`)
exec(`curl --unix-socket /var/run/docker.sock -X DELETE http:/v1.24/containers/test`)
我收到以下错误:
{错误:命令失败:curl --unix-socket /var/run/docker.sock -XPOST http:/v1.24/containers/test/stop curl:(7)无法连接到服务器
at ChildProcess.exithandler (child_process.js:299:12) at ChildProcess.emit (events.js:193:13) at maybeClose (internal/child_process.js:999:16) at Process.ChildProcess._handle.onexit (internal/child_process.js:266:5) killed: false, code: 7,
信号:null,cmd:
我认为在构建容器时,可以通过完成诸如external_links之类的操作来解决此类问题。
任何想法,如果这是正确的选择?或我该如何解决这个问题?单位看起来像是网络问题。
让docker容器按照您所描述的方式控制其他docker容器的唯一方法是将docker套接字(/var/run/docker.sock
)暴露给“控制”容器。您可以这样做:
darkstar:~$ docker run \
-v /var/run/docker.sock:/var/run/docker.sock \
<my_image>
darkstar:~$ docker exec -u root -it <container id> /bin/bash
现在,作为容器内部的根目录,您可以安装Docker CLI(这并不是严格必要的,这取决于您计划如何从容器内部操作Docker。而且,我假设使用的是Debian式的Linux,YMMV):] >
root@host:/# apt-get update root@host:/# apt-get -y install apt-transport-https \ ca-certificates \ curl \ gnupg2 \ software-properties-common root@host:/# rel_id=$(. /etc/os-release; echo "$ID") root@host:/# curl -fsSL https://download.docker.com/linux/${rel_id}/gpg > /tmp/dkey root@host:/# apt-key add /tmp/dkey root@host:/# add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/${rel_id} \ $(lsb_release -cs) stable" root@host:/# apt-get update root@host:/# apt-get -y install docker-ce
[我建议在此处(从主机)进行
docker commit
以保存图像的状态,因此您无需在每次重建时都重复上述步骤。
现在容器应该可以访问套接字了:
root@host:/# docker ps -a CONTAINER ID IMAGE COMMAND CREATED ... 69340bc13bb2 my_image "/sbin/tini -- /usr/…" 8 minutes ago ...
这是一个好主意还是值得商bat的。如果有任何避免的方法,我建议不要这样做。从本质上讲,这是一个安全漏洞,使使用容器的一些主要好处无处可挡:隔离和对特权升级的控制。