Docker Certified Associate(DCA)認證考試學習-進入Container環境 Docker Certified Associate(DCA)認證相關資源、Accessing Container Shell、docker run `-d`、`-i`、`-t` 區別

Published on Thursday, February 16, 2023

Container Shell

在這篇文章中: Docker Certified Associate(DCA)認證考試學習-Dockerfile

我們選擇了Ubuntu作為我們的底層,並且透過COPY與CMD指令了解到Docker似乎有辦法把外部的文件複製到Container內部系統並執行
那麼我們有沒辦法手動進入Container內部的系統呢?
有的,在開始之前先準備一下測試環境

首先要進入container內部的首要步驟就是要有一個運行中的container 目前container的狀態總共有以下幾種

  • created
  • restarting
  • running
  • removing
  • paused
  • exited
  • dead

當我們在終端機下docker ps -a命令時可以看到有一個欄位叫做STATUS
內容呢就會是以上狀態列表中的其中一個,其實主要只有正常狀態跟不正常狀態兩種,也就是running跟其他狀態 running狀態會顯示Up + 已經運行的總時間 接下來運行以下命令

docker run -dit ubuntu

這邊注意docker run多帶了三個參數-d-i-t

  • --detach , -d 讓container在背景運行,並且回傳container的ID
  • --interactive , -i 開啟container的STDIN才能接收到我們終端機輸入的命令
  • --tty , -t 分配一個pseudo-TTY(pty)

在解釋之前須要先知道container有兩種,一種是需要長時間運行服務的容器
例如Nginx等web server的服務就是需要在背景監聽端口所以基本上不會停止或有一個結束點
另一種是單次執行的container,有明確的結束點,例如hello-worldimage輸出完內容之後就完成使命可以關閉container了

所以這邊如果像以前一樣直接運行docker run ubuntu只會得到一個馬上關閉的容器,因為我們沒有跟container說該執行甚麼任務,所以container會覺得任務已達成進而直接關閉容器

這邊因為三個參數很常使用,所以依次對他們進行探討

  • docker run -d ubuntu
  • docker run -i ubuntu
  • docker run -t ubuntu
  • docker run -di ubuntu
  • docker run -dt ubuntu
  • docker run -it ubuntu
  • docker run -dit ubuntu

docker run -d ubuntu,這個命令沒有什麼疑問,就是建立起一個container並且要求他在背景運行並回傳ID,成功運行之後馬上結束

[node1] (local) root@192.168.0.18 ~
$ docker run -d ubuntu
e2cbdafdd1a6c1ba8ac7bafbbbd143ac98fedc4646bfc475ed50c4451f2b6be8
[node1] (local) root@192.168.0.18 ~
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                     PORTS     NAMES
e2cbdafdd1a6   ubuntu    "/bin/bash"   4 seconds ago   Exited (0) 3 seconds ago             dazzling_sutherland

docker run -i ubuntu,此命令乍看之下沒有反應,不過這個命令會開啟container的STDIN並且與我們終端機做連結,所以我們輸入的命令會轉送到container內,這邊可以做一下測試

開啟互動模式後直接輸入cat /etc/os-release回傳的結果是ubuntu代表命令有正常轉送到container內並且回傳結果

此時container的狀態是運行中,這邊我們可以輸入exit進行退出,不過隨之container也會關閉

$ docker run -i ubuntu
cat /etc/os-release

PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

docker run -t ubuntu,與傳入-i參數類似,會附加一個模擬的終端機在container,但是因為沒有傳入-i參數就代表沒有開啟STDIN,也就是雖然已經在container內部了但是外面的命令傳不到container裡面

此時container的狀態是運行中,因為沒辦法互動的關係所以沒辦法退出

[node1] (local) root@192.168.0.18 ~
$ docker run -t ubuntu
root@01c433db058e:/# cat /etc/os-release

docker run -di ubuntu,與傳入-i參數類似,但會要求container在背景運行所以不會直接進入互動模式,但比較不同的是此時container是在運行中
並不像只有-d參數那樣會直接關閉,這邊可以使用docker attach <ID>直接附加到container內部

[node1] (local) root@192.168.0.18 ~
$ docker run -di ubuntu
67be2187ad02952d2c066901377afc360b851f5060a2d6a95983e00ee1cae898
$ docker attach 67be

cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

docker run -dt ubuntu,與傳入-t參數類似,但container會在背景運行,不會直接附加
可以使用docker attach <ID>直接附加到container但問題一樣會無法退出


docker run -it ubuntu,傳入-i-t為最常用的,開啟STDIN與模擬的終端機

$ docker run -it ubuntu
root@5dc8827b550a:/# cat /etc/os-release 
PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

docker run -dit ubuntu,與傳入-i-t相同,但是不會直接附加

[node1] (local) root@192.168.0.18 ~
$ docker run -dit ubuntu
d4effa01d867ed52fe5d79ab9500570331a948e7f4d0be2972a6f5c76a664532
[node1] (local) root@192.168.0.18 ~
$ docker attach d4ef
root@d4effa01d867:/# cat /etc/os-release 
PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

Summary

以上為dotnet run常用在附加container的參數分析,可以看出比較實用的只有-itdit,分析過後之後再碰到相同的參數就不會搞混了