大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

Docker教程
Docker安裝
Docker使用
Docker實例

Docker容器

容器是鏡像的運行時實例。正如從虛擬機模板上啟動 VM 一樣,用戶也同樣可以從單個鏡像上啟動一個或多個容器。

虛擬機和容器最大的區別是容器更快并且更輕量級——與虛擬機運行在完整的操作系統之上相比,容器會共享其所在主機的操作系統/內核。

下圖為使用單個 Docker 鏡像啟動多個容器的示意圖。

啟動容器的簡便方式是使用docker container run命令。

該命令可以攜帶很多參數,在其基礎的格式docker container run 中,指定了啟動所需的鏡像以及要運行的應用。

docker container run -it ubuntu /bin/bash則會啟動某個 Ubuntu Linux 容器,并運行 Bash Shell 作為其應用。

如果想啟動 PowerShell 并運行一個應用,則可以使用命令docker container run -it microsoft- /powershell:nanoserver pwsh.exe。

-it 參數可以將當前終端連接到容器的 Shell 終端之上。

容器隨著其中運行應用的退出而終止。其中 Linux 容器會在 Bash Shell 退出后終止,而 Windows 容器會在 PowerShell 進程終止后退出。

一個簡單的驗證方法就是啟動新的容器,并運行 sleep 命令休眠 10s。容器會啟動,然后運行休眠命令,在 10s 后退出。

如果在 Linux 主機(或者在 Linux 容器模式下的 Windows 主機上)運行docker container run alpine:latest sleep 10命令,Shell 會連接到容器 Shell 10s 的時間,然后退出。

可以使用 docker container stop 命令手動停止容器運行,并且使用 docker container start 再次啟動該容器。

如果再也不需要該容器,則使用 docker container rm 命令來刪除容器。

容器和虛擬機

容器和虛擬機都依賴于宿主機才能運行。宿主機可以是筆記本,是數據中心的物理服務器,也可以是公有云的某個實例。

在下面的示例中,假設宿主機是一臺需要運行 4 個業務應用的物理服務器。

在虛擬機模型中,首先要開啟物理機并啟動 Hypervisor 引導程序。一旦 Hypervisor 啟動,就會占有機器上的全部物理資源,如 CPU、RAM、存儲和 NIC。

Hypervisor 接下來就會將這些物理資源劃分為虛擬資源,并且看起來與真實物理資源完全一致。

然后 Hypervisor 會將這些資源打包進一個叫作虛擬機(VM)的軟件結構當中。這樣用戶就可以使用這些虛擬機,并在其中安裝操作系統和應用。

前面提到需要在物理機上運行 4 個應用,所以在 Hypervisor 之上需要創建 4 個虛擬機并安裝 4 個操作系統,然后安裝 4 個應用。當操作完成后,結構如下圖所示。

而容器模型則略有不同。

服務器啟動之后,所選擇的操作系統會啟動。在 Docker 世界中可以選擇 Linux,或者內核支持內核中的容器原語的新版本 Windows。

與虛擬機模型相同,OS 也占用了全部硬件資源。在 OS 層之上,需要安裝容器引擎(如 Docker)。

容器引擎可以獲取系統資源,比如進程樹、文件系統以及網絡棧,接著將資源分割為安全的互相隔離的資源結構,稱之為容器。

每個容器看起來就像一個真實的操作系統,在其內部可以運行應用。按照前面的假設,需要在物理機上運行 4 個應用。

因此,需要劃分出 4 個容器并在每個容器中運行一個應用,如下圖所示。

從更高層面上來講,Hypervisor 是硬件虛擬化(Hardware Virtualization)——Hypervisor 將硬件物理資源劃分為虛擬資源。

容器是操作系統虛擬化(OS Virtualization)——容器將系統資源劃分為虛擬資源。

虛擬機的額外開銷

基于前文所述內容,接下來會著重探討 Hypervisor 模型的一個主要問題。

首先我們的目標是在一臺物理機上運行 4 個業務相關應用。每種模型示例中都安裝了一個操作系統或者 Hypervisor(一種針對虛擬機高度優化后的操作系統)。

