iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0
自我挑戰組

用 Docker 了嗎? 30 天的 Docker 基本教學系列 第 13

Day 13 深入 Docker Container 內部 ( 下 )

  • 分享至 

  • xImage
  •  

該文章同步發佈於:我的部落格

也歡迎關注我的 Facebook 以及 Instagram 接收軟體相關的資訊!

以及這個 30 天的 Docker 教學有出書喔!如果喜歡這個系列可以支持一下,天瓏書局

前情提要

昨天介紹了如何和容器內的作業系統透過終端機進行溝通,而今天則會介紹關於容器的初始指令。

也攸關於容器在什麼時候會進入退出狀態。

容器的初始指令

這是昨天的範例:

$ docker container run --interactive --tty nginx bash

為什麼在 nginx 後面還要加上 bash 這個指令呢?

我們利用 Docker 提供的 --help 方法來看看,到底後面能夠接受什麼樣的參數呢?

$ docker container run --help
Usage: docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
....

可以看到 IMAGE 的後方還可以接受 COMMAND 的參數,而這個 COMMAND 就是容器啟動時會執行的指令。

那為什麼之前又不需要呢?是因為映像檔在設計的時候大部分都會給予一個 COMMAND 來當作初始指令,如果沒有輸入額外的 COMMAND 去取代的話,預計就會使用原本的。

而 nginx 這個映像檔原先的初始指令就是 nginx -g daemon off,也就是啟動 nginx 的意思。

在上面的範例中,我們就是利用了 bash 來取代掉 nginx -g daemon off 這段初始指令,變成容器在啟動時執行 bash 這個命令處理器。

接著我們回到容器內部,再次輸入相同的指令,並且離開:

$ docker container run --interactive --tty nginx bash
root@d33940b87e66:/# exit

透過列出容器的指令,我們會發現這個容器竟然進入了退出狀態。

$ docker container list
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

$ docker container list --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d3394......  nginx "/doc.. 7 sec.. Exited       eleme...

容器的退出機制

還記得我們在一開始啟動 nginx 容器時,使用 Ctrl + C 的方式就使容器進入退出狀態吧?但為什麼這邊是退出了 bash 執行程序就退出容器了呢?
先說結論:

只有終止了初始指令所執行的程序,才會使容器進入退出狀態

這句話可能有點難以理解,但依照本書的方式,我們就是會不斷地進行驗證,來理解基本觀念。

在驗證上面那段結論之前,我們要先學會進入運作中的容器才有辦法進行驗證。

進入運作中的容器

剛剛的示範都是在第一次啟動容器時進入,但其實大部分時候程序是一直在執行,所以我們隨時都有進入容器的可能。

這邊我們先讓 nginx 在背景執行,接著我們試著進入內部:

$ docker container run --detach --publish 80:80 nginx
64d52ea0e08797aade7f86701b60ed903373f53713d6f7eca62...

$ docker container list
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS              NAMES
64d52ea0... nginx "/doc..  31 se.. Up 2.. 0.0.0.0:80->80/tcp hungry..

這邊確定了 nginx 正在背景執行,接著我們進入正在運作的容器:

$ docker container exec --interactive --tty 64d52 bash
root@64d52ea0e087:/# ls
bin  boot  dev	docker-entrypoint.d  docker-entrypoint.sh  etc	home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@64d52ea0e087:/# exit
exit

我們進入後一樣用了 ls 這個 Linux 指令來查看容器中的檔案,並且輸入 exit 退出,注意到這邊我們使用了 exec 這個新的指令,只要是對正在運作中的容器下指令,都需要加入 exec 才能執行。

這邊我們退出了 nginx 的容器,查看一下容器列表會發現其還在運作:

$ docker container list
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS              NAMES
64d52ea0... nginx "/doc..  31 se.. Up 1.. 0.0.0.0:80->80/tcp hungry..

這就回歸到上一個段落所提到的:

只有終止了初始指令所執行的程序,才會使容器進入退出狀態

但這邊我們退出的程序並不是這個容器的初始指令,這個容器的初始指令是 nginx 一開始預設的,所以我們退出 bash 程序並不會造成容器退出。

我們可以再試試看另外一個例子,這邊我們啟動一個 Ubuntu 的容器:

$ docker container run --interactive --tty --name ubuntu ubuntu # 不換行
root@c4131a4bd1fa:/#

你可能會想問,這邊為什麼不用加 bash 在最後面呢?

這是因為 Ubuntu 這個映像檔本身的初始指令就是 bash 喲!所以我們不需要用別的指令來取代預設的,就會自動啟動 bash 這個程序。

那舉一反三可得知,我們輸入 exit 後,Ubuntu 容器就會進入退出狀態。

root@c4131a4bd1fa:/# exit
exit 

$ docker container list --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS              NAMES
64d52ea0a1.. nginx "/doc.. 31 se.. Up 2.. 0.0.0.0:80->80/tcp hungry..
c4131a4bd1.. ubu.. "bash"  2 min.. Exited                    ubuntu

小結

今天介紹了容器的初始指令,也證實了容器進入退出狀態的原因。

明天開始我們將會進入 Docker 的虛擬網路世界!


上一篇
Day 12 深入 Docker Container 內部 ( 上 )
下一篇
Day 14 Docker 的網路世界 ( 上 )
系列文
用 Docker 了嗎? 30 天的 Docker 基本教學30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言