2014-09-19 49 views
2

我有一个docker image正确设置所有必要的工具和环境。但是,我很难在后台运行它。Docker SSH或分离/附加

好像有两种方法:

(1)可以运行框,守护,我可以连接到它,每当我想用箱子。但是,在我将其作为守护程序运行后,容器以零代码退出。

$:~/docker/docker_scrapy$ sudo docker run -ti -v ~/docker/docker_scrapy/myvolume:/var/myvolume 3fb9894af1d9 /bin/bash 
[email protected]:/# python -c 'from bs4 import BeautifulSoup' 
[email protected]:/# cd /var/myvolume/ 
[email protected]:/var/myvolume# 

$:~/docker/docker_scrapy$ sudo docker run -d -v ~/docker/docker_scrapy/myvolume:/var/myvolume 3fb9894af1d9 
c5fab6e6ac02a579e3371aa641b18ca67feb93a9f4f4934b6d083157182fe4e1 
$:~/docker/docker_scrapy$ sudo docker ps 
CONTAINER ID  IMAGE    COMMAND    CREATED    STATUS    PORTS    NAMES 

很显然,我可以在交互模式下启动箱,但是当我尝试运行它作为一个守护进程,它会与代码0退出,我开始之后。我不能附加它,因为我需要启动它。这是否意味着如果它处于空闲状态,您将无法在守护进程模式下运行映像? (2)或者将它设置为一个SSH服务器,并且我可以在任何时候ssh进入并执行工作。像流浪了/ SSH ..

总结:

(1)我做了什么不对的分离/附加?

(2)哪种方法可以在后台运行docker?守护进程/ ssh

+0

你可以包括实际运行的命令,当你在后台启动的容器? – 2014-09-19 20:05:00

+0

我有一个类似的问题,试图在容器中运行Oracle数据库(它作为服务运行)。当我用* -it *运行时,它工作正常;当我使用* -d *时,只要入口点脚本到达EOF,它就会退出。看起来Docker类似于在守护进程容器模式下运行守护进程(除其他之外)... – Asotos 2014-11-25 08:04:38

回答

3

如果您在启动等待输入的服务后为其提供另一个命令,那么该容器将继续运行,直到您附加并退出命令。服务启动后,我通常会留下一个shell,以便调试。这里有一个简单的例子:

首先让我们创建一个在后台运行的服务

[email protected]:~$ docker run -ti ubuntu bash 
[email protected]:/# cat <<'EOF' >start-service.sh 
> while true 
> do 
> echo service is running >> service.log 
> sleep 10 
> done 
> EOF 
[email protected]:/# chmod +x start-service.sh 
[email protected]:/# exit 
[email protected]:~$ docker ps -l 
CONTAINER ID  IMAGE    COMMAND    CREATED    STATUS      PORTS    NAMES 
5dc7f330b947  ubuntu:12.04  bash    50 seconds ago  Exited (0) 3 seconds ago      jolly_nobel   
[email protected]:~$ docker commit 5dc7f330b947 service/example 
4c37b69b129287d79a6fe3916e4293f935194966b1de49d125f1cf8d6ab14f6f 

那么我们就可以启动它(用&在这里,我的背景就在您的示例&将不需要。) 。请注意,使用交互式选项和分离选项都可以。

[email protected]:~$ docker run -ti -d service/example bash -c "./start-service.sh & bash" 
b35a5397ea2d29b4085d93ef32270379b09e49118380b0376309bca74fd719d0 
[email protected]:~$ docker ps 
CONTAINER ID  IMAGE     COMMAND    CREATED    STATUS    PORTS    NAMES 
b35a5397ea2d  service/example:latest bash -c './start-ser 7 seconds ago  Up 7 seconds       cranky_wright  

以后,我们可以将与通过查看它检查服务的日志文件:

[email protected]:~$ docker attach b35a5397ea2d 

[email protected]:/# cat service.log 
service is running 
service is running 
service is running 
[email protected]:/# 

我不建议正在运行的sshd的容器内,因为它留下了一个选项,即ISN攻击”对我来说严格有用。

+0

+1您能否在'docker run -ti -d service/example bash中解释第一个'bash'的含义? c“./start-service.sh&bash”'。它是[docker run](https://docs.docker.com/engine/reference/run/)语法的命令吗?我目前正在尝试'docker run -ti -d service/example bash -c bash'(用于允许'ssh'进入分离的容器),并想知道是否一个'bash'可能是多余的。 – Drux 2016-07-17 14:56:29

+1

是的第二个bash是多余的。 -c是程序bash的参数,而不是名为docker的程序的参数。 bash -c“这里的命令行”启动bash shell /程序并指示它在命令提示符处键入之后运行-c后面的任何内容。新版本的docker会在很多情况下自动插入对bash -c的调用,这很有帮助,并且不清楚你实际需要这些东西的地方 – 2016-07-17 20:54:50

0

那里有很多问题。我首先建议你通过Docker教程来掌握一些基本概念。这说...

Dockerfile将永远不会在后台运行,这不是如何码头工程。没有cmd,没有入口点,没有什么可运行的。

默认情况下,Docker运行一个任务,当它返回容器时停止。所以,如果你想要的只是一个sshd,你可以在非守护进程模式下运行它作为你的CMD。 (sshd的-D)

有办法,虽然运行的应用程序进程化:

使用supervisord,如记录在docker site

另一种选择是phusion/baseimage

Phusion/baseimage提供了ssh访问,但老实说要做我需要的容器,我发现nsenter更容易使用。尤其是在与phusion docker-bash工具配对时。

0

通知:这个答案推广了我写的一个工具。

首先,概念上在一个容器中运行多个进程并不是正确的方法(https://docs.docker.com/articles/dockerfile_best-practices/)。更有利的解决方案是涉及多个容器,每个容器运行自己的过程/服务。将它们连接在一起会产生一个连贯的应用程序。

我已经创建了一个容器化的SSH服务器,可以“粘”到任何正在运行的容器。这样你就可以创建每个容器的组合,没有那个容器甚至不知道ssh。唯一的要求是容器有bash。

以下示例将启动附加到名称为“sshd-web-server1”的容器的SSH服务器。

docker run -ti --name sshd-web-server1 -e CONTAINER=web-server1 -p 2222:22 \ 
-v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker \ 
jeroenpeeters/docker-ssh 

您可以使用您选择的ssh客户端连接到SSH服务器,就像您通常那样。

请注意:Docker-SSH目前仍在开发中,但它确实有效!请让我知道你在想什么

更多的指针和文档见:https://github.com/jeroenpeeters/docker-ssh