虛擬機模型將底層硬件資源劃分到虛擬機當中。每個虛擬機都是包含了虛擬 CPU、虛擬 RAM、虛擬磁盤等資源的一種軟件結構。

因此,每個虛擬機都需要有自己的操作系統來聲明、初始化并管理這些虛擬資源。

但是,操作系統本身是有其額外開銷的。例如,每個操作系統都消耗一點 CPU、一點 RAM、一點存儲空間等。

每個操作系統都需要獨立的許可證,并且都需要打補丁升級,每個操作系統也都面臨被攻擊的風險。

通常將這種現象稱作 OS Tax 或者 VM Tax,每個操作系統都占用一定的資源。

容器模型具有在宿主機操作系統中運行的單個內核。在一臺主機上運行數十個甚至數百個容器都是可能的——容器共享一個操作系統/內核。

這意味著只有一個操作系統消耗 CPU、RAM 和存儲資源,只有一個操作系統需要授權,只有一個操作系統需要升級和打補丁。同時,只有一個操作系統面臨被攻擊的風險。簡言之,就是只有一份 OS 損耗。

在上述單臺機器上只需要運行 4 個業務應用的場景中,也許問題尚不明顯。但當需要運行成百上千應用的時候,就會引起質的變化。

另一個值得考慮的事情是啟動時間。因為容器并不是完整的操作系統,所以其啟動要遠比虛擬機快。

切記,在容器內部并不需要內核,也就沒有定位、解壓以及初始化的過程——更不用提在內核啟動過程中對硬件的遍歷和初始化了。

這些在容器啟動的過程中統統都不需要!唯一需要的是位于下層操作系統的共享內核是啟動了的!最終結果就是,容器可以在 1s 內啟動。唯一對容器啟動時間有影響的就是容器內應用啟動所花費的時間。

這就是容器模型要比虛擬機模型簡潔并且高效的原因了。使用容器可以在更少的資源上運行更多的應用,啟動更快,并且支付更少的授權和管理費用,同時面對未知攻擊的風險也更小。

除了上述的理論基礎之外,接下來請跟隨本書一起使用容器完成一些實戰。

檢查 Docker daemon

通常登錄 Docker 主機后的第一件事情是檢查 Docker 是否正在運行。

$ docker version
Client:
Version: API 17.05.0-ce
version: Go 1.29
version: Git go1.7.5
commit: 89658be
Built: Thu May 4 22:10:54 2017
OS/Arch: linux/amd64

Server:
Version: 17.05.0-ce
API version: 1.29 (minimum version 1.12)
Go version: go1.7.5
Git commit: 89658be
Built: Thu May 4 22:10:54 2017
OS/Arch: linux/amd64
Experimental: false

當命令輸出中包含 Client 和 Server 的內容時,可以繼續下面的操作。如果在 Server 部分中包含了錯誤碼,這表示 Docker daemon 很可能沒有運行,或者當前用戶沒有權限訪問。

如果在 Linux 中遇到無權限訪問的問題,需要確認當前用戶是否屬于本地 Docker UNIX 組。如果不是,可以通過usermod -aG docker 來添加,然后退出并重新登錄 Shell,改動即可生效。

如果當前用戶已經屬于本地 docker 用戶組,那么問題可能是 Docker daemon 沒有運行導致。

根據 Docker 主機的操作系統在下面的內容中選擇一條合適的命令,來檢查 Docker daemon 的狀態。

//使用 Systemd 在 Linux 系統中執行該命令
$ service docker status
docker start/running, process 29393

//使用Systemd在Linux系統中執行該命令
$ systemctl is-active docker
active

//在Windows Server 2016的PowerShell窗口中運行該命令
> Get-Service docker

Status Name DisplayName
------ ---- -----------
Running Docker docker

啟動一個簡單容器

啟動容器的一個簡單的方式是通過 docker container run 命令。

下面的命令啟動了一個簡單的容器,其中運行了容器化版本的 Ubuntu Linux。

Windows 示例。

docker container run -it microsoft/powershell:nanoserver pwsh.exe

命令的基礎格式為:

docker container run  : 

示例中使用 docker container run 來啟動容器,這也是啟動新容器的標準命令。

命令中使用了 -it 參數使容器具備交互性并與終端進行連接。接下來,命令中指定了具體鏡像 ubuntu:latest 或者 microsoft/powershell:nanoserver。

最終,在命令中指定了運行在容器中的程序,Linux 示例中是 Bash Shell,Windows 示例中為 PowerShell。

當敲擊回車鍵之后,Docker 客戶端選擇合適的 API 來調用 Docker daemon。

Docker daemon 接收到命令并搜索 Docker 本地緩存,觀察是否有命令所請求的鏡像。

在上面引用的示例中,本地緩存并未包含該鏡像,所以 Docker 接下來查詢在 Docker Hub 中是否存在對應鏡像。找到該鏡像后,Docker 將鏡像拉取到本地,存儲在本地緩存當中。

在標準的、開箱即用的 Linux 安裝版中,Docker daemon 通過位于 /var/run/docker.sock 的本地 IPC/Unix socket 來實現 Docker 遠程 API;在 Windows 中,Docker daemon 通過監聽名為 npipe:////./pipe/docker_engine 的管道來實現。

通過配置,也可以借助網絡來實現 Docker Client 和 daemon 之間的通信。

Docker 默認非 TLS 網絡端口為 2375,TLS 默認端口為 2376。

一旦鏡像拉取到本地,daemon 就創建容器并在其中運行指定的應用。

如果仔細觀察,就會發現 Shell 提示符發生了變化,說明目前已經位于容器內部了。

在上面的示例中,Shell 提示符已經變為 root@3027eb644874:/#。@ 之后的一長串數字就是容器唯一 ID 的前 12 個字符。

若嘗試在容器內執行一些基礎命令,可能會發現某些指令無法正常工作。這是因為大部分容器鏡像都是經過高度優化的。這意味著某些命令或者包可能沒有安裝。

下面的示例展示了兩個命令,一條執行成功,一條執行失敗。

root@3027eb644874:/# ls -l
total 64
drwxr-xr-x 2 root root 4096 Aug 19 00:50 bin
drwxr-xr-x 2 root root 4096 Apr 12 20:14 boot
drwxr-xr-x 5 root root 380 Sep 13 00:47 dev
drwxr-xr-x 45 root root 4096 Sep 13 00:47 etc
drwxr-xr-x 2 root root 4096 Apr 12 20:14 home
drwxr-xr-x 8 root root 4096 Sep 13 2015 lib
drwxr-xr-x 2 root root 4096 Aug 19 00:50 lib64
drwxr-xr-x 2 root root 4096 Aug 19 00:50 media
drwxr-xr-x 2 root root 4096 Aug 19 00:50 mnt
drwxr-xr-x 2 root root 4096 Aug 19 00:50 opt
dr-xr-xr-x 129 root root 0 Sep 13 00:47 proc
drwx------ 2 root root 4096 Aug 19 00:50 root
drwxr-xr-x 6 root root 4096 Aug 26 18:50 run
drwxr-xr-x 2 root root 4096 Aug 26 18:50 sbin
drwxr-xr-x 2 root root 4096 Aug 19 00:50 srv
dr-xr-xr-x 13 root root 0 Sep 13 00:47 sys
drwxrwxrwt 2 root root 4096 Aug 19 00:50 tmp
drwxr-xr-x 11 root root 4096 Aug 26 18:50 usr
drwxr-xr-x 13 root root 4096 Aug 26 18:50 var

root@3027eb644874:/# ping www.docker.com
bash: ping: command not found

從上面的輸出中可以看出,ping 工具包并不是官方 Ubuntu 鏡像的一部分。

容器進程

在前面啟動 Ubuntu 容器之時,讓容器運行 Bash Shell(/bin/bash)。這使得 Bash Shell 成為容器中運行的且唯一運行的進程??梢酝ㄟ^ps -elf命令在容器內部查看。

root@3027eb644874:/# ps -elf
F S UID 4 PID PPID NI ADDR SZ WCHAN STIME TTY TIME CMD
S root 0 1 0 0 - 4558 wait 00:47 ? 00:00:00 /bin/bash
R root 11 1 0 - 8604 - 00:52 ? 00:00:00 ps -elf

上面的輸出中看起來好像有兩個正在運行的進程,其實并非如此。

列表中 PID 為 1 的進程,是容器被告知要運行的 Bash Shell;第二個進程是 ps -elf 命令產生的,這是個臨時進程,并且在輸出后就已經退出了。也就是說,這個容器當前只運行了一個進程 /bin/bash。

Windows 容器有所不同,通常會運行相當多的進程。

這意味著如果通過輸入 exit 退出 Bash Shell,那么容器也會退出(終止)。

原因是容器如果不運行任何進程則無法存在,殺死 Bash Shell 即殺死了容器唯一運行的進程,導致這個容器也被殺死。

這對于 Windows 容器來說也是一樣的,殺死容器中的主進程,則容器也會被殺死。

按下 Ctrl-PQ 組合鍵則會退出容器但并不終止容器運行。這樣做會切回到 Docker 主機的 Shell,并保持容器在后臺運行。

可以使用 docker container ls 命令來觀察當前系統正在運行的容器列表。

$ docker container ls
CNTNR ID IMAGE COMMAND CREATED STATUS NAMES
302...74 ubuntu:latest /bin/bash 6 mins Up 6mins sick_montalcini

當前容器仍然在運行,并且可以通過 docker container exec 命令將終端重新連接到 Docker,理解這一點很重要。

$ docker container exec -it 3027eb644874 bash
root@3027eb644874:/#

用于重連 Windows Nano Server PowerShell 容器的命令是 docker container exec -it pwsh.exe。

Shell 提示符切換到了容器。這時再次運行 ps 命令,會看到兩個 Bash 或者 PowerShell 進程,這是因為 docker container exec 命令創建了新的 Bash 或者 PowerShell 進程并且連接到容器。

這意味著在當前 Shell 輸入 exit 并不會導致容器終止,因為原 Bash 或者 PowerShell 進程還在運行當中。

輸入 exit 退出容器,并通過命令 docker container ps 來確認容器依然在運行中。果然容器還在運行。

如果在自己的 Docker 主機上運行示例,則需要使用下面兩個命令來停止并刪除容器(需要將 ID 替換為自己容器的 ID)。

$ docker container stop 3027eb64487
3027eb64487

$ docker container rm 3027eb64487
3027eb64487

容器生命周期

人們認為容器不擅長持久化工作或者持久化數據,很大程度上是因為容器在非持久化領域上表現得太出色。

但是在一個領域做得很好并不意味著不擅長其他的領域。很多虛擬機管理員會記得微軟或者 Oracle 告訴他們不能在虛擬機中運行他們的應用,至少他們不會支持這么做。

下面來介紹一下容器的生命周期,從創建、運行、休眠,直至銷毀的整個過程。

前面介紹了如何使用 docker container run 命令來啟動容器。接下來會重新啟動一個新的容器,這樣就可以觀察期完整的生命周期。

下面的示例中會采用 Linux Docker 主機來運行 Ubuntu 容器。但同時,示例內容在前面例子中使用過的 Windows PowerShell 容器中也是生效的。

$ docker container run --name percy -it ubuntu:latest /bin/bash
root@9cb2d2fd1d65:/#

這就是新建的容器,名稱為“percy”,意指持久化(persistent)。

接下來把該容器投入使用,將一部分數據寫入其中。

在新容器內部 Shell 中,執行下面的步驟來將部分數據寫入到 tmp 目錄下的某個文件中,并確認數據是否寫入成功。

root@9cb2d2fd1d65:/# cd tmp

root@9cb2d2fd1d65:/tmp# ls -l
total 0

root@9cb2d2fd1d65:/tmp# echo "DevOps FTW" > newfile

root@9cb2d2fd1d65:/tmp# ls -l
total 4
-rw-r--r-- 1 root root 14 May 23 11:22 newfile

root@9cb2d2fd1d65:/tmp# cat newfile
DevOps FTW

按 Ctrl-PQ 組合鍵退出當前容器。

