Linux 下的 Docker 入門教程
面向初學者的 Docker 基本命令指南。
這篇詳細的 Docker 教程覆蓋了核心的 Docker 命令,比如,如何創建新容器、運行容器、刪除容器等。另外,這篇教程也解釋了如何從已有的容器構建你自己的 Docker 鏡像,如何移除容器和鏡像。言歸正傳,現在開始 Docker 的基本用法。
Docker 安裝步驟
大多數現代 Linux 操作系統都可以安裝 Docker。如果還沒安裝過 Docker,請參考下面的步驟:
- 在 AlmaLinux、CentOS、Rocky Linux 上 安裝 Docker Engine 和 Docker Compose
- 如何在 Ubuntu 上 安裝 Docker 和 Docker Compose
什麼是 Docker 鏡像和 Docker 容器?
在開始 Docker 之前,我先說明一下 Docker 鏡像和 Docker 容器是什麼。
Docker 鏡像是一個描述容器如何運行的的文件,Docker 容器是 Docker 鏡像在運行或被終止時的一個階段。
容器和主機上的其他文件是隔離的。
當我們運行一個 Docker 容器的時候,它會使用一個被隔離出來的文件系統,這個文件系統是由一個 Docker 鏡像提供的。Docker 鏡像包含了運行應用程序所需要的一切東西 - 所有的依賴、配置、腳本、二進位文件等等。
鏡像也包含容器所需要的其他配置項,比如說環境變數、默認運行的命令,以及其他元數據。
Linux 下的 Docker 入門
下面的所有步驟都已在 Ubuntu 22.04、20.04 以及 18.04 LTS 伺服器版本中測試通過。後續小節中提供的步驟對於所有 Linux 平台都是通用的。比如,在基於 RHEL 的系統中(比如 AlmaLinux)可以運行相同的命令。
1、搜索 Docker 鏡像
我們可以從叫做 Docker hub 的 Docker 官方庫獲得鏡像,或者我們也可以製作自己的鏡像。
有些人可能不清楚,Docker hub 是一個線上的中心化倉庫,Docker 用戶們在上面構建、測試、然後保存他們的 Docker 鏡像。Docker hub 有數以萬計的 Docker 鏡像,而且這個數字還在每天增長。
你可以從命令行通過 `docker search
命令搜索任意 Docker 鏡像。
比如要搜索基於 Alpine Linux 的 Docker 鏡像,運行:
$ sudo docker search alpine
輸出結果:
搜索基於 Ubuntu 的鏡像,運行:
$ sudo docker search ubuntu
你還可以搜索其他任意的應用,比如 Nginx,像下面這樣:
$ sudo docker search nginx
Docker hub 有各種各樣的鏡像。你能在 Docker hub 上找到各種已構建好的 Docker 鏡像,比如說操作系統、應用,或者多個應用的合體(比如 LAMP 棧)。
如果你找的東西不在上面,你還可以構建一個鏡像,然後通過 Docker hub 向其他人開放,或者只是自己用。
2、下載 Docker 鏡像
從終端運行下面的命令可以下載 Ubuntu OS 的 Docker 鏡像:
$ sudo docker pull ubuntu
上面的這個命令會從 Docker hub 下載最新的 Ubuntu 鏡像。
輸出結果:
Using default tag: latest
latest: Pulling from library/ubuntu
405f018f9d1d: Pull complete
Digest: sha256:b6b83d3c331794420340093eb706a6f152d9c1fa51b262d9bf34594887c2c7ac
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
你也可以用下面的命令下載指定版本的 Ubuntu 鏡像:
$ sudo docker pull ubuntu:20.04
Docker 允許我們下載任何鏡像,並且在那個鏡像上創建容器,這些操作與主機的操作系統無關。
比如要下載 Alpine 系統的鏡像,運行:
$ sudo docker pull alpine
3、列出 Docker 鏡像
所有已下載的 Docker 鏡像都保存在 /var/lib/docker
路徑下。
要查看所有已下載的 Docker 鏡像,運行:
$ sudo docker images
輸出結果:
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 27941809078c 3 weeks ago 77.8MB
ubuntu 20.04 20fffa419e3a 3 weeks ago 72.8MB
alpine latest e66264b98777 5 weeks ago 5.52MB
從上面可以看出來,我已經下載了三個 Docker 鏡像 - Ubuntu latest、Ubuntu 20.04 和 Alpine Linux。
現在,我們看一下接下來如何從下載的鏡像啟動或者運行容器。
4、運行 Docker 容器
有兩種方法我們可以啟動一個容器 - 使用 Docker 鏡像的 標籤 或者 鏡像 ID 。
標籤指的是一個特定的鏡像快照, 鏡像 ID 是那個鏡像對應的唯一識別碼。
可以查看下面這個截圖:
從上面的解脫可以看到,標籤是 latest
和 20.04
。
27941809078c
是 Ubuntu latest 的 Docker 鏡像的鏡像 ID,20fffa419e3a
是 Ubuntu 20.04 的 Docker 鏡像的鏡像 ID,- 而
e66264b98777
是 Alpine latest 的 Docker 鏡像的鏡像 ID。
4.1、使用標籤運行容器
下載選擇好的 Docker 鏡像後,運行下面的命令來啟動 Docker 容器,並且通過它的標籤進行連接。
$ sudo docker run -t -i ubuntu:latest /bin/bash
或者,
$ sudo docker run -it ubuntu:latest /bin/bash
這裡,
-t
:在 Ubuntu 容器內分配一個偽終端。-i
:通過從容器獲取一個標準輸入(STDIN),允許我們創建一個可交互的連接。ubuntu:latest
:標籤為latest
的 Ubuntu Docker 鏡像。/bin/bash
:新容器的 BASH shell。這個是可選項。如果你不加 shell 的話,會分配默認的 shell 給容器。
啟動容器後,會自動進入容器的 shell(命令行):
基於最新 Ubuntu 鏡像的容器現在已經啟動了。所有的新容器都會被賦予一個名字和唯一的 ID。從上面的輸出可以看到,那個 Ubuntu 容器的 ID 是 2f2a5b826762
。一會兒我們會看到從哪找到容器的名字。
現在就可以在容器裡面工作了。當你完成容器內的工作後,你可以回到主機操作系統的終端(在我這個例子中,操作系統是 Ubuntu 22.04 LTS)而不需要關掉容器(客戶機)。
4.2、從運行中的容器中脫離
使用 CTRL+P
然後 CTRL+Q
就可以從運行中的容器脫離(不需要關閉)。
現在,你就回到了你原來的主機的終端窗口。請注意,容器還在後台運行中,我們並沒有關掉它。
4.3、使用鏡像 ID 運行容器
另一種啟動容器並且連接進去的方式是通過使用鏡像 ID,像下面這樣:
$ sudo docker run -it 20fffa419e3a /bin/bash
這裡,
20fffa419e3a
- 鏡像 ID
按 CTRL+P
然後 CTRL+Q
可以從當前容器中脫離回到主機系統的終端。我們只是從容器中脫離,但是沒有讓它停止。容器仍然在後台運行中。
4.4. 在脫離模式中運行容器
在前面的小結中,我們啟動了一個容器並且立刻連接了進去。然後當容器中的工作結束後,我們從容器中脫離了出來。
你也可以在脫離模式(不需要自動連接進去)中啟動容器。
在後台運行一個容器,輸入命令:
$ sudo docker run -it -d alpine:latest
輸出結果:
d74f2ceb5f3ad2dbddb0b26e372adb14efff91e75e7763418dbd12d1d227129d
上面輸出結果的前 12 字元代表的是容器的 ID。
通過 docker ps
命令,你可以驗證容器是否在運行:
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d74f2ceb5f3a alpine:latest "/bin/sh" 3 seconds ago Up 2 seconds zen_pascal
從上面個的輸出結果中可以看到,我們創建了一個 Alpine 容器,但是還沒有連接進去。
如果你想連接進去,很簡單,運行:
$ sudo docker attach d74f2ceb5f3a
5、查看運行中的容器
查看運行中的容器,運行下面的命令:
$ sudo docker ps
輸出結果:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7e04eed577e 20fffa419e3a "/bin/bash" 6 minutes ago Up 6 minutes brave_mclean
2f2a5b826762 ubuntu:latest "/bin/bash" 18 minutes ago Up 18 minutes hungry_leavitt
這裡,
f7e04eed577e
是由鏡像2f2a5b826762
創建的 Ubuntu 容器的 ID。並且,brave_mclean
是這個容器的名字。2f2a5b826762
是由鏡像 「ubuntu:latest」 創建的 Ubuntu 容器的 ID。並且,hungry_leavitt
是這個容器的名字。
當一個新容器被創建後,會賦給它一個唯一的 ID 和名字,這樣我們就能通過它的 ID 和名字來連接它。
注意:請注意容器 ID 和 Docker 鏡像 ID 是不同的。
列出所有可用的(運行或者停止)容器,運行:
$ sudo docker ps -a
6、從運行中的容器脫離或連接
首先,通過 docker ps
命令找到容器的 ID。
$ sudo docker ps
然後,運行 docker attach
命令連接到運行中的容器。
$ sudo docker attach <container-id>
比如像下面這樣,我要連接到 ID 為 f7e04eed577e
的容器:
$ sudo docker attach f7e04eed577e
你也可以通過使用它的名字連接到一個容器。
$ sudo docker attach brave_mclean
現在你就登錄到這個容器了。
想要從容器脫離,只要按 CTRL+P
然後 CTRL+Q
。
7、啟動、重啟、暫停和終止容器
你可以使用容器的名字或 ID 來啟動,重啟,暫停或者終止一個 Docker 容器。
首先,通過 docker ps -a
命令找到容器的名字或 ID。
現在,通過使用 docker start
命令,加上名字或 ID,你可以啟動一個容器,像下面這樣:
$ sudo docker start modest_cray
$ sudo docker start 10615254bb45
用空格隔開,就可以啟動多個容器,像下面這樣:
$ sudo docker start 24b5ee8c3d3a 56faac6d20ad d74f2ceb5f3a
優雅的重啟一個運行中的容器,運行:
$ sudo docker start 10615254bb45
暫停一個運行中的容器:
$ sudo docker pause 10615254bb45
把暫停的容器恢復過來:
$ sudo docker unpause 10615254bb45
直到其它容器都停止前,阻塞一個容器:
$ sudo docker wait 10615254bb45
我們可以很容易地通過使用它的名字或 ID 來終止一個容器。如果你已經在容器的 shell 里了,只需要運行下面的命令就可以非常簡單的終止:
# exit
你也可以使用下面的命令從 Docker 的主機系統中終止(關閉容器)容器:
$ sudo docker stop 10615254bb45
用空格隔開,你可以退出多個容器,像下面這樣。
$ sudo docker stop 35b5ee8c3d3a 10615254bb45
在退出容器之後,通過列出所有容器的命令來確保它確實被終止了:
$ sudo docker ps
8、強行關閉 Docker 容器
docker stop
命令可以非常優雅的關掉運行中的容器。有時候,你可能卡在一個沒有響應的容器,或者你想強制關掉容器。
通過給一個運行中的容器發送 SIGKILL
來強行關閉容器,運行:
$ sudo docker kill 10615254bb45
9、在關閉容器後自動刪除他們
也許你想測試一個容器,然後當你完成在容器中的工作就把它刪掉。如果是這樣,通過使用 --rm
標籤在關閉後自動刪掉容器:
$ sudo docker run -it --rm debian:latest
當你從容器中退出,它會自動被刪掉。
從上面的結果可以看到,我先創建了一個新的 Debian 容器。當我退出這個容器的時候,它就被自動刪掉了。docker ps -a
命令的輸出結果顯示,Debian 容器現在不存在。
10、給容器命名
如果你再看一下之前命令的輸出結果,當你啟動一個容器的時候,每個容器都被賦予了一個隨機的名字。如果你不命名你的容器,Docker 會自動替你給他們命名。
現在看一下下面的例子:
$ sudo docker run -it -d alpine:latest
2af79e97a825c91bf374b4862b9e7c22fc22acd1598005e8bea3439805ec335d
$ sudo docker run -it -d alpine:latest
80b53b7e661d33696b65c78267fc3f067b6100799c925910db4721963e3fae0a
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
80b53b7e661d alpine:latest "/bin/sh" 3 seconds ago Up 2 seconds bold_margulis
2af79e97a825 alpine:latest "/bin/sh" 6 seconds ago Up 5 seconds recursing_taussig
從上面的結果可以看到,儘管我用同一個 Docker 鏡像創建了兩個容器,它們獲得了不同的 ID 和名字。
如果你想給容器賦一個不變的名字,使用 --name
標籤,像下面這樣:
$ sudo docker run -it -d --name ostechnix_alpine alpine:latest
上面的命令會在脫離模式中創建一個叫做 ostechnix_alpine
的新容器。
我們看一下當前運行的容器列表:
$ sudo docker ps
輸出結果:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
397111fac537 alpine:latest "/bin/sh" 2 seconds ago Up 2 seconds ostechnix_alpine
80b53b7e661d alpine:latest "/bin/sh" 7 minutes ago Up 7 minutes bold_margulis
2af79e97a825 alpine:latest "/bin/sh" 7 minutes ago Up 7 minutes recursing_taussig
注意到上面輸出結果中的第一個容器的名字了嗎?對了,我們給這個容器分配了一個自定義的名字(也就是 ostechnix_alpine
)。
給容器分配自定義的名字可以給我們帶來其他好處。只要看一下容器的名字,我們就能很容易的確定那個容器裡面安裝了什麼。
11、構建自定義 Docker 鏡像
Docker 不僅僅是下載和使用已存在的容器。你也可以創建自己的自定義 Docker 鏡像。
現在我們開始一個 Ubuntu 容器:
$ sudo docker run -it ubuntu:latest
現在,你會進入到容器的 shell。
然後,在容器中,你可以安裝任何的軟體或者做你想做的事情。
比如,我們在容器中安裝 Apache Web 伺服器。
# apt update
# apt install apache2
相似地,在容器中,可以根據自己的需要安裝和測試軟體。
完成以後,從容器脫離(不要退出)回到主機系統的 shell。不要終止或者關閉容器。使用 CTRL+P
然後 CTRL+Q
從容器中脫離,這樣不會關閉容器。
在你的 Docker 主機的終端,運行下面的命令來找到容器 ID:
$ sudo docker ps
最後,創建一個當前運行中的容器的 Docker 鏡像,使用命令:
$ sudo docker commit 377e6d77ebb5 ostechnix/ubuntu_apache
輸出結果:
sha256:bc5e5f95ca592a3585fda2c5a40ec30c98e292046ef70390a2c3b7863cc6f7c1
這裡,
377e6d77ebb5
– Ubuntu 容器的 ID。ostechnix
– 創建容器的用戶的名字。ubuntu_apache
– 用戶ostechnix
創建的 Docker 鏡像的名字。
現在我們查看一下新的 Docker 鏡像是否被創建了,使用下面的命令:
$ sudo docker images
輸出結果:
ostechnix/ubuntu_apache
從上面給的結果中可以看到,從運行中的容器創建的新 Docker 鏡像已經在我們的 Docker 主機系統中了。
現在你就可以從這個新的 Docker 鏡像創建行容器了,用之前的命令:
$ sudo docker run -it ostechnix/ubuntu_apache
12、移除容器
當你在 Docker 容器中完成所有開發後,如果你不需要它們了,你可以刪掉它們。
為此,首先我們需要終止(關閉)運行中的容器。
用這個命令來看一下運行中的容器:
$ sudo docker ps
輸出結果:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
377e6d77ebb5 ubuntu:latest "bash" 7 minutes ago Up 7 minutes elegant_beaver
通過使用它的 ID 來終止運行中的容器:
$ sudo docker stop 377e6d77ebb5
現在,使用這個命令刪除容器:
$ sudo docker rm 377e6d77ebb5
同樣,如果不再需要所有的容器,關閉並刪除它們。
一個一個的刪除多個容器會是一項繁瑣的工作。所以,我們可以把所有停止的容器一次性刪掉,運行:
$ sudo docker container prune
敲 Y
然後回車鍵,這些容器就被刪掉了。
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
397111fac5374921b974721ee646b2d5fbae61ca9c6e8b90fbf47952f382a46b
80b53b7e661d33696b65c78267fc3f067b6100799c925910db4721963e3fae0a
[...]
Total reclaimed space: 176B
這個命令只有在最新版中有效。
使用下面的命令來驗證是否所有容器都被刪除了:
$ sudo docker ps -a
如果看不到任何結果,說明所有容器被刪掉了。
13、刪除 Docker 鏡像
記住,在刪除所有鏡像之前,首先要刪掉所有從那些鏡像創建的容器。
當你刪掉容器後,你可以刪掉你不需要的 Docker 鏡像。
列出所有下載的 Docker 鏡像:
$ sudo docker images
輸出結果:
REPOSITORY TAG IMAGE ID CREATED SIZE
ostechnix/ubuntu_apache latest bc5e5f95ca59 14 minutes ago 229MB
debian latest d2780094a226 11 days ago 124MB
ubuntu latest 27941809078c 3 weeks ago 77.8MB
ubuntu 20.04 20fffa419e3a 3 weeks ago 72.8MB
alpine latest e66264b98777 5 weeks ago 5.52MB
從上面可以看到,在我們的主機上有 5 個 Docker 鏡像。
通過使用鏡像 ID 來刪掉它們:
$ sudo docker rmi ce5aa74a48f1
輸出結果:
Untagged: ostechnix/ubuntu_apache:latest
Deleted: sha256:bc5e5f95ca592a3585fda2c5a40ec30c98e292046ef70390a2c3b7863cc6f7c1
Deleted: sha256:a8e4797160a2b2d33d8bd1bd67e008260c022b3a53fbcc198b2b74d9eae5961d
同樣,刪除其他所有 Docker 鏡像。
刪掉所有未運行的容器、所有鏡像、構建的緩存、所有網路,運行:
$ sudo docker system prune -a
使用這個命令的時候要注意,它會刪掉所有沒有使用的容器、網路、鏡像(包括 掛起 和 未使用 的)
默認情況下,即使當前沒有容器在使用 磁碟卷 ,為防止重要數據被刪除,磁碟卷也不會被刪除。
如果你想刪掉所有東西,包括分配的卷,使用 --volumes
標籤。
$ sudo docker system prune -a --volumes
Docker 問題匯總
如果 Docker 鏡像正在被運行或停止的容器使用,Docker 不會允許你刪除這些鏡像。
比如,當我嘗試從一個以前的 Ubuntu 伺服器上刪除 ID 為 b72889fa879c
的 Docker 鏡像。我會得到下面的錯誤:
Error response from daemon: conflict: unable to delete b72889fa879c (must be forced) - image is being used by stopped container dde4dd285377
這是因為你想刪除的 Docker 鏡像正在被另一個容器使用。
所以,我們先查看一下運行中的容器,使用命令:
$ sudo docker ps
輸出結果:
噢,沒有運行中的容器。
我們在看一下所有的容器(運行和停止的),用這個命令:
$ sudo docker ps -a
輸出結果:
可以看到,仍然有停止的容器在使用其中一個 Docker 鏡像。所以,我們先把所有容器刪掉。
比如:
$ sudo docker rm 12e892156219
類似地,向上面那樣,用對應容器的 ID 將它們都刪除。
當把所有容器刪掉後,移除掉 Docker 鏡像。
比如:
$ sudo docker rmi b72889fa879c
就這麼簡單。現在確認是否還有其他 Docker 鏡像在主機上,使用命令:
$ sudo docker images
你現在應該不再有任何 docker 鏡像了。
總結
在這篇全面的 Docker 入門教程中,我們解釋了 Docker 的基本操作,比如創建、運行、搜索、刪除容器,還有從 Docker 鏡像構建你自己的容器。同時,我們也解釋了如何在不需要 Docker 容器和鏡像的時候刪除它們。
希望你現在對 Docker 的使用 有一個基本的了解。
更多細節,請參考這篇教程最下面的官方資源鏈接,或者在下面的評論區進行評論。
相關資料
via: https://ostechnix.com/getting-started-with-docker/
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive