2014-09-19 99 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