現在使用 docker container stop 命令來停止容器運行,切換到暫停(vacation)狀態。

$ docker container stop percy
percy

可以在 docker container stop命令中指定容器的名稱或者 ID。具體格式為:

docker container stop <container-id or container-name>

現在運行 docker container ls 命令列出全部處于運行中狀態的容器。

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

新建的容器沒有在上面的列表中出現,原因是讀者通過 docker container stop 命令使該容器停止運行。加上 -a 參數再次運行前面的命令,就會顯示出全部的容器,包括處于停止狀態的。

$ docker container ls -a
CNTNR ID IMAGE COMMAND CREATED STATUS NAMES
9cb...65 ubuntu:latest /bin/bash 4 mins Exited (0) percy

現在可以看到該容器顯示當前狀態為 Exited(0)。停止容器就像停止虛擬機一樣。盡管已經停止運行,容器的全部配置和內容仍然保存在 Docker 主機的文件系統之中,并且隨時可以重新啟動。

使用 docker container start 命令可以將容器重新啟動。

$ docker container start percy
percy

$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
9cb2d2fd1d65 ubuntu:latest "/bin/bash" 4 mins Up 3 secs percy

現在停止的容器已經重新啟動了,此時可以確認之前創建的文件是否還存在。使用 docker container exec 命令連接到重啟后的容器。

$ docker container exec -it percy bash
root@9cb2d2fd1d65:/#

Shell 提示符發生變化,提示正在容器內部空間進行操作。

確認之前創建的文件依然存在,并且文件中仍包含之前寫入的數據。

root@9cb2d2fd1d65:/# cd tmp
root@9cb2d2fd1d65:/# ls -l
-rw-r--r-- 1 root root 14 Sep 13 04:22 newfile
root@9cb2d2fd1d65:/#
root@9cb2d2fd1d65:/# cat newfile
DevOps FTW

像是魔術一般,之前創建的文件依然存在,并且文件中包含的數據正是離開的方式!這證明停止容器運行并不會損毀容器或者其中的數據。

盡管上面的示例闡明了容器的持久化特性,還是需要指出卷(volume)才是在容器中存儲持久化數據的首選方式。

現在停止該容器并從系統中刪除它。

通過在 docker container rm 命令后面添加 -f 參數來一次性刪除運行中的容器是可行的。

但是,刪除容器的最佳方式還是分兩步,先停止容器然后刪除。這樣可以給容器中運行的應用/進程一個停止運行并清理殘留數據的機會。

在下一個示例中會停止 percy 容器,刪除它并確認操作成功。如果讀者終端仍連接到 percy 容器,則需要按下 Ctrl-PQ 組合鍵先返回 Docker 主機終端。

$ docker container stop percy
percy

$ docker container rm percy
percy

$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

現在容器已經刪除了——在系統中消失。如果這是一個有用的容器,那么之后可以作為無服務的工具使用;如果沒有用處,則充其量也就是一個蹩腳的終端。

總結一下容器的生命周期??梢愿鶕枰啻瓮V?、啟動、暫停以及重啟容器,并且這些操作執行得很快。

但是容器及其數據是安全的。直至明確刪除容器前,容器都不會丟棄其中的數據。就算容器被刪除了,如果將容器數據存儲在卷中,數據也會被保存下來。

優雅地停止容器

Linux 世界中,大部分容器都會運行單一進程;在Windows 中可能運行若干個,但是下面的原則對于兩者都適用。

前面的示例中容器正在運行 /bin/bash 應用。當使用 docker container rm -f來銷毀運行中的容器時,不會發出任何告警。

這個過程相當暴力——有點像悄悄接近容器后在腦后突施冷槍。毫無征兆地被銷毀,會令容器和應用猝不及防,來不及“處理后事”。

但是,docker container stop 命令就有禮貌多了(就像用槍指著容器的腦袋然后說“你有 10s 時間說出你的遺言”)。

該命令給容器內進程發送將要停止的警告信息,給進程機會來有序處理停止前要做的事情。一旦 docker stop 命令返回后,就可以使用 docker container rm 命令刪除容器了。

