錯(cuò)覺
第一次接觸 docker,都會(huì)有個(gè)錯(cuò)覺,認(rèn)為運(yùn)行一個(gè) container 就和運(yùn)行一個(gè)虛擬機(jī)一樣, docker run ...
之后,該 container 即一直處于 running 狀態(tài)属提。
Sorry! You are absolutely wrong!
container 剛起來的時(shí)候,用戶可以通過 dockerfile 中的 CMD,ENTRYPOINT裆馒,或者直接在 docker run
后面接 comand,來指定 container 啟動(dòng)時(shí)執(zhí)行的程序凡桥。如果指定的程序只是一個(gè)短暫的任務(wù)蟀伸,比如 echo sorry
。那么,sorry啊掏,container 在輸出 “sorry” 之后蠢络,就退出了〕倜郏可以通過 docker inspect
看到刹孔,container 狀態(tài)變成了 Exited。
有人說娜睛,這有什么關(guān)系髓霞,container 還在那里,沒有銷毀畦戒,只是狀態(tài)值不是 running 而已方库。
可是,可是障斋,這個(gè)真是有關(guān)系白萘省!
一旦進(jìn)入 Exited 狀態(tài)垃环,以下命令將不再 work:
docker exec <container>
docker attach <container>
這兩個(gè)命令都需要 <container>
處于 running!
重啟邀层,重啟
在非常不情愿接受以上事實(shí)之后,你或許馬上想到了解決方案—— docker start
官方文檔里有明確指出遂庄,docker start <container>
可以重新啟動(dòng) <container>
寥院,那它又可以轉(zhuǎn)成 running 狀態(tài)啦~~
是的,沒錯(cuò)涧团!
但是只磷,(很殘忍滴告訴你)問題依然沒有解決!
剛剛 start 的 container 在啟動(dòng)之后泌绣,會(huì)再一次執(zhí)行 CMD 的命令钮追。然后。阿迈。然后元媚。。它又很快完成任務(wù)苗沧,進(jìn)入 Exited 狀態(tài)休息了刊棕。。待逞。
Solution甥角!
如果啟動(dòng)一個(gè) container 之后,想把它當(dāng)做一個(gè)虛擬機(jī)使用(也就說识樱,使用 docker exec 在 container 內(nèi)部環(huán)境中運(yùn)行程序)嗤无,那么一定要保證這個(gè) container 一直處于 running 的狀態(tài)震束。
有兩種情況需要考慮:
- container 在啟動(dòng)的時(shí)候,CMD 沒有指定一些 service 任務(wù)
- CMD 中指定了一些重要的 service当犯,比如 web 服務(wù)
對(duì)于第二種情況垢村,container 中一直運(yùn)行著 web 服務(wù)器,作為一個(gè) service嚎卫,除非你主動(dòng) stop 它嘉栓,這個(gè) service 會(huì)一直跑著。于是拓诸,起來的 container 也會(huì)一直 running侵佃,于是執(zhí)行 docker exec
沒有任何問題
對(duì)于第一種情況,很明顯 container 不久之后就會(huì) Exited恰响。讓它一直處于 running 的方法至少有兩種:
既然 CMD 沒有指定啥 service趣钱,那么可以假設(shè) CMD 指定的任務(wù)不重要,如果真的很重要胚宦,可以在制作 dockerfile 的時(shí)候通過 RUN 指定首有。所以,我們可以修改 CMD枢劝,比如
docker run <image> tail -f /dev/null
其中tail -f /dev/null
這個(gè)程序會(huì)一直 block 住井联,沒有外界 signal 的情況下,不會(huì)退出您旁,于是 container 就一直 running上面這種方法烙常,畢竟有可能會(huì)覆蓋 dockerfile 中的 CMD,一個(gè)更好的方法是——
docker commit
.
docker run <image>
docker commit `docker ps -ql` <new_image>
docker stop `docker ps -ql`
docker rm `docker ps -ql`
docker run <new_image> tail -f /dev/null
其中鹤盒,docker ps -ql
用于獲得最近創(chuàng)建的 container 的 id蚕脏。這個(gè)方法的缺點(diǎn)在于,多創(chuàng)建了一個(gè) image侦锯,占用空間驼鞭。這里可能看不出來有啥影響,考慮 CI/CD 情形的話尺碰,這個(gè)缺點(diǎn)幾乎是不能忍挣棕。