1. 程式人生 > >容器建立後,隨意更改容器內啟動指令碼

容器建立後,隨意更改容器內啟動指令碼

Docker.io上有無數的映象,但是很多用起來並不順手。很多情況下有報錯,容器起不來,而且沒有辦法進行排錯。

個人感覺,好用的基礎映象應該滿足幾點:
1、安全,比如說官方的CentOS、Ubuntu映象,選用軟體用自己信得過的,或者官方的yum
2、有shell,Docker.io上很多映象,但是貌似很多映象執行起來會報錯,沒有shell,無法進行排錯。如果把應用放到一個可能起不來的映象中,我覺得並不好。

關於第一點,很簡單,用Docker.io的映象,或者有大神自己做純淨的;用yum或者github之類的下原始碼編譯。

關於第二點,比較複雜,但是實現起來並不麻煩,用起來會很順手,可以隨時調整容器內部的啟動指令碼。

使用的工具如下:
1、Dockerfile,ENTRYPOINT、CMD
2、docker run -v,-v是個好引數,很靈活
3、supervisord,提供守護程序,防止容器內程序執行完畢退出
4、bootstrap.sh,從million12/supervisord這個容器中提取的,下面貼出來

按操作順序說吧:
1、基礎映象,centos:latest,直接Docker.io下載就好,又新又安全。
2、yum install supervisor,先要安裝epel-release源。
3、建立/config/init目錄,把bootstrap.sh放到/config目錄下。
4、docker commit > docker build

詳細解釋下各項:
1、bootstrap.sh:
通過ENTRYPOINT,啟動容器的時候執行這個指令碼,這個指令碼有兩個作用:
1)啟動supervisord,作為守護程序,也可以通過這個程序監控應用是否執行。
2)將/config/init目錄下的指令碼執行,這個地方就可以寫我們自己的應用的執行指令碼。執行哪個寫哪個。

#!/bin/bash

set -e
set -u

# Supervisord default params
SUPERVISOR_PARAMS='-c /etc/supervisord.conf'


# Create directories for supervisor's UNIX socket and logs (which might be missing
# as container might start with /data mounted from another data-container). mkdir -p /data/conf /data/run /data/logs chmod 711 /data/conf /data/run /data/logs if [ "$(ls /config/init/)" ]; then for init in /config/init/*.sh; do . $init done fi # We have TTY, so probably an interactive container... if test -t 0; then # Run supervisord detached... supervisord $SUPERVISOR_PARAMS # Some command(s) has been passed to container? Execute them and exit. # No commands provided? Run bash. if [[ [email protected] ]]; then eval [email protected] else export PS1='[\[email protected]\h : \w]\$ ' /bin/bash fi # Detached mode? Run supervisord in foreground, which will stay until container is stopped. else # If some extra params were passed, execute them before. # @TODO It is a bit confusing that the passed command runs *before* supervisord, # while in interactive mode they run *after* supervisor. # Not sure about that, but maybe when any command is passed to container, # it should be executed *always* after supervisord? And when the command ends, # container exits as well. if [[ [email protected] ]]; then eval [email protected] fi supervisord -n $SUPERVISOR_PARAMS fi

2、Dockerfile

FROM centos:latest
MAINTAINER artemus717@gmail.com
ENTRYPOINT ["/config/bootstrap.sh"]
CMD ["/bin/bash"]

很簡單,只修改需要修改的,畢竟是作為基礎映象。
CMD保證我們一定是有bash的,也不用每次docker run都要在最後加一個/bin/bash。

4、docker run -v path:/config/init/
這一步是最重要的,映象執行為容器後,執行的命令或指令碼是被寫死的,無法靈活的調整,但是可以通過bootstrap.sh這個指令碼和docker run -v 來實現應用的靈活啟動。
將本機的一個目錄對映到容器內部,我們就把控制容器內部應用啟動的目錄映射出去。
目前判斷,docker run -v 是會先於ENTRYPOINT執行的,所以可以通過這個操作,靈活控制、隨時更改容器內部的應用啟動。

如果做了什麼喪盡天良、慘無人道的操作,應用啟動就報錯,導致容器起不來,那就把本機目錄中的啟動指令碼刪掉,只啟動容器的系統,然後通過shell來排查錯誤,保證能正常啟動了再把啟動指令碼加到目錄裡就可以了;如果刪掉了所有的啟動指令碼還是起不來,那就說明是容器基礎的系統有問題了,我覺得可以直接重做容器了。

這樣一個可以在建立容器後還可以隨便修改容器啟動指令碼的映象就誕生了。