這背后的原理可以通過 Linux/POSIX 信號來解釋。docker container stop 命令向容器內的 PID 1 進程發送了 SIGTERM 這樣的信號。

就像前文提到的一樣,會為進程預留一個清理并優雅停止的機會。如果 10s 內進程沒有終止,那么就會收到 SIGKILL 信號。這是致命一擊。但是,進程起碼有 10s 的時間來“解決”自己。

docker container rm -f 命令不會先友好地發送 SIGTERM,這條命令會直接發出 SIGKILL。就像剛剛所打的比方一樣,該命令悄悄接近并對容器發起致命一擊。

利用重啟策略進行容器的自我修復

通常建議在運行容器時配置好重啟策略。這是容器的一種自我修復能力,可以在指定事件或者錯誤后重啟來完成自我修復。

重啟策略應用于每個容器,可以作為參數被強制傳入 docker-container run 命令中,或者在 Compose 文件中聲明(在使用 Docker Compose 以及 Docker Stacks 的情況下)。

容器支持的重啟策略包括 always、unless-stopped 和 on-failed。

always 策略是一種簡單的方式。除非容器被明確停止,比如通過 docker container stop 命令,否則該策略會一直嘗試重啟處于停止狀態的容器。

一種簡單的證明方式是啟動一個新的交互式容器,并在命令后面指定 --restart always 策略,同時在命令中指定運行 Shell 進程。

當容器啟動的時候,會登錄到該 Shell。退出 Shell 時會殺死容器中 PID 為 1 的進程,并且殺死這個容器。

但是因為指定了 --restart always 策略,所以容器會自動重啟。如果運行 docker container ls 命令,就會看到容器的啟動時間小于創建時間。下面請看示例。

$ docker container run --name neversaydie -it --restart always alpine sh

//等待幾秒后輸入exit

/# exit

$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS
0901afb84439 alpine "sh" 35 seconds ago Up 1 second

注意,容器于 35s 前被創建,但卻在 1s 前才啟動。這是因為在容器中輸入退出命令的時候,容器被殺死,然后 Docker 又重新啟動了該容器。

--restart always 策略有一個很有意思的特性,當 daemon 重啟的時候,停止的容器也會被重啟。

例如,新創建一個容器并指定 --restart always 策略,然后通過 docker container stop命令停止該容器。

現在容器處于 Stopped (Exited) 狀態。但是,如果重啟 Docker daemon,當 daemon 啟動完成時,該容器也會重新啟動。

always 和 unless-stopped 的最大區別,就是那些指定了 --restart unless-stopped 并處于 Stopped (Exited) 狀態的容器,不會在 Docker daemon 重啟的時候被重啟。

下面創建兩個新容器,其中“always”容器指定 --restart always 策略,另一個“unless- stopped”容器指定了 --restart unless-stopped 策略。

兩個容器均通過 docker container stop 命令停止,接著重啟 Docker。結果“always”容器會重啟,但是“unless-stopped”容器不會。

⒈ 創建兩個新容器

$ docker container run -d --name always \
--restart always \
alpine sleep 1d

$ docker container run -d --name unless-stopped \
--restart unless-stopped \
alpine sleep 1d

$ docker container ls
CONTAINER ID IMAGE COMMAND STATUS NAMES
3142bd91ecc4 alpine "sleep 1d" Up 2 secs unless-stopped
4f1b431ac729 alpine "sleep 1d" Up 17 secs always

現在有兩個運行的容器了。一個叫作“always”,另一個叫作“unless-stopped”。

⒉ 停止兩個容器

$ docker container stop always unless-stopped

$ docker container ls -a
CONTAINER ID IMAGE STATUS NAMES
3142bd91ecc4 alpine Exited (137) 3 seconds ago unless-stopped
4f1b431ac729 alpine Exited (137) 3 seconds ago always

⒊ 重啟 Docker

重啟 Docker 的過程在不同的操作系統上可能不同。下面介紹一下如何在 Linux 上使用 systemd 重啟 Docker,在 Windows Server 2016 上可以使用 restart-service 重啟。

$ systemlctl restart docker

⒋ 一旦 Docker 重啟成功,檢查兩個容器的狀態

$ docker container ls -a
CONTAINER CREATED STATUS NAMES
314..cc4 2 minutes ago Exited (137) 2 minutes ago unless-stopped
4f1..729 2 minutes ago Up 9 seconds always

注意到“always”容器(啟動時指定了 --restart always 策略)已經重啟了,但是“unless-stopped”容器(啟動時指定了 --restart unless-stopped 策略)并沒有重啟。

on-failure 策略會在退出容器并且返回值不是 0 的時候,重啟容器。

就算容器處于 stopped 狀態,在 Docker daemon 重啟的時候,容器也會被重啟。

如果讀者使用 Docker Compose 或者 Docker Stack,可以在 service 對象中配置重啟策略,示例如下。

version: "3.5"
services:
myservice:
<Snip>
restart_policy:
condition: always | unless-stopped | on-failure

Web 服務器示例

到目前為止,已經介紹了如何啟動一個簡單的容器,并與其進行交互。同時也知道了如何停止、重啟以及刪除一個容器?,F在來看一個 Linux Web 服務器示例。

在該示例中,會使用到 Pluralsight 視頻教程網站中的一個鏡像。這個鏡像會在 8080 端口啟動一個相當簡單的 Web 服務。

使用 docker container stop 以及 docker container rm 命令清理當前系統中的全部容器,然后運行下面的 docker container run 命令。

$ docker container run -d --name webserver -p 80:8080 \
nigelpoulton/pluralsight-docker-ci

Unable to find image 'nigelpoulton/pluralsight-docker-ci:latest' locally
latest: Pulling from nigelpoulton/pluralsight-docker-ci
a3ed95caeb02: Pull complete
3b231ed5aa2f: Pull complete
7e4f9cd54d46: Pull complete
929432235e51: Pull complete
6899ef41c594: Pull complete
0b38fccd0dab: Pull complete
Digest: sha256:7a6b0125fe7893e70dc63b2...9b12a28e2c38bd8d3d
Status: Downloaded newer image for nigelpoulton/plur...docker-ci:latest
6efa1838cd51b92a4817e0e7483d103bf72a7ba7ffb5855080128d85043fef21

注意,當前 Shell 提示符并未發生變化。這是因為使用了 -d 參數啟動容器,并在后臺運行。這種后臺啟動的方式不會將當前終端連接到容器當中。

該示例在 docker container run命令中拋出了一些額外的參數,一起來快速了解一下。

已經知道 docker container run 會啟動一個新容器,但是這次使用 -d 參數替換了 -it。-d 表示后臺模式,告知容器在后臺運行。

然后為容器命名,并且指定了 -p 80:8080。-p 參數將 Docker 主機的端口映射到容器內。

本例中,將 Docker 主機的 80 端口映射到了容器內的 8080 端口。這意味著當有流量訪問主機的 80 端口的時候,流量會直接映射到容器內的 8080 端口。

之所以如此是因為當前使用的鏡像,其 Web 服務監聽了 8080 端口。這意味著容器啟動時會運行一個 Web 服務,監聽 8080 端口。

最終,命令中還指定 Docker 所使用的鏡像:nigelpoulton/pluralsight-docker-ci。這個鏡像不一定保持更新,并且可能存在缺陷。

使用 docker container ls 命令可以查看當前運行的容器以及端口的映射情況。端口信息按照 host-port:container-port 的格式顯示,明確這一點很重要。

$ docker container ls
CONTAINER ID COMMAND STATUS PORTS NAMES
6efa1838cd51 /bin/sh -c... Up 2 mins 0.0.0.0:80->8080/tcp webserver

為了提高可讀性,上面輸出中的部分列并未展示。

現在容器已經運行,端口也映射成功,可以通過瀏覽器來訪問該容器,需要在瀏覽器中指定 Docker 主機的 IP 地址或 DNS 名稱,端口號是 80。下圖展示了由容器服務提供的網頁。

docker container stop、docker container pause、docker container start 和 docker container rm命令同樣適用于容器。

同時,持久性的規則也適用于容器——停止或暫停容器并不會導致容器銷毀,或者內部存儲的數據丟失。

查看容器詳情

在前面的示例當中,讀者可能發現當運行docker container run 命令的時候,并沒有指定容器中的具體應用。但是容器卻啟動了一個簡單的 Web 服務。這是如何發生的?

當構建 Docker 鏡像的時候,可以通過嵌入指令來列出希望容器運行時啟動的默認應用。如果運行 docker image inspect 命令來查看運行容器時使用的鏡像,就能看到容器啟動時將要運行的應用列表了。

$ docker image inspect nigelpoulton/pluralsight-docker-ci
[
{
"Id": "sha256:07e574331ce3768f30305519...49214bf3020ee69bba1",
"RepoTags": [
  "nigelpoulton/pluralsight-docker-ci:latest"

  <Snip>

],
"Cmd": [
  "/bin/sh",
  "-c",
  "#(nop) CMD [\"/bin/sh\" \"-c\" \"cd /src \u0026\u0026 node \
  .app.js\"]"
],
<Snip>

為了方便閱讀,僅截取輸出內容中我們感興趣的部分。

Cmd 一項中展示了容器將會執行的命令或應用,除非在啟動的時候讀者指定另外的應用。如果去掉示例腳本中的轉義字符,可以得到這樣的命令:/bin/sh -c "cd /src && node ./app.js。這是基于該鏡像的容器會默認運行的應用。

在構建鏡像時指定默認命令是一種很普遍的做法,因為這樣可以簡化容器的啟動。

這也為鏡像指定了默認的行為,并且從側面闡述了鏡像的用途——可以通過 Inspect 鏡像的方式來了解所要運行的應用。

快速清理

接下來了解一種簡單且快速的清理 Docker 主機上全部運行容器的方法。

這種處理方式會強制刪除所有的容器,并且不會給容器完成清理的機會。

這種操作一定不能在生產環境系統或者運行著重要容器的系統上執行。

在 Docker 主機的 Shell 中運行下面的命令,可以刪除全部容器。

$()

在本例中,因為只有一個運行中的容器,所以只有一個容器被刪除(6efa1838cd51)。

但是該命令的工作方式,就跟前面章節中用于刪除某臺 Docker 主機上全部容器的命令 rm $(docker image ls -q) 一樣,docker container rm 命令會刪除容器。

如果將 $(docker container ls -aq) 作為參數傳遞給 docker container rm 命令,等價于將系統中每個容器的 ID 傳給該命令。

-f 標識表示強制執行,所以即使是處于運行狀態的容器也會被刪除。接下來,無論是運行中還是停止的容器,都會被刪除并從系統中移除。

上面的命令在 Windows Docker 主機的 PowerShell 終端內同樣生效。

全部教程
主站蜘蛛池模板: 国内精品久久久久影院网站 | 久久九九精品一区二区 | 欧美a视频在线观看 | 国内精品久久久久久 | 在线观看自拍视频 | 亚洲免费毛片 | 欧美日韩高清一区二区三区 | 精品中文字幕在线 | 三级a做爰大乳在线观看 | 欧美成人精品不卡视频在线观看 | 日韩不卡视频在线观看 | 亚洲日本va中文字幕婷婷 | 久久成人免费观看草草影院 | a拍拍男女免费看全片 | 欧美成人aaa大片 | 奇米4色| 伊人久久精品一区二区三区 | 免费特黄一级欧美大片 | 久久夜色精品国产尤物 | 深夜成人在线 | 一区二区三区在线观看免费 | 国产亚洲在线观看 | 国产综合欧美 | 午夜剧场在线观看 | 狠狠色婷婷丁香综合久久韩国 | 天天综合欧美 | 国四虎影永久 | 色综合天天操 | 亚洲国产欧洲综合997久久 | 草操影院| 久久网综合 | 67194老司机精品午夜 | 精久久 | 亚洲精国产一区二区三区 | 国产精品一级视频 | 国产成年女一区二区三区 | 人与禽交免费网站视频 | 久久精品视频8 | 成人小视频免费 | 国产婷婷高清在线观看免费 | 久久香蕉国产线看精品 |